From e50a8c8435e0c80e3b9881f58e335305d1c1e366 Mon Sep 17 00:00:00 2001 From: Stefan Pintilie Date: Wed, 29 Jun 2022 14:33:08 -0500 Subject: [PATCH] [GlobalMerge] Ensure that the MustKeepGlobalVariables has all globals from each landingpad clause. The filter clause in the landingpad may not have a GlobalVariable operand. It may instead have a ConstantArray of operands and each operand within this ConstantArray should also be checked to see if it is a GlobalVariable. This patch add the check for the ConstantArray as well as a debug message that outputs the contents of MustKeepGlobalVariables. Reviewed By: lei, amyk, scui Differential Revision: https://reviews.llvm.org/D128287 --- llvm/lib/CodeGen/GlobalMerge.cpp | 14 ++++++ llvm/test/Transforms/GlobalMerge/eh-filter.ll | 69 +++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 llvm/test/Transforms/GlobalMerge/eh-filter.ll diff --git a/llvm/lib/CodeGen/GlobalMerge.cpp b/llvm/lib/CodeGen/GlobalMerge.cpp index bbd9006..f5833d3 100644 --- a/llvm/lib/CodeGen/GlobalMerge.cpp +++ b/llvm/lib/CodeGen/GlobalMerge.cpp @@ -592,6 +592,13 @@ void GlobalMerge::setMustKeepGlobalVariables(Module &M) { if (const GlobalVariable *GV = dyn_cast(U->stripPointerCasts())) MustKeepGlobalVariables.insert(GV); + else if (const ConstantArray *CA = dyn_cast(U->stripPointerCasts())) { + for (const Use &Elt : CA->operands()) { + if (const GlobalVariable *GV = + dyn_cast(Elt->stripPointerCasts())) + MustKeepGlobalVariables.insert(GV); + } + } } } } @@ -609,6 +616,13 @@ bool GlobalMerge::doInitialization(Module &M) { bool Changed = false; setMustKeepGlobalVariables(M); + LLVM_DEBUG({ + dbgs() << "Number of GV that must be kept: " << + MustKeepGlobalVariables.size() << "\n"; + for (auto KeptGV = MustKeepGlobalVariables.begin(); + KeptGV != MustKeepGlobalVariables.end(); KeptGV++) + dbgs() << "Kept: " << **KeptGV << "\n"; + }); // Grab all non-const globals. for (auto &GV : M.globals()) { // Merge is safe for "normal" internal or external globals only diff --git a/llvm/test/Transforms/GlobalMerge/eh-filter.ll b/llvm/test/Transforms/GlobalMerge/eh-filter.ll new file mode 100644 index 0000000..95b5141 --- /dev/null +++ b/llvm/test/Transforms/GlobalMerge/eh-filter.ll @@ -0,0 +1,69 @@ +; RUN: opt -global-merge -debug-only=global-merge -S -o - %s 2>&1 | FileCheck %s + +;; Checks from the debug info. +; CHECK: Number of GV that must be kept: 5 +; CHECK-NEXT: Kept: @_ZTIi = external constant ptr +; CHECK-NEXT: Kept: @_ZTIf = external constant ptr +; CHECK-NEXT: Kept: @_ZTId = external constant ptr +; CHECK-NEXT: Kept: @_ZTIc = external constant ptr +; CHECK-NEXT: Kept: @_ZTIPi = external constant ptr + +;; Check that the landingpad, catch and filter have not changed. +; CHECK: %0 = landingpad { ptr, i32 } +; CHECK-NEXT: catch ptr @_ZTIi +; CHECK-NEXT: filter [5 x ptr] [ptr @_ZTIi, ptr @_ZTIf, ptr @_ZTId, ptr @_ZTIc, ptr @_ZTIPi] + +@_ZTIi = external constant ptr +@_ZTIf = external constant ptr +@_ZTId = external constant ptr +@_ZTIc = external constant ptr +@_ZTIPi = external constant ptr + +define noundef signext i32 @_Z6calleri(i32 noundef signext %a) local_unnamed_addr personality ptr @__xlcxx_personality_v1 { +entry: + invoke void @_Z16callee_can_throwi(i32 noundef signext %a) + to label %return unwind label %lpad + +lpad: ; preds = %entry + %0 = landingpad { ptr, i32 } + catch ptr @_ZTIi + filter [5 x ptr] [ptr @_ZTIi, ptr @_ZTIf, ptr @_ZTId, ptr @_ZTIc, ptr @_ZTIPi] + %1 = extractvalue { ptr, i32 } %0, 0 + %2 = extractvalue { ptr, i32 } %0, 1 + %3 = tail call i32 @llvm.eh.typeid.for(ptr nonnull @_ZTIi) + %matches = icmp eq i32 %2, %3 + br i1 %matches, label %catch, label %filter.dispatch + +filter.dispatch: ; preds = %lpad + %ehspec.fails = icmp slt i32 %2, 0 + br i1 %ehspec.fails, label %ehspec.unexpected, label %eh.resume + +ehspec.unexpected: ; preds = %filter.dispatch + tail call void @__cxa_call_unexpected(ptr %1) + unreachable + +catch: ; preds = %lpad + %4 = tail call ptr @__cxa_begin_catch(ptr %1) + %5 = load i32, ptr %4, align 4 + tail call void @__cxa_end_catch() + br label %return + +return: ; preds = %entry, %catch + %retval.0 = phi i32 [ %5, %catch ], [ 0, %entry ] + ret i32 %retval.0 + +eh.resume: ; preds = %filter.dispatch + resume { ptr, i32 } %0 +} + +declare void @_Z16callee_can_throwi(i32 noundef signext) local_unnamed_addr + +declare i32 @__xlcxx_personality_v1(...) + +declare i32 @llvm.eh.typeid.for(ptr) + +declare ptr @__cxa_begin_catch(ptr) local_unnamed_addr + +declare void @__cxa_end_catch() local_unnamed_addr + +declare void @__cxa_call_unexpected(ptr) local_unnamed_addr -- 2.7.4