[llvm] 252d1c4 - [InstCombine] Remove instructions before non-terminator unreachable

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 22 07:34:53 PDT 2023


Author: Nikita Popov
Date: 2023-06-22T16:33:53+02:00
New Revision: 252d1c48c4c0be3c72de7cb6b972a75c771dde72

URL: https://github.com/llvm/llvm-project/commit/252d1c48c4c0be3c72de7cb6b972a75c771dde72
DIFF: https://github.com/llvm/llvm-project/commit/252d1c48c4c0be3c72de7cb6b972a75c771dde72.diff

LOG: [InstCombine] Remove instructions before non-terminator unreachable

Treat non-terminator unreachable the same as unreachable, and
remove guaranteed-to-transfer instructions before it.

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineInternal.h
    llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
    llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
    llvm/test/Transforms/InstCombine/struct-assign-tbaa-new.ll
    llvm/test/Transforms/InstCombine/struct-assign-tbaa.ll
    llvm/test/Transforms/InstCombine/unreachable-code.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
index 27ac86c3641f2..4cdefba727ac3 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
+++ b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
@@ -661,6 +661,7 @@ class LLVM_LIBRARY_VISIBILITY InstCombinerImpl final
 
   bool tryToSinkInstruction(Instruction *I, BasicBlock *DestBlock);
 
+  bool removeInstructionsBeforeUnreachable(Instruction &I);
   bool handleUnreachableFrom(Instruction *I);
   bool handlePotentiallyDeadSuccessors(BasicBlock *BB, BasicBlock *LiveSucc);
 };

diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
index 95472fc6e1ba6..29568b7782e30 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
@@ -1561,8 +1561,10 @@ Instruction *InstCombinerImpl::visitStoreInst(StoreInst &SI) {
 
   // This is a non-terminator unreachable marker. Don't remove it.
   if (isa<UndefValue>(Ptr)) {
-    // Remove unreachable instructions after the marker.
-    if (handleUnreachableFrom(SI.getNextNode()))
+    // Remove all instructions after the marker and guaranteed-to-transfer
+    // instructions before the marker.
+    if (handleUnreachableFrom(SI.getNextNode()) ||
+        removeInstructionsBeforeUnreachable(SI))
       return &SI;
     return nullptr;
   }

diff  --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 9b40623547062..ad44cfdf358b5 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -2611,20 +2611,21 @@ Instruction *InstCombinerImpl::visitReturnInst(ReturnInst &RI) {
 }
 
 // WARNING: keep in sync with SimplifyCFGOpt::simplifyUnreachable()!
-Instruction *InstCombinerImpl::visitUnreachableInst(UnreachableInst &I) {
+bool InstCombinerImpl::removeInstructionsBeforeUnreachable(Instruction &I) {
   // Try to remove the previous instruction if it must lead to unreachable.
   // This includes instructions like stores and "llvm.assume" that may not get
   // removed by simple dead code elimination.
+  bool Changed = false;
   while (Instruction *Prev = I.getPrevNonDebugInstruction()) {
     // While we theoretically can erase EH, that would result in a block that
     // used to start with an EH no longer starting with EH, which is invalid.
     // To make it valid, we'd need to fixup predecessors to no longer refer to
     // this block, but that changes CFG, which is not allowed in InstCombine.
     if (Prev->isEHPad())
-      return nullptr; // Can not drop any more instructions. We're done here.
+      break; // Can not drop any more instructions. We're done here.
 
     if (!isGuaranteedToTransferExecutionToSuccessor(Prev))
-      return nullptr; // Can not drop any more instructions. We're done here.
+      break; // Can not drop any more instructions. We're done here.
     // Otherwise, this instruction can be freely erased,
     // even if it is not side-effect free.
 
@@ -2632,9 +2633,13 @@ Instruction *InstCombinerImpl::visitUnreachableInst(UnreachableInst &I) {
     // another unreachable block), so convert those to poison.
     replaceInstUsesWith(*Prev, PoisonValue::get(Prev->getType()));
     eraseInstFromFunction(*Prev);
+    Changed = true;
   }
-  assert(I.getParent()->sizeWithoutDebug() == 1 && "The block is now empty.");
-  // FIXME: recurse into unconditional predecessors?
+  return Changed;
+}
+
+Instruction *InstCombinerImpl::visitUnreachableInst(UnreachableInst &I) {
+  removeInstructionsBeforeUnreachable(I);
   return nullptr;
 }
 

diff  --git a/llvm/test/Transforms/InstCombine/struct-assign-tbaa-new.ll b/llvm/test/Transforms/InstCombine/struct-assign-tbaa-new.ll
index 622b558898a29..faf388b72e9db 100644
--- a/llvm/test/Transforms/InstCombine/struct-assign-tbaa-new.ll
+++ b/llvm/test/Transforms/InstCombine/struct-assign-tbaa-new.ll
@@ -26,9 +26,8 @@ entry:
 
 define ptr @test2() {
 ; CHECK-LABEL: @test2(
-; CHECK-NEXT:    [[TMP:%.*]] = alloca [[B:%.*]], align 8
 ; CHECK-NEXT:    store i1 true, ptr poison, align 1
-; CHECK-NEXT:    ret ptr [[TMP]]
+; CHECK-NEXT:    ret ptr poison
 ;
   %tmp = alloca %B, align 8
   call void @llvm.memcpy.p0.p0.i64(ptr align 8 %tmp, ptr align 8 undef, i64 8, i1 false), !tbaa !7  ; TAG_B

diff  --git a/llvm/test/Transforms/InstCombine/struct-assign-tbaa.ll b/llvm/test/Transforms/InstCombine/struct-assign-tbaa.ll
index 97eeea8a1f047..5c2ea3975f94e 100644
--- a/llvm/test/Transforms/InstCombine/struct-assign-tbaa.ll
+++ b/llvm/test/Transforms/InstCombine/struct-assign-tbaa.ll
@@ -26,9 +26,8 @@ entry:
 
 define ptr @test2() {
 ; CHECK-LABEL: @test2(
-; CHECK-NEXT:    [[TMP:%.*]] = alloca [[STRUCT_TEST2:%.*]], align 8
 ; CHECK-NEXT:    store i1 true, ptr poison, align 1
-; CHECK-NEXT:    ret ptr [[TMP]]
+; CHECK-NEXT:    ret ptr poison
 ;
   %tmp = alloca %struct.test2, align 8
   call void @llvm.memcpy.p0.p0.i64(ptr align 8 %tmp, ptr align 8 undef, i64 8, i1 false), !tbaa.struct !4

diff  --git a/llvm/test/Transforms/InstCombine/unreachable-code.ll b/llvm/test/Transforms/InstCombine/unreachable-code.ll
index 5b86c2b4cd340..89a7fbb41cf23 100644
--- a/llvm/test/Transforms/InstCombine/unreachable-code.ll
+++ b/llvm/test/Transforms/InstCombine/unreachable-code.ll
@@ -193,7 +193,6 @@ default:
 define void @non_term_unreachable() {
 ; CHECK-LABEL: define void @non_term_unreachable() {
 ; CHECK-NEXT:    call void @dummy()
-; CHECK-NEXT:    call void @dummy() #[[ATTR0:[0-9]+]]
 ; CHECK-NEXT:    store i1 true, ptr poison, align 1
 ; CHECK-NEXT:    ret void
 ;


        


More information about the llvm-commits mailing list