return getSequentialMinMaxExpr(Kind, Ops);
}
- // In %x umin_seq %y, if %y being poison implies %x is also poison, we can
- // use a non-sequential umin instead.
+ const SCEV *SaturationPoint;
+ switch (Kind) {
+ case scSequentialUMinExpr:
+ SaturationPoint = getZero(Ops[0]->getType());
+ break;
+ default:
+ llvm_unreachable("Not a sequential min/max type.");
+ }
+
+ // We can replace %x umin_seq %y with %x umin %y if either:
+ // * %y being poison implies %x is also poison.
+ // * %x cannot be the saturating value (e.g. zero for umin).
for (unsigned i = 1, e = Ops.size(); i != e; ++i) {
- if (::impliesPoison(Ops[i], Ops[i - 1])) {
+ if (::impliesPoison(Ops[i], Ops[i - 1]) ||
+ isKnownViaNonRecursiveReasoning(ICmpInst::ICMP_NE, Ops[i - 1],
+ SaturationPoint)) {
SmallVector<const SCEV *> SeqOps = {Ops[i - 1], Ops[i]};
Ops[i - 1] = getMinMaxExpr(
SCEVSequentialMinMaxExpr::getEquivalentNonSequentialSCEVType(Kind),
; CHECK-NEXT: %n1 = add i32 %n.ext, 1
; CHECK-NEXT: --> (1 + (zext i16 %n to i32))<nuw><nsw> 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: ((1 + (zext i16 %n to i32))<nuw><nsw> umin_seq %m) LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,65537) S: [0,65537) Exits: ((1 + (zext i16 %n to i32))<nuw><nsw> 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 + ((1 + (zext i16 %n to i32))<nuw><nsw> umin_seq %m))<nuw><nsw> LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,65538) S: [1,65538) Exits: (1 + ((1 + (zext i16 %n to i32))<nuw><nsw> umin %m))<nuw><nsw> 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: <<Unknown>> 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))<nuw><nsw> umin_seq %m)
+; CHECK-NEXT: Loop %loop: backedge-taken count is ((1 + (zext i16 %n to i32))<nuw><nsw> umin %m)
; CHECK-NEXT: Loop %loop: max backedge-taken count is 65536
-; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is ((1 + (zext i16 %n to i32))<nuw><nsw> umin_seq %m)
+; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is ((1 + (zext i16 %n to i32))<nuw><nsw> umin %m)
; CHECK-NEXT: Predicates:
; CHECK: Loop %loop: Trip multiple is 1
;