blob: f9d814d0d997d4f1cbb9e48c03bc24a6b300c04c [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
7; possibilities for each predicate. Note that folds to true/false
8; (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(
15; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 %x, %y
16; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i32 %x, i32 %y
17; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[SEL]], %x
18; CHECK-NEXT: ret i1 [[CMP2]]
19;
20 %cmp1 = icmp ult i32 %x, %y
21 %sel = select i1 %cmp1, i32 %x, i32 %y
22 %cmp2 = icmp eq i32 %sel, %x
23 ret i1 %cmp2
24}
25
26; Commute min operands.
27
28define i1 @eq_umin2(i32 %x, i32 %y) {
29; CHECK-LABEL: @eq_umin2(
30; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 %y, %x
31; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i32 %y, i32 %x
32; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[SEL]], %x
33; CHECK-NEXT: ret i1 [[CMP2]]
34;
35 %cmp1 = icmp ult i32 %y, %x
36 %sel = select i1 %cmp1, i32 %y, i32 %x
37 %cmp2 = icmp eq i32 %sel, %x
38 ret i1 %cmp2
39}
40
41; Disguise the icmp predicate by commuting the min op to the RHS.
42
43define i1 @eq_umin3(i32 %a, i32 %y) {
44; CHECK-LABEL: @eq_umin3(
45; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3
46; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[X]], %y
47; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i32 [[X]], i32 %y
48; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[X]], [[SEL]]
49; CHECK-NEXT: ret i1 [[CMP2]]
50;
51 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
52 %cmp1 = icmp ult i32 %x, %y
53 %sel = select i1 %cmp1, i32 %x, i32 %y
54 %cmp2 = icmp eq i32 %x, %sel
55 ret i1 %cmp2
56}
57
58; Commute min operands.
59
60define i1 @eq_umin4(i32 %a, i32 %y) {
61; CHECK-LABEL: @eq_umin4(
62; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3
63; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 [[X]], %y
64; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i32 %y, i32 [[X]]
65; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[X]], [[SEL]]
66; CHECK-NEXT: ret i1 [[CMP2]]
67;
68 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
69 %cmp1 = icmp ult i32 %y, %x
70 %sel = select i1 %cmp1, i32 %y, i32 %x
71 %cmp2 = icmp eq i32 %x, %sel
72 ret i1 %cmp2
73}
74
75; umin(X, Y) >= X --> X <= Y
76
77define i1 @uge_umin1(i32 %x, i32 %y) {
78; CHECK-LABEL: @uge_umin1(
79; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 %x, %y
80; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i32 %x, i32 %y
81; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 [[SEL]], %x
82; CHECK-NEXT: ret i1 [[CMP2]]
83;
84 %cmp1 = icmp ult i32 %x, %y
85 %sel = select i1 %cmp1, i32 %x, i32 %y
86 %cmp2 = icmp uge i32 %sel, %x
87 ret i1 %cmp2
88}
89
90; Commute min operands.
91
92define i1 @uge_umin2(i32 %x, i32 %y) {
93; CHECK-LABEL: @uge_umin2(
94; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 %y, %x
95; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i32 %y, i32 %x
96; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 [[SEL]], %x
97; CHECK-NEXT: ret i1 [[CMP2]]
98;
99 %cmp1 = icmp ult i32 %y, %x
100 %sel = select i1 %cmp1, i32 %y, i32 %x
101 %cmp2 = icmp uge i32 %sel, %x
102 ret i1 %cmp2
103}
104
105; Disguise the icmp predicate by commuting the min op to the RHS.
106
107define i1 @uge_umin3(i32 %a, i32 %y) {
108; CHECK-LABEL: @uge_umin3(
109; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3
110; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[X]], %y
111; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i32 [[X]], i32 %y
112; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[X]], [[SEL]]
113; CHECK-NEXT: ret i1 [[CMP2]]
114;
115 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
116 %cmp1 = icmp ult i32 %x, %y
117 %sel = select i1 %cmp1, i32 %x, i32 %y
118 %cmp2 = icmp ule i32 %x, %sel
119 ret i1 %cmp2
120}
121
122; Commute min operands.
123
124define i1 @uge_umin4(i32 %a, i32 %y) {
125; CHECK-LABEL: @uge_umin4(
126; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3
127; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 [[X]], %y
128; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i32 %y, i32 [[X]]
129; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[X]], [[SEL]]
130; CHECK-NEXT: ret i1 [[CMP2]]
131;
132 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
133 %cmp1 = icmp ult i32 %y, %x
134 %sel = select i1 %cmp1, i32 %y, i32 %x
135 %cmp2 = icmp ule i32 %x, %sel
136 ret i1 %cmp2
137}
138
139; umin(X, Y) != X --> X > Y
140
141define i1 @ne_umin1(i32 %x, i32 %y) {
142; CHECK-LABEL: @ne_umin1(
143; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 %x, %y
144; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i32 %x, i32 %y
145; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[SEL]], %x
146; CHECK-NEXT: ret i1 [[CMP2]]
147;
148 %cmp1 = icmp ult i32 %x, %y
149 %sel = select i1 %cmp1, i32 %x, i32 %y
150 %cmp2 = icmp ne i32 %sel, %x
151 ret i1 %cmp2
152}
153
154; Commute min operands.
155
156define i1 @ne_umin2(i32 %x, i32 %y) {
157; CHECK-LABEL: @ne_umin2(
158; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 %y, %x
159; CHECK-NEXT: ret i1 [[CMP1]]
160;
161 %cmp1 = icmp ult i32 %y, %x
162 %sel = select i1 %cmp1, i32 %y, i32 %x
163 %cmp2 = icmp ne i32 %sel, %x
164 ret i1 %cmp2
165}
166
167; Disguise the icmp predicate by commuting the min op to the RHS.
168
169define i1 @ne_umin3(i32 %a, i32 %y) {
170; CHECK-LABEL: @ne_umin3(
171; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3
172; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[X]], %y
173; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i32 [[X]], i32 %y
174; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[X]], [[SEL]]
175; CHECK-NEXT: ret i1 [[CMP2]]
176;
177 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
178 %cmp1 = icmp ult i32 %x, %y
179 %sel = select i1 %cmp1, i32 %x, i32 %y
180 %cmp2 = icmp ne i32 %x, %sel
181 ret i1 %cmp2
182}
183
184; Commute min operands.
185
186define i1 @ne_umin4(i32 %a, i32 %y) {
187; CHECK-LABEL: @ne_umin4(
188; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3
189; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 [[X]], %y
190; CHECK-NEXT: ret i1 [[CMP1]]
191;
192 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
193 %cmp1 = icmp ult i32 %y, %x
194 %sel = select i1 %cmp1, i32 %y, i32 %x
195 %cmp2 = icmp ne i32 %x, %sel
196 ret i1 %cmp2
197}
198
199; umin(X, Y) < X --> X > Y
200
201define i1 @ult_umin1(i32 %x, i32 %y) {
202; CHECK-LABEL: @ult_umin1(
203; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 %x, %y
204; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i32 %x, i32 %y
205; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[SEL]], %x
206; CHECK-NEXT: ret i1 [[CMP2]]
207;
208 %cmp1 = icmp ult i32 %x, %y
209 %sel = select i1 %cmp1, i32 %x, i32 %y
210 %cmp2 = icmp ult i32 %sel, %x
211 ret i1 %cmp2
212}
213
214; Commute min operands.
215
216define i1 @ult_umin2(i32 %x, i32 %y) {
217; CHECK-LABEL: @ult_umin2(
218; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 %y, %x
219; CHECK-NEXT: ret i1 [[CMP1]]
220;
221 %cmp1 = icmp ult i32 %y, %x
222 %sel = select i1 %cmp1, i32 %y, i32 %x
223 %cmp2 = icmp ult i32 %sel, %x
224 ret i1 %cmp2
225}
226
227; Disguise the icmp predicate by commuting the min op to the RHS.
228
229define i1 @ult_umin3(i32 %a, i32 %y) {
230; CHECK-LABEL: @ult_umin3(
231; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3
232; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[X]], %y
233; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i32 [[X]], i32 %y
234; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[X]], [[SEL]]
235; CHECK-NEXT: ret i1 [[CMP2]]
236;
237 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
238 %cmp1 = icmp ult i32 %x, %y
239 %sel = select i1 %cmp1, i32 %x, i32 %y
240 %cmp2 = icmp ugt i32 %x, %sel
241 ret i1 %cmp2
242}
243
244; Commute min operands.
245
246define i1 @ult_umin4(i32 %a, i32 %y) {
247; CHECK-LABEL: @ult_umin4(
248; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3
249; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 [[X]], %y
250; CHECK-NEXT: ret i1 [[CMP1]]
251;
252 %x = add i32 %a, 3 ; thwart complexity-based canonicalization
253 %cmp1 = icmp ult i32 %y, %x
254 %sel = select i1 %cmp1, i32 %y, i32 %x
255 %cmp2 = icmp ugt i32 %x, %sel
256 ret i1 %cmp2
257}
258