[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