From 1fc425380e9860a6beb53fa68d02e7fb14969963 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 25 May 2023 16:52:16 +0200 Subject: [PATCH] [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. --- llvm/lib/Transforms/InstCombine/InstructionCombining.cpp | 14 ++++++++++---- llvm/test/Transforms/InstCombine/unreachable-code.ll | 4 ---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index 8c10fe9..0df85be 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -3903,15 +3903,21 @@ static bool prepareICWorklistFromFunction(Function &F, const DataLayout &DL, // Recursively visit successors. If this is a branch or switch on a // constant, only visit the reachable successor. Instruction *TI = BB->getTerminator(); - if (BranchInst *BI = dyn_cast(TI)) { - if (BI->isConditional() && isa(BI->getCondition())) { - bool CondVal = cast(BI->getCondition())->getZExtValue(); + if (BranchInst *BI = dyn_cast(TI); BI && BI->isConditional()) { + if (isa(BI->getCondition())) + // Branch on undef is UB. + continue; + if (auto *Cond = dyn_cast(BI->getCondition())) { + bool CondVal = Cond->getZExtValue(); BasicBlock *ReachableBB = BI->getSuccessor(!CondVal); Worklist.push_back(ReachableBB); continue; } } else if (SwitchInst *SI = dyn_cast(TI)) { - if (ConstantInt *Cond = dyn_cast(SI->getCondition())) { + if (isa(SI->getCondition())) + // Switch on undef is UB. + continue; + if (auto *Cond = dyn_cast(SI->getCondition())) { Worklist.push_back(SI->findCaseValue(Cond)->getCaseSuccessor()); continue; } diff --git a/llvm/test/Transforms/InstCombine/unreachable-code.ll b/llvm/test/Transforms/InstCombine/unreachable-code.ll index 391d73f..4a85d08 100644 --- a/llvm/test/Transforms/InstCombine/unreachable-code.ll +++ b/llvm/test/Transforms/InstCombine/unreachable-code.ll @@ -52,10 +52,8 @@ define void @br_undef(i1 %x) { ; CHECK-SAME: (i1 [[X:%.*]]) { ; CHECK-NEXT: br i1 undef, label [[IF:%.*]], label [[ELSE:%.*]] ; CHECK: if: -; CHECK-NEXT: call void @dummy() ; CHECK-NEXT: ret void ; CHECK: else: -; CHECK-NEXT: call void @dummy() ; CHECK-NEXT: ret void ; %c = xor i1 %x, undef @@ -129,10 +127,8 @@ define void @switch_undef(i32 %x) { ; CHECK-NEXT: i32 0, label [[CASE0:%.*]] ; CHECK-NEXT: ] ; CHECK: case0: -; CHECK-NEXT: call void @dummy() ; CHECK-NEXT: ret void ; CHECK: default: -; CHECK-NEXT: call void @dummy() ; CHECK-NEXT: ret void ; %v = xor i32 %x, undef -- 2.7.4