Skip to content

Commit 1fc4253

Browse files
committed
[InstCombine] Handle undef when pruning unreachable code
If the branch condition is undef, then behavior is undefined and neither of the successors are live. This is to ensure that optimization quality does not decrease when a constant gets replaced with undef/poison in this context.
1 parent 8f12057 commit 1fc4253

File tree

2 files changed

+10
-8
lines changed

2 files changed

+10
-8
lines changed

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3903,15 +3903,21 @@ static bool prepareICWorklistFromFunction(Function &F, const DataLayout &DL,
39033903
// Recursively visit successors. If this is a branch or switch on a
39043904
// constant, only visit the reachable successor.
39053905
Instruction *TI = BB->getTerminator();
3906-
if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
3907-
if (BI->isConditional() && isa<ConstantInt>(BI->getCondition())) {
3908-
bool CondVal = cast<ConstantInt>(BI->getCondition())->getZExtValue();
3906+
if (BranchInst *BI = dyn_cast<BranchInst>(TI); BI && BI->isConditional()) {
3907+
if (isa<UndefValue>(BI->getCondition()))
3908+
// Branch on undef is UB.
3909+
continue;
3910+
if (auto *Cond = dyn_cast<ConstantInt>(BI->getCondition())) {
3911+
bool CondVal = Cond->getZExtValue();
39093912
BasicBlock *ReachableBB = BI->getSuccessor(!CondVal);
39103913
Worklist.push_back(ReachableBB);
39113914
continue;
39123915
}
39133916
} else if (SwitchInst *SI = dyn_cast<SwitchInst>(TI)) {
3914-
if (ConstantInt *Cond = dyn_cast<ConstantInt>(SI->getCondition())) {
3917+
if (isa<UndefValue>(SI->getCondition()))
3918+
// Switch on undef is UB.
3919+
continue;
3920+
if (auto *Cond = dyn_cast<ConstantInt>(SI->getCondition())) {
39153921
Worklist.push_back(SI->findCaseValue(Cond)->getCaseSuccessor());
39163922
continue;
39173923
}

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,8 @@ define void @br_undef(i1 %x) {
5252
; CHECK-SAME: (i1 [[X:%.*]]) {
5353
; CHECK-NEXT: br i1 undef, label [[IF:%.*]], label [[ELSE:%.*]]
5454
; CHECK: if:
55-
; CHECK-NEXT: call void @dummy()
5655
; CHECK-NEXT: ret void
5756
; CHECK: else:
58-
; CHECK-NEXT: call void @dummy()
5957
; CHECK-NEXT: ret void
6058
;
6159
%c = xor i1 %x, undef
@@ -129,10 +127,8 @@ define void @switch_undef(i32 %x) {
129127
; CHECK-NEXT: i32 0, label [[CASE0:%.*]]
130128
; CHECK-NEXT: ]
131129
; CHECK: case0:
132-
; CHECK-NEXT: call void @dummy()
133130
; CHECK-NEXT: ret void
134131
; CHECK: default:
135-
; CHECK-NEXT: call void @dummy()
136132
; CHECK-NEXT: ret void
137133
;
138134
%v = xor i32 %x, undef

0 commit comments

Comments
 (0)