assert(!Ops.empty() && "Cannot get empty (u|s)(min|max)!");
if (Ops.size() == 1)
return Ops[0];
- if (Ops.size() == 2 &&
- any_of(Ops, [](const SCEV *Op) { return isa<SCEVConstant>(Op); }))
- return getMinMaxExpr(
- SCEVSequentialMinMaxExpr::getEquivalentNonSequentialSCEVType(Kind),
- Ops);
#ifndef NDEBUG
Type *ETy = getEffectiveSCEVType(Ops[0]->getType());
for (unsigned i = 1, e = Ops.size(); i != e; ++i) {
}
const SCEV *SaturationPoint;
+ ICmpInst::Predicate Pred;
switch (Kind) {
case scSequentialUMinExpr:
SaturationPoint = getZero(Ops[0]->getType());
+ Pred = ICmpInst::ICMP_ULE;
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) {
+ // 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).
if (::impliesPoison(Ops[i], Ops[i - 1]) ||
isKnownViaNonRecursiveReasoning(ICmpInst::ICMP_NE, Ops[i - 1],
SaturationPoint)) {
Ops.erase(Ops.begin() + i);
return getSequentialMinMaxExpr(Kind, Ops);
}
+ // Fold %x umin_seq %y to %x if %x ule %y.
+ // TODO: We might be able to prove the predicate for a later operand.
+ if (isKnownViaNonRecursiveReasoning(Pred, Ops[i - 1], Ops[i])) {
+ Ops.erase(Ops.begin() + i);
+ return getSequentialMinMaxExpr(Kind, Ops);
+ }
}
// Okay, it looks like we really DO need an expr. Check to see if we
; CHECK-NEXT: %m.add = add i32 %m.ext, 65536
; CHECK-NEXT: --> (65536 + (zext i16 %m to i32))<nuw><nsw> U: [65536,131072) S: [65536,131072)
; 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 (65536 + (zext i16 %m to i32))<nuw><nsw>) LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,65536) S: [0,65536) Exits: (zext i16 %n 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 (65536 + (zext i16 %m to i32))<nuw><nsw>))<nuw><nsw> LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,65537) S: [1,65537) Exits: (1 + (zext i16 %n to i32))<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_known_smaller
-; CHECK-NEXT: Loop %loop: backedge-taken count is ((zext i16 %n to i32) umin_seq (65536 + (zext i16 %m to i32))<nuw><nsw>)
+; CHECK-NEXT: Loop %loop: backedge-taken count is (zext i16 %n to i32)
; CHECK-NEXT: Loop %loop: max backedge-taken count is 65535
-; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is ((zext i16 %n to i32) umin_seq (65536 + (zext i16 %m to i32))<nuw><nsw>)
+; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (zext i16 %n to i32)
; CHECK-NEXT: Predicates:
; CHECK: Loop %loop: Trip multiple is 1
;
; CHECK-NEXT: %m.add = add i32 %m.ext, 65535
; CHECK-NEXT: --> (65535 + (zext i16 %m to i32))<nuw><nsw> U: [65535,131071) S: [65535,131071)
; 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 (65535 + (zext i16 %m to i32))<nuw><nsw>) LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,65536) S: [0,65536) Exits: (zext i16 %n 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 (65535 + (zext i16 %m to i32))<nuw><nsw>))<nuw><nsw> LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,65537) S: [1,65537) Exits: (1 + (zext i16 %n to i32))<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_known_smaller_equal
-; CHECK-NEXT: Loop %loop: backedge-taken count is ((zext i16 %n to i32) umin_seq (65535 + (zext i16 %m to i32))<nuw><nsw>)
+; CHECK-NEXT: Loop %loop: backedge-taken count is (zext i16 %n to i32)
; CHECK-NEXT: Loop %loop: max backedge-taken count is 65535
-; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is ((zext i16 %n to i32) umin_seq (65535 + (zext i16 %m to i32))<nuw><nsw>)
+; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (zext i16 %n to i32)
; CHECK-NEXT: Predicates:
; CHECK: Loop %loop: Trip multiple is 1
;