• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -instcombine < %s | FileCheck %s
3
4define <2 x i32> @umin_of_nots(<2 x i32> %x, <2 x i32> %y) {
5; CHECK-LABEL: @umin_of_nots(
6; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt <2 x i32> [[X:%.*]], [[Y:%.*]]
7; CHECK-NEXT:    [[TMP2:%.*]] = select <2 x i1> [[TMP1]], <2 x i32> [[X]], <2 x i32> [[Y]]
8; CHECK-NEXT:    [[MIN:%.*]] = xor <2 x i32> [[TMP2]], <i32 -1, i32 -1>
9; CHECK-NEXT:    ret <2 x i32> [[MIN]]
10;
11  %notx = xor <2 x i32> %x, <i32 -1, i32 -1>
12  %noty = xor <2 x i32> %y, <i32 -1, i32 -1>
13  %cmp = icmp ult <2 x i32> %notx, %noty
14  %min = select <2 x i1> %cmp, <2 x i32> %notx, <2 x i32> %noty
15  ret <2 x i32> %min
16}
17
18define <2 x i32> @smin_of_nots(<2 x i32> %x, <2 x i32> %y) {
19; CHECK-LABEL: @smin_of_nots(
20; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt <2 x i32> [[X:%.*]], [[Y:%.*]]
21; CHECK-NEXT:    [[TMP2:%.*]] = select <2 x i1> [[TMP1]], <2 x i32> [[X]], <2 x i32> [[Y]]
22; CHECK-NEXT:    [[MIN:%.*]] = xor <2 x i32> [[TMP2]], <i32 -1, i32 -1>
23; CHECK-NEXT:    ret <2 x i32> [[MIN]]
24;
25  %notx = xor <2 x i32> %x, <i32 -1, i32 -1>
26  %noty = xor <2 x i32> %y, <i32 -1, i32 -1>
27  %cmp = icmp sle <2 x i32> %notx, %noty
28  %min = select <2 x i1> %cmp, <2 x i32> %notx, <2 x i32> %noty
29  ret <2 x i32> %min
30}
31
32define i32 @compute_min_2(i32 %x, i32 %y) {
33; CHECK-LABEL: @compute_min_2(
34; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]
35; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 [[Y]]
36; CHECK-NEXT:    ret i32 [[TMP2]]
37;
38  %not_x = sub i32 -1, %x
39  %not_y = sub i32 -1, %y
40  %cmp = icmp sgt i32 %not_x, %not_y
41  %not_min = select i1 %cmp, i32 %not_x, i32 %not_y
42  %min = sub i32 -1, %not_min
43  ret i32 %min
44}
45
46declare void @extra_use(i8)
47define i8 @umin_not_1_extra_use(i8 %x, i8 %y) {
48; CHECK-LABEL: @umin_not_1_extra_use(
49; CHECK-NEXT:    [[NX:%.*]] = xor i8 [[X:%.*]], -1
50; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i8 [[X]], [[Y:%.*]]
51; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i8 [[X]], i8 [[Y]]
52; CHECK-NEXT:    [[MINXY:%.*]] = xor i8 [[TMP2]], -1
53; CHECK-NEXT:    call void @extra_use(i8 [[NX]])
54; CHECK-NEXT:    ret i8 [[MINXY]]
55;
56  %nx = xor i8 %x, -1
57  %ny = xor i8 %y, -1
58  %cmpxy = icmp ult i8 %nx, %ny
59  %minxy = select i1 %cmpxy, i8 %nx, i8 %ny
60  call void @extra_use(i8 %nx)
61  ret i8 %minxy
62}
63
64define i8 @umin_not_2_extra_use(i8 %x, i8 %y) {
65; CHECK-LABEL: @umin_not_2_extra_use(
66; CHECK-NEXT:    [[NX:%.*]] = xor i8 [[X:%.*]], -1
67; CHECK-NEXT:    [[NY:%.*]] = xor i8 [[Y:%.*]], -1
68; CHECK-NEXT:    [[CMPXY:%.*]] = icmp ult i8 [[NX]], [[NY]]
69; CHECK-NEXT:    [[MINXY:%.*]] = select i1 [[CMPXY]], i8 [[NX]], i8 [[NY]]
70; CHECK-NEXT:    call void @extra_use(i8 [[NX]])
71; CHECK-NEXT:    call void @extra_use(i8 [[NY]])
72; CHECK-NEXT:    ret i8 [[MINXY]]
73;
74  %nx = xor i8 %x, -1
75  %ny = xor i8 %y, -1
76  %cmpxy = icmp ult i8 %nx, %ny
77  %minxy = select i1 %cmpxy, i8 %nx, i8 %ny
78  call void @extra_use(i8 %nx)
79  call void @extra_use(i8 %ny)
80  ret i8 %minxy
81}
82
83; PR35834 - https://bugs.llvm.org/show_bug.cgi?id=35834
84
85define i8 @umin3_not(i8 %x, i8 %y, i8 %z) {
86; CHECK-LABEL: @umin3_not(
87; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i8 [[X:%.*]], [[Z:%.*]]
88; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i8 [[X]], i8 [[Z]]
89; CHECK-NEXT:    [[TMP3:%.*]] = icmp ugt i8 [[TMP2]], [[Y:%.*]]
90; CHECK-NEXT:    [[R_V:%.*]] = select i1 [[TMP3]], i8 [[TMP2]], i8 [[Y]]
91; CHECK-NEXT:    [[R:%.*]] = xor i8 [[R_V]], -1
92; CHECK-NEXT:    ret i8 [[R]]
93;
94  %nx = xor i8 %x, -1
95  %ny = xor i8 %y, -1
96  %nz = xor i8 %z, -1
97  %cmpyx = icmp ult i8 %y, %x
98  %cmpxz = icmp ult i8 %nx, %nz
99  %minxz = select i1 %cmpxz, i8 %nx, i8 %nz
100  %cmpyz = icmp ult i8 %ny, %nz
101  %minyz = select i1 %cmpyz, i8 %ny, i8 %nz
102  %r = select i1 %cmpyx, i8 %minxz, i8 %minyz
103  ret i8 %r
104}
105
106; PR35875 - https://bugs.llvm.org/show_bug.cgi?id=35875
107
108define i8 @umin3_not_more_uses(i8 %x, i8 %y, i8 %z) {
109; CHECK-LABEL: @umin3_not_more_uses(
110; CHECK-NEXT:    [[NX:%.*]] = xor i8 [[X:%.*]], -1
111; CHECK-NEXT:    [[NY:%.*]] = xor i8 [[Y:%.*]], -1
112; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i8 [[X]], [[Z:%.*]]
113; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i8 [[X]], i8 [[Z]]
114; CHECK-NEXT:    [[TMP3:%.*]] = icmp ugt i8 [[TMP2]], [[Y]]
115; CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP3]], i8 [[TMP2]], i8 [[Y]]
116; CHECK-NEXT:    [[R:%.*]] = xor i8 [[TMP4]], -1
117; CHECK-NEXT:    call void @extra_use(i8 [[NX]])
118; CHECK-NEXT:    call void @extra_use(i8 [[NY]])
119; CHECK-NEXT:    ret i8 [[R]]
120;
121  %nx = xor i8 %x, -1
122  %ny = xor i8 %y, -1
123  %nz = xor i8 %z, -1
124  %cmpxz = icmp ult i8 %nx, %nz
125  %minxz = select i1 %cmpxz, i8 %nx, i8 %nz
126  %cmpyz = icmp ult i8 %ny, %nz
127  %minyz = select i1 %cmpyz, i8 %ny, i8 %nz
128  %cmpyx = icmp ult i8 %y, %x
129  %r = select i1 %cmpyx, i8 %minxz, i8 %minyz
130  call void @extra_use(i8 %nx)
131  call void @extra_use(i8 %ny)
132  ret i8 %r
133}
134
135declare void @use8(i8)
136
137define i8 @umin3_not_all_ops_extra_uses(i8 %x, i8 %y, i8 %z) {
138; CHECK-LABEL: @umin3_not_all_ops_extra_uses(
139; CHECK-NEXT:    [[XN:%.*]] = xor i8 [[X:%.*]], -1
140; CHECK-NEXT:    [[YN:%.*]] = xor i8 [[Y:%.*]], -1
141; CHECK-NEXT:    [[ZN:%.*]] = xor i8 [[Z:%.*]], -1
142; CHECK-NEXT:    [[CMPXZ:%.*]] = icmp ult i8 [[XN]], [[ZN]]
143; CHECK-NEXT:    [[MINXZ:%.*]] = select i1 [[CMPXZ]], i8 [[XN]], i8 [[ZN]]
144; CHECK-NEXT:    [[CMPXYZ:%.*]] = icmp ult i8 [[MINXZ]], [[YN]]
145; CHECK-NEXT:    [[MINXYZ:%.*]] = select i1 [[CMPXYZ]], i8 [[MINXZ]], i8 [[YN]]
146; CHECK-NEXT:    call void @use8(i8 [[XN]])
147; CHECK-NEXT:    call void @use8(i8 [[YN]])
148; CHECK-NEXT:    call void @use8(i8 [[ZN]])
149; CHECK-NEXT:    ret i8 [[MINXYZ]]
150;
151  %xn = xor i8 %x, -1
152  %yn = xor i8 %y, -1
153  %zn = xor i8 %z, -1
154  %cmpxz = icmp ult i8 %xn, %zn
155  %minxz = select i1 %cmpxz, i8 %xn, i8 %zn
156  %cmpxyz = icmp ult i8 %minxz, %yn
157  %minxyz = select i1 %cmpxyz, i8 %minxz, i8 %yn
158  call void @use8(i8 %xn)
159  call void @use8(i8 %yn)
160  call void @use8(i8 %zn)
161  ret i8 %minxyz
162}
163
164define void @umin3_not_all_ops_extra_uses_invert_subs(i8 %x, i8 %y, i8 %z) {
165; CHECK-LABEL: @umin3_not_all_ops_extra_uses_invert_subs(
166; CHECK-NEXT:    [[XN:%.*]] = xor i8 [[X:%.*]], -1
167; CHECK-NEXT:    [[YN:%.*]] = xor i8 [[Y:%.*]], -1
168; CHECK-NEXT:    [[ZN:%.*]] = xor i8 [[Z:%.*]], -1
169; CHECK-NEXT:    [[CMPXZ:%.*]] = icmp ult i8 [[XN]], [[ZN]]
170; CHECK-NEXT:    [[MINXZ:%.*]] = select i1 [[CMPXZ]], i8 [[XN]], i8 [[ZN]]
171; CHECK-NEXT:    [[CMPXYZ:%.*]] = icmp ult i8 [[MINXZ]], [[YN]]
172; CHECK-NEXT:    [[MINXYZ:%.*]] = select i1 [[CMPXYZ]], i8 [[MINXZ]], i8 [[YN]]
173; CHECK-NEXT:    [[XMIN:%.*]] = sub i8 [[XN]], [[MINXYZ]]
174; CHECK-NEXT:    [[YMIN:%.*]] = sub i8 [[YN]], [[MINXYZ]]
175; CHECK-NEXT:    [[ZMIN:%.*]] = sub i8 [[ZN]], [[MINXYZ]]
176; CHECK-NEXT:    call void @use8(i8 [[MINXYZ]])
177; CHECK-NEXT:    call void @use8(i8 [[XMIN]])
178; CHECK-NEXT:    call void @use8(i8 [[YMIN]])
179; CHECK-NEXT:    call void @use8(i8 [[ZMIN]])
180; CHECK-NEXT:    ret void
181;
182  %xn = xor i8 %x, -1
183  %yn = xor i8 %y, -1
184  %zn = xor i8 %z, -1
185  %cmpxz = icmp ult i8 %xn, %zn
186  %minxz = select i1 %cmpxz, i8 %xn, i8 %zn
187  %cmpxyz = icmp ult i8 %minxz, %yn
188  %minxyz = select i1 %cmpxyz, i8 %minxz, i8 %yn
189  %xmin = sub i8 %xn, %minxyz
190  %ymin = sub i8 %yn, %minxyz
191  %zmin = sub i8 %zn, %minxyz
192  call void @use8(i8 %minxyz)
193  call void @use8(i8 %xmin)
194  call void @use8(i8 %ymin)
195  call void @use8(i8 %zmin)
196  ret void
197}
198
199define i32 @compute_min_3(i32 %x, i32 %y, i32 %z) {
200; CHECK-LABEL: @compute_min_3(
201; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]
202; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 [[Y]]
203; CHECK-NEXT:    [[TMP3:%.*]] = icmp slt i32 [[TMP2]], [[Z:%.*]]
204; CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP3]], i32 [[TMP2]], i32 [[Z]]
205; CHECK-NEXT:    ret i32 [[TMP4]]
206;
207  %not_x = sub i32 -1, %x
208  %not_y = sub i32 -1, %y
209  %not_z = sub i32 -1, %z
210  %cmp_1 = icmp sgt i32 %not_x, %not_y
211  %not_min_1 = select i1 %cmp_1, i32 %not_x, i32 %not_y
212  %cmp_2 = icmp sgt i32 %not_min_1, %not_z
213  %not_min_2 = select i1 %cmp_2, i32 %not_min_1, i32 %not_z
214  %min = sub i32 -1, %not_min_2
215  ret i32 %min
216}
217
218; Don't increase the critical path by moving the 'not' op after the 'select'.
219
220define i32 @compute_min_arithmetic(i32 %x, i32 %y) {
221; CHECK-LABEL: @compute_min_arithmetic(
222; CHECK-NEXT:    [[NOT_VALUE:%.*]] = sub i32 3, [[X:%.*]]
223; CHECK-NEXT:    [[NOT_Y:%.*]] = xor i32 [[Y:%.*]], -1
224; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[NOT_VALUE]], [[NOT_Y]]
225; CHECK-NEXT:    [[NOT_MIN:%.*]] = select i1 [[CMP]], i32 [[NOT_VALUE]], i32 [[NOT_Y]]
226; CHECK-NEXT:    ret i32 [[NOT_MIN]]
227;
228  %not_value = sub i32 3, %x
229  %not_y = sub i32 -1, %y
230  %cmp = icmp sgt i32 %not_value, %not_y
231  %not_min = select i1 %cmp, i32 %not_value, i32 %not_y
232  ret i32 %not_min
233}
234
235declare void @fake_use(i32)
236
237define i32 @compute_min_pessimization(i32 %x, i32 %y) {
238; CHECK-LABEL: @compute_min_pessimization(
239; CHECK-NEXT:    [[NOT_VALUE:%.*]] = sub i32 3, [[X:%.*]]
240; CHECK-NEXT:    call void @fake_use(i32 [[NOT_VALUE]])
241; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X]], -4
242; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[TMP1]], [[Y:%.*]]
243; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[TMP2]], i32 [[Y]], i32 [[TMP1]]
244; CHECK-NEXT:    ret i32 [[MIN]]
245;
246  %not_value = sub i32 3, %x
247  call void @fake_use(i32 %not_value)
248  %not_y = sub i32 -1, %y
249  %cmp = icmp sgt i32 %not_value, %not_y
250  %not_min = select i1 %cmp, i32 %not_value, i32 %not_y
251  %min = sub i32 -1, %not_min
252  ret i32 %min
253}
254
255define i32 @max_of_nots(i32 %x, i32 %y) {
256; CHECK-LABEL: @max_of_nots(
257; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[Y:%.*]], 0
258; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[Y]], i32 0
259; CHECK-NEXT:    [[TMP3:%.*]] = icmp slt i32 [[TMP2]], [[X:%.*]]
260; CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP3]], i32 [[TMP2]], i32 [[X]]
261; CHECK-NEXT:    [[TMP5:%.*]] = xor i32 [[TMP4]], -1
262; CHECK-NEXT:    ret i32 [[TMP5]]
263;
264  %c0 = icmp sgt i32 %y, 0
265  %xor_y = xor i32 %y, -1
266  %s0 = select i1 %c0, i32 %xor_y, i32 -1
267  %xor_x = xor i32 %x, -1
268  %c1 = icmp slt i32 %s0, %xor_x
269  %smax96 = select i1 %c1, i32 %xor_x, i32 %s0
270  ret i32 %smax96
271}
272
273 ; negative test case (i.e. can not simplify) : ABS(MIN(NOT x,y))
274define i32 @abs_of_min_of_not(i32 %x, i32 %y) {
275; CHECK-LABEL: @abs_of_min_of_not(
276; CHECK-NEXT:    [[XORD:%.*]] = xor i32 [[X:%.*]], -1
277; CHECK-NEXT:    [[YADD:%.*]] = add i32 [[Y:%.*]], 2
278; CHECK-NEXT:    [[COND_I:%.*]] = icmp slt i32 [[YADD]], [[XORD]]
279; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[COND_I]], i32 [[YADD]], i32 [[XORD]]
280; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[MIN]], 0
281; CHECK-NEXT:    [[SUB:%.*]] = sub i32 0, [[MIN]]
282; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP2]], i32 [[SUB]], i32 [[MIN]]
283; CHECK-NEXT:    ret i32 [[ABS]]
284;
285
286  %xord = xor i32 %x, -1
287  %yadd = add i32 %y, 2
288  %cond.i = icmp sge i32 %yadd, %xord
289  %min = select i1 %cond.i, i32 %xord, i32 %yadd
290  %cmp2 = icmp sgt i32 %min, -1
291  %sub = sub i32 0, %min
292  %abs = select i1 %cmp2, i32 %min, i32 %sub
293  ret i32  %abs
294}
295
296define <2 x i32> @max_of_nots_vec(<2 x i32> %x, <2 x i32> %y) {
297; CHECK-LABEL: @max_of_nots_vec(
298; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt <2 x i32> [[Y:%.*]], zeroinitializer
299; CHECK-NEXT:    [[TMP2:%.*]] = select <2 x i1> [[TMP1]], <2 x i32> [[Y]], <2 x i32> zeroinitializer
300; CHECK-NEXT:    [[TMP3:%.*]] = icmp slt <2 x i32> [[TMP2]], [[X:%.*]]
301; CHECK-NEXT:    [[TMP4:%.*]] = select <2 x i1> [[TMP3]], <2 x i32> [[TMP2]], <2 x i32> [[X]]
302; CHECK-NEXT:    [[TMP5:%.*]] = xor <2 x i32> [[TMP4]], <i32 -1, i32 -1>
303; CHECK-NEXT:    ret <2 x i32> [[TMP5]]
304;
305  %c0 = icmp sgt <2 x i32> %y, zeroinitializer
306  %xor_y = xor <2 x i32> %y, <i32 -1, i32 -1>
307  %s0 = select <2 x i1> %c0, <2 x i32> %xor_y, <2 x i32> <i32 -1, i32 -1>
308  %xor_x = xor <2 x i32> %x, <i32 -1, i32 -1>
309  %c1 = icmp slt <2 x i32> %s0, %xor_x
310  %smax96 = select <2 x i1> %c1, <2 x i32> %xor_x, <2 x i32> %s0
311  ret <2 x i32> %smax96
312}
313
314define <2 x i37> @max_of_nots_weird_type_vec(<2 x i37> %x, <2 x i37> %y) {
315; CHECK-LABEL: @max_of_nots_weird_type_vec(
316; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt <2 x i37> [[Y:%.*]], zeroinitializer
317; CHECK-NEXT:    [[TMP2:%.*]] = select <2 x i1> [[TMP1]], <2 x i37> [[Y]], <2 x i37> zeroinitializer
318; CHECK-NEXT:    [[TMP3:%.*]] = icmp slt <2 x i37> [[TMP2]], [[X:%.*]]
319; CHECK-NEXT:    [[TMP4:%.*]] = select <2 x i1> [[TMP3]], <2 x i37> [[TMP2]], <2 x i37> [[X]]
320; CHECK-NEXT:    [[TMP5:%.*]] = xor <2 x i37> [[TMP4]], <i37 -1, i37 -1>
321; CHECK-NEXT:    ret <2 x i37> [[TMP5]]
322;
323  %c0 = icmp sgt <2 x i37> %y, zeroinitializer
324  %xor_y = xor <2 x i37> %y, <i37 -1, i37 -1>
325  %s0 = select <2 x i1> %c0, <2 x i37> %xor_y, <2 x i37> <i37 -1, i37 -1>
326  %xor_x = xor <2 x i37> %x, <i37 -1, i37 -1>
327  %c1 = icmp slt <2 x i37> %s0, %xor_x
328  %smax96 = select <2 x i1> %c1, <2 x i37> %xor_x, <2 x i37> %s0
329  ret <2 x i37> %smax96
330}
331
332; max(min(%a, -1), -1) == -1
333define i32 @max_of_min(i32 %a) {
334; CHECK-LABEL: @max_of_min(
335; CHECK-NEXT:    ret i32 -1
336;
337  %not_a = xor i32 %a, -1
338  %c0 = icmp sgt i32 %a, 0
339  %s0 = select i1 %c0, i32 %not_a, i32 -1
340  %c1 = icmp sgt i32 %s0, -1
341  %s1 = select i1 %c1, i32 %s0, i32 -1
342  ret i32 %s1
343}
344
345; max(min(%a, -1), -1) == -1 (swap predicate and select ops)
346define i32 @max_of_min_swap(i32 %a) {
347; CHECK-LABEL: @max_of_min_swap(
348; CHECK-NEXT:    ret i32 -1
349;
350  %not_a = xor i32 %a, -1
351  %c0 = icmp slt i32 %a, 0
352  %s0 = select i1 %c0, i32 -1, i32 %not_a
353  %c1 = icmp sgt i32 %s0, -1
354  %s1 = select i1 %c1, i32 %s0, i32 -1
355  ret i32 %s1
356}
357
358; min(max(%a, -1), -1) == -1
359define i32 @min_of_max(i32 %a) {
360; CHECK-LABEL: @min_of_max(
361; CHECK-NEXT:    ret i32 -1
362;
363  %not_a = xor i32 %a, -1
364  %c0 = icmp slt i32 %a, 0
365  %s0 = select i1 %c0, i32 %not_a, i32 -1
366  %c1 = icmp slt i32 %s0, -1
367  %s1 = select i1 %c1, i32 %s0, i32 -1
368  ret i32 %s1
369}
370
371; min(max(%a, -1), -1) == -1 (swap predicate and select ops)
372define i32 @min_of_max_swap(i32 %a) {
373; CHECK-LABEL: @min_of_max_swap(
374; CHECK-NEXT:    ret i32 -1
375;
376  %not_a = xor i32 %a, -1
377  %c0 = icmp sgt i32 %a, 0
378  %s0 = select i1 %c0, i32 -1, i32 %not_a
379  %c1 = icmp slt i32 %s0, -1
380  %s1 = select i1 %c1, i32 %s0, i32 -1
381  ret i32 %s1
382}
383
384define <2 x i32> @max_of_min_vec(<2 x i32> %a) {
385; CHECK-LABEL: @max_of_min_vec(
386; CHECK-NEXT:    ret <2 x i32> <i32 -1, i32 -1>
387;
388  %not_a = xor <2 x i32> %a, <i32 -1, i32 -1>
389  %c0 = icmp sgt <2 x i32> %a, zeroinitializer
390  %s0 = select <2 x i1> %c0, <2 x i32> %not_a, <2 x i32> <i32 -1, i32 -1>
391  %c1 = icmp sgt <2 x i32> %s0, <i32 -1, i32 -1>
392  %s1 = select <2 x i1> %c1, <2 x i32> %s0, <2 x i32> <i32 -1, i32 -1>
393  ret <2 x i32> %s1
394}
395
396