diff --git a/llvm/lib/Transforms/Utils/PredicateInfo.cpp b/llvm/lib/Transforms/Utils/PredicateInfo.cpp --- a/llvm/lib/Transforms/Utils/PredicateInfo.cpp +++ b/llvm/lib/Transforms/Utils/PredicateInfo.cpp @@ -53,6 +53,10 @@ DEBUG_COUNTER(RenameCounter, "predicateinfo-rename", "Controls which variables are renamed with predicateinfo"); +// Maximum number of conditions considered for renaming for each branch/assume. +// This limits renaming of deep and/or chains. +static const unsigned MaxCondsPerBranch = 8; + namespace { // Given a predicate info that is a type of branching terminator, get the // branching block. @@ -367,6 +371,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 +385,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 +405,32 @@ 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; + SmallPtrSet Visited; + Worklist.push_back(II->getOperand(0)); + while (!Worklist.empty()) { + Value *Cond = Worklist.pop_back_val(); + if (!Visited.insert(Cond).second) + continue; + if (Visited.size() > MaxCondsPerBranch) + break; + + 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 +442,46 @@ 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)) + + 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; + SmallPtrSet Visited; + Worklist.push_back(BI->getCondition()); + while (!Worklist.empty()) { + Value *Cond = Worklist.pop_back_val(); + if (!Visited.insert(Cond).second) continue; - PredicateBase *PB = - new PredicateBranch(Op, BranchBB, Succ, Cond, TakenEdge); - addInfoFor(OpsToRename, Op, PB); - if (!Succ->getSinglePredecessor()) - EdgeUsesOnly.insert({BranchBB, Succ}); - } - }; + if (Visited.size() > MaxCondsPerBranch) + break; + + 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); + } - // 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"); + 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 diff --git a/llvm/test/Transforms/NewGVN/assume-equal.ll b/llvm/test/Transforms/NewGVN/assume-equal.ll --- a/llvm/test/Transforms/NewGVN/assume-equal.ll +++ b/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]] diff --git a/llvm/test/Transforms/SCCP/conditions-ranges.ll b/llvm/test/Transforms/SCCP/conditions-ranges.ll --- a/llvm/test/Transforms/SCCP/conditions-ranges.ll +++ b/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 diff --git a/llvm/test/Transforms/Util/PredicateInfo/condprop.ll b/llvm/test/Transforms/Util/PredicateInfo/condprop.ll --- a/llvm/test/Transforms/Util/PredicateInfo/condprop.ll +++ b/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]] diff --git a/llvm/test/Transforms/Util/PredicateInfo/testandor.ll b/llvm/test/Transforms/Util/PredicateInfo/testandor.ll --- a/llvm/test/Transforms/Util/PredicateInfo/testandor.ll +++ b/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 @@ -288,20 +299,26 @@ ; CHECK-LABEL: @test_and_chain( ; CHECK-NEXT: [[AND1:%.*]] = and i1 [[A:%.*]], [[B:%.*]] ; CHECK-NEXT: [[AND2:%.*]] = and i1 [[AND1]], [[C:%.*]] +; CHECK: [[AND2_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[AND2]]) +; CHECK: [[AND2_1:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[AND2]]) +; CHECK: [[AND1_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[AND1]]) +; CHECK: [[A_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A]]) +; CHECK: [[B_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[B]]) +; CHECK: [[C_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[C]]) ; CHECK-NEXT: br i1 [[AND2]], label [[IF:%.*]], label [[ELSE:%.*]] ; CHECK: if: -; CHECK-NEXT: call void @foo(i1 [[A]]) -; CHECK-NEXT: call void @foo(i1 [[B]]) -; CHECK-NEXT: call void @foo(i1 [[C]]) -; CHECK-NEXT: call void @foo(i1 [[AND1]]) -; CHECK-NEXT: call void @foo(i1 [[AND2]]) +; CHECK-NEXT: call void @foo(i1 [[A_0]]) +; CHECK-NEXT: call void @foo(i1 [[B_0]]) +; CHECK-NEXT: call void @foo(i1 [[C_0]]) +; CHECK-NEXT: call void @foo(i1 [[AND1_0]]) +; CHECK-NEXT: call void @foo(i1 [[AND2_0]]) ; CHECK-NEXT: ret void ; CHECK: else: ; CHECK-NEXT: call void @foo(i1 [[A]]) ; CHECK-NEXT: call void @foo(i1 [[B]]) ; CHECK-NEXT: call void @foo(i1 [[C]]) ; CHECK-NEXT: call void @foo(i1 [[AND1]]) -; CHECK-NEXT: call void @foo(i1 [[AND2]]) +; CHECK-NEXT: call void @foo(i1 [[AND2_1]]) ; CHECK-NEXT: ret void ; %and1 = and i1 %a, %b @@ -329,20 +346,26 @@ ; CHECK-LABEL: @test_or_chain( ; CHECK-NEXT: [[OR1:%.*]] = or i1 [[A:%.*]], [[B:%.*]] ; CHECK-NEXT: [[OR2:%.*]] = or i1 [[OR1]], [[C:%.*]] +; CHECK: [[OR2_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[OR2]]) +; CHECK: [[OR2_1:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[OR2]]) +; CHECK: [[OR1_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[OR1]]) +; CHECK: [[A_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A]]) +; CHECK: [[B_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[B]]) +; CHECK: [[C_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[C]]) ; CHECK-NEXT: br i1 [[OR2]], label [[IF:%.*]], label [[ELSE:%.*]] ; CHECK: if: ; CHECK-NEXT: call void @foo(i1 [[A]]) ; CHECK-NEXT: call void @foo(i1 [[B]]) ; CHECK-NEXT: call void @foo(i1 [[C]]) ; CHECK-NEXT: call void @foo(i1 [[OR1]]) -; CHECK-NEXT: call void @foo(i1 [[OR2]]) +; CHECK-NEXT: call void @foo(i1 [[OR2_0]]) ; CHECK-NEXT: ret void ; CHECK: else: -; CHECK-NEXT: call void @foo(i1 [[A]]) -; CHECK-NEXT: call void @foo(i1 [[B]]) -; CHECK-NEXT: call void @foo(i1 [[C]]) -; CHECK-NEXT: call void @foo(i1 [[OR1]]) -; CHECK-NEXT: call void @foo(i1 [[OR2]]) +; CHECK-NEXT: call void @foo(i1 [[A_0]]) +; CHECK-NEXT: call void @foo(i1 [[B_0]]) +; CHECK-NEXT: call void @foo(i1 [[C_0]]) +; CHECK-NEXT: call void @foo(i1 [[OR1_0]]) +; CHECK-NEXT: call void @foo(i1 [[OR2_1]]) ; CHECK-NEXT: ret void ; %or1 = or i1 %a, %b @@ -370,20 +393,24 @@ ; CHECK-LABEL: @test_and_or_mixed( ; CHECK-NEXT: [[OR:%.*]] = or i1 [[A:%.*]], [[B:%.*]] ; CHECK-NEXT: [[AND:%.*]] = and i1 [[OR]], [[C:%.*]] +; CHECK: [[AND_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[AND]]) +; CHECK: [[AND_1:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[AND]]) +; CHECK: [[OR_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[OR]]) +; CHECK: [[C_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[C]]) ; CHECK-NEXT: br i1 [[AND]], label [[IF:%.*]], label [[ELSE:%.*]] ; CHECK: if: ; CHECK-NEXT: call void @foo(i1 [[A]]) ; CHECK-NEXT: call void @foo(i1 [[B]]) -; CHECK-NEXT: call void @foo(i1 [[C]]) -; CHECK-NEXT: call void @foo(i1 [[OR]]) -; CHECK-NEXT: call void @foo(i1 [[AND]]) +; CHECK-NEXT: call void @foo(i1 [[C_0]]) +; CHECK-NEXT: call void @foo(i1 [[OR_0]]) +; CHECK-NEXT: call void @foo(i1 [[AND_0]]) ; CHECK-NEXT: ret void ; CHECK: else: ; CHECK-NEXT: call void @foo(i1 [[A]]) ; CHECK-NEXT: call void @foo(i1 [[B]]) ; CHECK-NEXT: call void @foo(i1 [[C]]) ; CHECK-NEXT: call void @foo(i1 [[OR]]) -; CHECK-NEXT: call void @foo(i1 [[AND]]) +; CHECK-NEXT: call void @foo(i1 [[AND_1]]) ; CHECK-NEXT: ret void ; %or = or i1 %a, %b @@ -423,31 +450,38 @@ ; CHECK-NEXT: [[A13:%.*]] = and i1 [[A12]], true ; CHECK-NEXT: [[A14:%.*]] = and i1 [[A13]], true ; CHECK-NEXT: [[A15:%.*]] = and i1 [[A14]], true +; CHECK: [[A15_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A15]]) +; CHECK: [[A15_1:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A15]]) +; CHECK: [[A14_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A14]]) +; CHECK: [[A13_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A13]]) +; CHECK: [[A12_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A12]]) +; CHECK: [[A11_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A11]]) +; CHECK: [[A10_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A10]]) +; CHECK: [[A9_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A9]]) +; CHECK: [[A8_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A8]]) ; CHECK-NEXT: br i1 [[A15]], label [[IF:%.*]], label [[ELSE:%.*]] ; CHECK: if: ; CHECK-NEXT: call void @foo(i1 [[A1]]) ; CHECK-NEXT: call void @foo(i1 [[A2]]) ; CHECK-NEXT: call void @foo(i1 [[A3]]) ; CHECK-NEXT: call void @foo(i1 [[A4]]) -; CHECK-NEXT: call void @foo(i1 [[A4]]) ; CHECK-NEXT: call void @foo(i1 [[A5]]) ; CHECK-NEXT: call void @foo(i1 [[A6]]) ; CHECK-NEXT: call void @foo(i1 [[A7]]) -; CHECK-NEXT: call void @foo(i1 [[A8]]) -; CHECK-NEXT: call void @foo(i1 [[A9]]) -; CHECK-NEXT: call void @foo(i1 [[A10]]) -; CHECK-NEXT: call void @foo(i1 [[A11]]) -; CHECK-NEXT: call void @foo(i1 [[A12]]) -; CHECK-NEXT: call void @foo(i1 [[A13]]) -; CHECK-NEXT: call void @foo(i1 [[A14]]) -; CHECK-NEXT: call void @foo(i1 [[A15]]) +; CHECK-NEXT: call void @foo(i1 [[A8_0]]) +; CHECK-NEXT: call void @foo(i1 [[A9_0]]) +; CHECK-NEXT: call void @foo(i1 [[A10_0]]) +; CHECK-NEXT: call void @foo(i1 [[A11_0]]) +; CHECK-NEXT: call void @foo(i1 [[A12_0]]) +; CHECK-NEXT: call void @foo(i1 [[A13_0]]) +; CHECK-NEXT: call void @foo(i1 [[A14_0]]) +; CHECK-NEXT: call void @foo(i1 [[A15_0]]) ; CHECK-NEXT: ret void ; CHECK: else: ; CHECK-NEXT: call void @foo(i1 [[A1]]) ; CHECK-NEXT: call void @foo(i1 [[A2]]) ; CHECK-NEXT: call void @foo(i1 [[A3]]) ; CHECK-NEXT: call void @foo(i1 [[A4]]) -; CHECK-NEXT: call void @foo(i1 [[A4]]) ; CHECK-NEXT: call void @foo(i1 [[A5]]) ; CHECK-NEXT: call void @foo(i1 [[A6]]) ; CHECK-NEXT: call void @foo(i1 [[A7]]) @@ -458,7 +492,7 @@ ; CHECK-NEXT: call void @foo(i1 [[A12]]) ; CHECK-NEXT: call void @foo(i1 [[A13]]) ; CHECK-NEXT: call void @foo(i1 [[A14]]) -; CHECK-NEXT: call void @foo(i1 [[A15]]) +; CHECK-NEXT: call void @foo(i1 [[A15_1]]) ; CHECK-NEXT: ret void ; %a2 = and i1 %a1, true @@ -482,7 +516,6 @@ call void @foo(i1 %a2) call void @foo(i1 %a3) call void @foo(i1 %a4) - call void @foo(i1 %a4) call void @foo(i1 %a5) call void @foo(i1 %a6) call void @foo(i1 %a7) @@ -501,7 +534,6 @@ call void @foo(i1 %a2) call void @foo(i1 %a3) call void @foo(i1 %a4) - call void @foo(i1 %a4) call void @foo(i1 %a5) call void @foo(i1 %a6) call void @foo(i1 %a7) @@ -532,31 +564,38 @@ ; CHECK-NEXT: [[A13:%.*]] = and i1 [[A12]], [[A12]] ; CHECK-NEXT: [[A14:%.*]] = and i1 [[A13]], [[A13]] ; CHECK-NEXT: [[A15:%.*]] = and i1 [[A14]], [[A14]] +; CHECK: [[A15_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A15]]) +; CHECK: [[A15_1:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A15]]) +; CHECK: [[A14_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A14]]) +; CHECK: [[A13_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A13]]) +; CHECK: [[A12_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A12]]) +; CHECK: [[A11_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A11]]) +; CHECK: [[A10_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A10]]) +; CHECK: [[A9_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A9]]) +; CHECK: [[A8_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A8]]) ; CHECK-NEXT: br i1 [[A15]], label [[IF:%.*]], label [[ELSE:%.*]] ; CHECK: if: ; CHECK-NEXT: call void @foo(i1 [[A1]]) ; CHECK-NEXT: call void @foo(i1 [[A2]]) ; CHECK-NEXT: call void @foo(i1 [[A3]]) ; CHECK-NEXT: call void @foo(i1 [[A4]]) -; CHECK-NEXT: call void @foo(i1 [[A4]]) ; CHECK-NEXT: call void @foo(i1 [[A5]]) ; CHECK-NEXT: call void @foo(i1 [[A6]]) ; CHECK-NEXT: call void @foo(i1 [[A7]]) -; CHECK-NEXT: call void @foo(i1 [[A8]]) -; CHECK-NEXT: call void @foo(i1 [[A9]]) -; CHECK-NEXT: call void @foo(i1 [[A10]]) -; CHECK-NEXT: call void @foo(i1 [[A11]]) -; CHECK-NEXT: call void @foo(i1 [[A12]]) -; CHECK-NEXT: call void @foo(i1 [[A13]]) -; CHECK-NEXT: call void @foo(i1 [[A14]]) -; CHECK-NEXT: call void @foo(i1 [[A15]]) +; CHECK-NEXT: call void @foo(i1 [[A8_0]]) +; CHECK-NEXT: call void @foo(i1 [[A9_0]]) +; CHECK-NEXT: call void @foo(i1 [[A10_0]]) +; CHECK-NEXT: call void @foo(i1 [[A11_0]]) +; CHECK-NEXT: call void @foo(i1 [[A12_0]]) +; CHECK-NEXT: call void @foo(i1 [[A13_0]]) +; CHECK-NEXT: call void @foo(i1 [[A14_0]]) +; CHECK-NEXT: call void @foo(i1 [[A15_0]]) ; CHECK-NEXT: ret void ; CHECK: else: ; CHECK-NEXT: call void @foo(i1 [[A1]]) ; CHECK-NEXT: call void @foo(i1 [[A2]]) ; CHECK-NEXT: call void @foo(i1 [[A3]]) ; CHECK-NEXT: call void @foo(i1 [[A4]]) -; CHECK-NEXT: call void @foo(i1 [[A4]]) ; CHECK-NEXT: call void @foo(i1 [[A5]]) ; CHECK-NEXT: call void @foo(i1 [[A6]]) ; CHECK-NEXT: call void @foo(i1 [[A7]]) @@ -567,7 +606,7 @@ ; CHECK-NEXT: call void @foo(i1 [[A12]]) ; CHECK-NEXT: call void @foo(i1 [[A13]]) ; CHECK-NEXT: call void @foo(i1 [[A14]]) -; CHECK-NEXT: call void @foo(i1 [[A15]]) +; CHECK-NEXT: call void @foo(i1 [[A15_1]]) ; CHECK-NEXT: ret void ; %a2 = and i1 %a1, %a1 @@ -591,7 +630,6 @@ call void @foo(i1 %a2) call void @foo(i1 %a3) call void @foo(i1 %a4) - call void @foo(i1 %a4) call void @foo(i1 %a5) call void @foo(i1 %a6) call void @foo(i1 %a7) @@ -610,7 +648,6 @@ call void @foo(i1 %a2) call void @foo(i1 %a3) call void @foo(i1 %a4) - call void @foo(i1 %a4) call void @foo(i1 %a5) call void @foo(i1 %a6) call void @foo(i1 %a7) @@ -641,13 +678,21 @@ ; CHECK-NEXT: [[A13:%.*]] = or i1 [[A12]], [[A12]] ; CHECK-NEXT: [[A14:%.*]] = or i1 [[A13]], [[A13]] ; CHECK-NEXT: [[A15:%.*]] = or i1 [[A14]], [[A14]] +; CHECK: [[A15_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A15]]) +; CHECK: [[A15_1:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A15]]) +; CHECK: [[A14_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A14]]) +; CHECK: [[A13_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A13]]) +; CHECK: [[A12_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A12]]) +; CHECK: [[A11_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A11]]) +; CHECK: [[A10_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A10]]) +; CHECK: [[A9_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A9]]) +; CHECK: [[A8_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A8]]) ; CHECK-NEXT: br i1 [[A15]], label [[IF:%.*]], label [[ELSE:%.*]] ; CHECK: if: ; CHECK-NEXT: call void @foo(i1 [[A1]]) ; CHECK-NEXT: call void @foo(i1 [[A2]]) ; CHECK-NEXT: call void @foo(i1 [[A3]]) ; CHECK-NEXT: call void @foo(i1 [[A4]]) -; CHECK-NEXT: call void @foo(i1 [[A4]]) ; CHECK-NEXT: call void @foo(i1 [[A5]]) ; CHECK-NEXT: call void @foo(i1 [[A6]]) ; CHECK-NEXT: call void @foo(i1 [[A7]]) @@ -658,25 +703,24 @@ ; CHECK-NEXT: call void @foo(i1 [[A12]]) ; CHECK-NEXT: call void @foo(i1 [[A13]]) ; CHECK-NEXT: call void @foo(i1 [[A14]]) -; CHECK-NEXT: call void @foo(i1 [[A15]]) +; CHECK-NEXT: call void @foo(i1 [[A15_0]]) ; CHECK-NEXT: ret void ; CHECK: else: ; CHECK-NEXT: call void @foo(i1 [[A1]]) ; CHECK-NEXT: call void @foo(i1 [[A2]]) ; CHECK-NEXT: call void @foo(i1 [[A3]]) ; CHECK-NEXT: call void @foo(i1 [[A4]]) -; CHECK-NEXT: call void @foo(i1 [[A4]]) ; CHECK-NEXT: call void @foo(i1 [[A5]]) ; CHECK-NEXT: call void @foo(i1 [[A6]]) ; CHECK-NEXT: call void @foo(i1 [[A7]]) -; CHECK-NEXT: call void @foo(i1 [[A8]]) -; CHECK-NEXT: call void @foo(i1 [[A9]]) -; CHECK-NEXT: call void @foo(i1 [[A10]]) -; CHECK-NEXT: call void @foo(i1 [[A11]]) -; CHECK-NEXT: call void @foo(i1 [[A12]]) -; CHECK-NEXT: call void @foo(i1 [[A13]]) -; CHECK-NEXT: call void @foo(i1 [[A14]]) -; CHECK-NEXT: call void @foo(i1 [[A15]]) +; CHECK-NEXT: call void @foo(i1 [[A8_0]]) +; CHECK-NEXT: call void @foo(i1 [[A9_0]]) +; CHECK-NEXT: call void @foo(i1 [[A10_0]]) +; CHECK-NEXT: call void @foo(i1 [[A11_0]]) +; CHECK-NEXT: call void @foo(i1 [[A12_0]]) +; CHECK-NEXT: call void @foo(i1 [[A13_0]]) +; CHECK-NEXT: call void @foo(i1 [[A14_0]]) +; CHECK-NEXT: call void @foo(i1 [[A15_1]]) ; CHECK-NEXT: ret void ; %a2 = or i1 %a1, %a1 @@ -700,7 +744,6 @@ call void @foo(i1 %a2) call void @foo(i1 %a3) call void @foo(i1 %a4) - call void @foo(i1 %a4) call void @foo(i1 %a5) call void @foo(i1 %a6) call void @foo(i1 %a7) @@ -719,7 +762,6 @@ call void @foo(i1 %a2) call void @foo(i1 %a3) call void @foo(i1 %a4) - call void @foo(i1 %a4) call void @foo(i1 %a5) call void @foo(i1 %a6) call void @foo(i1 %a7) @@ -739,11 +781,16 @@ ; CHECK-NEXT: [[AND1:%.*]] = and i1 [[A:%.*]], [[B:%.*]] ; CHECK-NEXT: [[AND2:%.*]] = and i1 [[AND1]], [[C:%.*]] ; CHECK-NEXT: call void @llvm.assume(i1 [[AND2]]) -; CHECK-NEXT: call void @foo(i1 [[A]]) -; CHECK-NEXT: call void @foo(i1 [[B]]) -; CHECK-NEXT: call void @foo(i1 [[C]]) -; CHECK-NEXT: call void @foo(i1 [[AND1]]) -; CHECK-NEXT: call void @foo(i1 [[AND2]]) +; CHECK: [[TMP1:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[C]]) +; CHECK: [[TMP2:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[B]]) +; CHECK: [[TMP3:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A]]) +; CHECK: [[TMP4:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[AND1]]) +; CHECK: [[TMP5:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[AND2]]) +; CHECK-NEXT: call void @foo(i1 [[TMP3]]) +; CHECK-NEXT: call void @foo(i1 [[TMP2]]) +; CHECK-NEXT: call void @foo(i1 [[TMP1]]) +; CHECK-NEXT: call void @foo(i1 [[TMP4]]) +; CHECK-NEXT: call void @foo(i1 [[TMP5]]) ; CHECK-NEXT: ret void ; %and1 = and i1 %a, %b @@ -762,11 +809,12 @@ ; CHECK-NEXT: [[OR1:%.*]] = or i1 [[A:%.*]], [[B:%.*]] ; CHECK-NEXT: [[OR2:%.*]] = or i1 [[OR1]], [[C:%.*]] ; CHECK-NEXT: call void @llvm.assume(i1 [[OR2]]) +; CHECK: [[TMP1:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[OR2]]) ; CHECK-NEXT: call void @foo(i1 [[A]]) ; CHECK-NEXT: call void @foo(i1 [[B]]) ; CHECK-NEXT: call void @foo(i1 [[C]]) ; CHECK-NEXT: call void @foo(i1 [[OR1]]) -; CHECK-NEXT: call void @foo(i1 [[OR2]]) +; CHECK-NEXT: call void @foo(i1 [[TMP1]]) ; CHECK-NEXT: ret void ; %or1 = or i1 %a, %b @@ -797,22 +845,29 @@ ; CHECK-NEXT: [[A14:%.*]] = and i1 [[A13]], [[A13]] ; CHECK-NEXT: [[A15:%.*]] = and i1 [[A14]], [[A14]] ; CHECK-NEXT: call void @llvm.assume(i1 [[A15]]) +; CHECK: [[TMP1:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A8]]) +; CHECK: [[TMP2:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A9]]) +; CHECK: [[TMP3:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A10]]) +; CHECK: [[TMP4:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A11]]) +; CHECK: [[TMP5:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A12]]) +; CHECK: [[TMP6:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A13]]) +; CHECK: [[TMP7:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A14]]) +; CHECK: [[TMP8:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[A15]]) ; CHECK-NEXT: call void @foo(i1 [[A1]]) ; CHECK-NEXT: call void @foo(i1 [[A2]]) ; CHECK-NEXT: call void @foo(i1 [[A3]]) ; CHECK-NEXT: call void @foo(i1 [[A4]]) -; CHECK-NEXT: call void @foo(i1 [[A4]]) ; CHECK-NEXT: call void @foo(i1 [[A5]]) ; CHECK-NEXT: call void @foo(i1 [[A6]]) ; CHECK-NEXT: call void @foo(i1 [[A7]]) -; CHECK-NEXT: call void @foo(i1 [[A8]]) -; CHECK-NEXT: call void @foo(i1 [[A9]]) -; CHECK-NEXT: call void @foo(i1 [[A10]]) -; CHECK-NEXT: call void @foo(i1 [[A11]]) -; CHECK-NEXT: call void @foo(i1 [[A12]]) -; CHECK-NEXT: call void @foo(i1 [[A13]]) -; CHECK-NEXT: call void @foo(i1 [[A14]]) -; CHECK-NEXT: call void @foo(i1 [[A15]]) +; CHECK-NEXT: call void @foo(i1 [[TMP1]]) +; CHECK-NEXT: call void @foo(i1 [[TMP2]]) +; CHECK-NEXT: call void @foo(i1 [[TMP3]]) +; CHECK-NEXT: call void @foo(i1 [[TMP4]]) +; CHECK-NEXT: call void @foo(i1 [[TMP5]]) +; CHECK-NEXT: call void @foo(i1 [[TMP6]]) +; CHECK-NEXT: call void @foo(i1 [[TMP7]]) +; CHECK-NEXT: call void @foo(i1 [[TMP8]]) ; CHECK-NEXT: ret void ; %a2 = and i1 %a1, %a1 @@ -834,7 +889,6 @@ call void @foo(i1 %a2) call void @foo(i1 %a3) call void @foo(i1 %a4) - call void @foo(i1 %a4) call void @foo(i1 %a5) call void @foo(i1 %a6) call void @foo(i1 %a7)