[llvm] 4a9ff28 - [InstCombine] Fix freeze instruction getting inserted before landingpad

Danila Malyutin via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 18 07:44:01 PDT 2022


Author: Danila Malyutin
Date: 2022-08-18T17:43:42+03:00
New Revision: 4a9ff289fbaa76e8a6c2ea0d566ed2aafedefe86

URL: https://github.com/llvm/llvm-project/commit/4a9ff289fbaa76e8a6c2ea0d566ed2aafedefe86
DIFF: https://github.com/llvm/llvm-project/commit/4a9ff289fbaa76e8a6c2ea0d566ed2aafedefe86.diff

LOG: [InstCombine] Fix freeze instruction getting inserted before landingpad

The code would use first non-phi instruction as an insertion point, however
this could lead to freeze getting inserted between phi and landingpad
causing a verifier assert.

Differential Revision: https://reviews.llvm.org/D132105

Added: 
    llvm/test/Transforms/InstCombine/freeze-landingpad.ll

Modified: 
    llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index de551e049035d..a351e9ced602c 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -3897,26 +3897,26 @@ 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.
-  Instruction *MoveBefore = nullptr;
+  BasicBlock::iterator MoveBefore;
   if (isa<Argument>(Op)) {
-    MoveBefore = &FI.getFunction()->getEntryBlock().front();
-    while (isa<AllocaInst>(MoveBefore))
-      MoveBefore = MoveBefore->getNextNode();
+    MoveBefore = FI.getFunction()->getEntryBlock().begin();
+    while (isa<AllocaInst>(*MoveBefore))
+      ++MoveBefore;
   } else if (auto *PN = dyn_cast<PHINode>(Op)) {
-    MoveBefore = PN->getParent()->getFirstNonPHI();
+    MoveBefore = PN->getParent()->getFirstInsertionPt();
   } else if (auto *II = dyn_cast<InvokeInst>(Op)) {
-    MoveBefore = II->getNormalDest()->getFirstNonPHI();
+    MoveBefore = II->getNormalDest()->getFirstInsertionPt();
   } else if (auto *CB = dyn_cast<CallBrInst>(Op)) {
-    MoveBefore = CB->getDefaultDest()->getFirstNonPHI();
+    MoveBefore = CB->getDefaultDest()->getFirstInsertionPt();
   } else {
     auto *I = cast<Instruction>(Op);
     assert(!I->isTerminator() && "Cannot be a terminator");
-    MoveBefore = I->getNextNode();
+    MoveBefore = std::next(I->getIterator());
   }
 
   bool Changed = false;
-  if (&FI != MoveBefore) {
-    FI.moveBefore(MoveBefore);
+  if (FI.getIterator() != MoveBefore) {
+    FI.moveBefore(*MoveBefore->getParent(), MoveBefore);
     Changed = true;
   }
 

diff  --git a/llvm/test/Transforms/InstCombine/freeze-landingpad.ll b/llvm/test/Transforms/InstCombine/freeze-landingpad.ll
new file mode 100644
index 0000000000000..68ad840ebe85c
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/freeze-landingpad.ll
@@ -0,0 +1,53 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; Check that no freeze instruction gets inserted before landingpad in a basic block
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+
+define i32 @propagate_freeze_in_landingpad() personality i32* ()* null {
+; CHECK-LABEL: @propagate_freeze_in_landingpad(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[INVOKE_BB1:%.*]]
+; CHECK:       invoke.bb1:
+; CHECK-NEXT:    [[X:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[NORMAL_RETURN:%.*]] ]
+; CHECK-NEXT:    [[RES0:%.*]] = invoke i32 @foo()
+; CHECK-NEXT:    to label [[INVOKE_BB2:%.*]] unwind label [[EXCEPTIONAL_RETURN:%.*]]
+; CHECK:       invoke.bb2:
+; CHECK-NEXT:    [[RES1:%.*]] = invoke i32 @foo()
+; CHECK-NEXT:    to label [[NORMAL_RETURN]] unwind label [[EXCEPTIONAL_RETURN]]
+; CHECK:       normal_return:
+; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[X]], 1
+; CHECK-NEXT:    br label [[INVOKE_BB1]]
+; CHECK:       exceptional_return:
+; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ [[X]], [[INVOKE_BB1]] ], [ 0, [[INVOKE_BB2]] ]
+; CHECK-NEXT:    [[LANDING_PAD:%.*]] = landingpad { i8*, i32 }
+; CHECK-NEXT:    cleanup
+; CHECK-NEXT:    [[FR:%.*]] = freeze i32 [[PHI]]
+; CHECK-NEXT:    [[RES:%.*]] = shl i32 [[FR]], 1
+; CHECK-NEXT:    ret i32 [[RES]]
+;
+entry:
+  br label %invoke.bb1
+
+invoke.bb1:                                 ; preds = %normal_return, %entry
+  %x = phi i32 [ 0, %entry ], [ %inc, %normal_return ]
+  %res0 = invoke i32 @foo()
+  to label %invoke.bb2 unwind label %exceptional_return
+
+invoke.bb2:                                  ; preds = %invoke.bb1
+  %res1 = invoke i32 @foo()
+  to label %normal_return unwind label %exceptional_return
+
+normal_return:                                ; preds = %invoke.bb2
+  %inc = add nuw nsw i32 %x, 1
+  br label %invoke.bb1
+
+exceptional_return:                             ; preds = %invoke.bb2, %invoke.bb1
+  %phi = phi i32 [ %x, %invoke.bb1 ], [ 0, %invoke.bb2 ]
+  %landing_pad = landingpad { i8*, i32 }
+  cleanup
+  %fr = freeze i32 %phi
+  %res = add i32 %fr, %phi
+  ret i32 %res
+}
+
+declare i32 @foo()
+


        


More information about the llvm-commits mailing list