1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -instcombine < %s | FileCheck %s
4 define i32 @smax_of_smax_smin_commute0(i32 %x, i32 %y) {
5 ; CHECK-LABEL: @smax_of_smax_smin_commute0(
6 ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[Y:%.*]], [[X:%.*]]
7 ; CHECK-NEXT: [[MAX:%.*]] = select i1 [[CMP2]], i32 [[X]], i32 [[Y]]
8 ; CHECK-NEXT: ret i32 [[MAX]]
10 %cmp1 = icmp slt i32 %x, %y
11 %min = select i1 %cmp1, i32 %x, i32 %y
12 %cmp2 = icmp slt i32 %y, %x
13 %max = select i1 %cmp2, i32 %x, i32 %y
14 %cmp3 = icmp sgt i32 %max, %min
15 %r = select i1 %cmp3, i32 %max, i32 %min
19 define i32 @smax_of_smax_smin_commute1(i32 %x, i32 %y) {
20 ; CHECK-LABEL: @smax_of_smax_smin_commute1(
21 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
22 ; CHECK-NEXT: [[MAX:%.*]] = select i1 [[CMP2]], i32 [[X]], i32 [[Y]]
23 ; CHECK-NEXT: ret i32 [[MAX]]
25 %cmp1 = icmp sgt i32 %x, %y
26 %min = select i1 %cmp1, i32 %y, i32 %x
27 %cmp2 = icmp sgt i32 %x, %y
28 %max = select i1 %cmp2, i32 %x, i32 %y
29 %cmp3 = icmp sgt i32 %max, %min
30 %r = select i1 %cmp3, i32 %max, i32 %min
34 define i32 @smax_of_smax_smin_commute2(i32 %x, i32 %y) {
35 ; CHECK-LABEL: @smax_of_smax_smin_commute2(
36 ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[Y:%.*]], [[X:%.*]]
37 ; CHECK-NEXT: [[MAX:%.*]] = select i1 [[CMP2]], i32 [[X]], i32 [[Y]]
38 ; CHECK-NEXT: ret i32 [[MAX]]
40 %cmp1 = icmp slt i32 %x, %y
41 %min = select i1 %cmp1, i32 %x, i32 %y
42 %cmp2 = icmp slt i32 %y, %x
43 %max = select i1 %cmp2, i32 %x, i32 %y
44 %cmp3 = icmp slt i32 %min, %max
45 %r = select i1 %cmp3, i32 %max, i32 %min
49 define <2 x i32> @smax_of_smax_smin_commute3(<2 x i32> %x, <2 x i32> %y) {
50 ; CHECK-LABEL: @smax_of_smax_smin_commute3(
51 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt <2 x i32> [[X:%.*]], [[Y:%.*]]
52 ; CHECK-NEXT: [[MAX:%.*]] = select <2 x i1> [[CMP2]], <2 x i32> [[X]], <2 x i32> [[Y]]
53 ; CHECK-NEXT: ret <2 x i32> [[MAX]]
55 %cmp1 = icmp sgt <2 x i32> %x, %y
56 %min = select <2 x i1> %cmp1, <2 x i32> %y, <2 x i32> %x
57 %cmp2 = icmp sgt <2 x i32> %x, %y
58 %max = select <2 x i1> %cmp2, <2 x i32> %x, <2 x i32> %y
59 %cmp3 = icmp slt <2 x i32> %min, %max
60 %r = select <2 x i1> %cmp3, <2 x i32> %max, <2 x i32> %min
64 define i32 @smin_of_smin_smax_commute0(i32 %x, i32 %y) {
65 ; CHECK-LABEL: @smin_of_smin_smax_commute0(
66 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[Y:%.*]], [[X:%.*]]
67 ; CHECK-NEXT: [[MIN:%.*]] = select i1 [[CMP2]], i32 [[X]], i32 [[Y]]
68 ; CHECK-NEXT: ret i32 [[MIN]]
70 %cmp1 = icmp sgt i32 %x, %y
71 %max = select i1 %cmp1, i32 %x, i32 %y
72 %cmp2 = icmp sgt i32 %y, %x
73 %min = select i1 %cmp2, i32 %x, i32 %y
74 %cmp3 = icmp sgt i32 %max, %min
75 %r = select i1 %cmp3, i32 %min, i32 %max
79 define i32 @smin_of_smin_smax_commute1(i32 %x, i32 %y) {
80 ; CHECK-LABEL: @smin_of_smin_smax_commute1(
81 ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]
82 ; CHECK-NEXT: [[MIN:%.*]] = select i1 [[CMP2]], i32 [[X]], i32 [[Y]]
83 ; CHECK-NEXT: ret i32 [[MIN]]
85 %cmp1 = icmp slt i32 %x, %y
86 %max = select i1 %cmp1, i32 %y, i32 %x
87 %cmp2 = icmp slt i32 %x, %y
88 %min = select i1 %cmp2, i32 %x, i32 %y
89 %cmp3 = icmp sgt i32 %max, %min
90 %r = select i1 %cmp3, i32 %min, i32 %max
94 define <2 x i32> @smin_of_smin_smax_commute2(<2 x i32> %x, <2 x i32> %y) {
95 ; CHECK-LABEL: @smin_of_smin_smax_commute2(
96 ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt <2 x i32> [[X:%.*]], [[Y:%.*]]
97 ; CHECK-NEXT: [[MIN:%.*]] = select <2 x i1> [[CMP2]], <2 x i32> [[X]], <2 x i32> [[Y]]
98 ; CHECK-NEXT: ret <2 x i32> [[MIN]]
100 %cmp1 = icmp sgt <2 x i32> %x, %y
101 %max = select <2 x i1> %cmp1, <2 x i32> %x, <2 x i32> %y
102 %cmp2 = icmp slt <2 x i32> %x, %y
103 %min = select <2 x i1> %cmp2, <2 x i32> %x, <2 x i32> %y
104 %cmp3 = icmp slt <2 x i32> %min, %max
105 %r = select <2 x i1> %cmp3, <2 x i32> %min, <2 x i32> %max
109 define i32 @smin_of_smin_smax_commute3(i32 %x, i32 %y) {
110 ; CHECK-LABEL: @smin_of_smin_smax_commute3(
111 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[Y:%.*]], [[X:%.*]]
112 ; CHECK-NEXT: [[MIN:%.*]] = select i1 [[CMP2]], i32 [[X]], i32 [[Y]]
113 ; CHECK-NEXT: ret i32 [[MIN]]
115 %cmp1 = icmp slt i32 %x, %y
116 %max = select i1 %cmp1, i32 %y, i32 %x
117 %cmp2 = icmp sgt i32 %y, %x
118 %min = select i1 %cmp2, i32 %x, i32 %y
119 %cmp3 = icmp slt i32 %min, %max
120 %r = select i1 %cmp3, i32 %min, i32 %max
124 define i32 @umax_of_umax_umin_commute0(i32 %x, i32 %y) {
125 ; CHECK-LABEL: @umax_of_umax_umin_commute0(
126 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], [[X:%.*]]
127 ; CHECK-NEXT: [[MAX:%.*]] = select i1 [[CMP2]], i32 [[X]], i32 [[Y]]
128 ; CHECK-NEXT: ret i32 [[MAX]]
130 %cmp1 = icmp ult i32 %x, %y
131 %min = select i1 %cmp1, i32 %x, i32 %y
132 %cmp2 = icmp ult i32 %y, %x
133 %max = select i1 %cmp2, i32 %x, i32 %y
134 %cmp3 = icmp ugt i32 %max, %min
135 %r = select i1 %cmp3, i32 %max, i32 %min
139 define i32 @umax_of_umax_umin_commute1(i32 %x, i32 %y) {
140 ; CHECK-LABEL: @umax_of_umax_umin_commute1(
141 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]]
142 ; CHECK-NEXT: [[MAX:%.*]] = select i1 [[CMP2]], i32 [[X]], i32 [[Y]]
143 ; CHECK-NEXT: ret i32 [[MAX]]
145 %cmp1 = icmp ugt i32 %x, %y
146 %min = select i1 %cmp1, i32 %y, i32 %x
147 %cmp2 = icmp ugt i32 %x, %y
148 %max = select i1 %cmp2, i32 %x, i32 %y
149 %cmp3 = icmp ugt i32 %max, %min
150 %r = select i1 %cmp3, i32 %max, i32 %min
154 define i32 @umax_of_umax_umin_commute2(i32 %x, i32 %y) {
155 ; CHECK-LABEL: @umax_of_umax_umin_commute2(
156 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], [[X:%.*]]
157 ; CHECK-NEXT: [[MAX:%.*]] = select i1 [[CMP2]], i32 [[X]], i32 [[Y]]
158 ; CHECK-NEXT: ret i32 [[MAX]]
160 %cmp1 = icmp ult i32 %x, %y
161 %min = select i1 %cmp1, i32 %x, i32 %y
162 %cmp2 = icmp ult i32 %y, %x
163 %max = select i1 %cmp2, i32 %x, i32 %y
164 %cmp3 = icmp ult i32 %min, %max
165 %r = select i1 %cmp3, i32 %max, i32 %min
169 define <2 x i32> @umax_of_umax_umin_commute3(<2 x i32> %x, <2 x i32> %y) {
170 ; CHECK-LABEL: @umax_of_umax_umin_commute3(
171 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt <2 x i32> [[X:%.*]], [[Y:%.*]]
172 ; CHECK-NEXT: [[MAX:%.*]] = select <2 x i1> [[CMP2]], <2 x i32> [[X]], <2 x i32> [[Y]]
173 ; CHECK-NEXT: ret <2 x i32> [[MAX]]
175 %cmp1 = icmp ugt <2 x i32> %x, %y
176 %min = select <2 x i1> %cmp1, <2 x i32> %y, <2 x i32> %x
177 %cmp2 = icmp ugt <2 x i32> %x, %y
178 %max = select <2 x i1> %cmp2, <2 x i32> %x, <2 x i32> %y
179 %cmp3 = icmp ult <2 x i32> %min, %max
180 %r = select <2 x i1> %cmp3, <2 x i32> %max, <2 x i32> %min
184 define i32 @umin_of_umin_umax_commute0(i32 %x, i32 %y) {
185 ; CHECK-LABEL: @umin_of_umin_umax_commute0(
186 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[Y:%.*]], [[X:%.*]]
187 ; CHECK-NEXT: [[MIN:%.*]] = select i1 [[CMP2]], i32 [[X]], i32 [[Y]]
188 ; CHECK-NEXT: ret i32 [[MIN]]
190 %cmp1 = icmp ugt i32 %x, %y
191 %max = select i1 %cmp1, i32 %x, i32 %y
192 %cmp2 = icmp ugt i32 %y, %x
193 %min = select i1 %cmp2, i32 %x, i32 %y
194 %cmp3 = icmp ugt i32 %max, %min
195 %r = select i1 %cmp3, i32 %min, i32 %max
199 define i32 @umin_of_umin_umax_commute1(i32 %x, i32 %y) {
200 ; CHECK-LABEL: @umin_of_umin_umax_commute1(
201 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
202 ; CHECK-NEXT: [[MIN:%.*]] = select i1 [[CMP2]], i32 [[X]], i32 [[Y]]
203 ; CHECK-NEXT: ret i32 [[MIN]]
205 %cmp1 = icmp ult i32 %x, %y
206 %max = select i1 %cmp1, i32 %y, i32 %x
207 %cmp2 = icmp ult i32 %x, %y
208 %min = select i1 %cmp2, i32 %x, i32 %y
209 %cmp3 = icmp ugt i32 %max, %min
210 %r = select i1 %cmp3, i32 %min, i32 %max
214 define <2 x i32> @umin_of_umin_umax_commute2(<2 x i32> %x, <2 x i32> %y) {
215 ; CHECK-LABEL: @umin_of_umin_umax_commute2(
216 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult <2 x i32> [[X:%.*]], [[Y:%.*]]
217 ; CHECK-NEXT: [[MIN:%.*]] = select <2 x i1> [[CMP2]], <2 x i32> [[X]], <2 x i32> [[Y]]
218 ; CHECK-NEXT: ret <2 x i32> [[MIN]]
220 %cmp1 = icmp ugt <2 x i32> %x, %y
221 %max = select <2 x i1> %cmp1, <2 x i32> %x, <2 x i32> %y
222 %cmp2 = icmp ult <2 x i32> %x, %y
223 %min = select <2 x i1> %cmp2, <2 x i32> %x, <2 x i32> %y
224 %cmp3 = icmp ult <2 x i32> %min, %max
225 %r = select <2 x i1> %cmp3, <2 x i32> %min, <2 x i32> %max
229 define i32 @umin_of_umin_umax_commute3(i32 %x, i32 %y) {
230 ; CHECK-LABEL: @umin_of_umin_umax_commute3(
231 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[Y:%.*]], [[X:%.*]]
232 ; CHECK-NEXT: [[MIN:%.*]] = select i1 [[CMP2]], i32 [[X]], i32 [[Y]]
233 ; CHECK-NEXT: ret i32 [[MIN]]
235 %cmp1 = icmp ult i32 %x, %y
236 %max = select i1 %cmp1, i32 %y, i32 %x
237 %cmp2 = icmp ugt i32 %y, %x
238 %min = select i1 %cmp2, i32 %x, i32 %y
239 %cmp3 = icmp ult i32 %min, %max
240 %r = select i1 %cmp3, i32 %min, i32 %max
244 ; Negative test - mismatch of min/max flavor
246 define i32 @umin_of_smin_umax_wrong_pattern(i32 %x, i32 %y) {
247 ; CHECK-LABEL: @umin_of_smin_umax_wrong_pattern(
248 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]]
249 ; CHECK-NEXT: [[MAX:%.*]] = select i1 [[CMP1]], i32 [[X]], i32 [[Y]]
250 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[Y]], [[X]]
251 ; CHECK-NEXT: [[MIN:%.*]] = select i1 [[CMP2]], i32 [[X]], i32 [[Y]]
252 ; CHECK-NEXT: [[CMP3:%.*]] = icmp ugt i32 [[MAX]], [[MIN]]
253 ; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP3]], i32 [[MIN]], i32 [[MAX]]
254 ; CHECK-NEXT: ret i32 [[R]]
256 %cmp1 = icmp ugt i32 %x, %y
257 %max = select i1 %cmp1, i32 %x, i32 %y
258 %cmp2 = icmp sgt i32 %y, %x
259 %min = select i1 %cmp2, i32 %x, i32 %y
260 %cmp3 = icmp ugt i32 %max, %min
261 %r = select i1 %cmp3, i32 %min, i32 %max
265 ; Negative test - mismatch of min/max flavor
267 define i32 @smin_of_umin_umax_wrong_pattern2(i32 %x, i32 %y) {
268 ; CHECK-LABEL: @smin_of_umin_umax_wrong_pattern2(
269 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
270 ; CHECK-NEXT: [[MAX:%.*]] = select i1 [[CMP1]], i32 [[Y]], i32 [[X]]
271 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[X]], [[Y]]
272 ; CHECK-NEXT: [[MIN:%.*]] = select i1 [[CMP2]], i32 [[X]], i32 [[Y]]
273 ; CHECK-NEXT: [[CMP3:%.*]] = icmp sgt i32 [[MAX]], [[MIN]]
274 ; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP3]], i32 [[MIN]], i32 [[MAX]]
275 ; CHECK-NEXT: ret i32 [[R]]
277 %cmp1 = icmp ult i32 %x, %y
278 %max = select i1 %cmp1, i32 %y, i32 %x
279 %cmp2 = icmp ult i32 %x, %y
280 %min = select i1 %cmp2, i32 %x, i32 %y
281 %cmp3 = icmp sgt i32 %max, %min
282 %r = select i1 %cmp3, i32 %min, i32 %max
286 ; Negative test - operands must match
288 define <2 x i32> @umin_of_umin_umax_wrong_operand(<2 x i32> %x, <2 x i32> %y, <2 x i32> %z) {
289 ; CHECK-LABEL: @umin_of_umin_umax_wrong_operand(
290 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt <2 x i32> [[X:%.*]], [[Y:%.*]]
291 ; CHECK-NEXT: [[MAX:%.*]] = select <2 x i1> [[CMP1]], <2 x i32> [[X]], <2 x i32> [[Y]]
292 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult <2 x i32> [[X]], [[Z:%.*]]
293 ; CHECK-NEXT: [[MIN:%.*]] = select <2 x i1> [[CMP2]], <2 x i32> [[X]], <2 x i32> [[Z]]
294 ; CHECK-NEXT: [[CMP3:%.*]] = icmp ult <2 x i32> [[MIN]], [[MAX]]
295 ; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[CMP3]], <2 x i32> [[MIN]], <2 x i32> [[MAX]]
296 ; CHECK-NEXT: ret <2 x i32> [[R]]
298 %cmp1 = icmp ugt <2 x i32> %x, %y
299 %max = select <2 x i1> %cmp1, <2 x i32> %x, <2 x i32> %y
300 %cmp2 = icmp ult <2 x i32> %x, %z
301 %min = select <2 x i1> %cmp2, <2 x i32> %x, <2 x i32> %z
302 %cmp3 = icmp ult <2 x i32> %min, %max
303 %r = select <2 x i1> %cmp3, <2 x i32> %min, <2 x i32> %max
307 ; Negative test - operands must match
309 define i32 @umin_of_umin_umax_wrong_operand2(i32 %x, i32 %y, i32 %z) {
310 ; CHECK-LABEL: @umin_of_umin_umax_wrong_operand2(
311 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[X:%.*]], [[Z:%.*]]
312 ; CHECK-NEXT: [[MAX:%.*]] = select i1 [[CMP1]], i32 [[Z]], i32 [[X]]
313 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[Y:%.*]], [[X]]
314 ; CHECK-NEXT: [[MIN:%.*]] = select i1 [[CMP2]], i32 [[X]], i32 [[Y]]
315 ; CHECK-NEXT: [[CMP3:%.*]] = icmp ult i32 [[MIN]], [[MAX]]
316 ; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP3]], i32 [[MIN]], i32 [[MAX]]
317 ; CHECK-NEXT: ret i32 [[R]]
319 %cmp1 = icmp ult i32 %x, %z
320 %max = select i1 %cmp1, i32 %z, i32 %x
321 %cmp2 = icmp ugt i32 %y, %x
322 %min = select i1 %cmp2, i32 %x, i32 %y
323 %cmp3 = icmp ult i32 %min, %max
324 %r = select i1 %cmp3, i32 %min, i32 %max