[llvm] 68e1ba8 - [SCEV] Fold umin_seq using known predicate

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Mon May 9 07:35:19 PDT 2022


Author: Nikita Popov
Date: 2022-05-09T16:35:08+02:00
New Revision: 68e1ba818869d6312a2774ccc320c0de86a8249c

URL: https://github.com/llvm/llvm-project/commit/68e1ba818869d6312a2774ccc320c0de86a8249c
DIFF: https://github.com/llvm/llvm-project/commit/68e1ba818869d6312a2774ccc320c0de86a8249c.diff

LOG: [SCEV] Fold umin_seq using known predicate

Fold %x umin_seq %y to %x if %x ule %y. This also subsumes the
special handling for constant operands, as if %y is constant this
folds to umin via implied poison reasoning, and if %x is constant
then either %x is not zero and it folds to umin, or it is known
zero, in which case it is ule anything.

Added: 
    

Modified: 
    llvm/lib/Analysis/ScalarEvolution.cpp
    llvm/test/Analysis/ScalarEvolution/exit-count-select-safe.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index b43526da98a3..bde03f63b8ac 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -4076,11 +4076,6 @@ ScalarEvolution::getSequentialMinMaxExpr(SCEVTypes Kind,
   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) {
@@ -4130,18 +4125,20 @@ ScalarEvolution::getSequentialMinMaxExpr(SCEVTypes Kind,
   }
 
   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)) {
@@ -4152,6 +4149,12 @@ ScalarEvolution::getSequentialMinMaxExpr(SCEVTypes Kind,
       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

diff  --git a/llvm/test/Analysis/ScalarEvolution/exit-count-select-safe.ll b/llvm/test/Analysis/ScalarEvolution/exit-count-select-safe.ll
index e8fb7c9d779c..28adb9c05953 100644
--- a/llvm/test/Analysis/ScalarEvolution/exit-count-select-safe.ll
+++ b/llvm/test/Analysis/ScalarEvolution/exit-count-select-safe.ll
@@ -1058,15 +1058,15 @@ define i32 @logical_and_known_smaller(i16 %n, i16 %m) {
 ; 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
 ;
@@ -1096,15 +1096,15 @@ define i32 @logical_and_known_smaller_equal(i16 %n, i16 %m) {
 ; 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
 ;


        


More information about the llvm-commits mailing list