[llvm] ac87480 - [SCEV] Recognize min/max intrinsics

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Sat Sep 5 07:31:39 PDT 2020


Author: Nikita Popov
Date: 2020-09-05T16:30:11+02:00
New Revision: ac87480bd8beef0a4e93981e38df2c21652e1393

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

LOG: [SCEV] Recognize min/max intrinsics

Recognize umin/umax/smin/smax intrinsics and convert them to the
already existing SCEV nodes of the same name.

In the future we'll want SCEVExpander to also produce the intrinsics,
but we're not ready for that yet.

Differential Revision: https://reviews.llvm.org/D87160

Added: 
    

Modified: 
    llvm/lib/Analysis/ScalarEvolution.cpp
    llvm/test/Analysis/ScalarEvolution/minmax-intrinsics.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 9c9b9c53c939..40d89fff0458 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -6341,6 +6341,25 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
   case Instruction::Invoke:
     if (Value *RV = cast<CallBase>(U)->getReturnedArgOperand())
       return getSCEV(RV);
+
+    if (auto *II = dyn_cast<IntrinsicInst>(U)) {
+      switch (II->getIntrinsicID()) {
+      case Intrinsic::umax:
+        return getUMaxExpr(getSCEV(II->getArgOperand(0)),
+                           getSCEV(II->getArgOperand(1)));
+      case Intrinsic::umin:
+        return getUMinExpr(getSCEV(II->getArgOperand(0)),
+                           getSCEV(II->getArgOperand(1)));
+      case Intrinsic::smax:
+        return getSMaxExpr(getSCEV(II->getArgOperand(0)),
+                           getSCEV(II->getArgOperand(1)));
+      case Intrinsic::smin:
+        return getSMinExpr(getSCEV(II->getArgOperand(0)),
+                           getSCEV(II->getArgOperand(1)));
+      default:
+        break;
+      }
+    }
     break;
   }
 

diff  --git a/llvm/test/Analysis/ScalarEvolution/minmax-intrinsics.ll b/llvm/test/Analysis/ScalarEvolution/minmax-intrinsics.ll
index c0395c328fca..86ba0b7b658e 100644
--- a/llvm/test/Analysis/ScalarEvolution/minmax-intrinsics.ll
+++ b/llvm/test/Analysis/ScalarEvolution/minmax-intrinsics.ll
@@ -11,7 +11,7 @@ define i32 @umax(i32 %x, i32 %y) {
 ; CHECK-LABEL: 'umax'
 ; CHECK-NEXT:  Classifying expressions for: @umax
 ; CHECK-NEXT:    %z = call i32 @llvm.umax.i32(i32 %x, i32 %y)
-; CHECK-NEXT:    --> %z U: full-set S: full-set
+; CHECK-NEXT:    --> (%x umax %y) U: full-set S: full-set
 ; CHECK-NEXT:  Determining loop execution counts for: @umax
 ;
   %z = call i32 @llvm.umax.i32(i32 %x, i32 %y)
@@ -22,7 +22,7 @@ define i32 @umin(i32 %x, i32 %y) {
 ; CHECK-LABEL: 'umin'
 ; CHECK-NEXT:  Classifying expressions for: @umin
 ; CHECK-NEXT:    %z = call i32 @llvm.umin.i32(i32 %x, i32 %y)
-; CHECK-NEXT:    --> %z U: full-set S: full-set
+; CHECK-NEXT:    --> (%x umin %y) U: full-set S: full-set
 ; CHECK-NEXT:  Determining loop execution counts for: @umin
 ;
   %z = call i32 @llvm.umin.i32(i32 %x, i32 %y)
@@ -33,7 +33,7 @@ define i32 @smax(i32 %x, i32 %y) {
 ; CHECK-LABEL: 'smax'
 ; CHECK-NEXT:  Classifying expressions for: @smax
 ; CHECK-NEXT:    %z = call i32 @llvm.smax.i32(i32 %x, i32 %y)
-; CHECK-NEXT:    --> %z U: full-set S: full-set
+; CHECK-NEXT:    --> (%x smax %y) U: full-set S: full-set
 ; CHECK-NEXT:  Determining loop execution counts for: @smax
 ;
   %z = call i32 @llvm.smax.i32(i32 %x, i32 %y)
@@ -44,7 +44,7 @@ define i32 @smin(i32 %x, i32 %y) {
 ; CHECK-LABEL: 'smin'
 ; CHECK-NEXT:  Classifying expressions for: @smin
 ; CHECK-NEXT:    %z = call i32 @llvm.smin.i32(i32 %x, i32 %y)
-; CHECK-NEXT:    --> %z U: full-set S: full-set
+; CHECK-NEXT:    --> (%x smin %y) U: full-set S: full-set
 ; CHECK-NEXT:  Determining loop execution counts for: @smin
 ;
   %z = call i32 @llvm.smin.i32(i32 %x, i32 %y)
@@ -55,9 +55,9 @@ define i32 @clamp(i32 %x) {
 ; CHECK-LABEL: 'clamp'
 ; CHECK-NEXT:  Classifying expressions for: @clamp
 ; CHECK-NEXT:    %y = call i32 @llvm.umax.i32(i32 %x, i32 10)
-; CHECK-NEXT:    --> %y U: full-set S: full-set
+; CHECK-NEXT:    --> (10 umax %x) U: [10,0) S: [10,0)
 ; CHECK-NEXT:    %z = call i32 @llvm.umin.i32(i32 %y, i32 20)
-; CHECK-NEXT:    --> %z U: full-set S: full-set
+; CHECK-NEXT:    --> (20 umin (10 umax %x)) U: [10,21) S: [10,21)
 ; CHECK-NEXT:  Determining loop execution counts for: @clamp
 ;
   %y = call i32 @llvm.umax.i32(i32 %x, i32 10)


        


More information about the llvm-commits mailing list