summaryrefslogtreecommitdiff
path: root/test/Transforms
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2017-12-13 21:58:15 +0000
committerSanjay Patel <spatel@rotateright.com>2017-12-13 21:58:15 +0000
commit9a3e5b040137a7bd6b395ba98e6171fd42066bb0 (patch)
tree18d4e3bafdd2a71638eb29772004304773e92046 /test/Transforms
parent2b46be6545def38ecf555e22a0031e1f628ce654 (diff)
[EarlyCSE] recognize commuted and swapped variants of min/max as equivalent (PR35642)
As shown in: https://bugs.llvm.org/show_bug.cgi?id=35642 ...we can have different forms of min/max, so we should recognize those here in EarlyCSE similar to how we already handle binops and compares that can commute. Differential Revision: https://reviews.llvm.org/D41136 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@320640 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Transforms')
-rw-r--r--test/Transforms/EarlyCSE/commute.ll49
1 files changed, 27 insertions, 22 deletions
diff --git a/test/Transforms/EarlyCSE/commute.ll b/test/Transforms/EarlyCSE/commute.ll
index dcdcdae6465..3adee77ec3d 100644
--- a/test/Transforms/EarlyCSE/commute.ll
+++ b/test/Transforms/EarlyCSE/commute.ll
@@ -78,8 +78,7 @@ define i8 @smin_commute(i8 %a, i8 %b) {
; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i8 %a, %b
; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i8 %b, %a
; CHECK-NEXT: [[M1:%.*]] = select i1 [[CMP1]], i8 %a, i8 %b
-; CHECK-NEXT: [[M2:%.*]] = select i1 [[CMP2]], i8 %b, i8 %a
-; CHECK-NEXT: [[R:%.*]] = mul i8 [[M1]], [[M2]]
+; CHECK-NEXT: [[R:%.*]] = mul i8 [[M1]], [[M1]]
; CHECK-NEXT: ret i8 [[R]]
;
%cmp1 = icmp slt i8 %a, %b
@@ -97,9 +96,7 @@ define i1 @smin_swapped(i8 %a, i8 %b) {
; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i8 %a, %b
; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i8 %a, %b
; CHECK-NEXT: [[M1:%.*]] = select i1 [[CMP1]], i8 %b, i8 %a
-; CHECK-NEXT: [[M2:%.*]] = select i1 [[CMP2]], i8 %a, i8 %b
-; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[M2]], [[M1]]
-; CHECK-NEXT: ret i1 [[R]]
+; CHECK-NEXT: ret i1 true
;
%cmp1 = icmp sgt i8 %a, %b
%cmp2 = icmp slt i8 %a, %b
@@ -114,9 +111,7 @@ define i8 @smax_commute(i8 %a, i8 %b) {
; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i8 %a, %b
; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i8 %b, %a
; CHECK-NEXT: [[M1:%.*]] = select i1 [[CMP1]], i8 %a, i8 %b
-; CHECK-NEXT: [[M2:%.*]] = select i1 [[CMP2]], i8 %b, i8 %a
-; CHECK-NEXT: [[R:%.*]] = urem i8 [[M2]], [[M1]]
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 0
;
%cmp1 = icmp sgt i8 %a, %b
%cmp2 = icmp sgt i8 %b, %a
@@ -131,9 +126,7 @@ define i8 @smax_swapped(i8 %a, i8 %b) {
; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i8 %a, %b
; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i8 %a, %b
; CHECK-NEXT: [[M1:%.*]] = select i1 [[CMP1]], i8 %b, i8 %a
-; CHECK-NEXT: [[M2:%.*]] = select i1 [[CMP2]], i8 %a, i8 %b
-; CHECK-NEXT: [[R:%.*]] = sdiv i8 [[M1]], [[M2]]
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 1
;
%cmp1 = icmp slt i8 %a, %b
%cmp2 = icmp sgt i8 %a, %b
@@ -148,9 +141,7 @@ define i8 @umin_commute(i8 %a, i8 %b) {
; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i8 %a, %b
; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i8 %b, %a
; CHECK-NEXT: [[M1:%.*]] = select i1 [[CMP1]], i8 %a, i8 %b
-; CHECK-NEXT: [[M2:%.*]] = select i1 [[CMP2]], i8 %b, i8 %a
-; CHECK-NEXT: [[R:%.*]] = sub i8 [[M2]], [[M1]]
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 0
;
%cmp1 = icmp ult i8 %a, %b
%cmp2 = icmp ult i8 %b, %a
@@ -167,9 +158,7 @@ define <2 x i8> @umin_swapped(<2 x i8> %a, <2 x i8> %b) {
; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt <2 x i8> %a, %b
; CHECK-NEXT: [[CMP2:%.*]] = icmp ult <2 x i8> %a, %b
; CHECK-NEXT: [[M1:%.*]] = select <2 x i1> [[CMP1]], <2 x i8> %b, <2 x i8> %a
-; CHECK-NEXT: [[M2:%.*]] = select <2 x i1> [[CMP2]], <2 x i8> %a, <2 x i8> %b
-; CHECK-NEXT: [[R:%.*]] = sub <2 x i8> [[M2]], [[M1]]
-; CHECK-NEXT: ret <2 x i8> [[R]]
+; CHECK-NEXT: ret <2 x i8> zeroinitializer
;
%cmp1 = icmp ugt <2 x i8> %a, %b
%cmp2 = icmp ult <2 x i8> %a, %b
@@ -184,9 +173,7 @@ define i8 @umax_commute(i8 %a, i8 %b) {
; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i8 %a, %b
; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i8 %b, %a
; CHECK-NEXT: [[M1:%.*]] = select i1 [[CMP1]], i8 %a, i8 %b
-; CHECK-NEXT: [[M2:%.*]] = select i1 [[CMP2]], i8 %b, i8 %a
-; CHECK-NEXT: [[R:%.*]] = udiv i8 [[M1]], [[M2]]
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 1
;
%cmp1 = icmp ugt i8 %a, %b
%cmp2 = icmp ugt i8 %b, %a
@@ -201,8 +188,7 @@ define i8 @umax_swapped(i8 %a, i8 %b) {
; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i8 %a, %b
; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i8 %a, %b
; CHECK-NEXT: [[M1:%.*]] = select i1 [[CMP1]], i8 %b, i8 %a
-; CHECK-NEXT: [[M2:%.*]] = select i1 [[CMP2]], i8 %a, i8 %b
-; CHECK-NEXT: [[R:%.*]] = add i8 [[M2]], [[M1]]
+; CHECK-NEXT: [[R:%.*]] = add i8 [[M1]], [[M1]]
; CHECK-NEXT: ret i8 [[R]]
;
%cmp1 = icmp ult i8 %a, %b
@@ -213,3 +199,22 @@ define i8 @umax_swapped(i8 %a, i8 %b) {
ret i8 %r
}
+; Min/max may exist with non-canonical operands. Value tracking can match those.
+
+define i8 @smax_nsw(i8 %a, i8 %b) {
+; CHECK-LABEL: @smax_nsw(
+; CHECK-NEXT: [[SUB:%.*]] = sub nsw i8 %a, %b
+; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i8 %a, %b
+; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i8 [[SUB]], 0
+; CHECK-NEXT: [[M1:%.*]] = select i1 [[CMP1]], i8 0, i8 [[SUB]]
+; CHECK-NEXT: ret i8 0
+;
+ %sub = sub nsw i8 %a, %b
+ %cmp1 = icmp slt i8 %a, %b
+ %cmp2 = icmp sgt i8 %sub, 0
+ %m1 = select i1 %cmp1, i8 0, i8 %sub
+ %m2 = select i1 %cmp2, i8 %sub, i8 0
+ %r = sub i8 %m2, %m1
+ ret i8 %r
+}
+