diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h --- a/llvm/include/llvm/Analysis/ValueTracking.h +++ b/llvm/include/llvm/Analysis/ValueTracking.h @@ -617,6 +617,18 @@ /// if I is executed and that operand has a poison value. void getGuaranteedNonPoisonOps(const Instruction *I, SmallPtrSetImpl &Ops); + +/// Return true if \p PoisonOp's user yields poison or raises UB if its +/// operand \p PoisonOp is poison. +/// +/// If \p PoisonOp is a vector or an aggregate and the operation's result is a +/// single value, any poison element in /p PoisonOp should make the result +/// poison or raise UB. +/// +/// To filter out operands that raise UB on poison, you can use +/// getGuaranteedNonPoisonOp. +bool propagatesPoison(const Use &PoisonOp); + /// Insert operands of I into Ops such that I will trigger undefined behavior /// if I is executed and that operand is not a well-defined value /// (i.e. has undef bits or poison). diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -7294,8 +7294,9 @@ while (!PoisonStack.empty() && !LatchControlDependentOnPoison) { const Instruction *Poison = PoisonStack.pop_back_val(); - for (const auto *PoisonUser : Poison->users()) { - if (propagatesPoison(cast(PoisonUser))) { + for (const Use &U : Poison->uses()) { + const User *PoisonUser = U.getUser(); + if (propagatesPoison(U)) { if (Pushed.insert(cast(PoisonUser)).second) PoisonStack.push_back(cast(PoisonUser)); } else if (auto *BI = dyn_cast(PoisonUser)) { diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -5330,15 +5330,12 @@ return false; if (const auto *I = dyn_cast(V)) { - if (propagatesPoison(cast(I))) - return any_of(I->operands(), [=](const Value *Op) { - return directlyImpliesPoison(ValAssumedPoison, Op, Depth + 1); - }); + if (any_of(I->operands(), [=](const Use &Op) { + return propagatesPoison(Op) && + directlyImpliesPoison(ValAssumedPoison, Op, Depth + 1); + })) + return true; - // 'select ValAssumedPoison, _, _' is poison. - if (const auto *SI = dyn_cast(I)) - return directlyImpliesPoison(ValAssumedPoison, SI->getCondition(), - Depth + 1); // V = extractvalue V0, idx // V2 = extractvalue V0, idx2 // V0's elements are all poison or not. (e.g., add_with_overflow) @@ -5496,7 +5493,8 @@ else if (PoisonOnly && isa(Cond)) { // For poison, we can analyze further auto *Opr = cast(Cond); - if (propagatesPoison(Opr) && is_contained(Opr->operand_values(), V)) + if (any_of(Opr->operands(), + [V](const Use &U) { return V == U && propagatesPoison(U); })) return true; } } @@ -5618,13 +5616,15 @@ llvm_unreachable("Instruction not contained in its own parent basic block."); } -bool llvm::propagatesPoison(const Operator *I) { +bool llvm::propagatesPoison(const Use &PoisonOp) { + const Operator *I = cast(PoisonOp.getUser()); switch (I->getOpcode()) { case Instruction::Freeze: - case Instruction::Select: case Instruction::PHI: case Instruction::Invoke: return false; + case Instruction::Select: + return PoisonOp.getOperandNo() == 0; case Instruction::Call: if (auto *II = dyn_cast(I)) { switch (II->getIntrinsicID()) { @@ -5807,7 +5807,8 @@ // If this instruction propagates poison, mark it as poison if any of // its operands are poison - if (propagatesPoison(cast(&I))) { + if (any_of(I.operands(), + [=](const Use &Op) { return propagatesPoison(Op); })) { for (const Value *Op : I.operands()) { if (YieldsPoison.count(Op)) { YieldsPoison.insert(&I); diff --git a/llvm/lib/Transforms/Instrumentation/PoisonChecking.cpp b/llvm/lib/Transforms/Instrumentation/PoisonChecking.cpp --- a/llvm/lib/Transforms/Instrumentation/PoisonChecking.cpp +++ b/llvm/lib/Transforms/Instrumentation/PoisonChecking.cpp @@ -289,9 +289,11 @@ } SmallVector Checks; - if (propagatesPoison(cast(&I))) - for (Value *V : I.operands()) - Checks.push_back(getPoisonFor(ValToPoison, V)); + for (const Use &U : I.operands()) { + if (ValToPoison.find(U) != ValToPoison.end() && + propagatesPoison(U) ) + Checks.push_back(getPoisonFor(ValToPoison, U)); + } if (canCreatePoison(cast(&I))) generateCreationChecks(I, Checks); diff --git a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp --- a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp +++ b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp @@ -788,7 +788,9 @@ // If we can't analyze propagation through this instruction, just skip it // and transitive users. Safe as false is a conservative result. - if (!propagatesPoison(cast(I)) && I != Root) + if (I != Root && !any_of(I->operands(), [&KnownPoison](const Use &U) { + return KnownPoison.contains(U) && propagatesPoison(U); + })) continue; if (KnownPoison.insert(I).second) diff --git a/llvm/test/Analysis/LoopAccessAnalysis/forked-pointers.ll b/llvm/test/Analysis/LoopAccessAnalysis/forked-pointers.ll --- a/llvm/test/Analysis/LoopAccessAnalysis/forked-pointers.ll +++ b/llvm/test/Analysis/LoopAccessAnalysis/forked-pointers.ll @@ -27,10 +27,10 @@ ; CHECK-NEXT: Member: {%Dest,+,4}<%loop> ; CHECK-NEXT: Group [[G2]]: ; CHECK-NEXT: (Low: %Base1 High: (400 + %Base1)) -; CHECK-NEXT: Member: {%Base1,+,4}<%loop> +; CHECK-NEXT: Member: {%Base1,+,4}<%loop> ; CHECK-NEXT: Group [[G3]]: ; CHECK-NEXT: (Low: %Base2 High: (400 + %Base2)) -; CHECK-NEXT: Member: {%Base2,+,4}<%loop> +; CHECK-NEXT: Member: {%Base2,+,4}<%loop> ; CHECK-EMPTY: ; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. ; CHECK-NEXT: SCEV assumptions: diff --git a/llvm/test/Analysis/ScalarEvolution/exit-count-select-safe.ll b/llvm/test/Analysis/ScalarEvolution/exit-count-select-safe.ll --- a/llvm/test/Analysis/ScalarEvolution/exit-count-select-safe.ll +++ b/llvm/test/Analysis/ScalarEvolution/exit-count-select-safe.ll @@ -5,16 +5,16 @@ ; CHECK-LABEL: 'logical_and_2ops' ; CHECK-NEXT: Classifying expressions for: @logical_and_2ops ; CHECK-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin_seq %m) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin %m) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq %m)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin %m)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (%cond_p0 umin %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_2ops -; CHECK-NEXT: Loop %loop: backedge-taken count is (%n umin_seq %m) +; CHECK-NEXT: Loop %loop: backedge-taken count is (%n umin %m) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 -; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (%n umin_seq %m) -; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (%n umin_seq %m) +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (%n umin %m) +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (%n umin %m) ; CHECK-NEXT: Predicates: ; CHECK: Loop %loop: Trip multiple is 1 ; @@ -35,16 +35,16 @@ ; CHECK-LABEL: 'logical_or_2ops' ; CHECK-NEXT: Classifying expressions for: @logical_or_2ops ; CHECK-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin_seq %m) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin %m) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq %m)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin %m)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 true, i1 %cond_p1 -; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq (true + %cond_p1))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (true + ((true + %cond_p0) umin (true + %cond_p1))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_or_2ops -; CHECK-NEXT: Loop %loop: backedge-taken count is (%n umin_seq %m) +; CHECK-NEXT: Loop %loop: backedge-taken count is (%n umin %m) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 -; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (%n umin_seq %m) -; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (%n umin_seq %m) +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (%n umin %m) +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (%n umin %m) ; CHECK-NEXT: Predicates: ; CHECK: Loop %loop: Trip multiple is 1 ; @@ -65,18 +65,18 @@ ; CHECK-LABEL: 'logical_and_3ops' ; CHECK-NEXT: Classifying expressions for: @logical_and_3ops ; CHECK-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin_seq %m umin_seq %k) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin %m umin %k) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq %m umin_seq %k)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin %m umin %k)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond_p3 = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (%cond_p0 umin %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %cond = select i1 %cond_p3, i1 %cond_p2, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1 umin_seq %cond_p2) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (%cond_p0 umin %cond_p1 umin %cond_p2) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_3ops -; CHECK-NEXT: Loop %loop: backedge-taken count is (%n umin_seq %m umin_seq %k) +; CHECK-NEXT: Loop %loop: backedge-taken count is (%n umin %m umin %k) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 -; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (%n umin_seq %m umin_seq %k) -; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (%n umin_seq %m umin_seq %k) +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (%n umin %m umin %k) +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (%n umin %m umin %k) ; CHECK-NEXT: Predicates: ; CHECK: Loop %loop: Trip multiple is 1 ; @@ -99,18 +99,18 @@ ; CHECK-LABEL: 'logical_or_3ops' ; CHECK-NEXT: Classifying expressions for: @logical_or_3ops ; CHECK-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin_seq %m umin_seq %k) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin %m umin %k) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq %m umin_seq %k)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin %m umin %k)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond_p3 = select i1 %cond_p0, i1 true, i1 %cond_p1 -; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq (true + %cond_p1))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (true + ((true + %cond_p0) umin (true + %cond_p1))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %cond = select i1 %cond_p3, i1 true, i1 %cond_p2 -; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq (true + %cond_p1) umin_seq (true + %cond_p2))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (true + ((true + %cond_p2) umin (true + %cond_p0) umin (true + %cond_p1))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_or_3ops -; CHECK-NEXT: Loop %loop: backedge-taken count is (%n umin_seq %m umin_seq %k) +; CHECK-NEXT: Loop %loop: backedge-taken count is (%n umin %m umin %k) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 -; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (%n umin_seq %m umin_seq %k) -; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (%n umin_seq %m umin_seq %k) +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (%n umin %m umin %k) +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (%n umin %m umin %k) ; CHECK-NEXT: Predicates: ; CHECK: Loop %loop: Trip multiple is 1 ; @@ -133,20 +133,20 @@ ; CHECK-LABEL: 'logical_or_3ops_duplicate' ; CHECK-NEXT: Classifying expressions for: @logical_or_3ops_duplicate ; CHECK-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin_seq %m umin_seq %k) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin %m umin %k) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq %m umin_seq %k)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin %m umin %k)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond_p4 = select i1 %cond_p0, i1 true, i1 %cond_p1 -; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq (true + %cond_p1))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (true + ((true + %cond_p0) umin (true + %cond_p1))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %cond_p5 = select i1 %cond_p4, i1 true, i1 %cond_p2 -; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq (true + %cond_p1) umin_seq (true + %cond_p2))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (true + ((true + %cond_p2) umin (true + %cond_p0) umin (true + %cond_p1))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %cond = select i1 %cond_p5, i1 true, i1 %cond_p3 -; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq (true + %cond_p1) umin_seq (true + %cond_p2) umin_seq (true + %cond_p3))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (true + ((true + %cond_p3) umin (true + %cond_p2) umin (true + %cond_p0) umin (true + %cond_p1))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_or_3ops_duplicate -; CHECK-NEXT: Loop %loop: backedge-taken count is (%n umin_seq %m umin_seq %k) +; CHECK-NEXT: Loop %loop: backedge-taken count is (%n umin %m umin %k) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 -; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (%n umin_seq %m umin_seq %k) -; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (%n umin_seq %m umin_seq %k) +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (%n umin %m umin %k) +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (%n umin %m umin %k) ; CHECK-NEXT: Predicates: ; CHECK: Loop %loop: Trip multiple is 1 ; @@ -171,20 +171,20 @@ ; CHECK-LABEL: 'logical_or_3ops_redundant_uminseq_operand' ; CHECK-NEXT: Classifying expressions for: @logical_or_3ops_redundant_uminseq_operand ; CHECK-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: ((%n umin %m) umin_seq %k) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin %m umin %k) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((%n umin %m) umin_seq %k)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin %m umin %k)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %umin = call i32 @llvm.umin.i32(i32 %n, i32 %m) ; CHECK-NEXT: --> (%n umin %m) U: full-set S: full-set Exits: (%n umin %m) LoopDispositions: { %loop: Invariant } ; CHECK-NEXT: %cond_p3 = select i1 %cond_p0, i1 true, i1 %cond_p1 -; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq (true + %cond_p1))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (true + ((true + %cond_p0) umin (true + %cond_p1))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %cond = select i1 %cond_p3, i1 true, i1 %cond_p2 -; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq (true + %cond_p1) umin_seq (true + %cond_p2))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (true + ((true + %cond_p2) umin (true + %cond_p0) umin (true + %cond_p1))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_or_3ops_redundant_uminseq_operand -; CHECK-NEXT: Loop %loop: backedge-taken count is ((%n umin %m) umin_seq %k) +; CHECK-NEXT: Loop %loop: backedge-taken count is (%n umin %m umin %k) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 -; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((%n umin %m) umin_seq %k) -; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is ((%n umin %m) umin_seq %k) +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (%n umin %m umin %k) +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (%n umin %m umin %k) ; CHECK-NEXT: Predicates: ; CHECK: Loop %loop: Trip multiple is 1 ; @@ -208,20 +208,20 @@ ; CHECK-LABEL: 'logical_or_3ops_redundant_umin_operand' ; CHECK-NEXT: Classifying expressions for: @logical_or_3ops_redundant_umin_operand ; CHECK-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin_seq %k umin_seq %m) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: ((%n umin %k) umin_seq %m) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq %k umin_seq %m)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((%n umin %k) umin_seq %m)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %umin = call i32 @llvm.umin.i32(i32 %n, i32 %m) ; CHECK-NEXT: --> (%n umin %m) U: full-set S: full-set Exits: (%n umin %m) LoopDispositions: { %loop: Invariant } ; CHECK-NEXT: %cond_p3 = select i1 %cond_p0, i1 true, i1 %cond_p1 -; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq (true + %cond_p1))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (true + ((true + %cond_p0) umin (true + %cond_p1))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %cond = select i1 %cond_p3, i1 true, i1 %cond_p2 -; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq (true + %cond_p1) umin_seq (true + %cond_p2))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (true + ((true + %cond_p2) umin (true + %cond_p0) umin (true + %cond_p1))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_or_3ops_redundant_umin_operand -; CHECK-NEXT: Loop %loop: backedge-taken count is (%n umin_seq %k umin_seq %m) +; CHECK-NEXT: Loop %loop: backedge-taken count is ((%n umin %k) umin_seq %m) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 -; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (%n umin_seq %k umin_seq %m) -; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (%n umin_seq %k umin_seq %m) +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((%n umin %k) umin_seq %m) +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is ((%n umin %k) umin_seq %m) ; CHECK-NEXT: Predicates: ; CHECK: Loop %loop: Trip multiple is 1 ; @@ -245,22 +245,22 @@ ; CHECK-LABEL: 'logical_or_4ops_redundant_operand_across_umins' ; CHECK-NEXT: Classifying expressions for: @logical_or_4ops_redundant_operand_across_umins ; CHECK-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: ((%n umin %m) umin_seq %k umin_seq %q) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: ((%n umin %m umin %k) umin_seq %q) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((%n umin %m) umin_seq %k umin_seq %q)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((%n umin %m umin %k) umin_seq %q)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %umin = call i32 @llvm.umin.i32(i32 %n, i32 %m) ; CHECK-NEXT: --> (%n umin %m) U: full-set S: full-set Exits: (%n umin %m) LoopDispositions: { %loop: Invariant } ; CHECK-NEXT: %umin2 = call i32 @llvm.umin.i32(i32 %n, i32 %q) ; CHECK-NEXT: --> (%n umin %q) U: full-set S: full-set Exits: (%n umin %q) LoopDispositions: { %loop: Invariant } ; CHECK-NEXT: %cond_p3 = select i1 %cond_p0, i1 true, i1 %cond_p1 -; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq (true + %cond_p1))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (true + ((true + %cond_p0) umin (true + %cond_p1))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %cond = select i1 %cond_p3, i1 true, i1 %cond_p2 -; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq (true + %cond_p1) umin_seq (true + %cond_p2))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (true + ((true + %cond_p2) umin (true + %cond_p0) umin (true + %cond_p1))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_or_4ops_redundant_operand_across_umins -; CHECK-NEXT: Loop %loop: backedge-taken count is ((%n umin %m) umin_seq %k umin_seq %q) +; CHECK-NEXT: Loop %loop: backedge-taken count is ((%n umin %m umin %k) umin_seq %q) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 -; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((%n umin %m) umin_seq %k umin_seq %q) -; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is ((%n umin %m) umin_seq %k umin_seq %q) +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((%n umin %m umin %k) umin_seq %q) +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is ((%n umin %m umin %k) umin_seq %q) ; CHECK-NEXT: Predicates: ; CHECK: Loop %loop: Trip multiple is 1 ; @@ -285,22 +285,22 @@ ; CHECK-LABEL: 'logical_or_3ops_operand_wise_redundant_umin' ; CHECK-NEXT: Classifying expressions for: @logical_or_3ops_operand_wise_redundant_umin ; CHECK-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: ((%n umin %m) umin_seq %k) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin %m umin %k) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((%n umin %m) umin_seq %k)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin %m umin %k)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %umin = call i32 @llvm.umin.i32(i32 %n, i32 %m) ; CHECK-NEXT: --> (%n umin %m) U: full-set S: full-set Exits: (%n umin %m) LoopDispositions: { %loop: Invariant } ; CHECK-NEXT: %umin2 = call i32 @llvm.umin.i32(i32 %n, i32 %k) ; CHECK-NEXT: --> (%n umin %k) U: full-set S: full-set Exits: (%n umin %k) LoopDispositions: { %loop: Invariant } ; CHECK-NEXT: %cond_p3 = select i1 %cond_p0, i1 true, i1 %cond_p1 -; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq (true + %cond_p1))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (true + ((true + %cond_p0) umin (true + %cond_p1))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %cond = select i1 %cond_p3, i1 true, i1 %cond_p2 -; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq (true + %cond_p1) umin_seq (true + %cond_p2))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (true + ((true + %cond_p2) umin (true + %cond_p0) umin (true + %cond_p1))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_or_3ops_operand_wise_redundant_umin -; CHECK-NEXT: Loop %loop: backedge-taken count is ((%n umin %m) umin_seq %k) +; CHECK-NEXT: Loop %loop: backedge-taken count is (%n umin %m umin %k) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 -; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((%n umin %m) umin_seq %k) -; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is ((%n umin %m) umin_seq %k) +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (%n umin %m umin %k) +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (%n umin %m umin %k) ; CHECK-NEXT: Predicates: ; CHECK: Loop %loop: Trip multiple is 1 ; @@ -333,7 +333,7 @@ ; CHECK-NEXT: %umin2 = call i32 @llvm.umin.i32(i32 %umin, i32 %k) ; CHECK-NEXT: --> (%n umin %m umin %k) U: full-set S: full-set Exits: (%n umin %m umin %k) LoopDispositions: { %loop: Invariant } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 true, i1 %cond_p1 -; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq (true + %cond_p1))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (true + ((true + %cond_p0) umin (true + %cond_p1))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_or_3ops_partially_redundant_umin ; CHECK-NEXT: Loop %loop: backedge-taken count is (%n umin_seq (%m umin %k)) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 @@ -361,36 +361,36 @@ ; CHECK-LABEL: 'logical_or_5ops_redundant_opearand_of_inner_uminseq' ; CHECK-NEXT: Classifying expressions for: @logical_or_5ops_redundant_opearand_of_inner_uminseq ; CHECK-NEXT: %first.i = phi i32 [ 0, %entry ], [ %first.i.next, %first.loop ] -; CHECK-NEXT: --> {0,+,1}<%first.loop> U: full-set S: full-set Exits: (%e umin_seq %d umin_seq %a) LoopDispositions: { %first.loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%first.loop> U: full-set S: full-set Exits: (%a umin %d umin %e) LoopDispositions: { %first.loop: Computable } ; CHECK-NEXT: %first.i.next = add i32 %first.i, 1 -; CHECK-NEXT: --> {1,+,1}<%first.loop> U: full-set S: full-set Exits: (1 + (%e umin_seq %d umin_seq %a)) LoopDispositions: { %first.loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%first.loop> U: full-set S: full-set Exits: (1 + (%a umin %d umin %e)) LoopDispositions: { %first.loop: Computable } ; CHECK-NEXT: %cond_p3 = select i1 %cond_p0, i1 true, i1 %cond_p1 -; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq (true + %cond_p1))) U: full-set S: full-set Exits: <> LoopDispositions: { %first.loop: Variant } +; CHECK-NEXT: --> (true + ((true + %cond_p0) umin (true + %cond_p1))) U: full-set S: full-set Exits: <> LoopDispositions: { %first.loop: Variant } ; CHECK-NEXT: %cond_p4 = select i1 %cond_p3, i1 true, i1 %cond_p2 -; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq (true + %cond_p1) umin_seq (true + %cond_p2))) U: full-set S: full-set Exits: <> LoopDispositions: { %first.loop: Variant } +; CHECK-NEXT: --> (true + ((true + %cond_p2) umin (true + %cond_p0) umin (true + %cond_p1))) U: full-set S: full-set Exits: <> LoopDispositions: { %first.loop: Variant } ; CHECK-NEXT: %i = phi i32 [ 0, %first.loop.exit ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%a umin_seq %b umin_seq ((%e umin_seq %d) umin %c)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%a umin_seq %b umin_seq (%c umin %d umin %e)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%a umin_seq %b umin_seq ((%e umin_seq %d) umin %c))) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%a umin_seq %b umin_seq (%c umin %d umin %e))) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %umin = call i32 @llvm.umin.i32(i32 %c, i32 %d) ; CHECK-NEXT: --> (%c umin %d) U: full-set S: full-set Exits: (%c umin %d) LoopDispositions: { %loop: Invariant } ; CHECK-NEXT: %umin2 = call i32 @llvm.umin.i32(i32 %umin, i32 %first.i) -; CHECK-NEXT: --> ({0,+,1}<%first.loop> umin %c umin %d) U: full-set S: full-set --> ((%e umin_seq %d umin_seq %a) umin %c umin %d) U: full-set S: full-set Exits: ((%e umin_seq %d umin_seq %a) umin %c umin %d) LoopDispositions: { %loop: Invariant } +; CHECK-NEXT: --> ({0,+,1}<%first.loop> umin %c umin %d) U: full-set S: full-set --> (%a umin %c umin %d umin %e) U: full-set S: full-set Exits: (%a umin %c umin %d umin %e) LoopDispositions: { %loop: Invariant } ; CHECK-NEXT: %cond_p8 = select i1 %cond_p5, i1 true, i1 %cond_p6 -; CHECK-NEXT: --> (true + ((true + %cond_p5) umin_seq (true + %cond_p6))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (true + ((true + %cond_p5) umin (true + %cond_p6))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %cond = select i1 %cond_p8, i1 true, i1 %cond_p7 -; CHECK-NEXT: --> (true + ((true + %cond_p5) umin_seq (true + %cond_p6) umin_seq (true + %cond_p7))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (true + ((true + %cond_p7) umin (true + %cond_p5) umin (true + %cond_p6))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_or_5ops_redundant_opearand_of_inner_uminseq -; CHECK-NEXT: Loop %loop: backedge-taken count is (%a umin_seq %b umin_seq ((%e umin_seq %d) umin %c)) +; CHECK-NEXT: Loop %loop: backedge-taken count is (%a umin_seq %b umin_seq (%c umin %d umin %e)) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 -; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (%a umin_seq %b umin_seq ((%e umin_seq %d) umin %c)) -; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (%a umin_seq %b umin_seq ((%e umin_seq %d) umin %c)) +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (%a umin_seq %b umin_seq (%c umin %d umin %e)) +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (%a umin_seq %b umin_seq (%c umin %d umin %e)) ; CHECK-NEXT: Predicates: ; CHECK: Loop %loop: Trip multiple is 1 -; CHECK-NEXT: Loop %first.loop: backedge-taken count is (%e umin_seq %d umin_seq %a) +; CHECK-NEXT: Loop %first.loop: backedge-taken count is (%a umin %d umin %e) ; CHECK-NEXT: Loop %first.loop: constant max backedge-taken count is -1 -; CHECK-NEXT: Loop %first.loop: symbolic max backedge-taken count is (%e umin_seq %d umin_seq %a) -; CHECK-NEXT: Loop %first.loop: Predicated backedge-taken count is (%e umin_seq %d umin_seq %a) +; CHECK-NEXT: Loop %first.loop: symbolic max backedge-taken count is (%a umin %d umin %e) +; CHECK-NEXT: Loop %first.loop: Predicated backedge-taken count is (%a umin %d umin %e) ; CHECK-NEXT: Predicates: ; CHECK: Loop %first.loop: Trip multiple is 1 ; @@ -432,7 +432,7 @@ ; CHECK-NEXT: %umin = call i32 @llvm.umin.i32(i32 %n, i32 42) ; CHECK-NEXT: --> (42 umin %n) U: [0,43) S: [0,43) Exits: (42 umin %n) LoopDispositions: { %loop: Invariant } ; CHECK-NEXT: %cond = select i1 %cond_p1, i1 true, i1 %cond_p0 -; CHECK-NEXT: --> (true + ((true + %cond_p1) umin_seq (true + %cond_p0))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (true + ((true + %cond_p1) umin (true + %cond_p0))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_2ops_and_constant ; CHECK-NEXT: Loop %loop: backedge-taken count is (42 umin %n) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 42 @@ -463,7 +463,7 @@ ; CHECK-NEXT: %e.1 = phi i32 [ %inc3, %for.body ], [ %d.0, %for.cond.preheader ] ; CHECK-NEXT: --> {%d.0,+,1}<%for.cond> U: full-set S: full-set Exits: 0 LoopDispositions: { %for.cond: Computable, %while.cond: Variant } ; CHECK-NEXT: %0 = select i1 %tobool1, i1 %tobool2, i1 false -; CHECK-NEXT: --> (%tobool1 umin_seq %tobool2) U: full-set S: full-set Exits: false LoopDispositions: { %for.cond: Variant, %while.cond: Variant } +; CHECK-NEXT: --> (%tobool1 umin %tobool2) U: full-set S: full-set Exits: false LoopDispositions: { %for.cond: Variant, %while.cond: Variant } ; CHECK-NEXT: %inc = add nsw i32 %d.1, 1 ; CHECK-NEXT: --> {(1 + %d.0),+,1}<%for.cond> U: full-set S: full-set Exits: 1 LoopDispositions: { %for.cond: Computable, %while.cond: Variant } ; CHECK-NEXT: %inc3 = add nsw i32 %e.1, 1 @@ -532,20 +532,20 @@ ; CHECK-LABEL: 'uminseq_vs_ptrtoint_complexity' ; CHECK-NEXT: Classifying expressions for: @uminseq_vs_ptrtoint_complexity ; CHECK-NEXT: %i = phi i64 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin_seq %m) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin %m) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i64 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq %m)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin %m)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (%cond_p0 umin %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %ptr.int = ptrtoint ptr %ptr to i64 ; CHECK-NEXT: --> (ptrtoint ptr %ptr to i64) U: full-set S: full-set ; CHECK-NEXT: %r = add i64 %i, %ptr.int -; CHECK-NEXT: --> {(ptrtoint ptr %ptr to i64),+,1}<%loop> U: full-set S: full-set --> ((%n umin_seq %m) + (ptrtoint ptr %ptr to i64)) U: full-set S: full-set +; CHECK-NEXT: --> {(ptrtoint ptr %ptr to i64),+,1}<%loop> U: full-set S: full-set --> ((%n umin %m) + (ptrtoint ptr %ptr to i64)) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @uminseq_vs_ptrtoint_complexity -; CHECK-NEXT: Loop %loop: backedge-taken count is (%n umin_seq %m) +; CHECK-NEXT: Loop %loop: backedge-taken count is (%n umin %m) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 -; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (%n umin_seq %m) -; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (%n umin_seq %m) +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (%n umin %m) +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (%n umin %m) ; CHECK-NEXT: Predicates: ; CHECK: Loop %loop: Trip multiple is 1 ; @@ -574,7 +574,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((1 + %n) umin %n)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (%cond_p0 umin %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_implies_poison1 ; CHECK-NEXT: Loop %loop: backedge-taken count is ((1 + %n) umin %n) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 @@ -607,7 +607,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((1 + %n) umin %n)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (%cond_p1 umin %cond_p0) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_implies_poison2 ; CHECK-NEXT: Loop %loop: backedge-taken count is ((1 + %n) umin %n) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 @@ -640,7 +640,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((%n + %m) umin %n)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (%cond_p1 umin %cond_p0) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_implies_poison3 ; CHECK-NEXT: Loop %loop: backedge-taken count is ((%n + %m) umin %n) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 @@ -669,16 +669,16 @@ ; CHECK-NEXT: %add = add i32 %n, %m ; CHECK-NEXT: --> (%n + %m) U: full-set S: full-set ; CHECK-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin_seq (%n + %m)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: ((%n + %m) umin %n) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq (%n + %m))) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((%n + %m) umin %n)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (%cond_p0 umin %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_implies_poison_wrong_direction -; CHECK-NEXT: Loop %loop: backedge-taken count is (%n umin_seq (%n + %m)) +; CHECK-NEXT: Loop %loop: backedge-taken count is ((%n + %m) umin %n) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 -; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (%n umin_seq (%n + %m)) -; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (%n umin_seq (%n + %m)) +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((%n + %m) umin %n) +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is ((%n + %m) umin %n) ; CHECK-NEXT: Predicates: ; CHECK: Loop %loop: Trip multiple is 1 ; @@ -704,7 +704,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin %m)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (%cond_p0 umin %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_implies_poison_noundef ; CHECK-NEXT: Loop %loop: backedge-taken count is (%n umin %m) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 @@ -730,16 +730,16 @@ ; CHECK-LABEL: 'logical_and_implies_poison_noundef_wrong_direction' ; CHECK-NEXT: Classifying expressions for: @logical_and_implies_poison_noundef_wrong_direction ; CHECK-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%m umin_seq %n) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin %m) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%m umin_seq %n)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin %m)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (%cond_p1 umin %cond_p0) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_implies_poison_noundef_wrong_direction -; CHECK-NEXT: Loop %loop: backedge-taken count is (%m umin_seq %n) +; CHECK-NEXT: Loop %loop: backedge-taken count is (%n umin %m) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 -; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (%m umin_seq %n) -; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (%m umin_seq %n) +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (%n umin %m) +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (%n umin %m) ; CHECK-NEXT: Predicates: ; CHECK: Loop %loop: Trip multiple is 1 ; @@ -768,7 +768,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((%n + %m) umin (1 + %n + %m))) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (%cond_p0 umin %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_implies_poison_complex1 ; CHECK-NEXT: Loop %loop: backedge-taken count is ((%n + %m) umin (1 + %n + %m)) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 @@ -804,7 +804,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((%n + %m) umin (%n + %m + %l))) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (%cond_p0 umin %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_implies_poison_complex2 ; CHECK-NEXT: Loop %loop: backedge-taken count is ((%n + %m) umin (%n + %m + %l)) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 @@ -836,16 +836,16 @@ ; CHECK-NEXT: %add1 = add i32 %add, %l ; CHECK-NEXT: --> (%n + %m + %l) U: full-set S: full-set ; CHECK-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: ((%n + %m) umin_seq (%n + %m + %l)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: ((%n + %m) umin (%n + %m + %l)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((%n + %m) umin_seq (%n + %m + %l))) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((%n + %m) umin (%n + %m + %l))) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (%cond_p0 umin %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_implies_poison_complex_wrong_direction -; CHECK-NEXT: Loop %loop: backedge-taken count is ((%n + %m) umin_seq (%n + %m + %l)) +; CHECK-NEXT: Loop %loop: backedge-taken count is ((%n + %m) umin (%n + %m + %l)) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 -; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((%n + %m) umin_seq (%n + %m + %l)) -; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is ((%n + %m) umin_seq (%n + %m + %l)) +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((%n + %m) umin (%n + %m + %l)) +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is ((%n + %m) umin (%n + %m + %l)) ; CHECK-NEXT: Predicates: ; CHECK: Loop %loop: Trip multiple is 1 ; @@ -870,18 +870,18 @@ ; CHECK-NEXT: %add = add i32 %n, 1 ; CHECK-NEXT: --> (1 + %n) U: full-set S: full-set ; CHECK-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (((1 + %n) umin %n) umin_seq %m) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: ((1 + %n) umin %n umin %m) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (((1 + %n) umin %n) umin_seq %m)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((1 + %n) umin %n umin %m)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (%cond_p0 umin %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %cond2 = select i1 %cond, i1 %cond_p2, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1 umin_seq %cond_p2) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (%cond_p0 umin %cond_p2 umin %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_implies_multiple_ops -; CHECK-NEXT: Loop %loop: backedge-taken count is (((1 + %n) umin %n) umin_seq %m) +; CHECK-NEXT: Loop %loop: backedge-taken count is ((1 + %n) umin %n umin %m) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 -; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (((1 + %n) umin %n) umin_seq %m) -; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (((1 + %n) umin %n) umin_seq %m) +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((1 + %n) umin %n umin %m) +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is ((1 + %n) umin %n umin %m) ; CHECK-NEXT: Predicates: ; CHECK: Loop %loop: Trip multiple is 1 ; @@ -907,18 +907,18 @@ ; CHECK-NEXT: %add = add i32 %n, 1 ; CHECK-NEXT: --> (1 + %n) U: full-set S: full-set ; CHECK-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin_seq %m umin_seq (1 + %n)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: ((1 + %n) umin %n umin %m) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq %m umin_seq (1 + %n))) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((1 + %n) umin %n umin %m)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (%cond_p0 umin %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %cond2 = select i1 %cond, i1 %cond_p2, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1 umin_seq %cond_p2) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (%cond_p0 umin %cond_p1 umin %cond_p2) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_implies_multiple_ops2 -; CHECK-NEXT: Loop %loop: backedge-taken count is (%n umin_seq %m umin_seq (1 + %n)) +; CHECK-NEXT: Loop %loop: backedge-taken count is ((1 + %n) umin %n umin %m) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 -; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (%n umin_seq %m umin_seq (1 + %n)) -; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (%n umin_seq %m umin_seq (1 + %n)) +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((1 + %n) umin %n umin %m) +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is ((1 + %n) umin %n umin %m) ; CHECK-NEXT: Predicates: ; CHECK: Loop %loop: Trip multiple is 1 ; @@ -944,18 +944,18 @@ ; CHECK-NEXT: %add = add i32 %n, 1 ; CHECK-NEXT: --> (1 + %n) U: full-set S: full-set ; CHECK-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%m umin_seq ((1 + %n) umin %n)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: ((1 + %n) umin %n umin %m) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%m umin_seq ((1 + %n) umin %n))) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((1 + %n) umin %n umin %m)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (%cond_p1 umin %cond_p0) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %cond2 = select i1 %cond, i1 %cond_p2, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1 umin_seq %cond_p2) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (%cond_p1 umin %cond_p0 umin %cond_p2) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_implies_multiple_ops3 -; CHECK-NEXT: Loop %loop: backedge-taken count is (%m umin_seq ((1 + %n) umin %n)) +; CHECK-NEXT: Loop %loop: backedge-taken count is ((1 + %n) umin %n umin %m) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 -; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (%m umin_seq ((1 + %n) umin %n)) -; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (%m umin_seq ((1 + %n) umin %n)) +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((1 + %n) umin %n umin %m) +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is ((1 + %n) umin %n umin %m) ; CHECK-NEXT: Predicates: ; CHECK: Loop %loop: Trip multiple is 1 ; @@ -987,7 +987,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,65538) S: [1,65538) Exits: (1 + ((1 + (zext i16 %n to i32)) umin %m)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (%cond_p1 umin %cond_p0) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_not_zero ; CHECK-NEXT: Loop %loop: backedge-taken count is ((1 + (zext i16 %n to i32)) umin %m) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 65536 @@ -1019,16 +1019,16 @@ ; CHECK-NEXT: %n1 = add i32 %n.ext, 1 ; CHECK-NEXT: --> (1 + (zext i16 %n to i32)) U: [1,65537) S: [1,65537) ; CHECK-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,65537) S: [0,65537) Exits: (%m umin_seq (1 + (zext i16 %n to i32))) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,65537) S: [0,65537) Exits: ((1 + (zext i16 %n to i32)) umin %m) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,65538) S: [1,65538) Exits: (1 + (%m umin_seq (1 + (zext i16 %n to i32)))) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,65538) S: [1,65538) Exits: (1 + ((1 + (zext i16 %n to i32)) umin %m)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (%cond_p0 umin %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_not_zero_wrong_order -; CHECK-NEXT: Loop %loop: backedge-taken count is (%m umin_seq (1 + (zext i16 %n to i32))) +; CHECK-NEXT: Loop %loop: backedge-taken count is ((1 + (zext i16 %n to i32)) umin %m) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 65536 -; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (%m umin_seq (1 + (zext i16 %n to i32))) -; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (%m umin_seq (1 + (zext i16 %n to i32))) +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((1 + (zext i16 %n to i32)) umin %m) +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is ((1 + (zext i16 %n to i32)) umin %m) ; CHECK-NEXT: Predicates: ; CHECK: Loop %loop: Trip multiple is 1 ; @@ -1055,7 +1055,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq %m)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (%cond_p0 umin %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_not_zero_needs_context ; CHECK-NEXT: Loop %loop: backedge-taken count is (%n umin_seq %m) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1 @@ -1094,7 +1094,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,65537) S: [1,65537) Exits: (1 + (zext i16 %n to i32)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (%cond_p1 umin %cond_p0) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_known_smaller ; CHECK-NEXT: Loop %loop: backedge-taken count is (zext i16 %n to i32) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 65535 @@ -1133,7 +1133,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,65537) S: [1,65537) Exits: (1 + (zext i16 %n to i32)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (%cond_p1 umin %cond_p0) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_known_smaller_equal ; CHECK-NEXT: Loop %loop: backedge-taken count is (zext i16 %n to i32) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 65535 @@ -1168,16 +1168,16 @@ ; CHECK-NEXT: %m.add = add i32 %m.ext, 65534 ; CHECK-NEXT: --> (65534 + (zext i16 %m to i32)) U: [65534,131070) S: [65534,131070) ; CHECK-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] -; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,65536) S: [0,65536) Exits: ((zext i16 %n to i32) umin_seq (65534 + (zext i16 %m to i32))) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,65536) S: [0,65536) Exits: ((zext i16 %n to i32) umin (65534 + (zext i16 %m to i32))) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %i.next = add i32 %i, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,65537) S: [1,65537) Exits: (1 + ((zext i16 %n to i32) umin_seq (65534 + (zext i16 %m to i32)))) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,65537) S: [1,65537) Exits: (1 + ((zext i16 %n to i32) umin (65534 + (zext i16 %m to i32)))) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (%cond_p1 umin %cond_p0) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_not_known_smaller_equal -; CHECK-NEXT: Loop %loop: backedge-taken count is ((zext i16 %n to i32) umin_seq (65534 + (zext i16 %m to i32))) +; CHECK-NEXT: Loop %loop: backedge-taken count is ((zext i16 %n to i32) umin (65534 + (zext i16 %m to i32))) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 65535 -; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((zext i16 %n to i32) umin_seq (65534 + (zext i16 %m to i32))) -; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is ((zext i16 %n to i32) umin_seq (65534 + (zext i16 %m to i32))) +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((zext i16 %n to i32) umin (65534 + (zext i16 %m to i32))) +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is ((zext i16 %n to i32) umin (65534 + (zext i16 %m to i32))) ; CHECK-NEXT: Predicates: ; CHECK: Loop %loop: Trip multiple is 1 ; @@ -1211,7 +1211,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,65537) S: [1,65537) Exits: (1 + (zext i16 %n to i32)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (%cond_p0 umin %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_known_greater ; CHECK-NEXT: Loop %loop: backedge-taken count is (zext i16 %n to i32) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 65535 @@ -1250,7 +1250,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,65537) S: [1,65537) Exits: (1 + (zext i16 %n to i32)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (%cond_p0 umin %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_known_greater_equal ; CHECK-NEXT: Loop %loop: backedge-taken count is (zext i16 %n to i32) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 65535 @@ -1289,7 +1289,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,65537) S: [1,65537) Exits: (1 + ((zext i16 %n to i32) umin (65534 + (zext i16 %m to i32)))) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (%cond_p0 umin %cond_p1) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_not_known_greater_equal ; CHECK-NEXT: Loop %loop: backedge-taken count is ((zext i16 %n to i32) umin (65534 + (zext i16 %m to i32))) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 65535 @@ -1322,7 +1322,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,2) S: [1,2) Exits: 1 LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: false LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (%cond_p0 umin %cond_p1) U: full-set S: full-set Exits: false LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_zero_arg1 ; CHECK-NEXT: Loop %loop: backedge-taken count is 0 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 0 @@ -1352,7 +1352,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,2) S: [1,2) Exits: 1 LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false -; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: false LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (%cond_p1 umin %cond_p0) U: full-set S: full-set Exits: false LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_zero_arg2 ; CHECK-NEXT: Loop %loop: backedge-taken count is 0 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 0 diff --git a/llvm/test/Analysis/ScalarEvolution/exit-count-select.ll b/llvm/test/Analysis/ScalarEvolution/exit-count-select.ll --- a/llvm/test/Analysis/ScalarEvolution/exit-count-select.ll +++ b/llvm/test/Analysis/ScalarEvolution/exit-count-select.ll @@ -11,7 +11,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,4) S: [1,4) Exits: (1 + (2 umin %n)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_i, i1 %cond_i2, i1 false -; CHECK-NEXT: --> (%cond_i umin_seq %cond_i2) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (%cond_i2 umin %cond_i) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_m_const ; CHECK-NEXT: Loop %loop: backedge-taken count is (2 umin %n) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 2 @@ -43,7 +43,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,4) S: [1,4) Exits: (1 + (2 umin %m)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_i, i1 %cond_i2, i1 false -; CHECK-NEXT: --> (%cond_i umin_seq %cond_i2) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (%cond_i umin %cond_i2) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_nonzero ; CHECK-NEXT: Loop %loop: backedge-taken count is (2 umin %m) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 2 @@ -76,7 +76,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,2) S: [1,2) Exits: 1 LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_i, i1 %cond_i2, i1 false -; CHECK-NEXT: --> (%cond_i umin_seq %cond_i2) U: full-set S: full-set Exits: false LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (%cond_i umin %cond_i2) U: full-set S: full-set Exits: false LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_zero ; CHECK-NEXT: Loop %loop: backedge-taken count is 0 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 0 @@ -110,7 +110,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_i, i1 %cond_i2, i1 false -; CHECK-NEXT: --> (%cond_i umin_seq %cond_i2) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (%cond_i umin %cond_i2) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_and_inversed ; CHECK-NEXT: Loop %loop: Unpredictable backedge-taken count. ; CHECK-NEXT: Loop %loop: Unpredictable constant max backedge-taken count. @@ -140,7 +140,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,4) S: [1,4) Exits: (1 + (2 umin %n)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_i, i1 true, i1 %cond_i2 -; CHECK-NEXT: --> (true + ((true + %cond_i) umin_seq (true + %cond_i2))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (true + ((true + %cond_i) umin (true + %cond_i2))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_or_m_const ; CHECK-NEXT: Loop %loop: backedge-taken count is (2 umin %n) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 2 @@ -172,7 +172,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,4) S: [1,4) Exits: (1 + (2 umin %m)) LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_i, i1 true, i1 %cond_i2 -; CHECK-NEXT: --> (true + ((true + %cond_i) umin_seq (true + %cond_i2))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (true + ((true + %cond_i) umin (true + %cond_i2))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_or_nonzero ; CHECK-NEXT: Loop %loop: backedge-taken count is (2 umin %m) ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 2 @@ -205,7 +205,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,2) S: [1,2) Exits: 1 LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_i, i1 true, i1 %cond_i2 -; CHECK-NEXT: --> (true + ((true + %cond_i) umin_seq (true + %cond_i2))) U: full-set S: full-set Exits: true LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (true + ((true + %cond_i) umin (true + %cond_i2))) U: full-set S: full-set Exits: true LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_or_zero ; CHECK-NEXT: Loop %loop: backedge-taken count is 0 ; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 0 @@ -239,7 +239,7 @@ ; CHECK-NEXT: %i.next = add i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %cond = select i1 %cond_i, i1 true, i1 %cond_i2 -; CHECK-NEXT: --> (true + ((true + %cond_i) umin_seq (true + %cond_i2))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (true + ((true + %cond_i) umin (true + %cond_i2))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @logical_or_inversed ; CHECK-NEXT: Loop %loop: Unpredictable backedge-taken count. ; CHECK-NEXT: Loop %loop: Unpredictable constant max backedge-taken count. diff --git a/llvm/test/Analysis/ScalarEvolution/nsw.ll b/llvm/test/Analysis/ScalarEvolution/nsw.ll --- a/llvm/test/Analysis/ScalarEvolution/nsw.ll +++ b/llvm/test/Analysis/ScalarEvolution/nsw.ll @@ -412,7 +412,7 @@ ; CHECK-NEXT: %iv = phi i32 [ %iv.next, %loop ], [ 0, %entry ] ; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: <> LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv.next = add nsw i32 %iv, 1 -; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,0) S: [1,0) Exits: <> LoopDispositions: { %loop: Computable } +; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: <> LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %sel = select i1 %cmp, i32 10, i32 20 ; CHECK-NEXT: --> %sel U: [0,31) S: [0,31) Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %cond = call i1 @cond() diff --git a/llvm/test/Analysis/ScalarEvolution/symbolic_max_exit_count.ll b/llvm/test/Analysis/ScalarEvolution/symbolic_max_exit_count.ll --- a/llvm/test/Analysis/ScalarEvolution/symbolic_max_exit_count.ll +++ b/llvm/test/Analysis/ScalarEvolution/symbolic_max_exit_count.ll @@ -524,7 +524,7 @@ ; CHECK-NEXT: %c2 = and i1 %zero_check_2, %scam_2 ; CHECK-NEXT: --> (%zero_check_2 umin %scam_2) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %merged_cond = select i1 %c1, i1 true, i1 %c2 -; CHECK-NEXT: --> (true + ((true + (%zero_check_1 umin %scam_1)) umin_seq (true + (%zero_check_2 umin %scam_2)))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (true + ((true + (%zero_check_1 umin %scam_1)) umin (true + (%zero_check_2 umin %scam_2)))) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %iv.minus.1 = add i32 %iv_1, -1 ; CHECK-NEXT: --> {(-1 + %start_1),+,-1}<%loop> U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv_1.next = add i32 %iv_1, -1 @@ -597,7 +597,7 @@ ; CHECK-NEXT: %c2 = and i1 %zero_check_2, %scam_2 ; CHECK-NEXT: --> (%zero_check_2 umin %scam_2) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %merged_cond = select i1 %c1, i1 %c2, i1 false -; CHECK-NEXT: --> ((%zero_check_1 umin %scam_1) umin_seq (%zero_check_2 umin %scam_2)) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> (%zero_check_1 umin %zero_check_2 umin %scam_1 umin %scam_2) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %iv.minus.1 = add i32 %iv_1, -1 ; CHECK-NEXT: --> {(-1 + %start_1),+,-1}<%loop> U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %iv_1.next = add i32 %iv_1, -1 diff --git a/llvm/test/Instrumentation/PoisonChecking/ub-checks.ll b/llvm/test/Instrumentation/PoisonChecking/ub-checks.ll --- a/llvm/test/Instrumentation/PoisonChecking/ub-checks.ll +++ b/llvm/test/Instrumentation/PoisonChecking/ub-checks.ll @@ -140,6 +140,8 @@ ; CHECK-NEXT: [[ADD:%.*]] = add nuw i32 [[A]], 1 ; CHECK-NEXT: [[T:%.*]] = trunc i32 [[ADD]] to i1 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[T]], i32 [[ADD]], i32 [[B:%.*]] +; CHECK-NEXT: [[TMP3:%.*]] = xor i1 [[TMP2]], true +; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP3]]) ; CHECK-NEXT: ret i32 [[SEL]] ; %add = add nuw i32 %a, 1 diff --git a/llvm/test/Transforms/IndVarSimplify/exit-count-select.ll b/llvm/test/Transforms/IndVarSimplify/exit-count-select.ll --- a/llvm/test/Transforms/IndVarSimplify/exit-count-select.ll +++ b/llvm/test/Transforms/IndVarSimplify/exit-count-select.ll @@ -4,12 +4,11 @@ define i32 @logical_and_2ops(i32 %n, i32 %m) { ; CHECK-LABEL: @logical_and_2ops( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = freeze i32 [[M:%.*]] ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: br i1 false, label [[LOOP]], label [[EXIT:%.*]] ; CHECK: exit: -; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[TMP0]], i32 [[N:%.*]]) +; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[M:%.*]], i32 [[N:%.*]]) ; CHECK-NEXT: ret i32 [[UMIN]] ; entry: @@ -28,12 +27,11 @@ define i32 @logical_or_2ops(i32 %n, i32 %m) { ; CHECK-LABEL: @logical_or_2ops( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = freeze i32 [[M:%.*]] ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: br i1 true, label [[EXIT:%.*]], label [[LOOP]] ; CHECK: exit: -; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[TMP0]], i32 [[N:%.*]]) +; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[M:%.*]], i32 [[N:%.*]]) ; CHECK-NEXT: ret i32 [[UMIN]] ; entry: @@ -52,9 +50,7 @@ define i32 @logical_and_3ops(i32 %n, i32 %m, i32 %k) { ; CHECK-LABEL: @logical_and_3ops( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = freeze i32 [[K:%.*]] -; CHECK-NEXT: [[TMP1:%.*]] = freeze i32 [[M:%.*]] -; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[TMP0]], i32 [[TMP1]]) +; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[K:%.*]], i32 [[M:%.*]]) ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: br i1 false, label [[LOOP]], label [[EXIT:%.*]] @@ -80,9 +76,7 @@ define i32 @logical_or_3ops(i32 %n, i32 %m, i32 %k) { ; CHECK-LABEL: @logical_or_3ops( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = freeze i32 [[K:%.*]] -; CHECK-NEXT: [[TMP1:%.*]] = freeze i32 [[M:%.*]] -; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[TMP0]], i32 [[TMP1]]) +; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[K:%.*]], i32 [[M:%.*]]) ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: br i1 true, label [[EXIT:%.*]], label [[LOOP]] diff --git a/llvm/test/Transforms/LoopUnroll/runtime-loop-multiple-exits.ll b/llvm/test/Transforms/LoopUnroll/runtime-loop-multiple-exits.ll --- a/llvm/test/Transforms/LoopUnroll/runtime-loop-multiple-exits.ll +++ b/llvm/test/Transforms/LoopUnroll/runtime-loop-multiple-exits.ll @@ -3105,19 +3105,18 @@ ; ; EPILOG-BLOCK-LABEL: @unique_exit( ; EPILOG-BLOCK-NEXT: preheader: -; EPILOG-BLOCK-NEXT: %M.shifted = shl i32 %M, 3 -; EPILOG-BLOCK-NEXT: %umax = call i32 @llvm.umax.i32(i32 %M.shifted, i32 1) +; EPILOG-BLOCK-NEXT: %M.shifted = shl nuw i32 %M, 3 +; EPILOG-BLOCK-NEXT: %umax = call i32 @llvm.umax.i32(i32 %N, i32 1) ; EPILOG-BLOCK-NEXT: %0 = add i32 %umax, -1 -; EPILOG-BLOCK-NEXT: %1 = freeze i32 %0 -; EPILOG-BLOCK-NEXT: %umax1 = call i32 @llvm.umax.i32(i32 %N, i32 1) -; EPILOG-BLOCK-NEXT: %2 = add i32 %umax1, -1 -; EPILOG-BLOCK-NEXT: %umin = call i32 @llvm.umin.i32(i32 %1, i32 %2) -; EPILOG-BLOCK-NEXT: %3 = add nuw i32 %umin, 1 -; EPILOG-BLOCK-NEXT: %xtraiter = and i32 %3, 1 -; EPILOG-BLOCK-NEXT: %4 = icmp ult i32 %umin, 1 -; EPILOG-BLOCK-NEXT: br i1 %4, label %latchExit.unr-lcssa, label %preheader.new +; EPILOG-BLOCK-NEXT: %umax1 = call i32 @llvm.umax.i32(i32 %M.shifted, i32 1) +; EPILOG-BLOCK-NEXT: %1 = add i32 %umax1, -1 +; EPILOG-BLOCK-NEXT: %umin = call i32 @llvm.umin.i32(i32 %0, i32 %1) +; EPILOG-BLOCK-NEXT: %2 = add nuw i32 %umin, 1 +; EPILOG-BLOCK-NEXT: %xtraiter = and i32 %2, 1 +; EPILOG-BLOCK-NEXT: %3 = icmp ult i32 %umin, 1 +; EPILOG-BLOCK-NEXT: br i1 %3, label %latchExit.unr-lcssa, label %preheader.new ; EPILOG-BLOCK: preheader.new: -; EPILOG-BLOCK-NEXT: %unroll_iter = sub i32 %3, %xtraiter +; EPILOG-BLOCK-NEXT: %unroll_iter = sub i32 %2, %xtraiter ; EPILOG-BLOCK-NEXT: br label %header ; EPILOG-BLOCK: header: ; EPILOG-BLOCK-NEXT: %i4 = phi i32 [ 0, %preheader.new ], [ %inc.1, %header ] @@ -3157,15 +3156,14 @@ ; ; PROLOG-BLOCK-LABEL: @unique_exit( ; PROLOG-BLOCK-NEXT: preheader: -; PROLOG-BLOCK-NEXT: %M.shifted = shl i32 %M, 3 -; PROLOG-BLOCK-NEXT: %umax = call i32 @llvm.umax.i32(i32 %M.shifted, i32 1) +; PROLOG-BLOCK-NEXT: %M.shifted = shl nuw i32 %M, 3 +; PROLOG-BLOCK-NEXT: %umax = call i32 @llvm.umax.i32(i32 %N, i32 1) ; PROLOG-BLOCK-NEXT: %0 = add i32 %umax, -1 -; PROLOG-BLOCK-NEXT: %1 = freeze i32 %0 -; PROLOG-BLOCK-NEXT: %umax1 = call i32 @llvm.umax.i32(i32 %N, i32 1) -; PROLOG-BLOCK-NEXT: %2 = add i32 %umax1, -1 -; PROLOG-BLOCK-NEXT: %umin = call i32 @llvm.umin.i32(i32 %1, i32 %2) -; PROLOG-BLOCK-NEXT: %3 = add nuw i32 %umin, 1 -; PROLOG-BLOCK-NEXT: %xtraiter = and i32 %3, 1 +; PROLOG-BLOCK-NEXT: %umax1 = call i32 @llvm.umax.i32(i32 %M.shifted, i32 1) +; PROLOG-BLOCK-NEXT: %1 = add i32 %umax1, -1 +; PROLOG-BLOCK-NEXT: %umin = call i32 @llvm.umin.i32(i32 %0, i32 %1) +; PROLOG-BLOCK-NEXT: %2 = add nuw i32 %umin, 1 +; PROLOG-BLOCK-NEXT: %xtraiter = and i32 %2, 1 ; PROLOG-BLOCK-NEXT: %lcmp.mod = icmp ne i32 %xtraiter, 0 ; PROLOG-BLOCK-NEXT: br i1 %lcmp.mod, label %header.prol.preheader, label %header.prol.loopexit ; PROLOG-BLOCK: header.prol.preheader: @@ -3174,8 +3172,8 @@ ; PROLOG-BLOCK-NEXT: br label %header.prol.loopexit ; PROLOG-BLOCK: header.prol.loopexit: ; PROLOG-BLOCK-NEXT: %i4.unr = phi i32 [ 0, %preheader ], [ 1, %header.prol ] -; PROLOG-BLOCK-NEXT: %4 = icmp ult i32 %umin, 1 -; PROLOG-BLOCK-NEXT: br i1 %4, label %latchExit, label %preheader.new +; PROLOG-BLOCK-NEXT: %3 = icmp ult i32 %umin, 1 +; PROLOG-BLOCK-NEXT: br i1 %3, label %latchExit, label %preheader.new ; PROLOG-BLOCK: preheader.new: ; PROLOG-BLOCK-NEXT: br label %header ; PROLOG-BLOCK: header: diff --git a/llvm/unittests/Analysis/ValueTrackingTest.cpp b/llvm/unittests/Analysis/ValueTrackingTest.cpp --- a/llvm/unittests/Analysis/ValueTrackingTest.cpp +++ b/llvm/unittests/Analysis/ValueTrackingTest.cpp @@ -847,68 +847,89 @@ "i1 %cond, i8* %p) {\n"; std::string AsmTail = " ret void\n}"; // (propagates poison?, IR instruction) - SmallVector, 32> Data = { - {true, "add i32 %x, %y"}, - {true, "add nsw nuw i32 %x, %y"}, - {true, "ashr i32 %x, %y"}, - {true, "lshr exact i32 %x, 31"}, - {true, "fadd float %fx, %fy"}, - {true, "fsub float %fx, %fy"}, - {true, "fmul float %fx, %fy"}, - {true, "fdiv float %fx, %fy"}, - {true, "frem float %fx, %fy"}, - {true, "fneg float %fx"}, - {true, "fcmp oeq float %fx, %fy"}, - {true, "icmp eq i32 %x, %y"}, - {true, "getelementptr i8, i8* %p, i32 %x"}, - {true, "getelementptr inbounds i8, i8* %p, i32 %x"}, - {true, "bitcast float %fx to i32"}, - {false, "select i1 %cond, i32 %x, i32 %y"}, - {false, "freeze i32 %x"}, - {true, "udiv i32 %x, %y"}, - {true, "urem i32 %x, %y"}, - {true, "sdiv exact i32 %x, %y"}, - {true, "srem i32 %x, %y"}, - {false, "call i32 @g(i32 %x)"}, - {true, "call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %x, i32 %y)"}, - {true, "call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %x, i32 %y)"}, - {true, "call {i32, i1} @llvm.smul.with.overflow.i32(i32 %x, i32 %y)"}, - {true, "call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %x, i32 %y)"}, - {true, "call {i32, i1} @llvm.usub.with.overflow.i32(i32 %x, i32 %y)"}, - {true, "call {i32, i1} @llvm.umul.with.overflow.i32(i32 %x, i32 %y)"}, - {false, "call float @llvm.sqrt.f32(float %fx)"}, - {false, "call float @llvm.powi.f32.i32(float %fx, i32 %x)"}, - {false, "call float @llvm.sin.f32(float %fx)"}, - {false, "call float @llvm.cos.f32(float %fx)"}, - {false, "call float @llvm.pow.f32(float %fx, float %fy)"}, - {false, "call float @llvm.exp.f32(float %fx)"}, - {false, "call float @llvm.exp2.f32(float %fx)"}, - {false, "call float @llvm.log.f32(float %fx)"}, - {false, "call float @llvm.log10.f32(float %fx)"}, - {false, "call float @llvm.log2.f32(float %fx)"}, - {false, "call float @llvm.fma.f32(float %fx, float %fx, float %fy)"}, - {false, "call float @llvm.fabs.f32(float %fx)"}, - {false, "call float @llvm.minnum.f32(float %fx, float %fy)"}, - {false, "call float @llvm.maxnum.f32(float %fx, float %fy)"}, - {false, "call float @llvm.minimum.f32(float %fx, float %fy)"}, - {false, "call float @llvm.maximum.f32(float %fx, float %fy)"}, - {false, "call float @llvm.copysign.f32(float %fx, float %fy)"}, - {false, "call float @llvm.floor.f32(float %fx)"}, - {false, "call float @llvm.ceil.f32(float %fx)"}, - {false, "call float @llvm.trunc.f32(float %fx)"}, - {false, "call float @llvm.rint.f32(float %fx)"}, - {false, "call float @llvm.nearbyint.f32(float %fx)"}, - {false, "call float @llvm.round.f32(float %fx)"}, - {false, "call float @llvm.roundeven.f32(float %fx)"}, - {false, "call i32 @llvm.lround.f32(float %fx)"}, - {false, "call i64 @llvm.llround.f32(float %fx)"}, - {false, "call i32 @llvm.lrint.f32(float %fx)"}, - {false, "call i64 @llvm.llrint.f32(float %fx)"}, - {false, "call float @llvm.fmuladd.f32(float %fx, float %fx, float %fy)"}}; + SmallVector, 32> Data = { + {true, "add i32 %x, %y", 0}, + {true, "add i32 %x, %y", 1}, + {true, "add nsw nuw i32 %x, %y", 0}, + {true, "add nsw nuw i32 %x, %y", 1}, + {true, "ashr i32 %x, %y", 0}, + {true, "ashr i32 %x, %y", 1}, + {true, "lshr exact i32 %x, 31", 0}, + {true, "lshr exact i32 %x, 31", 1}, + {true, "fadd float %fx, %fy", 0}, + {true, "fadd float %fx, %fy", 1}, + {true, "fsub float %fx, %fy", 0}, + {true, "fsub float %fx, %fy", 1}, + {true, "fmul float %fx, %fy", 0}, + {true, "fmul float %fx, %fy", 1}, + {true, "fdiv float %fx, %fy", 0}, + {true, "fdiv float %fx, %fy", 1}, + {true, "frem float %fx, %fy", 0}, + {true, "frem float %fx, %fy", 1}, + {true, "fneg float %fx", 0}, + {true, "fcmp oeq float %fx, %fy", 0}, + {true, "fcmp oeq float %fx, %fy", 1}, + {true, "icmp eq i32 %x, %y", 0}, + {true, "icmp eq i32 %x, %y", 1}, + {true, "getelementptr i8, i8* %p, i32 %x", 0}, + {true, "getelementptr i8, i8* %p, i32 %x", 1}, + {true, "getelementptr inbounds i8, i8* %p, i32 %x", 0}, + {true, "getelementptr inbounds i8, i8* %p, i32 %x", 1}, + {true, "bitcast float %fx to i32", 0}, + {true, "select i1 %cond, i32 %x, i32 %y", 0}, + {false, "select i1 %cond, i32 %x, i32 %y", 1}, + {false, "select i1 %cond, i32 %x, i32 %y", 2}, + {false, "freeze i32 %x", 0}, + {true, "udiv i32 %x, %y", 0}, + {true, "udiv i32 %x, %y", 1}, + {true, "urem i32 %x, %y", 0}, + {true, "urem i32 %x, %y", 1}, + {true, "sdiv exact i32 %x, %y", 0}, + {true, "sdiv exact i32 %x, %y", 1}, + {true, "srem i32 %x, %y", 0}, + {true, "srem i32 %x, %y", 1}, + {false, "call i32 @g(i32 %x)", 0}, + {false, "call i32 @g(i32 %x)", 1}, + {true, "call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %x, i32 %y)", 0}, + {true, "call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %x, i32 %y)", 0}, + {true, "call {i32, i1} @llvm.smul.with.overflow.i32(i32 %x, i32 %y)", 0}, + {true, "call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %x, i32 %y)", 0}, + {true, "call {i32, i1} @llvm.usub.with.overflow.i32(i32 %x, i32 %y)", 0}, + {true, "call {i32, i1} @llvm.umul.with.overflow.i32(i32 %x, i32 %y)", 0}, + {false, "call float @llvm.sqrt.f32(float %fx)", 0}, + {false, "call float @llvm.powi.f32.i32(float %fx, i32 %x)", 0}, + {false, "call float @llvm.sin.f32(float %fx)", 0}, + {false, "call float @llvm.cos.f32(float %fx)", 0}, + {false, "call float @llvm.pow.f32(float %fx, float %fy)", 0}, + {false, "call float @llvm.exp.f32(float %fx)", 0}, + {false, "call float @llvm.exp2.f32(float %fx)", 0}, + {false, "call float @llvm.log.f32(float %fx)", 0}, + {false, "call float @llvm.log10.f32(float %fx)", 0}, + {false, "call float @llvm.log2.f32(float %fx)", 0}, + {false, "call float @llvm.fma.f32(float %fx, float %fx, float %fy)", 0}, + {false, "call float @llvm.fabs.f32(float %fx)", 0}, + {false, "call float @llvm.minnum.f32(float %fx, float %fy)", 0}, + {false, "call float @llvm.maxnum.f32(float %fx, float %fy)", 0}, + {false, "call float @llvm.minimum.f32(float %fx, float %fy)", 0}, + {false, "call float @llvm.maximum.f32(float %fx, float %fy)", 0}, + {false, "call float @llvm.copysign.f32(float %fx, float %fy)", 0}, + {false, "call float @llvm.floor.f32(float %fx)", 0}, + {false, "call float @llvm.ceil.f32(float %fx)", 0}, + {false, "call float @llvm.trunc.f32(float %fx)", 0}, + {false, "call float @llvm.rint.f32(float %fx)", 0}, + {false, "call float @llvm.nearbyint.f32(float %fx)", 0}, + {false, "call float @llvm.round.f32(float %fx)", 0}, + {false, "call float @llvm.roundeven.f32(float %fx)", 0}, + {false, "call i32 @llvm.lround.f32(float %fx)", 0}, + {false, "call i64 @llvm.llround.f32(float %fx)", 0}, + {false, "call i32 @llvm.lrint.f32(float %fx)", 0}, + {false, "call i64 @llvm.llrint.f32(float %fx)", 0}, + {false, "call float @llvm.fmuladd.f32(float %fx, float %fx, float %fy)", + 0}}; std::string AssemblyStr = AsmHead; for (auto &Itm : Data) - AssemblyStr += Itm.second + "\n"; + AssemblyStr += std::get<1>(Itm) + "\n"; AssemblyStr += AsmTail; LLVMContext Context; @@ -925,7 +946,9 @@ for (auto &I : BB) { if (isa(&I)) break; - EXPECT_EQ(propagatesPoison(cast(&I)), Data[Index].first) + bool ExpectedVal = std::get<0>(Data[Index]); + unsigned OpIdx = std::get<2>(Data[Index]); + EXPECT_EQ(propagatesPoison(I.getOperandUse(OpIdx)), ExpectedVal) << "Incorrect answer at instruction " << Index << " = " << I; Index++; }