gn build: Extract git() and git_out() functions in sync script
[llvm-complete.git] / test / Transforms / InstCombine / canonicalize-clamp-like-pattern-between-negative-and-positive-thresholds.ll
blob141bf660ee420c5639605bf6c5bdf3fb336c1cb8
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 ; Given a pattern like:
5 ;   %old_cmp1 = icmp slt i32 %x, C2
6 ;   %old_replacement = select i1 %old_cmp1, i32 %target_low, i32 %target_high
7 ;   %old_x_offseted = add i32 %x, C1
8 ;   %old_cmp0 = icmp ult i32 %old_x_offseted, C0
9 ;   %r = select i1 %old_cmp0, i32 %x, i32 %old_replacement
10 ; it can be rewriten as more canonical pattern:
11 ;   %new_cmp1 = icmp slt i32 %x, -C1
12 ;   %new_cmp2 = icmp sge i32 %x, C0-C1
13 ;   %new_clamped_low = select i1 %new_cmp1, i32 %target_low, i32 %x
14 ;   %r = select i1 %new_cmp2, i32 %target_high, i32 %new_clamped_low
15 ; Iff -C1 s<= C2 s<= C0-C1
16 ; Also, ULT predicate can also be UGE; or UGT iff C0 != -1 (+invert result)
17 ; Also, SLT predicate can also be SGE; or SGT iff C2 != INT_MAX (+invert res.)
19 ;-------------------------------------------------------------------------------
21 ; Basic pattern. There is no 'and', so lower threshold is 0 (inclusive).
22 ; The upper threshold is 127 (inclusive).
23 ; There are 2 icmp's so for scalars there are 4 possible combinations.
24 ; The constant in %t0 has to be between the thresholds, i.e 128 <= Ct0 <= 0.
26 define i32 @t0_ult_slt_128(i32 %x, i32 %replacement_low, i32 %replacement_high) {
27 ; CHECK-LABEL: @t0_ult_slt_128(
28 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 [[X:%.*]], 128
29 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
30 ; CHECK-NEXT:    [[T2:%.*]] = add i32 [[X]], 16
31 ; CHECK-NEXT:    [[T3:%.*]] = icmp ult i32 [[T2]], 144
32 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[T3]], i32 [[X]], i32 [[T1]]
33 ; CHECK-NEXT:    ret i32 [[R]]
35   %t0 = icmp slt i32 %x, 128
36   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
37   %t2 = add i32 %x, 16
38   %t3 = icmp ult i32 %t2, 144
39   %r = select i1 %t3, i32 %x, i32 %t1
40   ret i32 %r
42 define i32 @t1_ult_slt_0(i32 %x, i32 %replacement_low, i32 %replacement_high) {
43 ; CHECK-LABEL: @t1_ult_slt_0(
44 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 [[X:%.*]], -16
45 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
46 ; CHECK-NEXT:    [[T2:%.*]] = add i32 [[X]], 16
47 ; CHECK-NEXT:    [[T3:%.*]] = icmp ult i32 [[T2]], 144
48 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[T3]], i32 [[X]], i32 [[T1]]
49 ; CHECK-NEXT:    ret i32 [[R]]
51   %t0 = icmp slt i32 %x, -16
52   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
53   %t2 = add i32 %x, 16
54   %t3 = icmp ult i32 %t2, 144
55   %r = select i1 %t3, i32 %x, i32 %t1
56   ret i32 %r
59 define i32 @t2_ult_sgt_128(i32 %x, i32 %replacement_low, i32 %replacement_high) {
60 ; CHECK-LABEL: @t2_ult_sgt_128(
61 ; CHECK-NEXT:    [[T0:%.*]] = icmp sgt i32 [[X:%.*]], 127
62 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_HIGH:%.*]], i32 [[REPLACEMENT_LOW:%.*]]
63 ; CHECK-NEXT:    [[T2:%.*]] = add i32 [[X]], 16
64 ; CHECK-NEXT:    [[T3:%.*]] = icmp ult i32 [[T2]], 144
65 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[T3]], i32 [[X]], i32 [[T1]]
66 ; CHECK-NEXT:    ret i32 [[R]]
68   %t0 = icmp sgt i32 %x, 127
69   %t1 = select i1 %t0, i32 %replacement_high, i32 %replacement_low
70   %t2 = add i32 %x, 16
71   %t3 = icmp ult i32 %t2, 144
72   %r = select i1 %t3, i32 %x, i32 %t1
73   ret i32 %r
75 define i32 @t3_ult_sgt_neg1(i32 %x, i32 %replacement_low, i32 %replacement_high) {
76 ; CHECK-LABEL: @t3_ult_sgt_neg1(
77 ; CHECK-NEXT:    [[T0:%.*]] = icmp sgt i32 [[X:%.*]], -17
78 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_HIGH:%.*]], i32 [[REPLACEMENT_LOW:%.*]]
79 ; CHECK-NEXT:    [[T2:%.*]] = add i32 [[X]], 16
80 ; CHECK-NEXT:    [[T3:%.*]] = icmp ult i32 [[T2]], 144
81 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[T3]], i32 [[X]], i32 [[T1]]
82 ; CHECK-NEXT:    ret i32 [[R]]
84   %t0 = icmp sgt i32 %x, -17
85   %t1 = select i1 %t0, i32 %replacement_high, i32 %replacement_low
86   %t2 = add i32 %x, 16
87   %t3 = icmp ult i32 %t2, 144
88   %r = select i1 %t3, i32 %x, i32 %t1
89   ret i32 %r
92 define i32 @t4_ugt_slt_128(i32 %x, i32 %replacement_low, i32 %replacement_high) {
93 ; CHECK-LABEL: @t4_ugt_slt_128(
94 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 [[X:%.*]], 128
95 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
96 ; CHECK-NEXT:    [[T2:%.*]] = add i32 [[X]], 16
97 ; CHECK-NEXT:    [[T3:%.*]] = icmp ugt i32 [[T2]], 143
98 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[T3]], i32 [[T1]], i32 [[X]]
99 ; CHECK-NEXT:    ret i32 [[R]]
101   %t0 = icmp slt i32 %x, 128
102   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
103   %t2 = add i32 %x, 16
104   %t3 = icmp ugt i32 %t2, 143
105   %r = select i1 %t3, i32 %t1, i32 %x
106   ret i32 %r
108 define i32 @t5_ugt_slt_0(i32 %x, i32 %replacement_low, i32 %replacement_high) {
109 ; CHECK-LABEL: @t5_ugt_slt_0(
110 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 [[X:%.*]], -16
111 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
112 ; CHECK-NEXT:    [[T2:%.*]] = add i32 [[X]], 16
113 ; CHECK-NEXT:    [[T3:%.*]] = icmp ugt i32 [[T2]], 143
114 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[T3]], i32 [[T1]], i32 [[X]]
115 ; CHECK-NEXT:    ret i32 [[R]]
117   %t0 = icmp slt i32 %x, -16
118   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
119   %t2 = add i32 %x, 16
120   %t3 = icmp ugt i32 %t2, 143
121   %r = select i1 %t3, i32 %t1, i32 %x
122   ret i32 %r
125 define i32 @t6_ugt_sgt_128(i32 %x, i32 %replacement_low, i32 %replacement_high) {
126 ; CHECK-LABEL: @t6_ugt_sgt_128(
127 ; CHECK-NEXT:    [[T0:%.*]] = icmp sgt i32 [[X:%.*]], 127
128 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_HIGH:%.*]], i32 [[REPLACEMENT_LOW:%.*]]
129 ; CHECK-NEXT:    [[T2:%.*]] = add i32 [[X]], 16
130 ; CHECK-NEXT:    [[T3:%.*]] = icmp ugt i32 [[T2]], 143
131 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[T3]], i32 [[T1]], i32 [[X]]
132 ; CHECK-NEXT:    ret i32 [[R]]
134   %t0 = icmp sgt i32 %x, 127
135   %t1 = select i1 %t0, i32 %replacement_high, i32 %replacement_low
136   %t2 = add i32 %x, 16
137   %t3 = icmp ugt i32 %t2, 143
138   %r = select i1 %t3, i32 %t1, i32 %x
139   ret i32 %r
141 define i32 @t7_ugt_sgt_neg1(i32 %x, i32 %replacement_low, i32 %replacement_high) {
142 ; CHECK-LABEL: @t7_ugt_sgt_neg1(
143 ; CHECK-NEXT:    [[T0:%.*]] = icmp sgt i32 [[X:%.*]], -17
144 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_HIGH:%.*]], i32 [[REPLACEMENT_LOW:%.*]]
145 ; CHECK-NEXT:    [[T2:%.*]] = add i32 [[X]], 16
146 ; CHECK-NEXT:    [[T3:%.*]] = icmp ugt i32 [[T2]], 143
147 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[T3]], i32 [[T1]], i32 [[X]]
148 ; CHECK-NEXT:    ret i32 [[R]]
150   %t0 = icmp sgt i32 %x, -17
151   %t1 = select i1 %t0, i32 %replacement_high, i32 %replacement_low
152   %t2 = add i32 %x, 16
153   %t3 = icmp ugt i32 %t2, 143
154   %r = select i1 %t3, i32 %t1, i32 %x
155   ret i32 %r
158 ;-------------------------------------------------------------------------------
160 ; So Ct0 can not be s> 128, or s< -16
162 define i32 @n8_ult_slt_129(i32 %x, i32 %replacement_low, i32 %replacement_high) {
163 ; CHECK-LABEL: @n8_ult_slt_129(
164 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 [[X:%.*]], 129
165 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
166 ; CHECK-NEXT:    [[T2:%.*]] = add i32 [[X]], 16
167 ; CHECK-NEXT:    [[T3:%.*]] = icmp ult i32 [[T2]], 144
168 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[T3]], i32 [[X]], i32 [[T1]]
169 ; CHECK-NEXT:    ret i32 [[R]]
171   %t0 = icmp slt i32 %x, 129
172   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
173   %t2 = add i32 %x, 16
174   %t3 = icmp ult i32 %t2, 144
175   %r = select i1 %t3, i32 %x, i32 %t1
176   ret i32 %r
178 define i32 @n9_ult_slt_neg17(i32 %x, i32 %replacement_low, i32 %replacement_high) {
179 ; CHECK-LABEL: @n9_ult_slt_neg17(
180 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 [[X:%.*]], -17
181 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
182 ; CHECK-NEXT:    [[T2:%.*]] = add i32 [[X]], 16
183 ; CHECK-NEXT:    [[T3:%.*]] = icmp ult i32 [[T2]], 144
184 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[T3]], i32 [[X]], i32 [[T1]]
185 ; CHECK-NEXT:    ret i32 [[R]]
187   %t0 = icmp slt i32 %x, -17
188   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
189   %t2 = add i32 %x, 16
190   %t3 = icmp ult i32 %t2, 144
191   %r = select i1 %t3, i32 %x, i32 %t1
192   ret i32 %r
195 ;-------------------------------------------------------------------------------
197 declare void @use32(i32)
198 declare void @use1(i1)
200 ; One-use restrictions: here the entire pattern needs to be one-use.
201 ; FIXME: if %t0 could be reused then it's less restrictive.
203 ; This one is ok.
204 define i32 @t10_oneuse0(i32 %x, i32 %replacement_low, i32 %replacement_high) {
205 ; CHECK-LABEL: @t10_oneuse0(
206 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 [[X:%.*]], 64
207 ; CHECK-NEXT:    call void @use1(i1 [[T0]])
208 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
209 ; CHECK-NEXT:    [[T2:%.*]] = add i32 [[X]], 16
210 ; CHECK-NEXT:    [[T3:%.*]] = icmp ult i32 [[T2]], 144
211 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[T3]], i32 [[X]], i32 [[T1]]
212 ; CHECK-NEXT:    ret i32 [[R]]
214   %t0 = icmp slt i32 %x, 64
215   call void @use1(i1 %t0)
216   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
217   %t2 = add i32 %x, 16
218   %t3 = icmp ult i32 %t2, 144
219   %r = select i1 %t3, i32 %x, i32 %t1
220   ret i32 %r
222 define i32 @n11_oneuse1(i32 %x, i32 %replacement_low, i32 %replacement_high) {
223 ; CHECK-LABEL: @n11_oneuse1(
224 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 [[X:%.*]], 64
225 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
226 ; CHECK-NEXT:    call void @use32(i32 [[T1]])
227 ; CHECK-NEXT:    [[T2:%.*]] = add i32 [[X]], 16
228 ; CHECK-NEXT:    [[T3:%.*]] = icmp ult i32 [[T2]], 144
229 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[T3]], i32 [[X]], i32 [[T1]]
230 ; CHECK-NEXT:    ret i32 [[R]]
232   %t0 = icmp slt i32 %x, 64
233   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
234   call void @use32(i32 %t1)
235   %t2 = add i32 %x, 16
236   %t3 = icmp ult i32 %t2, 144
237   %r = select i1 %t3, i32 %x, i32 %t1
238   ret i32 %r
241 ; This one is ok.
242 define i32 @t12_oneuse2(i32 %x, i32 %replacement_low, i32 %replacement_high) {
243 ; CHECK-LABEL: @t12_oneuse2(
244 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 [[X:%.*]], 64
245 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
246 ; CHECK-NEXT:    [[T2:%.*]] = add i32 [[X]], 16
247 ; CHECK-NEXT:    call void @use32(i32 [[T2]])
248 ; CHECK-NEXT:    [[T3:%.*]] = icmp ult i32 [[T2]], 144
249 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[T3]], i32 [[X]], i32 [[T1]]
250 ; CHECK-NEXT:    ret i32 [[R]]
252   %t0 = icmp slt i32 %x, 64
253   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
254   %t2 = add i32 %x, 16
255   call void @use32(i32 %t2)
256   %t3 = icmp ult i32 %t2, 144
257   %r = select i1 %t3, i32 %x, i32 %t1
258   ret i32 %r
261 define i32 @n13_oneuse3(i32 %x, i32 %replacement_low, i32 %replacement_high) {
262 ; CHECK-LABEL: @n13_oneuse3(
263 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 [[X:%.*]], 64
264 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
265 ; CHECK-NEXT:    [[T2:%.*]] = add i32 [[X]], 16
266 ; CHECK-NEXT:    [[T3:%.*]] = icmp ult i32 [[T2]], 144
267 ; CHECK-NEXT:    call void @use1(i1 [[T3]])
268 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[T3]], i32 [[X]], i32 [[T1]]
269 ; CHECK-NEXT:    ret i32 [[R]]
271   %t0 = icmp slt i32 %x, 64
272   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
273   %t2 = add i32 %x, 16
274   %t3 = icmp ult i32 %t2, 144
275   call void @use1(i1 %t3)
276   %r = select i1 %t3, i32 %x, i32 %t1
277   ret i32 %r
280 define i32 @n14_oneuse4(i32 %x, i32 %replacement_low, i32 %replacement_high) {
281 ; CHECK-LABEL: @n14_oneuse4(
282 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 [[X:%.*]], 64
283 ; CHECK-NEXT:    call void @use1(i1 [[T0]])
284 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
285 ; CHECK-NEXT:    call void @use32(i32 [[T1]])
286 ; CHECK-NEXT:    [[T2:%.*]] = add i32 [[X]], 16
287 ; CHECK-NEXT:    [[T3:%.*]] = icmp ult i32 [[T2]], 144
288 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[T3]], i32 [[X]], i32 [[T1]]
289 ; CHECK-NEXT:    ret i32 [[R]]
291   %t0 = icmp slt i32 %x, 64
292   call void @use1(i1 %t0)
293   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
294   call void @use32(i32 %t1)
295   %t2 = add i32 %x, 16
296   %t3 = icmp ult i32 %t2, 144
297   %r = select i1 %t3, i32 %x, i32 %t1
298   ret i32 %r
300 define i32 @n15_oneuse5(i32 %x, i32 %replacement_low, i32 %replacement_high) {
301 ; CHECK-LABEL: @n15_oneuse5(
302 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 [[X:%.*]], 64
303 ; CHECK-NEXT:    call void @use1(i1 [[T0]])
304 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
305 ; CHECK-NEXT:    [[T2:%.*]] = add i32 [[X]], 16
306 ; CHECK-NEXT:    call void @use32(i32 [[T2]])
307 ; CHECK-NEXT:    [[T3:%.*]] = icmp ult i32 [[T2]], 144
308 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[T3]], i32 [[X]], i32 [[T1]]
309 ; CHECK-NEXT:    ret i32 [[R]]
311   %t0 = icmp slt i32 %x, 64
312   call void @use1(i1 %t0)
313   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
314   %t2 = add i32 %x, 16
315   call void @use32(i32 %t2)
316   %t3 = icmp ult i32 %t2, 144
317   %r = select i1 %t3, i32 %x, i32 %t1
318   ret i32 %r
320 define i32 @n16_oneuse6(i32 %x, i32 %replacement_low, i32 %replacement_high) {
321 ; CHECK-LABEL: @n16_oneuse6(
322 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 [[X:%.*]], 64
323 ; CHECK-NEXT:    call void @use1(i1 [[T0]])
324 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
325 ; CHECK-NEXT:    [[T2:%.*]] = add i32 [[X]], 16
326 ; CHECK-NEXT:    [[T3:%.*]] = icmp ult i32 [[T2]], 144
327 ; CHECK-NEXT:    call void @use1(i1 [[T3]])
328 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[T3]], i32 [[X]], i32 [[T1]]
329 ; CHECK-NEXT:    ret i32 [[R]]
331   %t0 = icmp slt i32 %x, 64
332   call void @use1(i1 %t0)
333   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
334   %t2 = add i32 %x, 16
335   %t3 = icmp ult i32 %t2, 144
336   call void @use1(i1 %t3)
337   %r = select i1 %t3, i32 %x, i32 %t1
338   ret i32 %r
341 define i32 @n17_oneuse7(i32 %x, i32 %replacement_low, i32 %replacement_high) {
342 ; CHECK-LABEL: @n17_oneuse7(
343 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 [[X:%.*]], 64
344 ; CHECK-NEXT:    call void @use1(i1 [[T0]])
345 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
346 ; CHECK-NEXT:    call void @use32(i32 [[T1]])
347 ; CHECK-NEXT:    [[T2:%.*]] = add i32 [[X]], 16
348 ; CHECK-NEXT:    call void @use32(i32 [[T2]])
349 ; CHECK-NEXT:    [[T3:%.*]] = icmp ult i32 [[T2]], 144
350 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[T3]], i32 [[X]], i32 [[T1]]
351 ; CHECK-NEXT:    ret i32 [[R]]
353   %t0 = icmp slt i32 %x, 64
354   call void @use1(i1 %t0)
355   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
356   call void @use32(i32 %t1)
357   %t2 = add i32 %x, 16
358   call void @use32(i32 %t2)
359   %t3 = icmp ult i32 %t2, 144
360   %r = select i1 %t3, i32 %x, i32 %t1
361   ret i32 %r
363 define i32 @n18_oneuse8(i32 %x, i32 %replacement_low, i32 %replacement_high) {
364 ; CHECK-LABEL: @n18_oneuse8(
365 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 [[X:%.*]], 64
366 ; CHECK-NEXT:    call void @use1(i1 [[T0]])
367 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
368 ; CHECK-NEXT:    call void @use32(i32 [[T1]])
369 ; CHECK-NEXT:    [[T2:%.*]] = add i32 [[X]], 16
370 ; CHECK-NEXT:    [[T3:%.*]] = icmp ult i32 [[T2]], 144
371 ; CHECK-NEXT:    call void @use1(i1 [[T3]])
372 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[T3]], i32 [[X]], i32 [[T1]]
373 ; CHECK-NEXT:    ret i32 [[R]]
375   %t0 = icmp slt i32 %x, 64
376   call void @use1(i1 %t0)
377   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
378   call void @use32(i32 %t1)
379   %t2 = add i32 %x, 16
380   %t3 = icmp ult i32 %t2, 144
381   call void @use1(i1 %t3)
382   %r = select i1 %t3, i32 %x, i32 %t1
383   ret i32 %r
386 define i32 @n19_oneuse9(i32 %x, i32 %replacement_low, i32 %replacement_high) {
387 ; CHECK-LABEL: @n19_oneuse9(
388 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 [[X:%.*]], 64
389 ; CHECK-NEXT:    call void @use1(i1 [[T0]])
390 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
391 ; CHECK-NEXT:    call void @use32(i32 [[T1]])
392 ; CHECK-NEXT:    [[T2:%.*]] = add i32 [[X]], 16
393 ; CHECK-NEXT:    call void @use32(i32 [[T2]])
394 ; CHECK-NEXT:    [[T3:%.*]] = icmp ult i32 [[T2]], 144
395 ; CHECK-NEXT:    call void @use1(i1 [[T3]])
396 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[T3]], i32 [[X]], i32 [[T1]]
397 ; CHECK-NEXT:    ret i32 [[R]]
399   %t0 = icmp slt i32 %x, 64
400   call void @use1(i1 %t0)
401   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
402   call void @use32(i32 %t1)
403   %t2 = add i32 %x, 16
404   call void @use32(i32 %t2)
405   %t3 = icmp ult i32 %t2, 144
406   call void @use1(i1 %t3)
407   %r = select i1 %t3, i32 %x, i32 %t1
408   ret i32 %r
411 ;-------------------------------------------------------------------------------
413 ; Vectors
415 define <2 x i32> @t20_ult_slt_vec_splat(<2 x i32> %x, <2 x i32> %replacement_low, <2 x i32> %replacement_high) {
416 ; CHECK-LABEL: @t20_ult_slt_vec_splat(
417 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt <2 x i32> [[X:%.*]], <i32 128, i32 128>
418 ; CHECK-NEXT:    [[T1:%.*]] = select <2 x i1> [[T0]], <2 x i32> [[REPLACEMENT_LOW:%.*]], <2 x i32> [[REPLACEMENT_HIGH:%.*]]
419 ; CHECK-NEXT:    [[T2:%.*]] = add <2 x i32> [[X]], <i32 16, i32 16>
420 ; CHECK-NEXT:    [[T3:%.*]] = icmp ult <2 x i32> [[T2]], <i32 144, i32 144>
421 ; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[T3]], <2 x i32> [[X]], <2 x i32> [[T1]]
422 ; CHECK-NEXT:    ret <2 x i32> [[R]]
424   %t0 = icmp slt <2 x i32> %x, <i32 128, i32 128>
425   %t1 = select <2 x i1> %t0, <2 x i32> %replacement_low, <2 x i32> %replacement_high
426   %t2 = add <2 x i32> %x, <i32 16, i32 16>
427   %t3 = icmp ult <2 x i32> %t2, <i32 144, i32 144>
428   %r = select <2 x i1> %t3, <2 x i32> %x, <2 x i32> %t1
429   ret <2 x i32> %r
431 define <2 x i32> @t21_ult_slt_vec_nonsplat(<2 x i32> %x, <2 x i32> %replacement_low, <2 x i32> %replacement_high) {
432 ; CHECK-LABEL: @t21_ult_slt_vec_nonsplat(
433 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt <2 x i32> [[X:%.*]], <i32 128, i32 64>
434 ; CHECK-NEXT:    [[T1:%.*]] = select <2 x i1> [[T0]], <2 x i32> [[REPLACEMENT_LOW:%.*]], <2 x i32> [[REPLACEMENT_HIGH:%.*]]
435 ; CHECK-NEXT:    [[T2:%.*]] = add <2 x i32> [[X]], <i32 16, i32 8>
436 ; CHECK-NEXT:    [[T3:%.*]] = icmp ult <2 x i32> [[T2]], <i32 144, i32 264>
437 ; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[T3]], <2 x i32> [[X]], <2 x i32> [[T1]]
438 ; CHECK-NEXT:    ret <2 x i32> [[R]]
440   %t0 = icmp slt <2 x i32> %x, <i32 128, i32 64>
441   %t1 = select <2 x i1> %t0, <2 x i32> %replacement_low, <2 x i32> %replacement_high
442   %t2 = add <2 x i32> %x, <i32 16, i32 8>
443   %t3 = icmp ult <2 x i32> %t2, <i32 144, i32 264>
444   %r = select <2 x i1> %t3, <2 x i32> %x, <2 x i32> %t1
445   ret <2 x i32> %r
448 ; Non-canonical predicates
450 declare void @use2xi1(<2 x i1>)
452 declare void @use(<2 x i1>)
453 define <2 x i32> @t22_uge_slt(<2 x i32> %x, <2 x i32> %replacement_low, <2 x i32> %replacement_high) {
454 ; CHECK-LABEL: @t22_uge_slt(
455 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt <2 x i32> [[X:%.*]], <i32 128, i32 128>
456 ; CHECK-NEXT:    [[T1:%.*]] = select <2 x i1> [[T0]], <2 x i32> [[REPLACEMENT_LOW:%.*]], <2 x i32> [[REPLACEMENT_HIGH:%.*]]
457 ; CHECK-NEXT:    [[T2:%.*]] = add <2 x i32> [[X]], <i32 16, i32 16>
458 ; CHECK-NEXT:    [[T3:%.*]] = icmp uge <2 x i32> [[T2]], <i32 144, i32 0>
459 ; CHECK-NEXT:    call void @use2xi1(<2 x i1> [[T3]])
460 ; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[T3]], <2 x i32> [[T1]], <2 x i32> [[X]]
461 ; CHECK-NEXT:    ret <2 x i32> [[R]]
463   %t0 = icmp slt <2 x i32> %x, <i32 128, i32 128>
464   %t1 = select <2 x i1> %t0, <2 x i32> %replacement_low, <2 x i32> %replacement_high
465   %t2 = add <2 x i32> %x, <i32 16, i32 16>
466   %t3 = icmp uge <2 x i32> %t2, <i32 144, i32 0>
467   call void @use2xi1(<2 x i1> %t3)
468   %r = select <2 x i1> %t3, <2 x i32> %t1, <2 x i32> %x
469   ret <2 x i32> %r
472 define <2 x i32> @t23_ult_sge(<2 x i32> %x, <2 x i32> %replacement_low, <2 x i32> %replacement_high) {
473 ; CHECK-LABEL: @t23_ult_sge(
474 ; CHECK-NEXT:    [[T0:%.*]] = icmp sge <2 x i32> [[X:%.*]], <i32 128, i32 -2147483648>
475 ; CHECK-NEXT:    call void @use2xi1(<2 x i1> [[T0]])
476 ; CHECK-NEXT:    [[T1:%.*]] = select <2 x i1> [[T0]], <2 x i32> [[REPLACEMENT_HIGH:%.*]], <2 x i32> [[REPLACEMENT_LOW:%.*]]
477 ; CHECK-NEXT:    [[T2:%.*]] = add <2 x i32> [[X]], <i32 16, i32 -2147483648>
478 ; CHECK-NEXT:    [[T3:%.*]] = icmp ult <2 x i32> [[T2]], <i32 144, i32 -1>
479 ; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[T3]], <2 x i32> [[X]], <2 x i32> [[T1]]
480 ; CHECK-NEXT:    ret <2 x i32> [[R]]
482   %t0 = icmp sge <2 x i32> %x, <i32 128, i32 -2147483648>
483   call void @use2xi1(<2 x i1> %t0)
484   %t1 = select <2 x i1> %t0, <2 x i32> %replacement_high, <2 x i32> %replacement_low
485   %t2 = add <2 x i32> %x, <i32 16, i32 -2147483648>
486   %t3 = icmp ult <2 x i32> %t2, <i32 144, i32 -1>
487   %r = select <2 x i1> %t3, <2 x i32> %x, <2 x i32> %t1
488   ret <2 x i32> %r