[llvm] 6c5f3f6 - [reg2mem] Add special handling to CatchSwitchInst
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Fri Dec 16 07:07:33 PST 2022
Author: HanSheng Zhang
Date: 2022-12-16T16:04:35+01:00
New Revision: 6c5f3f62bdb29d1bffc11e8ad41c7e0fee9cb164
URL: https://github.com/llvm/llvm-project/commit/6c5f3f62bdb29d1bffc11e8ad41c7e0fee9cb164
DIFF: https://github.com/llvm/llvm-project/commit/6c5f3f62bdb29d1bffc11e8ad41c7e0fee9cb164.diff
LOG: [reg2mem] Add special handling to CatchSwitchInst
When promoting a phi in a catchswitch block to memory, we cannot
insert load/store instruction in that block, and need to insert
them inside all successors instead.
Fixes https://github.com/llvm/llvm-project/issues/59185.
Differential Revision: https://reviews.llvm.org/D138641
Added:
llvm/test/Transforms/Reg2Mem/catchswitch-crash2.ll
Modified:
llvm/lib/Transforms/Utils/DemoteRegToStack.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Utils/DemoteRegToStack.cpp b/llvm/lib/Transforms/Utils/DemoteRegToStack.cpp
index f6f80540ad957..086ea088dc5ec 100644
--- a/llvm/lib/Transforms/Utils/DemoteRegToStack.cpp
+++ b/llvm/lib/Transforms/Utils/DemoteRegToStack.cpp
@@ -92,8 +92,15 @@ AllocaInst *llvm::DemoteRegToStack(Instruction &I, bool VolatileLoads,
BasicBlock::iterator InsertPt;
if (!I.isTerminator()) {
InsertPt = ++I.getIterator();
+ // Don't insert before PHI nodes or landingpad instrs.
for (; isa<PHINode>(InsertPt) || InsertPt->isEHPad(); ++InsertPt)
- /* empty */; // Don't insert before PHI nodes or landingpad instrs.
+ if (isa<CatchSwitchInst>(InsertPt))
+ break;
+ if (isa<CatchSwitchInst>(InsertPt)) {
+ for (BasicBlock *Handler : successors(&*InsertPt))
+ new StoreInst(&I, Slot, &*Handler->getFirstInsertionPt());
+ return Slot;
+ }
} else {
InvokeInst &II = cast<InvokeInst>(I);
InsertPt = II.getNormalDest()->getFirstInsertionPt();
@@ -138,14 +145,27 @@ AllocaInst *llvm::DemotePHIToStack(PHINode *P, Instruction *AllocaPoint) {
// Insert a load in place of the PHI and replace all uses.
BasicBlock::iterator InsertPt = P->getIterator();
-
+ // Don't insert before PHI nodes or landingpad instrs.
for (; isa<PHINode>(InsertPt) || InsertPt->isEHPad(); ++InsertPt)
- /* empty */; // Don't insert before PHI nodes or landingpad instrs.
-
- Value *V =
- new LoadInst(P->getType(), Slot, P->getName() + ".reload", &*InsertPt);
- P->replaceAllUsesWith(V);
-
+ if (isa<CatchSwitchInst>(InsertPt))
+ break;
+ if (isa<CatchSwitchInst>(InsertPt)) {
+ // We need a separate load before each actual use of the PHI
+ SmallVector<Instruction *, 4> Users;
+ for (User *U : P->users()) {
+ Instruction *User = cast<Instruction>(U);
+ Users.push_back(User);
+ }
+ for (Instruction *User : Users) {
+ Value *V =
+ new LoadInst(P->getType(), Slot, P->getName() + ".reload", User);
+ User->replaceUsesOfWith(P, V);
+ }
+ } else {
+ Value *V =
+ new LoadInst(P->getType(), Slot, P->getName() + ".reload", &*InsertPt);
+ P->replaceAllUsesWith(V);
+ }
// Delete PHI.
P->eraseFromParent();
return Slot;
diff --git a/llvm/test/Transforms/Reg2Mem/catchswitch-crash2.ll b/llvm/test/Transforms/Reg2Mem/catchswitch-crash2.ll
new file mode 100644
index 0000000000000..799e263e97bed
--- /dev/null
+++ b/llvm/test/Transforms/Reg2Mem/catchswitch-crash2.ll
@@ -0,0 +1,76 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -passes=reg2mem -S < %s | FileCheck %s
+%opaque = type opaque
+
+declare i32 @__CxxFrameHandler3(...)
+
+define void @testreg2mem(i8* %_Val) personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
+; CHECK-LABEL: @testreg2mem(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[_STATE_3_REG2MEM:%.*]] = alloca i32, align 4
+; CHECK-NEXT: [[_STATE_3_REG2MEM1:%.*]] = alloca i32, align 4
+; CHECK-NEXT: %"reg2mem alloca point" = bitcast i32 0 to i32
+; CHECK-NEXT: store i32 0, i32* [[_STATE_3_REG2MEM1]], align 4
+; CHECK-NEXT: [[CALL_I166167:%.*]] = invoke noundef i64 @extfunc_i64()
+; CHECK-NEXT: to label [[IF_END56:%.*]] unwind label [[CATCH_DISPATCH:%.*]]
+; CHECK: if.end56:
+; CHECK-NEXT: store i32 1, i32* [[_STATE_3_REG2MEM1]], align 4
+; CHECK-NEXT: invoke void @extfunc()
+; CHECK-NEXT: to label [[INVOKE_CONT75:%.*]] unwind label [[CATCH_DISPATCH]]
+; CHECK: invoke.cont75:
+; CHECK-NEXT: unreachable
+; CHECK: catch.dispatch:
+; CHECK-NEXT: [[TMP0:%.*]] = catchswitch within none [label %catch] unwind label [[EHCLEANUP105:%.*]]
+; CHECK: catch:
+; CHECK-NEXT: [[TMP1:%.*]] = catchpad within [[TMP0]] [i8* null, i32 64, i8* null]
+; CHECK-NEXT: [[_STATE_3_RELOAD2:%.*]] = load i32, i32* [[_STATE_3_REG2MEM1]], align 4
+; CHECK-NEXT: store i32 [[_STATE_3_RELOAD2]], i32* [[_STATE_3_REG2MEM]], align 4
+; CHECK-NEXT: invoke void @extfunc() [ "funclet"(token [[TMP1]]) ]
+; CHECK-NEXT: to label [[INVOKE_CONT98:%.*]] unwind label [[EHCLEANUP105]]
+; CHECK: invoke.cont98:
+; CHECK-NEXT: catchret from [[TMP1]] to label [[IF_END99:%.*]]
+; CHECK: if.end99:
+; CHECK-NEXT: [[_STATE_3_RELOAD:%.*]] = load i32, i32* [[_STATE_3_REG2MEM]], align 4
+; CHECK-NEXT: [[OR_I:%.*]] = or i32 0, [[_STATE_3_RELOAD]]
+; CHECK-NEXT: unreachable
+; CHECK: ehcleanup105:
+; CHECK-NEXT: [[TMP2:%.*]] = cleanuppad within none []
+; CHECK-NEXT: [[_STATE_3_RELOAD3:%.*]] = load i32, i32* [[_STATE_3_REG2MEM1]], align 4
+; CHECK-NEXT: store i32 [[_STATE_3_RELOAD3]], i32* [[_STATE_3_REG2MEM]], align 4
+; CHECK-NEXT: cleanupret from [[TMP2]] unwind to caller
+;
+entry:
+ %call.i166167 = invoke noundef i64 @"extfunc_i64"()
+ to label %if.end56 unwind label %catch.dispatch
+
+if.end56: ; preds = %entry
+ invoke void @"extfunc"()
+ to label %invoke.cont75 unwind label %catch.dispatch
+
+invoke.cont75: ; preds = %if.end56
+ unreachable
+
+catch.dispatch: ; preds = %if.end56, %entry
+ %_State.3 = phi i32 [ 1, %if.end56 ], [ 0, %entry ]
+ %0 = catchswitch within none [label %catch] unwind label %ehcleanup105
+
+catch: ; preds = %catch.dispatch
+ %1 = catchpad within %0 [i8* null, i32 64, i8* null]
+ invoke void @"extfunc"() [ "funclet"(token %1) ]
+ to label %invoke.cont98 unwind label %ehcleanup105
+
+invoke.cont98: ; preds = %catch
+ catchret from %1 to label %if.end99
+
+if.end99: ; preds = %invoke.cont98
+ %or.i = or i32 0, %_State.3
+ unreachable
+
+ehcleanup105: ; preds = %catch, %catch.dispatch
+ %2 = cleanuppad within none []
+ cleanupret from %2 unwind to caller
+}
+
+declare void @"extfunc"()
+
+declare i64 @"extfunc_i64"()
More information about the llvm-commits
mailing list