Skip to content

Commit 8a3efcd

Browse files
committed
[ValueTracking] Consider single poison operands in propgatesPoison.
This patch updates propgatesPoison to take a Use as argument and propagatesPoison now returns true if the passed in operand causes the user to yield poison if the operand is poison This allows propagating poison if the condition of a select is poison. This helps improve results for programUndefinedIfUndefOrPoison. Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D111643
1 parent 6022873 commit 8a3efcd

File tree

10 files changed

+141
-113
lines changed

10 files changed

+141
-113
lines changed

llvm/include/llvm/Analysis/ValueTracking.h

+9-7
Original file line numberDiff line numberDiff line change
@@ -603,20 +603,22 @@ bool isGuaranteedToTransferExecutionToSuccessor(
603603
bool isGuaranteedToExecuteForEveryIteration(const Instruction *I,
604604
const Loop *L);
605605

606-
/// Return true if I yields poison or raises UB if any of its operands is
607-
/// poison.
608-
/// Formally, given I = `r = op v1 v2 .. vN`, propagatesPoison returns true
609-
/// if, for all i, r is evaluated to poison or op raises UB if vi = poison.
610-
/// If vi is a vector or an aggregate and r is a single value, any poison
611-
/// element in vi should make r poison or raise UB.
606+
/// Return true if \p PoisonOp's user yields poison or raises UB if its
607+
/// operand \p PoisonOp is poison.
608+
///
609+
/// If \p PoisonOp is a vector or an aggregate and the operation's result is a
610+
/// single value, any poison element in /p PoisonOp should make the result
611+
/// poison or raise UB.
612+
///
612613
/// To filter out operands that raise UB on poison, you can use
613614
/// getGuaranteedNonPoisonOp.
614-
bool propagatesPoison(const Operator *I);
615+
bool propagatesPoison(const Use &PoisonOp);
615616

616617
/// Insert operands of I into Ops such that I will trigger undefined behavior
617618
/// if I is executed and that operand has a poison value.
618619
void getGuaranteedNonPoisonOps(const Instruction *I,
619620
SmallPtrSetImpl<const Value *> &Ops);
621+
620622
/// Insert operands of I into Ops such that I will trigger undefined behavior
621623
/// if I is executed and that operand is not a well-defined value
622624
/// (i.e. has undef bits or poison).

llvm/lib/Analysis/ScalarEvolution.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -7294,8 +7294,9 @@ bool ScalarEvolution::isAddRecNeverPoison(const Instruction *I, const Loop *L) {
72947294
while (!PoisonStack.empty() && !LatchControlDependentOnPoison) {
72957295
const Instruction *Poison = PoisonStack.pop_back_val();
72967296

7297-
for (const auto *PoisonUser : Poison->users()) {
7298-
if (propagatesPoison(cast<Operator>(PoisonUser))) {
7297+
for (const Use &U : Poison->uses()) {
7298+
const User *PoisonUser = U.getUser();
7299+
if (propagatesPoison(U)) {
72997300
if (Pushed.insert(cast<Instruction>(PoisonUser)).second)
73007301
PoisonStack.push_back(cast<Instruction>(PoisonUser));
73017302
} else if (auto *BI = dyn_cast<BranchInst>(PoisonUser)) {

llvm/lib/Analysis/ValueTracking.cpp

+16-19
Original file line numberDiff line numberDiff line change
@@ -5330,15 +5330,12 @@ static bool directlyImpliesPoison(const Value *ValAssumedPoison,
53305330
return false;
53315331

53325332
if (const auto *I = dyn_cast<Instruction>(V)) {
5333-
if (propagatesPoison(cast<Operator>(I)))
5334-
return any_of(I->operands(), [=](const Value *Op) {
5335-
return directlyImpliesPoison(ValAssumedPoison, Op, Depth + 1);
5336-
});
5333+
if (any_of(I->operands(), [=](const Use &Op) {
5334+
return propagatesPoison(Op) &&
5335+
directlyImpliesPoison(ValAssumedPoison, Op, Depth + 1);
5336+
}))
5337+
return true;
53375338

5338-
// 'select ValAssumedPoison, _, _' is poison.
5339-
if (const auto *SI = dyn_cast<SelectInst>(I))
5340-
return directlyImpliesPoison(ValAssumedPoison, SI->getCondition(),
5341-
Depth + 1);
53425339
// V = extractvalue V0, idx
53435340
// V2 = extractvalue V0, idx2
53445341
// V0's elements are all poison or not. (e.g., add_with_overflow)
@@ -5496,7 +5493,8 @@ static bool isGuaranteedNotToBeUndefOrPoison(const Value *V,
54965493
else if (PoisonOnly && isa<Operator>(Cond)) {
54975494
// For poison, we can analyze further
54985495
auto *Opr = cast<Operator>(Cond);
5499-
if (propagatesPoison(Opr) && is_contained(Opr->operand_values(), V))
5496+
if (any_of(Opr->operands(),
5497+
[V](const Use &U) { return V == U && propagatesPoison(U); }))
55005498
return true;
55015499
}
55025500
}
@@ -5618,13 +5616,15 @@ bool llvm::isGuaranteedToExecuteForEveryIteration(const Instruction *I,
56185616
llvm_unreachable("Instruction not contained in its own parent basic block.");
56195617
}
56205618

5621-
bool llvm::propagatesPoison(const Operator *I) {
5619+
bool llvm::propagatesPoison(const Use &PoisonOp) {
5620+
const Operator *I = cast<Operator>(PoisonOp.getUser());
56225621
switch (I->getOpcode()) {
56235622
case Instruction::Freeze:
5624-
case Instruction::Select:
56255623
case Instruction::PHI:
56265624
case Instruction::Invoke:
56275625
return false;
5626+
case Instruction::Select:
5627+
return PoisonOp.getOperandNo() == 0;
56285628
case Instruction::Call:
56295629
if (auto *II = dyn_cast<IntrinsicInst>(I)) {
56305630
switch (II->getIntrinsicID()) {
@@ -5805,14 +5805,11 @@ static bool programUndefinedIfUndefOrPoison(const Value *V,
58055805
if (!isGuaranteedToTransferExecutionToSuccessor(&I))
58065806
return false;
58075807

5808-
// If this instruction propagates poison, mark it as poison if any of
5809-
// its operands are poison
5810-
if (propagatesPoison(cast<Operator>(&I))) {
5811-
for (const Value *Op : I.operands()) {
5812-
if (YieldsPoison.count(Op)) {
5813-
YieldsPoison.insert(&I);
5814-
break;
5815-
}
5808+
// If an operand is poison and propagates it, mark I as yielding poison.
5809+
for (const Use &Op : I.operands()) {
5810+
if (YieldsPoison.count(Op) && propagatesPoison(Op)) {
5811+
YieldsPoison.insert(&I);
5812+
break;
58165813
}
58175814
}
58185815
}

llvm/lib/Transforms/Instrumentation/PoisonChecking.cpp

+4-3
Original file line numberDiff line numberDiff line change
@@ -289,9 +289,10 @@ static bool rewrite(Function &F) {
289289
}
290290

291291
SmallVector<Value*, 4> Checks;
292-
if (propagatesPoison(cast<Operator>(&I)))
293-
for (Value *V : I.operands())
294-
Checks.push_back(getPoisonFor(ValToPoison, V));
292+
for (const Use &U : I.operands()) {
293+
if (ValToPoison.count(U) && propagatesPoison(U))
294+
Checks.push_back(getPoisonFor(ValToPoison, U));
295+
}
295296

296297
if (canCreatePoison(cast<Operator>(&I)))
297298
generateCreationChecks(I, Checks);

llvm/lib/Transforms/Scalar/IndVarSimplify.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -788,7 +788,9 @@ static bool mustExecuteUBIfPoisonOnPathTo(Instruction *Root,
788788

789789
// If we can't analyze propagation through this instruction, just skip it
790790
// and transitive users. Safe as false is a conservative result.
791-
if (!propagatesPoison(cast<Operator>(I)) && I != Root)
791+
if (I != Root && !any_of(I->operands(), [&KnownPoison](const Use &U) {
792+
return KnownPoison.contains(U) && propagatesPoison(U);
793+
}))
792794
continue;
793795

794796
if (KnownPoison.insert(I).second)

llvm/test/Analysis/ScalarEvolution/exit-count-select-safe.ll

+18-18
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,9 @@ define i32 @logical_or_3ops_duplicate(i32 %n, i32 %m, i32 %k) {
139139
; CHECK-NEXT: %cond_p4 = select i1 %cond_p0, i1 true, i1 %cond_p1
140140
; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq (true + %cond_p1))) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
141141
; CHECK-NEXT: %cond_p5 = select i1 %cond_p4, i1 true, i1 %cond_p2
142-
; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq (true + %cond_p1) umin_seq (true + %cond_p2))) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
142+
; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq ((true + %cond_p1) umin (true + %cond_p2)))) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
143143
; CHECK-NEXT: %cond = select i1 %cond_p5, i1 true, i1 %cond_p3
144-
; 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: <<Unknown>> LoopDispositions: { %loop: Variant }
144+
; CHECK-NEXT: --> (true + ((true + %cond_p0) umin_seq ((true + %cond_p1) umin (true + %cond_p2)) umin_seq (true + %cond_p3))) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
145145
; CHECK-NEXT: Determining loop execution counts for: @logical_or_3ops_duplicate
146146
; CHECK-NEXT: Loop %loop: backedge-taken count is (%n umin_seq %m umin_seq %k)
147147
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1
@@ -432,7 +432,7 @@ define i32 @logical_and_2ops_and_constant(i32 %n, i32 %m, i32 %k) {
432432
; CHECK-NEXT: %umin = call i32 @llvm.umin.i32(i32 %n, i32 42)
433433
; CHECK-NEXT: --> (42 umin %n) U: [0,43) S: [0,43) Exits: (42 umin %n) LoopDispositions: { %loop: Invariant }
434434
; CHECK-NEXT: %cond = select i1 %cond_p1, i1 true, i1 %cond_p0
435-
; CHECK-NEXT: --> (true + ((true + %cond_p1) umin_seq (true + %cond_p0))) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
435+
; CHECK-NEXT: --> (true + ((true + %cond_p1) umin (true + %cond_p0))) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
436436
; CHECK-NEXT: Determining loop execution counts for: @logical_and_2ops_and_constant
437437
; CHECK-NEXT: Loop %loop: backedge-taken count is (42 umin %n)
438438
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 42
@@ -574,7 +574,7 @@ define i32 @logical_and_implies_poison1(i32 %n) {
574574
; CHECK-NEXT: %i.next = add i32 %i, 1
575575
; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((1 + %n) umin %n)) LoopDispositions: { %loop: Computable }
576576
; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false
577-
; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
577+
; CHECK-NEXT: --> (%cond_p0 umin %cond_p1) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
578578
; CHECK-NEXT: Determining loop execution counts for: @logical_and_implies_poison1
579579
; CHECK-NEXT: Loop %loop: backedge-taken count is ((1 + %n) umin %n)
580580
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1
@@ -607,7 +607,7 @@ define i32 @logical_and_implies_poison2(i32 %n) {
607607
; CHECK-NEXT: %i.next = add i32 %i, 1
608608
; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((1 + %n) umin %n)) LoopDispositions: { %loop: Computable }
609609
; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false
610-
; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
610+
; CHECK-NEXT: --> (%cond_p1 umin %cond_p0) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
611611
; CHECK-NEXT: Determining loop execution counts for: @logical_and_implies_poison2
612612
; CHECK-NEXT: Loop %loop: backedge-taken count is ((1 + %n) umin %n)
613613
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1
@@ -640,7 +640,7 @@ define i32 @logical_and_implies_poison3(i32 %n, i32 %m) {
640640
; CHECK-NEXT: %i.next = add i32 %i, 1
641641
; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((%n + %m) umin %n)) LoopDispositions: { %loop: Computable }
642642
; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false
643-
; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
643+
; CHECK-NEXT: --> (%cond_p1 umin %cond_p0) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
644644
; CHECK-NEXT: Determining loop execution counts for: @logical_and_implies_poison3
645645
; CHECK-NEXT: Loop %loop: backedge-taken count is ((%n + %m) umin %n)
646646
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1
@@ -704,7 +704,7 @@ define i32 @logical_and_implies_poison_noundef(i32 %n, i32 noundef %m) {
704704
; CHECK-NEXT: %i.next = add i32 %i, 1
705705
; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin %m)) LoopDispositions: { %loop: Computable }
706706
; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false
707-
; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
707+
; CHECK-NEXT: --> (%cond_p0 umin %cond_p1) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
708708
; CHECK-NEXT: Determining loop execution counts for: @logical_and_implies_poison_noundef
709709
; CHECK-NEXT: Loop %loop: backedge-taken count is (%n umin %m)
710710
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1
@@ -768,7 +768,7 @@ define i32 @logical_and_implies_poison_complex1(i32 %n, i32 %m) {
768768
; CHECK-NEXT: %i.next = add i32 %i, 1
769769
; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((%n + %m) umin (1 + %n + %m))) LoopDispositions: { %loop: Computable }
770770
; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false
771-
; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
771+
; CHECK-NEXT: --> (%cond_p0 umin %cond_p1) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
772772
; CHECK-NEXT: Determining loop execution counts for: @logical_and_implies_poison_complex1
773773
; CHECK-NEXT: Loop %loop: backedge-taken count is ((%n + %m) umin (1 + %n + %m))
774774
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1
@@ -804,7 +804,7 @@ define i32 @logical_and_implies_poison_complex2(i32 %n, i32 %m, i32 %l) {
804804
; CHECK-NEXT: %i.next = add i32 %i, 1
805805
; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + ((%n + %m) umin (%n + %m + %l))) LoopDispositions: { %loop: Computable }
806806
; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false
807-
; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
807+
; CHECK-NEXT: --> (%cond_p0 umin %cond_p1) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
808808
; CHECK-NEXT: Determining loop execution counts for: @logical_and_implies_poison_complex2
809809
; CHECK-NEXT: Loop %loop: backedge-taken count is ((%n + %m) umin (%n + %m + %l))
810810
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1
@@ -874,9 +874,9 @@ define i32 @logical_and_implies_multiple_ops(i32 %n, i32 %m) {
874874
; CHECK-NEXT: %i.next = add i32 %i, 1
875875
; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (((1 + %n) umin %n) umin_seq %m)) LoopDispositions: { %loop: Computable }
876876
; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false
877-
; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
877+
; CHECK-NEXT: --> (%cond_p0 umin %cond_p1) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
878878
; CHECK-NEXT: %cond2 = select i1 %cond, i1 %cond_p2, i1 false
879-
; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1 umin_seq %cond_p2) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
879+
; CHECK-NEXT: --> ((%cond_p0 umin %cond_p1) umin_seq %cond_p2) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
880880
; CHECK-NEXT: Determining loop execution counts for: @logical_and_implies_multiple_ops
881881
; CHECK-NEXT: Loop %loop: backedge-taken count is (((1 + %n) umin %n) umin_seq %m)
882882
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1
@@ -907,18 +907,18 @@ define i32 @logical_and_implies_multiple_ops2(i32 %n, i32 %m) {
907907
; CHECK-NEXT: %add = add i32 %n, 1
908908
; CHECK-NEXT: --> (1 + %n) U: full-set S: full-set
909909
; CHECK-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ]
910-
; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin_seq %m umin_seq (1 + %n)) LoopDispositions: { %loop: Computable }
910+
; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (%n umin_seq ((1 + %n) umin %m)) LoopDispositions: { %loop: Computable }
911911
; CHECK-NEXT: %i.next = add i32 %i, 1
912-
; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq %m umin_seq (1 + %n))) LoopDispositions: { %loop: Computable }
912+
; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: (1 + (%n umin_seq ((1 + %n) umin %m))) LoopDispositions: { %loop: Computable }
913913
; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false
914914
; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
915915
; CHECK-NEXT: %cond2 = select i1 %cond, i1 %cond_p2, i1 false
916-
; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1 umin_seq %cond_p2) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
916+
; CHECK-NEXT: --> (%cond_p0 umin_seq (%cond_p1 umin %cond_p2)) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
917917
; CHECK-NEXT: Determining loop execution counts for: @logical_and_implies_multiple_ops2
918-
; CHECK-NEXT: Loop %loop: backedge-taken count is (%n umin_seq %m umin_seq (1 + %n))
918+
; CHECK-NEXT: Loop %loop: backedge-taken count is (%n umin_seq ((1 + %n) umin %m))
919919
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is -1
920-
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (%n umin_seq %m umin_seq (1 + %n))
921-
; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (%n umin_seq %m umin_seq (1 + %n))
920+
; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (%n umin_seq ((1 + %n) umin %m))
921+
; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (%n umin_seq ((1 + %n) umin %m))
922922
; CHECK-NEXT: Predicates:
923923
; CHECK: Loop %loop: Trip multiple is 1
924924
;
@@ -1352,7 +1352,7 @@ define i32 @logical_and_zero_arg2(i32 %n) {
13521352
; CHECK-NEXT: %i.next = add i32 %i, 1
13531353
; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,2) S: [1,2) Exits: 1 LoopDispositions: { %loop: Computable }
13541354
; CHECK-NEXT: %cond = select i1 %cond_p0, i1 %cond_p1, i1 false
1355-
; CHECK-NEXT: --> (%cond_p0 umin_seq %cond_p1) U: full-set S: full-set Exits: false LoopDispositions: { %loop: Variant }
1355+
; CHECK-NEXT: --> (%cond_p1 umin %cond_p0) U: full-set S: full-set Exits: false LoopDispositions: { %loop: Variant }
13561356
; CHECK-NEXT: Determining loop execution counts for: @logical_and_zero_arg2
13571357
; CHECK-NEXT: Loop %loop: backedge-taken count is 0
13581358
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 0

llvm/test/Analysis/ScalarEvolution/exit-count-select.ll

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ define void @logical_and_m_const(i32 %n) {
1111
; CHECK-NEXT: %i.next = add i32 %i, 1
1212
; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,4) S: [1,4) Exits: (1 + (2 umin %n))<nuw><nsw> LoopDispositions: { %loop: Computable }
1313
; CHECK-NEXT: %cond = select i1 %cond_i, i1 %cond_i2, i1 false
14-
; CHECK-NEXT: --> (%cond_i umin_seq %cond_i2) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
14+
; CHECK-NEXT: --> (%cond_i2 umin %cond_i) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
1515
; CHECK-NEXT: Determining loop execution counts for: @logical_and_m_const
1616
; CHECK-NEXT: Loop %loop: backedge-taken count is (2 umin %n)
1717
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 2
@@ -140,7 +140,7 @@ define void @logical_or_m_const(i32 %n) {
140140
; CHECK-NEXT: %i.next = add i32 %i, 1
141141
; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,4) S: [1,4) Exits: (1 + (2 umin %n))<nuw><nsw> LoopDispositions: { %loop: Computable }
142142
; CHECK-NEXT: %cond = select i1 %cond_i, i1 true, i1 %cond_i2
143-
; CHECK-NEXT: --> (true + ((true + %cond_i) umin_seq (true + %cond_i2))) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
143+
; CHECK-NEXT: --> (true + ((true + %cond_i) umin (true + %cond_i2))) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
144144
; CHECK-NEXT: Determining loop execution counts for: @logical_or_m_const
145145
; CHECK-NEXT: Loop %loop: backedge-taken count is (2 umin %n)
146146
; CHECK-NEXT: Loop %loop: constant max backedge-taken count is 2

llvm/test/Analysis/ScalarEvolution/nsw.ll

+1-1
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,7 @@ define void @select_cond_poison_propagation(ptr %p, i32 %x) nounwind {
412412
; CHECK-NEXT: %iv = phi i32 [ %iv.next, %loop ], [ 0, %entry ]
413413
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
414414
; CHECK-NEXT: %iv.next = add nsw i32 %iv, 1
415-
; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
415+
; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
416416
; CHECK-NEXT: %sel = select i1 %cmp, i32 10, i32 20
417417
; CHECK-NEXT: --> %sel U: [0,31) S: [0,31) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
418418
; CHECK-NEXT: %cond = call i1 @cond()

llvm/test/Instrumentation/PoisonChecking/ub-checks.ll

+2
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ define noundef i32 @select_cond_may_be_poison(i32 %a, i32 %b) {
140140
; CHECK-NEXT: [[ADD:%.*]] = add nuw i32 [[A]], 1
141141
; CHECK-NEXT: [[T:%.*]] = trunc i32 [[ADD]] to i1
142142
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[T]], i32 [[ADD]], i32 [[B:%.*]]
143+
; CHECK-NEXT: [[TMP3:%.*]] = xor i1 [[TMP2]], true
144+
; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP3]])
143145
; CHECK-NEXT: ret i32 [[SEL]]
144146
;
145147
%add = add nuw i32 %a, 1

0 commit comments

Comments
 (0)