[llvm] 5cd695d - [InstSimplify] fold min/max with opposite of limit value

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 29 14:04:55 PDT 2020


Author: Sanjay Patel
Date: 2020-07-29T17:03:50-04:00
New Revision: 5cd695dd7fbd52af0f58ad75cc8d63ad2baa619f

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

LOG: [InstSimplify] fold min/max with opposite of limit value

Added: 
    

Modified: 
    llvm/lib/Analysis/InstructionSimplify.cpp
    llvm/test/Transforms/InstSimplify/maxmin_intrinsics.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index de4e23aac982..9d9999ea4372 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -5270,12 +5270,23 @@ static Value *simplifyBinaryIntrinsic(Function *F, Value *Op0, Value *Op1,
     if (!match(Op1, m_APIntAllowUndef(C)))
       break;
 
+    // Clamp to limit value. For example:
+    // umax(i8 %x, i8 255) --> 255
     if ((IID == Intrinsic::smax && C->isMaxSignedValue()) ||
         (IID == Intrinsic::smin && C->isMinSignedValue()) ||
         (IID == Intrinsic::umax && C->isMaxValue()) ||
         (IID == Intrinsic::umin && C->isMinValue()))
       return ConstantInt::get(ReturnType, *C);
 
+    // If the constant op is the opposite of the limit value, the other must be
+    // larger/smaller or equal. For example:
+    // umin(i8 %x, i8 255) --> %x
+    if ((IID == Intrinsic::smax && C->isMinSignedValue()) ||
+        (IID == Intrinsic::smin && C->isMaxSignedValue()) ||
+        (IID == Intrinsic::umax && C->isMinValue()) ||
+        (IID == Intrinsic::umin && C->isMaxValue()))
+      return Op0;
+
     break;
   }
   case Intrinsic::usub_with_overflow:

diff  --git a/llvm/test/Transforms/InstSimplify/maxmin_intrinsics.ll b/llvm/test/Transforms/InstSimplify/maxmin_intrinsics.ll
index 312056d745a9..a376ef8adf1a 100644
--- a/llvm/test/Transforms/InstSimplify/maxmin_intrinsics.ll
+++ b/llvm/test/Transforms/InstSimplify/maxmin_intrinsics.ll
@@ -146,8 +146,7 @@ define <2 x i8> @umin_minval_commute(<2 x i8> %x) {
 
 define i8 @smax_minval(i8 %x) {
 ; CHECK-LABEL: @smax_minval(
-; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 -128)
-; CHECK-NEXT:    ret i8 [[R]]
+; CHECK-NEXT:    ret i8 [[X:%.*]]
 ;
   %r = call i8 @llvm.smax.i8(i8 %x, i8 -128)
   ret i8 %r
@@ -155,8 +154,7 @@ define i8 @smax_minval(i8 %x) {
 
 define <2 x i8> @smax_minval_commute(<2 x i8> %x) {
 ; CHECK-LABEL: @smax_minval_commute(
-; CHECK-NEXT:    [[R:%.*]] = call <2 x i8> @llvm.smax.v2i8(<2 x i8> <i8 -128, i8 -128>, <2 x i8> [[X:%.*]])
-; CHECK-NEXT:    ret <2 x i8> [[R]]
+; CHECK-NEXT:    ret <2 x i8> [[X:%.*]]
 ;
   %r = call <2 x i8> @llvm.smax.v2i8(<2 x i8> <i8 -128, i8 -128>, <2 x i8> %x)
   ret <2 x i8> %r
@@ -164,8 +162,7 @@ define <2 x i8> @smax_minval_commute(<2 x i8> %x) {
 
 define i8 @smin_maxval(i8 %x) {
 ; CHECK-LABEL: @smin_maxval(
-; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.smin.i8(i8 127, i8 [[X:%.*]])
-; CHECK-NEXT:    ret i8 [[R]]
+; CHECK-NEXT:    ret i8 [[X:%.*]]
 ;
   %r = call i8 @llvm.smin.i8(i8 127, i8 %x)
   ret i8 %r
@@ -173,8 +170,7 @@ define i8 @smin_maxval(i8 %x) {
 
 define <2 x i8> @smin_maxval_commute(<2 x i8> %x) {
 ; CHECK-LABEL: @smin_maxval_commute(
-; CHECK-NEXT:    [[R:%.*]] = call <2 x i8> @llvm.smin.v2i8(<2 x i8> [[X:%.*]], <2 x i8> <i8 127, i8 127>)
-; CHECK-NEXT:    ret <2 x i8> [[R]]
+; CHECK-NEXT:    ret <2 x i8> [[X:%.*]]
 ;
   %r = call <2 x i8> @llvm.smin.v2i8(<2 x i8> %x, <2 x i8> <i8 127, i8 127>)
   ret <2 x i8> %r
@@ -182,8 +178,7 @@ define <2 x i8> @smin_maxval_commute(<2 x i8> %x) {
 
 define i8 @umax_minval(i8 %x) {
 ; CHECK-LABEL: @umax_minval(
-; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 0)
-; CHECK-NEXT:    ret i8 [[R]]
+; CHECK-NEXT:    ret i8 [[X:%.*]]
 ;
   %r = call i8 @llvm.umax.i8(i8 %x, i8 0)
   ret i8 %r
@@ -191,8 +186,7 @@ define i8 @umax_minval(i8 %x) {
 
 define <2 x i8> @umax_minval_commute(<2 x i8> %x) {
 ; CHECK-LABEL: @umax_minval_commute(
-; CHECK-NEXT:    [[R:%.*]] = call <2 x i8> @llvm.umax.v2i8(<2 x i8> zeroinitializer, <2 x i8> [[X:%.*]])
-; CHECK-NEXT:    ret <2 x i8> [[R]]
+; CHECK-NEXT:    ret <2 x i8> [[X:%.*]]
 ;
   %r = call <2 x i8> @llvm.umax.v2i8(<2 x i8> zeroinitializer, <2 x i8> %x)
   ret <2 x i8> %r
@@ -200,8 +194,7 @@ define <2 x i8> @umax_minval_commute(<2 x i8> %x) {
 
 define i8 @umin_maxval(i8 %x) {
 ; CHECK-LABEL: @umin_maxval(
-; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.umin.i8(i8 -1, i8 [[X:%.*]])
-; CHECK-NEXT:    ret i8 [[R]]
+; CHECK-NEXT:    ret i8 [[X:%.*]]
 ;
   %r = call i8 @llvm.umin.i8(i8 255, i8 %x)
   ret i8 %r
@@ -209,8 +202,7 @@ define i8 @umin_maxval(i8 %x) {
 
 define <2 x i8> @umin_maxval_commute(<2 x i8> %x) {
 ; CHECK-LABEL: @umin_maxval_commute(
-; CHECK-NEXT:    [[R:%.*]] = call <2 x i8> @llvm.umin.v2i8(<2 x i8> [[X:%.*]], <2 x i8> <i8 -1, i8 -1>)
-; CHECK-NEXT:    ret <2 x i8> [[R]]
+; CHECK-NEXT:    ret <2 x i8> [[X:%.*]]
 ;
   %r = call <2 x i8> @llvm.umin.v2i8(<2 x i8> %x, <2 x i8> <i8 255, i8 255>)
   ret <2 x i8> %r
@@ -250,8 +242,7 @@ define <2 x i8> @umin_minval_partial_undef(<2 x i8> %x) {
 
 define <2 x i8> @smax_minval_partial_undef(<2 x i8> %x) {
 ; CHECK-LABEL: @smax_minval_partial_undef(
-; CHECK-NEXT:    [[R:%.*]] = call <2 x i8> @llvm.smax.v2i8(<2 x i8> <i8 undef, i8 -128>, <2 x i8> [[X:%.*]])
-; CHECK-NEXT:    ret <2 x i8> [[R]]
+; CHECK-NEXT:    ret <2 x i8> [[X:%.*]]
 ;
   %r = call <2 x i8> @llvm.smax.v2i8(<2 x i8> <i8 undef, i8 -128>, <2 x i8> %x)
   ret <2 x i8> %r
@@ -259,8 +250,7 @@ define <2 x i8> @smax_minval_partial_undef(<2 x i8> %x) {
 
 define <2 x i8> @smin_maxval_partial_undef(<2 x i8> %x) {
 ; CHECK-LABEL: @smin_maxval_partial_undef(
-; CHECK-NEXT:    [[R:%.*]] = call <2 x i8> @llvm.smin.v2i8(<2 x i8> [[X:%.*]], <2 x i8> <i8 undef, i8 127>)
-; CHECK-NEXT:    ret <2 x i8> [[R]]
+; CHECK-NEXT:    ret <2 x i8> [[X:%.*]]
 ;
   %r = call <2 x i8> @llvm.smin.v2i8(<2 x i8> %x, <2 x i8> <i8 undef, i8 127>)
   ret <2 x i8> %r
@@ -268,8 +258,7 @@ define <2 x i8> @smin_maxval_partial_undef(<2 x i8> %x) {
 
 define <2 x i8> @umax_minval_partial_undef(<2 x i8> %x) {
 ; CHECK-LABEL: @umax_minval_partial_undef(
-; CHECK-NEXT:    [[R:%.*]] = call <2 x i8> @llvm.umax.v2i8(<2 x i8> <i8 0, i8 undef>, <2 x i8> [[X:%.*]])
-; CHECK-NEXT:    ret <2 x i8> [[R]]
+; CHECK-NEXT:    ret <2 x i8> [[X:%.*]]
 ;
   %r = call <2 x i8> @llvm.umax.v2i8(<2 x i8> <i8 0, i8 undef>, <2 x i8> %x)
   ret <2 x i8> %r
@@ -277,8 +266,7 @@ define <2 x i8> @umax_minval_partial_undef(<2 x i8> %x) {
 
 define <2 x i8> @umin_maxval_partial_undef(<2 x i8> %x) {
 ; CHECK-LABEL: @umin_maxval_partial_undef(
-; CHECK-NEXT:    [[R:%.*]] = call <2 x i8> @llvm.umin.v2i8(<2 x i8> [[X:%.*]], <2 x i8> <i8 -1, i8 undef>)
-; CHECK-NEXT:    ret <2 x i8> [[R]]
+; CHECK-NEXT:    ret <2 x i8> [[X:%.*]]
 ;
   %r = call <2 x i8> @llvm.umin.v2i8(<2 x i8> %x, <2 x i8> <i8 255, i8 undef>)
   ret <2 x i8> %r


        


More information about the llvm-commits mailing list