[llvm] ad66bc4 - [InstCombine] Use getInsertionPointAfterDef() in freeze fold
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 31 02:33:14 PDT 2022
Author: Nikita Popov
Date: 2022-08-31T11:32:57+02:00
New Revision: ad66bc42b0c377b1bff9841fc4715a17ca947222
URL: https://github.com/llvm/llvm-project/commit/ad66bc42b0c377b1bff9841fc4715a17ca947222
DIFF: https://github.com/llvm/llvm-project/commit/ad66bc42b0c377b1bff9841fc4715a17ca947222.diff
LOG: [InstCombine] Use getInsertionPointAfterDef() in freeze fold
This simplifies the code and fixes handling of catchswitch, in
which case we have no insertion point for the freeze.
Originally part of D129660.
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
llvm/test/Transforms/InstCombine/freeze.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 73b297c7377e..458f28decf7c 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -3893,26 +3893,20 @@ bool InstCombinerImpl::freezeOtherUses(FreezeInst &FI) {
// *all* uses if the operand is an invoke/callbr and the use is in a phi on
// the normal/default destination. This is why the domination check in the
// replacement below is still necessary.
- BasicBlock::iterator MoveBefore;
+ Instruction *MoveBefore;
if (isa<Argument>(Op)) {
- MoveBefore = FI.getFunction()->getEntryBlock().begin();
- while (isa<AllocaInst>(*MoveBefore))
- ++MoveBefore;
- } else if (auto *PN = dyn_cast<PHINode>(Op)) {
- MoveBefore = PN->getParent()->getFirstInsertionPt();
- } else if (auto *II = dyn_cast<InvokeInst>(Op)) {
- MoveBefore = II->getNormalDest()->getFirstInsertionPt();
- } else if (auto *CB = dyn_cast<CallBrInst>(Op)) {
- MoveBefore = CB->getDefaultDest()->getFirstInsertionPt();
+ MoveBefore = &FI.getFunction()->getEntryBlock().front();
+ while (isa<AllocaInst>(MoveBefore))
+ MoveBefore = MoveBefore->getNextNode();
} else {
- auto *I = cast<Instruction>(Op);
- assert(!I->isTerminator() && "Cannot be a terminator");
- MoveBefore = std::next(I->getIterator());
+ MoveBefore = cast<Instruction>(Op)->getInsertionPointAfterDef();
+ if (!MoveBefore)
+ return false;
}
bool Changed = false;
- if (FI.getIterator() != MoveBefore) {
- FI.moveBefore(*MoveBefore->getParent(), MoveBefore);
+ if (&FI != MoveBefore) {
+ FI.moveBefore(MoveBefore);
Changed = true;
}
diff --git a/llvm/test/Transforms/InstCombine/freeze.ll b/llvm/test/Transforms/InstCombine/freeze.ll
index 2d1773c62cd6..839763df51a3 100644
--- a/llvm/test/Transforms/InstCombine/freeze.ll
+++ b/llvm/test/Transforms/InstCombine/freeze.ll
@@ -232,6 +232,63 @@ end:
ret void
}
+declare i32 @__CxxFrameHandler3(...)
+
+define void @freeze_dominated_uses_catchswitch(i1 %c, i32 %x) personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
+; CHECK-LABEL: @freeze_dominated_uses_catchswitch(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
+; CHECK: if.then:
+; CHECK-NEXT: invoke void @use_i32(i32 0)
+; CHECK-NEXT: to label [[CLEANUP:%.*]] unwind label [[CATCH_DISPATCH:%.*]]
+; CHECK: if.else:
+; CHECK-NEXT: invoke void @use_i32(i32 1)
+; CHECK-NEXT: to label [[CLEANUP]] unwind label [[CATCH_DISPATCH]]
+; CHECK: catch.dispatch:
+; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 0, [[IF_THEN]] ], [ [[X:%.*]], [[IF_ELSE]] ]
+; CHECK-NEXT: [[CS:%.*]] = catchswitch within none [label [[CATCH:%.*]], label %catch2] unwind to caller
+; CHECK: catch:
+; CHECK-NEXT: [[CP:%.*]] = catchpad within [[CS]] [i8* null, i32 64, i8* null]
+; CHECK-NEXT: [[PHI_FREEZE:%.*]] = freeze i32 [[PHI]]
+; CHECK-NEXT: call void @use_i32(i32 [[PHI_FREEZE]]) [ "funclet"(token [[CP]]) ]
+; CHECK-NEXT: unreachable
+; CHECK: catch2:
+; CHECK-NEXT: [[CP2:%.*]] = catchpad within [[CS]] [i8* null, i32 64, i8* null]
+; CHECK-NEXT: call void @use_i32(i32 [[PHI]]) [ "funclet"(token [[CP2]]) ]
+; CHECK-NEXT: unreachable
+; CHECK: cleanup:
+; CHECK-NEXT: ret void
+;
+entry:
+ br i1 %c, label %if.then, label %if.else
+
+if.then:
+ invoke void @use_i32(i32 0)
+ to label %cleanup unwind label %catch.dispatch
+
+if.else:
+ invoke void @use_i32(i32 1)
+ to label %cleanup unwind label %catch.dispatch
+
+catch.dispatch:
+ %phi = phi i32 [ 0, %if.then ], [ %x, %if.else ]
+ %cs = catchswitch within none [label %catch, label %catch2] unwind to caller
+
+catch:
+ %cp = catchpad within %cs [i8* null, i32 64, i8* null]
+ %phi.freeze = freeze i32 %phi
+ call void @use_i32(i32 %phi.freeze) [ "funclet"(token %cp) ]
+ unreachable
+
+catch2:
+ %cp2 = catchpad within %cs [i8* null, i32 64, i8* null]
+ call void @use_i32(i32 %phi) [ "funclet"(token %cp2) ]
+ unreachable
+
+cleanup:
+ ret void
+}
+
declare i32 @get_i32()
define i32 @freeze_use_in_
diff erent_branches(i1 %c) {
More information about the llvm-commits
mailing list