diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index 35fead111aa96..a8c4b1cc34c6c 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -3376,7 +3376,8 @@ static bool FoldCondBranchOnValueKnownInPredecessor(BranchInst *BI, /// Given a BB that starts with the specified two-entry PHI node, /// see if we can eliminate it. static bool FoldTwoEntryPHINode(PHINode *PN, const TargetTransformInfo &TTI, - DomTreeUpdater *DTU, const DataLayout &DL) { + DomTreeUpdater *DTU, const DataLayout &DL, + AssumptionCache *AC) { // Ok, this is a two entry PHI node. Check to see if this is a simple "if // statement", which has a very simple dominance structure. Basically, we // are trying to find the condition that is being branched on, which @@ -3543,9 +3544,20 @@ static bool FoldTwoEntryPHINode(PHINode *PN, const TargetTransformInfo &TTI, Value *TrueVal = PN->getIncomingValueForBlock(IfTrue); Value *FalseVal = PN->getIncomingValueForBlock(IfFalse); - Value *Sel = Builder.CreateSelect(IfCond, TrueVal, FalseVal, "", DomBI); - PN->replaceAllUsesWith(Sel); - Sel->takeName(PN); + Value *ReplaceVal = nullptr; + if (isa(TrueVal) && + isGuaranteedNotToBePoison(FalseVal, AC, IfFalse->getTerminator(), + /*DT*/ nullptr, /*Depth*/ 0)) { + ReplaceVal = FalseVal; + } else if (isa(FalseVal) && + isGuaranteedNotToBePoison(TrueVal, AC, IfTrue->getTerminator(), + /*DT*/ nullptr, /*Depth*/ 0)) { + ReplaceVal = TrueVal; + } else { + ReplaceVal = Builder.CreateSelect(IfCond, TrueVal, FalseVal, "", DomBI); + ReplaceVal->takeName(PN); + } + PN->replaceAllUsesWith(ReplaceVal); PN->eraseFromParent(); } @@ -7406,7 +7418,7 @@ bool SimplifyCFGOpt::simplifyOnce(BasicBlock *BB) { // eliminate it, do so now. if (auto *PN = dyn_cast(BB->begin())) if (PN->getNumIncomingValues() == 2) - if (FoldTwoEntryPHINode(PN, TTI, DTU, DL)) + if (FoldTwoEntryPHINode(PN, TTI, DTU, DL, Options.AC)) return true; } diff --git a/llvm/test/Transforms/SimplifyCFG/pr67342.ll b/llvm/test/Transforms/SimplifyCFG/pr67342.ll new file mode 100644 index 0000000000000..c2c9f460d8e5f --- /dev/null +++ b/llvm/test/Transforms/SimplifyCFG/pr67342.ll @@ -0,0 +1,50 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3 +; RUN: opt -S -passes=simplifycfg < %s | FileCheck %s + +; Tests from PR67342 +define i16 @test1(i32 %err) { +; CHECK-LABEL: define i16 @test1( +; CHECK-SAME: i32 [[ERR:%.*]]) { +; CHECK-NEXT: bb3: +; CHECK-NEXT: [[_3:%.*]] = icmp slt i32 [[ERR]], 0 +; CHECK-NEXT: [[OK:%.*]] = trunc i32 [[ERR]] to i16 +; CHECK-NEXT: ret i16 [[OK]] +; + %_3 = icmp slt i32 %err, 0 + br i1 %_3, label %bb1, label %bb2 + +bb2: + %ok = trunc i32 %err to i16 + br label %bb3 + +bb1: + br label %bb3 + +bb3: + %r.sroa.3.0 = phi i16 [ undef, %bb1 ], [ %ok, %bb2 ] + ret i16 %r.sroa.3.0 +} + +; commuted test +define i16 @test2(i32 %err) { +; CHECK-LABEL: define i16 @test2( +; CHECK-SAME: i32 [[ERR:%.*]]) { +; CHECK-NEXT: bb3: +; CHECK-NEXT: [[_3:%.*]] = icmp slt i32 [[ERR]], 0 +; CHECK-NEXT: [[OK:%.*]] = trunc i32 [[ERR]] to i16 +; CHECK-NEXT: ret i16 [[OK]] +; + %_3 = icmp slt i32 %err, 0 + br i1 %_3, label %bb1, label %bb2 + +bb2: + br label %bb3 + +bb1: + %ok = trunc i32 %err to i16 + br label %bb3 + +bb3: + %r.sroa.3.0 = phi i16 [ %ok, %bb1 ], [ undef, %bb2 ] + ret i16 %r.sroa.3.0 +}