Skip to content

Commit 252d1c4

Browse files
committed
[InstCombine] Remove instructions before non-terminator unreachable
Treat non-terminator unreachable the same as unreachable, and remove guaranteed-to-transfer instructions before it.
1 parent a5b07ed commit 252d1c4

File tree

6 files changed

+17
-12
lines changed

6 files changed

+17
-12
lines changed

llvm/lib/Transforms/InstCombine/InstCombineInternal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,7 @@ class LLVM_LIBRARY_VISIBILITY InstCombinerImpl final
661661

662662
bool tryToSinkInstruction(Instruction *I, BasicBlock *DestBlock);
663663

664+
bool removeInstructionsBeforeUnreachable(Instruction &I);
664665
bool handleUnreachableFrom(Instruction *I);
665666
bool handlePotentiallyDeadSuccessors(BasicBlock *BB, BasicBlock *LiveSucc);
666667
};

llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1561,8 +1561,10 @@ Instruction *InstCombinerImpl::visitStoreInst(StoreInst &SI) {
15611561

15621562
// This is a non-terminator unreachable marker. Don't remove it.
15631563
if (isa<UndefValue>(Ptr)) {
1564-
// Remove unreachable instructions after the marker.
1565-
if (handleUnreachableFrom(SI.getNextNode()))
1564+
// Remove all instructions after the marker and guaranteed-to-transfer
1565+
// instructions before the marker.
1566+
if (handleUnreachableFrom(SI.getNextNode()) ||
1567+
removeInstructionsBeforeUnreachable(SI))
15661568
return &SI;
15671569
return nullptr;
15681570
}

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2611,30 +2611,35 @@ Instruction *InstCombinerImpl::visitReturnInst(ReturnInst &RI) {
26112611
}
26122612

26132613
// WARNING: keep in sync with SimplifyCFGOpt::simplifyUnreachable()!
2614-
Instruction *InstCombinerImpl::visitUnreachableInst(UnreachableInst &I) {
2614+
bool InstCombinerImpl::removeInstructionsBeforeUnreachable(Instruction &I) {
26152615
// Try to remove the previous instruction if it must lead to unreachable.
26162616
// This includes instructions like stores and "llvm.assume" that may not get
26172617
// removed by simple dead code elimination.
2618+
bool Changed = false;
26182619
while (Instruction *Prev = I.getPrevNonDebugInstruction()) {
26192620
// While we theoretically can erase EH, that would result in a block that
26202621
// used to start with an EH no longer starting with EH, which is invalid.
26212622
// To make it valid, we'd need to fixup predecessors to no longer refer to
26222623
// this block, but that changes CFG, which is not allowed in InstCombine.
26232624
if (Prev->isEHPad())
2624-
return nullptr; // Can not drop any more instructions. We're done here.
2625+
break; // Can not drop any more instructions. We're done here.
26252626

26262627
if (!isGuaranteedToTransferExecutionToSuccessor(Prev))
2627-
return nullptr; // Can not drop any more instructions. We're done here.
2628+
break; // Can not drop any more instructions. We're done here.
26282629
// Otherwise, this instruction can be freely erased,
26292630
// even if it is not side-effect free.
26302631

26312632
// A value may still have uses before we process it here (for example, in
26322633
// another unreachable block), so convert those to poison.
26332634
replaceInstUsesWith(*Prev, PoisonValue::get(Prev->getType()));
26342635
eraseInstFromFunction(*Prev);
2636+
Changed = true;
26352637
}
2636-
assert(I.getParent()->sizeWithoutDebug() == 1 && "The block is now empty.");
2637-
// FIXME: recurse into unconditional predecessors?
2638+
return Changed;
2639+
}
2640+
2641+
Instruction *InstCombinerImpl::visitUnreachableInst(UnreachableInst &I) {
2642+
removeInstructionsBeforeUnreachable(I);
26382643
return nullptr;
26392644
}
26402645

llvm/test/Transforms/InstCombine/struct-assign-tbaa-new.ll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,8 @@ entry:
2626

2727
define ptr @test2() {
2828
; CHECK-LABEL: @test2(
29-
; CHECK-NEXT: [[TMP:%.*]] = alloca [[B:%.*]], align 8
3029
; CHECK-NEXT: store i1 true, ptr poison, align 1
31-
; CHECK-NEXT: ret ptr [[TMP]]
30+
; CHECK-NEXT: ret ptr poison
3231
;
3332
%tmp = alloca %B, align 8
3433
call void @llvm.memcpy.p0.p0.i64(ptr align 8 %tmp, ptr align 8 undef, i64 8, i1 false), !tbaa !7 ; TAG_B

llvm/test/Transforms/InstCombine/struct-assign-tbaa.ll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,8 @@ entry:
2626

2727
define ptr @test2() {
2828
; CHECK-LABEL: @test2(
29-
; CHECK-NEXT: [[TMP:%.*]] = alloca [[STRUCT_TEST2:%.*]], align 8
3029
; CHECK-NEXT: store i1 true, ptr poison, align 1
31-
; CHECK-NEXT: ret ptr [[TMP]]
30+
; CHECK-NEXT: ret ptr poison
3231
;
3332
%tmp = alloca %struct.test2, align 8
3433
call void @llvm.memcpy.p0.p0.i64(ptr align 8 %tmp, ptr align 8 undef, i64 8, i1 false), !tbaa.struct !4

llvm/test/Transforms/InstCombine/unreachable-code.ll

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,6 @@ default:
193193
define void @non_term_unreachable() {
194194
; CHECK-LABEL: define void @non_term_unreachable() {
195195
; CHECK-NEXT: call void @dummy()
196-
; CHECK-NEXT: call void @dummy() #[[ATTR0:[0-9]+]]
197196
; CHECK-NEXT: store i1 true, ptr poison, align 1
198197
; CHECK-NEXT: ret void
199198
;

0 commit comments

Comments
 (0)