• 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 [[Y:%.*]], [[X]]
51; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i8 [[Y]], i8 [[X]]
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 [[Z:%.*]], [[X]]
113; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i8 [[Z]], i8 [[X]]
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 i32 @compute_min_3(i32 %x, i32 %y, i32 %z) {
165; CHECK-LABEL: @compute_min_3(
166; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]
167; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 [[Y]]
168; CHECK-NEXT:    [[TMP3:%.*]] = icmp slt i32 [[TMP2]], [[Z:%.*]]
169; CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP3]], i32 [[TMP2]], i32 [[Z]]
170; CHECK-NEXT:    ret i32 [[TMP4]]
171;
172  %not_x = sub i32 -1, %x
173  %not_y = sub i32 -1, %y
174  %not_z = sub i32 -1, %z
175  %cmp_1 = icmp sgt i32 %not_x, %not_y
176  %not_min_1 = select i1 %cmp_1, i32 %not_x, i32 %not_y
177  %cmp_2 = icmp sgt i32 %not_min_1, %not_z
178  %not_min_2 = select i1 %cmp_2, i32 %not_min_1, i32 %not_z
179  %min = sub i32 -1, %not_min_2
180  ret i32 %min
181}
182
183; Don't increase the critical path by moving the 'not' op after the 'select'.
184
185define i32 @compute_min_arithmetic(i32 %x, i32 %y) {
186; CHECK-LABEL: @compute_min_arithmetic(
187; CHECK-NEXT:    [[NOT_VALUE:%.*]] = sub i32 3, [[X:%.*]]
188; CHECK-NEXT:    [[NOT_Y:%.*]] = xor i32 [[Y:%.*]], -1
189; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[NOT_VALUE]], [[NOT_Y]]
190; CHECK-NEXT:    [[NOT_MIN:%.*]] = select i1 [[CMP]], i32 [[NOT_VALUE]], i32 [[NOT_Y]]
191; CHECK-NEXT:    ret i32 [[NOT_MIN]]
192;
193  %not_value = sub i32 3, %x
194  %not_y = sub i32 -1, %y
195  %cmp = icmp sgt i32 %not_value, %not_y
196  %not_min = select i1 %cmp, i32 %not_value, i32 %not_y
197  ret i32 %not_min
198}
199
200declare void @fake_use(i32)
201
202define i32 @compute_min_pessimization(i32 %x, i32 %y) {
203; CHECK-LABEL: @compute_min_pessimization(
204; CHECK-NEXT:    [[NOT_VALUE:%.*]] = sub i32 3, [[X:%.*]]
205; CHECK-NEXT:    call void @fake_use(i32 [[NOT_VALUE]])
206; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X]], -4
207; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[TMP1]], [[Y:%.*]]
208; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[TMP2]], i32 [[TMP1]], i32 [[Y]]
209; CHECK-NEXT:    ret i32 [[MIN]]
210;
211  %not_value = sub i32 3, %x
212  call void @fake_use(i32 %not_value)
213  %not_y = sub i32 -1, %y
214  %cmp = icmp sgt i32 %not_value, %not_y
215  %not_min = select i1 %cmp, i32 %not_value, i32 %not_y
216  %min = sub i32 -1, %not_min
217  ret i32 %min
218}
219
220define i32 @max_of_nots(i32 %x, i32 %y) {
221; CHECK-LABEL: @max_of_nots(
222; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[Y:%.*]], 0
223; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[Y]], i32 0
224; CHECK-NEXT:    [[TMP3:%.*]] = icmp slt i32 [[TMP2]], [[X:%.*]]
225; CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP3]], i32 [[TMP2]], i32 [[X]]
226; CHECK-NEXT:    [[SMAX96:%.*]] = xor i32 [[TMP4]], -1
227; CHECK-NEXT:    ret i32 [[SMAX96]]
228;
229  %c0 = icmp sgt i32 %y, 0
230  %xor_y = xor i32 %y, -1
231  %s0 = select i1 %c0, i32 %xor_y, i32 -1
232  %xor_x = xor i32 %x, -1
233  %c1 = icmp slt i32 %s0, %xor_x
234  %smax96 = select i1 %c1, i32 %xor_x, i32 %s0
235  ret i32 %smax96
236}
237
238 ; negative test case (i.e. can not simplify) : ABS(MIN(NOT x,y))
239define i32 @abs_of_min_of_not(i32 %x, i32 %y) {
240; CHECK-LABEL: @abs_of_min_of_not(
241; CHECK-NEXT:    [[XORD:%.*]] = xor i32 [[X:%.*]], -1
242; CHECK-NEXT:    [[YADD:%.*]] = add i32 [[Y:%.*]], 2
243; CHECK-NEXT:    [[COND_I:%.*]] = icmp slt i32 [[YADD]], [[XORD]]
244; CHECK-NEXT:    [[MIN:%.*]] = select i1 [[COND_I]], i32 [[YADD]], i32 [[XORD]]
245; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[MIN]], 0
246; CHECK-NEXT:    [[SUB:%.*]] = sub i32 0, [[MIN]]
247; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP2]], i32 [[SUB]], i32 [[MIN]]
248; CHECK-NEXT:    ret i32 [[ABS]]
249;
250
251  %xord = xor i32 %x, -1
252  %yadd = add i32 %y, 2
253  %cond.i = icmp sge i32 %yadd, %xord
254  %min = select i1 %cond.i, i32 %xord, i32 %yadd
255  %cmp2 = icmp sgt i32 %min, -1
256  %sub = sub i32 0, %min
257  %abs = select i1 %cmp2, i32 %min, i32 %sub
258  ret i32  %abs
259}
260
261define <2 x i32> @max_of_nots_vec(<2 x i32> %x, <2 x i32> %y) {
262; CHECK-LABEL: @max_of_nots_vec(
263; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt <2 x i32> [[Y:%.*]], zeroinitializer
264; CHECK-NEXT:    [[TMP2:%.*]] = select <2 x i1> [[TMP1]], <2 x i32> [[Y]], <2 x i32> zeroinitializer
265; CHECK-NEXT:    [[TMP3:%.*]] = icmp slt <2 x i32> [[TMP2]], [[X:%.*]]
266; CHECK-NEXT:    [[TMP4:%.*]] = select <2 x i1> [[TMP3]], <2 x i32> [[TMP2]], <2 x i32> [[X]]
267; CHECK-NEXT:    [[SMAX96:%.*]] = xor <2 x i32> [[TMP4]], <i32 -1, i32 -1>
268; CHECK-NEXT:    ret <2 x i32> [[SMAX96]]
269;
270  %c0 = icmp sgt <2 x i32> %y, zeroinitializer
271  %xor_y = xor <2 x i32> %y, <i32 -1, i32 -1>
272  %s0 = select <2 x i1> %c0, <2 x i32> %xor_y, <2 x i32> <i32 -1, i32 -1>
273  %xor_x = xor <2 x i32> %x, <i32 -1, i32 -1>
274  %c1 = icmp slt <2 x i32> %s0, %xor_x
275  %smax96 = select <2 x i1> %c1, <2 x i32> %xor_x, <2 x i32> %s0
276  ret <2 x i32> %smax96
277}
278
279define <2 x i37> @max_of_nots_weird_type_vec(<2 x i37> %x, <2 x i37> %y) {
280; CHECK-LABEL: @max_of_nots_weird_type_vec(
281; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt <2 x i37> [[Y:%.*]], zeroinitializer
282; CHECK-NEXT:    [[TMP2:%.*]] = select <2 x i1> [[TMP1]], <2 x i37> [[Y]], <2 x i37> zeroinitializer
283; CHECK-NEXT:    [[TMP3:%.*]] = icmp slt <2 x i37> [[TMP2]], [[X:%.*]]
284; CHECK-NEXT:    [[TMP4:%.*]] = select <2 x i1> [[TMP3]], <2 x i37> [[TMP2]], <2 x i37> [[X]]
285; CHECK-NEXT:    [[SMAX96:%.*]] = xor <2 x i37> [[TMP4]], <i37 -1, i37 -1>
286; CHECK-NEXT:    ret <2 x i37> [[SMAX96]]
287;
288  %c0 = icmp sgt <2 x i37> %y, zeroinitializer
289  %xor_y = xor <2 x i37> %y, <i37 -1, i37 -1>
290  %s0 = select <2 x i1> %c0, <2 x i37> %xor_y, <2 x i37> <i37 -1, i37 -1>
291  %xor_x = xor <2 x i37> %x, <i37 -1, i37 -1>
292  %c1 = icmp slt <2 x i37> %s0, %xor_x
293  %smax96 = select <2 x i1> %c1, <2 x i37> %xor_x, <2 x i37> %s0
294  ret <2 x i37> %smax96
295}
296
297; max(min(%a, -1), -1) == -1
298define i32 @max_of_min(i32 %a) {
299; CHECK-LABEL: @max_of_min(
300; CHECK-NEXT:    ret i32 -1
301;
302  %not_a = xor i32 %a, -1
303  %c0 = icmp sgt i32 %a, 0
304  %s0 = select i1 %c0, i32 %not_a, i32 -1
305  %c1 = icmp sgt i32 %s0, -1
306  %s1 = select i1 %c1, i32 %s0, i32 -1
307  ret i32 %s1
308}
309
310; max(min(%a, -1), -1) == -1 (swap predicate and select ops)
311define i32 @max_of_min_swap(i32 %a) {
312; CHECK-LABEL: @max_of_min_swap(
313; CHECK-NEXT:    ret i32 -1
314;
315  %not_a = xor i32 %a, -1
316  %c0 = icmp slt i32 %a, 0
317  %s0 = select i1 %c0, i32 -1, i32 %not_a
318  %c1 = icmp sgt i32 %s0, -1
319  %s1 = select i1 %c1, i32 %s0, i32 -1
320  ret i32 %s1
321}
322
323; min(max(%a, -1), -1) == -1
324define i32 @min_of_max(i32 %a) {
325; CHECK-LABEL: @min_of_max(
326; CHECK-NEXT:    ret i32 -1
327;
328  %not_a = xor i32 %a, -1
329  %c0 = icmp slt i32 %a, 0
330  %s0 = select i1 %c0, i32 %not_a, i32 -1
331  %c1 = icmp slt i32 %s0, -1
332  %s1 = select i1 %c1, i32 %s0, i32 -1
333  ret i32 %s1
334}
335
336; min(max(%a, -1), -1) == -1 (swap predicate and select ops)
337define i32 @min_of_max_swap(i32 %a) {
338; CHECK-LABEL: @min_of_max_swap(
339; CHECK-NEXT:    ret i32 -1
340;
341  %not_a = xor i32 %a, -1
342  %c0 = icmp sgt i32 %a, 0
343  %s0 = select i1 %c0, i32 -1, i32 %not_a
344  %c1 = icmp slt i32 %s0, -1
345  %s1 = select i1 %c1, i32 %s0, i32 -1
346  ret i32 %s1
347}
348
349define <2 x i32> @max_of_min_vec(<2 x i32> %a) {
350; CHECK-LABEL: @max_of_min_vec(
351; CHECK-NEXT:    ret <2 x i32> <i32 -1, i32 -1>
352;
353  %not_a = xor <2 x i32> %a, <i32 -1, i32 -1>
354  %c0 = icmp sgt <2 x i32> %a, zeroinitializer
355  %s0 = select <2 x i1> %c0, <2 x i32> %not_a, <2 x i32> <i32 -1, i32 -1>
356  %c1 = icmp sgt <2 x i32> %s0, <i32 -1, i32 -1>
357  %s1 = select <2 x i1> %c1, <2 x i32> %s0, <2 x i32> <i32 -1, i32 -1>
358  ret <2 x i32> %s1
359}
360
361declare void @use(i8, i8, i8, i8)
362
363define void @cmyk(i8 %r, i8 %g, i8 %b) {
364; CHECK-LABEL: @cmyk(
365; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i8 [[R:%.*]], [[B:%.*]]
366; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i8 [[R]], i8 [[B]]
367; CHECK-NEXT:    [[TMP3:%.*]] = icmp sgt i8 [[TMP2]], [[G:%.*]]
368; CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP3]], i8 [[TMP2]], i8 [[G]]
369; CHECK-NEXT:    [[TMP5:%.*]] = xor i8 [[TMP4]], -1
370; CHECK-NEXT:    [[CK:%.*]] = sub i8 [[TMP4]], [[R]]
371; CHECK-NEXT:    [[MK:%.*]] = sub i8 [[TMP4]], [[G]]
372; CHECK-NEXT:    [[YK:%.*]] = sub i8 [[TMP4]], [[B]]
373; CHECK-NEXT:    call void @use(i8 [[CK]], i8 [[MK]], i8 [[YK]], i8 [[TMP5]])
374; CHECK-NEXT:    ret void
375;
376  %notr = xor i8 %r, -1
377  %notg = xor i8 %g, -1
378  %notb = xor i8 %b, -1
379  %cmp_gr = icmp slt i8 %g, %r
380  %cmp_br = icmp slt i8 %notr, %notb
381  %min_br = select i1 %cmp_br, i8 %notr, i8 %notb
382  %cmp_gb = icmp slt i8 %notg, %notb
383  %min_gb = select i1 %cmp_gb, i8 %notg, i8 %notb
384  %k = select i1 %cmp_gr, i8 %min_br, i8 %min_gb
385  %ck = sub i8 %notr, %k
386  %mk = sub i8 %notg, %k
387  %yk = sub i8 %notb, %k
388  call void @use(i8 %ck, i8 %mk, i8 %yk, i8 %k)
389  ret void
390}
391
392define void @cmyk2(i8 %r, i8 %g, i8 %b) {
393; CHECK-LABEL: @cmyk2(
394; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i8 [[R:%.*]], [[B:%.*]]
395; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i8 [[R]], i8 [[B]]
396; CHECK-NEXT:    [[TMP3:%.*]] = icmp sgt i8 [[TMP2]], [[G:%.*]]
397; CHECK-NEXT:    [[K_V:%.*]] = select i1 [[TMP3]], i8 [[TMP2]], i8 [[G]]
398; CHECK-NEXT:    [[K:%.*]] = xor i8 [[K_V]], -1
399; CHECK-NEXT:    [[CK:%.*]] = sub i8 [[K_V]], [[R]]
400; CHECK-NEXT:    [[MK:%.*]] = sub i8 [[K_V]], [[G]]
401; CHECK-NEXT:    [[YK:%.*]] = sub i8 [[K_V]], [[B]]
402; CHECK-NEXT:    call void @use(i8 [[CK]], i8 [[MK]], i8 [[YK]], i8 [[K]])
403; CHECK-NEXT:    ret void
404;
405  %notr = xor i8 %r, -1
406  %notg = xor i8 %g, -1
407  %notb = xor i8 %b, -1
408  %cmp_gr = icmp slt i8 %g, %r
409  %cmp_br = icmp slt i8 %b, %r
410  %min_br = select i1 %cmp_br, i8 %notr, i8 %notb
411  %cmp_bg = icmp slt i8 %b, %g
412  %min_bg = select i1 %cmp_bg, i8 %notg, i8 %notb
413  %k = select i1 %cmp_gr, i8 %min_br, i8 %min_bg
414  %ck = sub i8 %notr, %k
415  %mk = sub i8 %notg, %k
416  %yk = sub i8 %notb, %k
417  call void @use(i8 %ck, i8 %mk, i8 %yk, i8 %k)
418  ret void
419}
420
421define void @cmyk3(i8 %r, i8 %g, i8 %b) {
422; CHECK-LABEL: @cmyk3(
423; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i8 [[R:%.*]], [[B:%.*]]
424; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i8 [[R]], i8 [[B]]
425; CHECK-NEXT:    [[TMP3:%.*]] = icmp sgt i8 [[TMP2]], [[G:%.*]]
426; CHECK-NEXT:    [[K_V:%.*]] = select i1 [[TMP3]], i8 [[TMP2]], i8 [[G]]
427; CHECK-NEXT:    [[K:%.*]] = xor i8 [[K_V]], -1
428; CHECK-NEXT:    [[CK:%.*]] = sub i8 [[K_V]], [[R]]
429; CHECK-NEXT:    [[MK:%.*]] = sub i8 [[K_V]], [[G]]
430; CHECK-NEXT:    [[YK:%.*]] = sub i8 [[K_V]], [[B]]
431; CHECK-NEXT:    call void @use(i8 [[CK]], i8 [[MK]], i8 [[YK]], i8 [[K]])
432; CHECK-NEXT:    ret void
433;
434  %notr = xor i8 %r, -1
435  %notg = xor i8 %g, -1
436  %notb = xor i8 %b, -1
437  %cmp_gr = icmp slt i8 %g, %r
438  %cmp_br = icmp sgt i8 %r, %b
439  %min_br = select i1 %cmp_br, i8 %notr, i8 %notb
440  %cmp_bg = icmp slt i8 %b, %g
441  %min_bg = select i1 %cmp_bg, i8 %notg, i8 %notb
442  %k = select i1 %cmp_gr, i8 %min_br, i8 %min_bg
443  %ck = sub i8 %notr, %k
444  %mk = sub i8 %notg, %k
445  %yk = sub i8 %notb, %k
446  call void @use(i8 %ck, i8 %mk, i8 %yk, i8 %k)
447  ret void
448}
449
450define void @cmyk4(i8 %r, i8 %g, i8 %b) {
451; CHECK-LABEL: @cmyk4(
452; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i8 [[R:%.*]], [[B:%.*]]
453; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i8 [[R]], i8 [[B]]
454; CHECK-NEXT:    [[TMP3:%.*]] = icmp sgt i8 [[TMP2]], [[G:%.*]]
455; CHECK-NEXT:    [[K_V:%.*]] = select i1 [[TMP3]], i8 [[TMP2]], i8 [[G]]
456; CHECK-NEXT:    [[K:%.*]] = xor i8 [[K_V]], -1
457; CHECK-NEXT:    [[CK:%.*]] = sub i8 [[K_V]], [[R]]
458; CHECK-NEXT:    [[MK:%.*]] = sub i8 [[K_V]], [[G]]
459; CHECK-NEXT:    [[YK:%.*]] = sub i8 [[K_V]], [[B]]
460; CHECK-NEXT:    call void @use(i8 [[CK]], i8 [[MK]], i8 [[YK]], i8 [[K]])
461; CHECK-NEXT:    ret void
462;
463  %notr = xor i8 %r, -1
464  %notg = xor i8 %g, -1
465  %notb = xor i8 %b, -1
466  %cmp_gr = icmp slt i8 %g, %r
467  %cmp_br = icmp sgt i8 %r, %b
468  %min_br = select i1 %cmp_br, i8 %notr, i8 %notb
469  %cmp_bg = icmp sgt i8 %g, %b
470  %min_bg = select i1 %cmp_bg, i8 %notg, i8 %notb
471  %k = select i1 %cmp_gr, i8 %min_br, i8 %min_bg
472  %ck = sub i8 %notr, %k
473  %mk = sub i8 %notg, %k
474  %yk = sub i8 %notb, %k
475  call void @use(i8 %ck, i8 %mk, i8 %yk, i8 %k)
476  ret void
477}
478
479define void @cmyk5(i8 %r, i8 %g, i8 %b) {
480; CHECK-LABEL: @cmyk5(
481; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i8 [[R:%.*]], [[B:%.*]]
482; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i8 [[R]], i8 [[B]]
483; CHECK-NEXT:    [[TMP3:%.*]] = icmp sgt i8 [[TMP2]], [[G:%.*]]
484; CHECK-NEXT:    [[K_V:%.*]] = select i1 [[TMP3]], i8 [[TMP2]], i8 [[G]]
485; CHECK-NEXT:    [[K:%.*]] = xor i8 [[K_V]], -1
486; CHECK-NEXT:    [[CK:%.*]] = sub i8 [[K_V]], [[R]]
487; CHECK-NEXT:    [[MK:%.*]] = sub i8 [[K_V]], [[G]]
488; CHECK-NEXT:    [[YK:%.*]] = sub i8 [[K_V]], [[B]]
489; CHECK-NEXT:    call void @use(i8 [[CK]], i8 [[MK]], i8 [[YK]], i8 [[K]])
490; CHECK-NEXT:    ret void
491;
492  %notr = xor i8 %r, -1
493  %notg = xor i8 %g, -1
494  %notb = xor i8 %b, -1
495  %cmp_gr = icmp sgt i8 %r, %g
496  %cmp_br = icmp sgt i8 %r, %b
497  %min_br = select i1 %cmp_br, i8 %notr, i8 %notb
498  %cmp_bg = icmp sgt i8 %g, %b
499  %min_bg = select i1 %cmp_bg, i8 %notg, i8 %notb
500  %k = select i1 %cmp_gr, i8 %min_br, i8 %min_bg
501  %ck = sub i8 %notr, %k
502  %mk = sub i8 %notg, %k
503  %yk = sub i8 %notb, %k
504  call void @use(i8 %ck, i8 %mk, i8 %yk, i8 %k)
505  ret void
506}
507
508define void @cmyk6(i8 %r, i8 %g, i8 %b) {
509; CHECK-LABEL: @cmyk6(
510; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i8 [[R:%.*]], [[B:%.*]]
511; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i8 [[R]], i8 [[B]]
512; CHECK-NEXT:    [[TMP3:%.*]] = icmp ugt i8 [[TMP2]], [[G:%.*]]
513; CHECK-NEXT:    [[K_V:%.*]] = select i1 [[TMP3]], i8 [[TMP2]], i8 [[G]]
514; CHECK-NEXT:    [[K:%.*]] = xor i8 [[K_V]], -1
515; CHECK-NEXT:    [[CK:%.*]] = sub i8 [[K_V]], [[R]]
516; CHECK-NEXT:    [[MK:%.*]] = sub i8 [[K_V]], [[G]]
517; CHECK-NEXT:    [[YK:%.*]] = sub i8 [[K_V]], [[B]]
518; CHECK-NEXT:    tail call void @use(i8 [[CK]], i8 [[MK]], i8 [[YK]], i8 [[K]])
519; CHECK-NEXT:    ret void
520;
521  %notr = xor i8 %r, -1
522  %notg = xor i8 %g, -1
523  %notb = xor i8 %b, -1
524  %cmp_gr = icmp ult i8 %g, %r
525  %cmp_br = icmp ult i8 %b, %r
526  %sel_rb = select i1 %cmp_br, i8 %notr, i8 %notb
527  %cmp_bg = icmp ult i8 %b, %g
528  %sel_gb = select i1 %cmp_bg, i8 %notg, i8 %notb
529  %k = select i1 %cmp_gr, i8 %sel_rb, i8 %sel_gb
530  %ck = sub i8 %notr, %k
531  %mk = sub i8 %notg, %k
532  %yk = sub i8 %notb, %k
533  tail call void @use(i8 %ck, i8 %mk, i8 %yk, i8 %k)
534  ret void
535}
536