Index: llvm/lib/Transforms/Utils/PredicateInfo.cpp =================================================================== --- llvm/lib/Transforms/Utils/PredicateInfo.cpp +++ llvm/lib/Transforms/Utils/PredicateInfo.cpp @@ -367,6 +367,13 @@ } } +bool shouldRename(Value *V) { + // Only want real values, not constants. Additionally, operands with one use + // are only being used in the comparison, which means they will not be useful + // for us to consider for predicateinfo. + return (isa(V) || isa(V)) && !V->hasOneUse(); +} + // Collect relevant operations from Comparison that we may want to insert copies // for. void collectCmpOps(CmpInst *Comparison, SmallVectorImpl &CmpOperands) { @@ -374,15 +381,9 @@ auto *Op1 = Comparison->getOperand(1); if (Op0 == Op1) return; - CmpOperands.push_back(Comparison); - // Only want real values, not constants. Additionally, operands with one use - // are only being used in the comparison, which means they will not be useful - // for us to consider for predicateinfo. - // - if ((isa(Op0) || isa(Op0)) && !Op0->hasOneUse()) - CmpOperands.push_back(Op0); - if ((isa(Op1) || isa(Op1)) && !Op1->hasOneUse()) - CmpOperands.push_back(Op1); + + CmpOperands.push_back(Op0); + CmpOperands.push_back(Op1); } // Add Op, PB to the list of value infos for Op, and mark Op to be renamed. @@ -400,38 +401,26 @@ void PredicateInfoBuilder::processAssume( IntrinsicInst *II, BasicBlock *AssumeBB, SmallVectorImpl &OpsToRename) { - // See if we have a comparison we support - SmallVector CmpOperands; - SmallVector ConditionsToProcess; - CmpInst::Predicate Pred; - Value *Operand = II->getOperand(0); - if (m_c_And(m_Cmp(Pred, m_Value(), m_Value()), - m_Cmp(Pred, m_Value(), m_Value())) - .match(II->getOperand(0))) { - ConditionsToProcess.push_back(cast(Operand)->getOperand(0)); - ConditionsToProcess.push_back(cast(Operand)->getOperand(1)); - ConditionsToProcess.push_back(Operand); - } else if (isa(Operand)) { - - ConditionsToProcess.push_back(Operand); - } - for (auto Cond : ConditionsToProcess) { - if (auto *Cmp = dyn_cast(Cond)) { - collectCmpOps(Cmp, CmpOperands); - // Now add our copy infos for our operands - for (auto *Op : CmpOperands) { - auto *PA = new PredicateAssume(Op, II, Cmp); - addInfoFor(OpsToRename, Op, PA); + SmallVector Worklist; + Worklist.push_back(II->getOperand(0)); + while (!Worklist.empty()) { + Value *Cond = Worklist.pop_back_val(); + Value *Op0, *Op1; + if (match(Cond, m_And(m_Value(Op0), m_Value(Op1)))) { + Worklist.push_back(Op1); + Worklist.push_back(Op0); + } + + SmallVector Values; + Values.push_back(Cond); + if (auto *Cmp = dyn_cast(Cond)) + collectCmpOps(Cmp, Values); + + for (Value *V : Values) { + if (shouldRename(V)) { + auto *PA = new PredicateAssume(V, II, Cond); + addInfoFor(OpsToRename, V, PA); } - CmpOperands.clear(); - } else if (auto *BinOp = dyn_cast(Cond)) { - // Otherwise, it should be an AND. - assert(BinOp->getOpcode() == Instruction::And && - "Should have been an AND"); - auto *PA = new PredicateAssume(BinOp, II, BinOp); - addInfoFor(OpsToRename, BinOp, PA); - } else { - llvm_unreachable("Unknown type of condition"); } } } @@ -443,68 +432,40 @@ SmallVectorImpl &OpsToRename) { BasicBlock *FirstBB = BI->getSuccessor(0); BasicBlock *SecondBB = BI->getSuccessor(1); - SmallVector SuccsToProcess; - SuccsToProcess.push_back(FirstBB); - SuccsToProcess.push_back(SecondBB); - SmallVector ConditionsToProcess; - - auto InsertHelper = [&](Value *Op, bool isAnd, bool isOr, Value *Cond) { - for (auto *Succ : SuccsToProcess) { - // Don't try to insert on a self-edge. This is mainly because we will - // eliminate during renaming anyway. - if (Succ == BranchBB) - continue; - bool TakenEdge = (Succ == FirstBB); - // For and, only insert on the true edge - // For or, only insert on the false edge - if ((isAnd && !TakenEdge) || (isOr && TakenEdge)) - continue; - PredicateBase *PB = - new PredicateBranch(Op, BranchBB, Succ, Cond, TakenEdge); - addInfoFor(OpsToRename, Op, PB); - if (!Succ->getSinglePredecessor()) - EdgeUsesOnly.insert({BranchBB, Succ}); - } - }; - // Match combinations of conditions. - CmpInst::Predicate Pred; - bool isAnd = false; - bool isOr = false; - SmallVector CmpOperands; - if (match(BI->getCondition(), m_And(m_Cmp(Pred, m_Value(), m_Value()), - m_Cmp(Pred, m_Value(), m_Value()))) || - match(BI->getCondition(), m_Or(m_Cmp(Pred, m_Value(), m_Value()), - m_Cmp(Pred, m_Value(), m_Value())))) { - auto *BinOp = cast(BI->getCondition()); - if (BinOp->getOpcode() == Instruction::And) - isAnd = true; - else if (BinOp->getOpcode() == Instruction::Or) - isOr = true; - ConditionsToProcess.push_back(BinOp->getOperand(0)); - ConditionsToProcess.push_back(BinOp->getOperand(1)); - ConditionsToProcess.push_back(BI->getCondition()); - } else if (isa(BI->getCondition())) { - ConditionsToProcess.push_back(BI->getCondition()); - } - for (auto Cond : ConditionsToProcess) { - if (auto *Cmp = dyn_cast(Cond)) { - collectCmpOps(Cmp, CmpOperands); - // Now add our copy infos for our operands - for (auto *Op : CmpOperands) - InsertHelper(Op, isAnd, isOr, Cmp); - } else if (auto *BinOp = dyn_cast(Cond)) { - // This must be an AND or an OR. - assert((BinOp->getOpcode() == Instruction::And || - BinOp->getOpcode() == Instruction::Or) && - "Should have been an AND or an OR"); - // The actual value of the binop is not subject to the same restrictions - // as the comparison. It's either true or false on the true/false branch. - InsertHelper(BinOp, false, false, BinOp); - } else { - llvm_unreachable("Unknown type of condition"); + for (BasicBlock *Succ : {FirstBB, SecondBB}) { + bool TakenEdge = Succ == FirstBB; + // Don't try to insert on a self-edge. This is mainly because we will + // eliminate during renaming anyway. + if (Succ == BranchBB) + continue; + + SmallVector Worklist; + Worklist.push_back(BI->getCondition()); + while (!Worklist.empty()) { + Value *Cond = Worklist.pop_back_val(); + Value *Op0, *Op1; + if (TakenEdge ? match(Cond, m_And(m_Value(Op0), m_Value(Op1))) + : match(Cond, m_Or(m_Value(Op0), m_Value(Op1)))) { + Worklist.push_back(Op1); + Worklist.push_back(Op0); + } + + SmallVector Values; + Values.push_back(Cond); + if (auto *Cmp = dyn_cast(Cond)) + collectCmpOps(Cmp, Values); + + for (Value *V : Values) { + if (shouldRename(V)) { + PredicateBase *PB = + new PredicateBranch(V, BranchBB, Succ, Cond, TakenEdge); + addInfoFor(OpsToRename, V, PB); + if (!Succ->getSinglePredecessor()) + EdgeUsesOnly.insert({BranchBB, Succ}); + } + } } - CmpOperands.clear(); } } // Process a block terminating switch, and place relevant operations to be Index: llvm/test/Transforms/NewGVN/assume-equal.ll =================================================================== --- llvm/test/Transforms/NewGVN/assume-equal.ll +++ llvm/test/Transforms/NewGVN/assume-equal.ll @@ -106,7 +106,7 @@ ; CHECK-NEXT: br label [[NEXT:%.*]] ; CHECK: next: ; CHECK-NEXT: tail call void @llvm.assume(i1 [[K:%.*]]) -; CHECK-NEXT: tail call void @llvm.assume(i1 [[K]]) +; CHECK-NEXT: tail call void @llvm.assume(i1 true) ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[VAL:%.*]], 50 ; CHECK-NEXT: br i1 [[CMP]], label [[NEXT]], label [[MEH:%.*]] ; CHECK: meh: @@ -132,7 +132,7 @@ ; CHECK-NEXT: br i1 [[J:%.*]], label [[NEXT:%.*]], label [[MEH:%.*]] ; CHECK: next: ; CHECK-NEXT: tail call void @llvm.assume(i1 [[K:%.*]]) -; CHECK-NEXT: tail call void @llvm.assume(i1 [[K]]) +; CHECK-NEXT: tail call void @llvm.assume(i1 true) ; CHECK-NEXT: br label [[MEH]] ; CHECK: meh: ; CHECK-NEXT: ret i1 [[K]] Index: llvm/test/Transforms/SCCP/conditions-ranges.ll =================================================================== --- llvm/test/Transforms/SCCP/conditions-ranges.ll +++ llvm/test/Transforms/SCCP/conditions-ranges.ll @@ -966,8 +966,6 @@ ret void } -; TODO: Currently only the information of the AND used as branch condition is -; used. define void @f18_conditions_chained_and(i32 %a, i32 %b) { ; CHECK-LABEL: @f18_conditions_chained_and( ; CHECK-NEXT: entry: @@ -978,18 +976,12 @@ ; CHECK-NEXT: [[BC_2:%.*]] = and i1 [[BC]], [[B_LT]] ; CHECK-NEXT: br i1 [[BC_2]], label [[TRUE:%.*]], label [[FALSE:%.*]] ; CHECK: true: -; CHECK-NEXT: [[F_1:%.*]] = icmp eq i32 [[A]], 0 -; CHECK-NEXT: call void @use(i1 [[F_1]]) -; CHECK-NEXT: [[F_2:%.*]] = icmp eq i32 [[A]], 20 -; CHECK-NEXT: call void @use(i1 [[F_2]]) -; CHECK-NEXT: [[F_3:%.*]] = icmp ugt i32 [[A]], 100 -; CHECK-NEXT: call void @use(i1 [[F_3]]) -; CHECK-NEXT: [[F_4:%.*]] = icmp ugt i32 [[B]], 100 -; CHECK-NEXT: call void @use(i1 [[F_4]]) -; CHECK-NEXT: [[T_1:%.*]] = icmp ult i32 [[A]], 100 -; CHECK-NEXT: call void @use(i1 [[T_1]]) -; CHECK-NEXT: [[T_2:%.*]] = icmp ne i32 [[A]], 20 -; CHECK-NEXT: call void @use(i1 [[T_2]]) +; CHECK-NEXT: call void @use(i1 false) +; CHECK-NEXT: call void @use(i1 false) +; CHECK-NEXT: call void @use(i1 false) +; CHECK-NEXT: call void @use(i1 false) +; CHECK-NEXT: call void @use(i1 true) +; CHECK-NEXT: call void @use(i1 true) ; CHECK-NEXT: [[C_1:%.*]] = icmp eq i32 [[A]], 21 ; CHECK-NEXT: call void @use(i1 [[C_1]]) ; CHECK-NEXT: [[C_2:%.*]] = icmp ugt i32 [[A]], 21 Index: llvm/test/Transforms/Util/PredicateInfo/condprop.ll =================================================================== --- llvm/test/Transforms/Util/PredicateInfo/condprop.ll +++ llvm/test/Transforms/Util/PredicateInfo/condprop.ll @@ -1,5 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt -print-predicateinfo < %s 2>&1 | FileCheck %s +; RUN: opt -print-predicateinfo -disable-output < %s 2>&1 | FileCheck %s @a = external global i32 ; [#uses=7] @@ -98,11 +98,11 @@ ; CHECK-NEXT: [[XZ:%.*]] = icmp eq i32 [[X:%.*]], 0 ; CHECK-NEXT: [[YZ:%.*]] = icmp eq i32 [[Y:%.*]], 0 ; CHECK-NEXT: [[Z:%.*]] = and i1 [[XZ]], [[YZ]] +; CHECK: [[Z_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[Z]]) ; CHECK: [[XZ_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[XZ]]) ; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X]]) ; CHECK: [[YZ_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[YZ]]) ; CHECK: [[Y_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[Y]]) -; CHECK: [[Z_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[Z]]) ; CHECK-NEXT: br i1 [[Z]], label [[BOTH_ZERO:%.*]], label [[NOPE:%.*]] ; CHECK: both_zero: ; CHECK-NEXT: call void @foo(i1 [[XZ_0]]) @@ -138,8 +138,8 @@ ; CHECK-NEXT: i32 2, label [[CASE0]] ; CHECK-NEXT: i32 3, label [[CASE3]] ; CHECK-NEXT: i32 4, label [[DEFAULT:%.*]] -; CHECK-NEXT: ] Edge: [label [[SW]],label %case1] -; CHECK-NEXT: [[X_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X:%.*]]) +; CHECK-NEXT: ] Edge: [label [[SW]],label %case1], RenamedOp: [[X:%.*]] } +; CHECK-NEXT: [[X_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X]]) ; CHECK-NEXT: switch i32 [[X]], label [[DEFAULT]] [ ; CHECK-NEXT: i32 0, label [[CASE0]] ; CHECK-NEXT: i32 1, label [[CASE1]] Index: llvm/test/Transforms/Util/PredicateInfo/testandor.ll =================================================================== --- llvm/test/Transforms/Util/PredicateInfo/testandor.ll +++ llvm/test/Transforms/Util/PredicateInfo/testandor.ll @@ -10,11 +10,11 @@ ; CHECK-NEXT: [[XZ:%.*]] = icmp eq i32 [[X:%.*]], 0 ; CHECK-NEXT: [[YZ:%.*]] = icmp eq i32 [[Y:%.*]], 0 ; CHECK-NEXT: [[Z:%.*]] = or i1 [[XZ]], [[YZ]] +; CHECK: [[Z_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[Z]]) ; CHECK: [[XZ_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[XZ]]) ; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X]]) ; CHECK: [[YZ_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[YZ]]) ; CHECK: [[Y_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[Y]]) -; CHECK: [[Z_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[Z]]) ; CHECK-NEXT: br i1 [[Z]], label [[ONEOF:%.*]], label [[NEITHER:%.*]] ; CHECK: oneof: ; CHECK-NEXT: call void @foo(i1 [[XZ]]) @@ -54,11 +54,11 @@ ; CHECK-NEXT: [[XZ:%.*]] = icmp eq i32 [[X:%.*]], 0 ; CHECK-NEXT: [[YZ:%.*]] = icmp eq i32 [[Y:%.*]], 0 ; CHECK-NEXT: [[Z:%.*]] = and i1 [[XZ]], [[YZ]] +; CHECK: [[Z_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[Z]]) ; CHECK: [[XZ_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[XZ]]) ; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X]]) ; CHECK: [[YZ_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[YZ]]) ; CHECK: [[Y_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[Y]]) -; CHECK: [[Z_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[Z]]) ; CHECK-NEXT: br i1 [[Z]], label [[BOTH:%.*]], label [[NOPE:%.*]] ; CHECK: both: ; CHECK-NEXT: call void @foo(i1 [[XZ_0]]) @@ -98,11 +98,11 @@ ; CHECK-NEXT: [[XGT:%.*]] = icmp sgt i32 [[X:%.*]], 0 ; CHECK-NEXT: [[XLT:%.*]] = icmp slt i32 [[X]], 100 ; CHECK-NEXT: [[Z:%.*]] = and i1 [[XGT]], [[XLT]] +; CHECK: [[Z_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[Z]]) ; CHECK: [[XGT_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[XGT]]) ; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X]]) ; CHECK: [[X_0_1:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X_0]]) ; CHECK: [[XLT_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[XLT]]) -; CHECK: [[Z_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[Z]]) ; CHECK-NEXT: br i1 [[Z]], label [[BOTH:%.*]], label [[NOPE:%.*]] ; CHECK: both: ; CHECK-NEXT: call void @foo(i1 [[XGT_0]]) @@ -137,25 +137,25 @@ ; CHECK-NEXT: [[YZ:%.*]] = icmp eq i32 [[Y:%.*]], 0 ; CHECK-NEXT: [[Z:%.*]] = and i1 [[XZ]], [[YZ]] ; CHECK-NEXT: call void @llvm.assume(i1 [[Z]]) -; CHECK: [[TMP1:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[Z]]) -; CHECK: [[TMP2:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[Y]]) -; CHECK: [[TMP3:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[YZ]]) -; CHECK: [[TMP4:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X]]) -; CHECK: [[TMP5:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[XZ]]) +; CHECK: [[TMP1:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[Y]]) +; CHECK: [[TMP2:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[YZ]]) +; CHECK: [[TMP3:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X]]) +; CHECK: [[TMP4:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[XZ]]) +; CHECK: [[TMP5:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[Z]]) ; CHECK: [[DOT0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[TMP5]]) -; CHECK: [[DOT01:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[TMP4]]) -; CHECK: [[DOT02:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[TMP3]]) -; CHECK: [[DOT03:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[TMP2]]) -; CHECK: [[DOT04:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[TMP1]]) -; CHECK-NEXT: br i1 [[TMP1]], label [[BOTH:%.*]], label [[NOPE:%.*]] +; CHECK: [[DOT01:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[TMP4]]) +; CHECK: [[DOT02:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[TMP3]]) +; CHECK: [[DOT03:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[TMP2]]) +; CHECK: [[DOT04:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[TMP1]]) +; CHECK-NEXT: br i1 [[TMP5]], label [[BOTH:%.*]], label [[NOPE:%.*]] ; CHECK: both: -; CHECK-NEXT: call void @foo(i1 [[DOT0]]) -; CHECK-NEXT: call void @foo(i1 [[DOT02]]) -; CHECK-NEXT: call void @bar(i32 [[DOT01]]) -; CHECK-NEXT: call void @bar(i32 [[DOT03]]) +; CHECK-NEXT: call void @foo(i1 [[DOT01]]) +; CHECK-NEXT: call void @foo(i1 [[DOT03]]) +; CHECK-NEXT: call void @bar(i32 [[DOT02]]) +; CHECK-NEXT: call void @bar(i32 [[DOT04]]) ; CHECK-NEXT: ret void ; CHECK: nope: -; CHECK-NEXT: call void @foo(i1 [[DOT04]]) +; CHECK-NEXT: call void @foo(i1 [[DOT0]]) ; CHECK-NEXT: ret void ; %xz = icmp eq i32 %x, 0 @@ -182,8 +182,9 @@ ; CHECK-NEXT: [[YZ:%.*]] = icmp eq i32 [[Y:%.*]], 0 ; CHECK-NEXT: [[Z:%.*]] = or i1 [[XZ]], [[YZ]] ; CHECK-NEXT: call void @llvm.assume(i1 [[Z]]) -; CHECK: [[Z_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[Z]]) -; CHECK-NEXT: br i1 [[Z]], label [[BOTH:%.*]], label [[NOPE:%.*]] +; CHECK: [[TMP1:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[Z]]) +; CHECK: [[DOT0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[TMP1]]) +; CHECK-NEXT: br i1 [[TMP1]], label [[BOTH:%.*]], label [[NOPE:%.*]] ; CHECK: both: ; CHECK-NEXT: call void @foo(i1 [[XZ]]) ; CHECK-NEXT: call void @foo(i1 [[YZ]]) @@ -191,7 +192,7 @@ ; CHECK-NEXT: call void @bar(i32 [[Y]]) ; CHECK-NEXT: ret void ; CHECK: nope: -; CHECK-NEXT: call void @foo(i1 [[Z_0]]) +; CHECK-NEXT: call void @foo(i1 [[DOT0]]) ; CHECK-NEXT: ret void ; %xz = icmp eq i32 %x, 0 @@ -214,18 +215,23 @@ ; CHECK-LABEL: @test_and_one_unknown_cond( ; CHECK-NEXT: [[C2:%.*]] = icmp eq i32 [[X:%.*]], 0 ; CHECK-NEXT: [[A:%.*]] = and i1 [[C1:%.*]], [[C2]] +; CHECK: [[A_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A]]) +; CHECK: [[A_1:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A]]) +; CHECK: [[C1_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[C1]]) +; CHECK: [[C2_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[C2]]) +; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X]]) ; CHECK-NEXT: br i1 [[A]], label [[BOTH:%.*]], label [[NOPE:%.*]] ; CHECK: both: -; CHECK-NEXT: call void @bar(i32 [[X]]) -; CHECK-NEXT: call void @foo(i1 [[C1]]) -; CHECK-NEXT: call void @foo(i1 [[C2]]) -; CHECK-NEXT: call void @foo(i1 [[A]]) +; CHECK-NEXT: call void @bar(i32 [[X_0]]) +; CHECK-NEXT: call void @foo(i1 [[C1_0]]) +; CHECK-NEXT: call void @foo(i1 [[C2_0]]) +; CHECK-NEXT: call void @foo(i1 [[A_0]]) ; CHECK-NEXT: ret void ; CHECK: nope: ; CHECK-NEXT: call void @bar(i32 [[X]]) ; CHECK-NEXT: call void @foo(i1 [[C1]]) ; CHECK-NEXT: call void @foo(i1 [[C2]]) -; CHECK-NEXT: call void @foo(i1 [[A]]) +; CHECK-NEXT: call void @foo(i1 [[A_1]]) ; CHECK-NEXT: ret void ; %c2 = icmp eq i32 %x, 0 @@ -251,18 +257,23 @@ ; CHECK-LABEL: @test_or_one_unknown_cond( ; CHECK-NEXT: [[C2:%.*]] = icmp eq i32 [[X:%.*]], 0 ; CHECK-NEXT: [[A:%.*]] = or i1 [[C1:%.*]], [[C2]] +; CHECK: [[A_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A]]) +; CHECK: [[A_1:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A]]) +; CHECK: [[C1_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[C1]]) +; CHECK: [[C2_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[C2]]) +; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X]]) ; CHECK-NEXT: br i1 [[A]], label [[NOPE:%.*]], label [[BOTH_INVERTED:%.*]] ; CHECK: both_inverted: -; CHECK-NEXT: call void @bar(i32 [[X]]) -; CHECK-NEXT: call void @foo(i1 [[C1]]) -; CHECK-NEXT: call void @foo(i1 [[C2]]) -; CHECK-NEXT: call void @foo(i1 [[A]]) +; CHECK-NEXT: call void @bar(i32 [[X_0]]) +; CHECK-NEXT: call void @foo(i1 [[C1_0]]) +; CHECK-NEXT: call void @foo(i1 [[C2_0]]) +; CHECK-NEXT: call void @foo(i1 [[A_1]]) ; CHECK-NEXT: ret void ; CHECK: nope: ; CHECK-NEXT: call void @bar(i32 [[X]]) ; CHECK-NEXT: call void @foo(i1 [[C1]]) ; CHECK-NEXT: call void @foo(i1 [[C2]]) -; CHECK-NEXT: call void @foo(i1 [[A]]) +; CHECK-NEXT: call void @foo(i1 [[A_0]]) ; CHECK-NEXT: ret void ; %c2 = icmp eq i32 %x, 0