[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