blob: 47954be5ab4f4fb3a1fb2586a6765ba3a4db8097 [file] [log] [blame]
Sanjay Patel568196b2016-12-08 23:44:58 +00001; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -instcombine < %s | FileCheck %s
3
4; If we have a umin feeding an unsigned or equality icmp that shares an
5; operand with the umin, the compare should always be folded.
6; Test all 4 foldable predicates (eq,ne,uge,ult) * 4 commutation
Sanjay Pateldd46b522016-12-19 17:32:37 +00007; possibilities for each predicate. Note that folds to true/false
Sanjay Patel568196b2016-12-08 23:44:58 +00008; (predicate is ule/ugt) or folds to an existing instruction should be
9; handled by InstSimplify.
10
11; umin(X, Y) == X --> X <= Y
12
13define i1 @eq_umin1(i32 %x, i32 %y) {
14; CHECK-LABEL: @eq_umin1(
Sanjay Pateldd46b522016-12-19 17:32:37 +000015; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 %x, %y
Sanjay Patel568196b2016-12-08 23:44:58 +000016; CHECK-NEXT: ret i1 [[CMP2]]
17;
18 %cmp1 = icmp ult i32 %x, %y
19 %sel = select i1 %cmp1, i32 %x, i32 %y
20 %cmp2 = icmp eq i32 %sel, %x
21 ret i1 %cmp2
22}
23
24; Commute min operands.
25
26define i1 @eq_umin2(i32 %x, i32 %y) {
27; CHECK-LABEL: @eq_umin2(
Sanjay Pateldd46b522016-12-19 17:32:37 +000028; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 %x, %y
Sanjay Patel568196b2016-12-08 23:44:58 +000029; CHECK-NEXT: ret i1 [[CMP2]]
30;
31 %cmp1 = icmp ult i32 %y, %x
32 %sel = select i1 %cmp1, i32 %y, i32 %x
33 %cmp2 = icmp eq i32 %sel, %x
34 ret i1 %cmp2
35}
36
37; Disguise the icmp predicate by commuting the min op to the RHS.
38
39define i1 @eq_umin3(i32 %a, i32 %y) {
40; CHECK-LABEL: @eq_umin3(
41; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3
Sanjay Pateldd46b522016-12-19 17:32:37 +000042; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[X]], %y
Sanjay Patel568196b2016-12-08 23:44:58 +000043; CHECK-NEXT: ret i1 [[CMP2]]
44;
45 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
46 %cmp1 = icmp ult i32 %x, %y
47 %sel = select i1 %cmp1, i32 %x, i32 %y
48 %cmp2 = icmp eq i32 %x, %sel
49 ret i1 %cmp2
50}
51
52; Commute min operands.
53
54define i1 @eq_umin4(i32 %a, i32 %y) {
55; CHECK-LABEL: @eq_umin4(
56; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3
Sanjay Pateldd46b522016-12-19 17:32:37 +000057; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[X]], %y
Sanjay Patel568196b2016-12-08 23:44:58 +000058; CHECK-NEXT: ret i1 [[CMP2]]
59;
60 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
61 %cmp1 = icmp ult i32 %y, %x
62 %sel = select i1 %cmp1, i32 %y, i32 %x
63 %cmp2 = icmp eq i32 %x, %sel
64 ret i1 %cmp2
65}
66
67; umin(X, Y) >= X --> X <= Y
68
69define i1 @uge_umin1(i32 %x, i32 %y) {
70; CHECK-LABEL: @uge_umin1(
Sanjay Pateldd46b522016-12-19 17:32:37 +000071; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 %x, %y
Sanjay Patel568196b2016-12-08 23:44:58 +000072; CHECK-NEXT: ret i1 [[CMP2]]
73;
74 %cmp1 = icmp ult i32 %x, %y
75 %sel = select i1 %cmp1, i32 %x, i32 %y
76 %cmp2 = icmp uge i32 %sel, %x
77 ret i1 %cmp2
78}
79
80; Commute min operands.
81
82define i1 @uge_umin2(i32 %x, i32 %y) {
83; CHECK-LABEL: @uge_umin2(
Sanjay Pateldd46b522016-12-19 17:32:37 +000084; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 %x, %y
Sanjay Patel568196b2016-12-08 23:44:58 +000085; CHECK-NEXT: ret i1 [[CMP2]]
86;
87 %cmp1 = icmp ult i32 %y, %x
88 %sel = select i1 %cmp1, i32 %y, i32 %x
89 %cmp2 = icmp uge i32 %sel, %x
90 ret i1 %cmp2
91}
92
93; Disguise the icmp predicate by commuting the min op to the RHS.
94
95define i1 @uge_umin3(i32 %a, i32 %y) {
96; CHECK-LABEL: @uge_umin3(
97; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3
Sanjay Pateldd46b522016-12-19 17:32:37 +000098; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[X]], %y
Sanjay Patel568196b2016-12-08 23:44:58 +000099; CHECK-NEXT: ret i1 [[CMP2]]
100;
101 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
102 %cmp1 = icmp ult i32 %x, %y
103 %sel = select i1 %cmp1, i32 %x, i32 %y
104 %cmp2 = icmp ule i32 %x, %sel
105 ret i1 %cmp2
106}
107
108; Commute min operands.
109
110define i1 @uge_umin4(i32 %a, i32 %y) {
111; CHECK-LABEL: @uge_umin4(
112; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3
Sanjay Pateldd46b522016-12-19 17:32:37 +0000113; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[X]], %y
Sanjay Patel568196b2016-12-08 23:44:58 +0000114; CHECK-NEXT: ret i1 [[CMP2]]
115;
116 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
117 %cmp1 = icmp ult i32 %y, %x
118 %sel = select i1 %cmp1, i32 %y, i32 %x
119 %cmp2 = icmp ule i32 %x, %sel
120 ret i1 %cmp2
121}
122
123; umin(X, Y) != X --> X > Y
124
125define i1 @ne_umin1(i32 %x, i32 %y) {
126; CHECK-LABEL: @ne_umin1(
Sanjay Pateldd46b522016-12-19 17:32:37 +0000127; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 %x, %y
Sanjay Patel568196b2016-12-08 23:44:58 +0000128; CHECK-NEXT: ret i1 [[CMP2]]
129;
130 %cmp1 = icmp ult i32 %x, %y
131 %sel = select i1 %cmp1, i32 %x, i32 %y
132 %cmp2 = icmp ne i32 %sel, %x
133 ret i1 %cmp2
134}
135
136; Commute min operands.
137
138define i1 @ne_umin2(i32 %x, i32 %y) {
139; CHECK-LABEL: @ne_umin2(
140; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 %y, %x
141; CHECK-NEXT: ret i1 [[CMP1]]
142;
143 %cmp1 = icmp ult i32 %y, %x
144 %sel = select i1 %cmp1, i32 %y, i32 %x
145 %cmp2 = icmp ne i32 %sel, %x
146 ret i1 %cmp2
147}
148
149; Disguise the icmp predicate by commuting the min op to the RHS.
150
151define i1 @ne_umin3(i32 %a, i32 %y) {
152; CHECK-LABEL: @ne_umin3(
153; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3
Sanjay Pateldd46b522016-12-19 17:32:37 +0000154; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[X]], %y
Sanjay Patel568196b2016-12-08 23:44:58 +0000155; CHECK-NEXT: ret i1 [[CMP2]]
156;
157 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
158 %cmp1 = icmp ult i32 %x, %y
159 %sel = select i1 %cmp1, i32 %x, i32 %y
160 %cmp2 = icmp ne i32 %x, %sel
161 ret i1 %cmp2
162}
163
164; Commute min operands.
165
166define i1 @ne_umin4(i32 %a, i32 %y) {
167; CHECK-LABEL: @ne_umin4(
168; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3
169; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 [[X]], %y
170; CHECK-NEXT: ret i1 [[CMP1]]
171;
172 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
173 %cmp1 = icmp ult i32 %y, %x
174 %sel = select i1 %cmp1, i32 %y, i32 %x
175 %cmp2 = icmp ne i32 %x, %sel
176 ret i1 %cmp2
177}
178
179; umin(X, Y) < X --> X > Y
180
181define i1 @ult_umin1(i32 %x, i32 %y) {
182; CHECK-LABEL: @ult_umin1(
Sanjay Pateldd46b522016-12-19 17:32:37 +0000183; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 %x, %y
Sanjay Patel568196b2016-12-08 23:44:58 +0000184; CHECK-NEXT: ret i1 [[CMP2]]
185;
186 %cmp1 = icmp ult i32 %x, %y
187 %sel = select i1 %cmp1, i32 %x, i32 %y
188 %cmp2 = icmp ult i32 %sel, %x
189 ret i1 %cmp2
190}
191
192; Commute min operands.
193
194define i1 @ult_umin2(i32 %x, i32 %y) {
195; CHECK-LABEL: @ult_umin2(
196; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 %y, %x
197; CHECK-NEXT: ret i1 [[CMP1]]
198;
199 %cmp1 = icmp ult i32 %y, %x
200 %sel = select i1 %cmp1, i32 %y, i32 %x
201 %cmp2 = icmp ult i32 %sel, %x
202 ret i1 %cmp2
203}
204
205; Disguise the icmp predicate by commuting the min op to the RHS.
206
207define i1 @ult_umin3(i32 %a, i32 %y) {
208; CHECK-LABEL: @ult_umin3(
209; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3
Sanjay Pateldd46b522016-12-19 17:32:37 +0000210; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[X]], %y
Sanjay Patel568196b2016-12-08 23:44:58 +0000211; CHECK-NEXT: ret i1 [[CMP2]]
212;
213 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
214 %cmp1 = icmp ult i32 %x, %y
215 %sel = select i1 %cmp1, i32 %x, i32 %y
216 %cmp2 = icmp ugt i32 %x, %sel
217 ret i1 %cmp2
218}
219
220; Commute min operands.
221
222define i1 @ult_umin4(i32 %a, i32 %y) {
223; CHECK-LABEL: @ult_umin4(
224; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3
225; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 [[X]], %y
226; CHECK-NEXT: ret i1 [[CMP1]]
227;
228 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
229 %cmp1 = icmp ult i32 %y, %x
230 %sel = select i1 %cmp1, i32 %y, i32 %x
231 %cmp2 = icmp ugt i32 %x, %sel
232 ret i1 %cmp2
233}
234