[SLP] Add cost model for `llvm.powi.*` intrinsics
[llvm-project.git] / llvm / test / Transforms / InstCombine / canonicalize-clamp-like-pattern-between-negative-and-positive-thresholds.ll
blobd03e22bc4c9fbf5cec351602773b24aa870147ba
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=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:    [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], -16
29 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[X]], 127
30 ; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]]
31 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP2]], i32 [[REPLACEMENT_HIGH:%.*]], i32 [[TMP3]]
32 ; CHECK-NEXT:    ret i32 [[R]]
34   %t0 = icmp slt i32 %x, 128
35   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
36   %t2 = add i32 %x, 16
37   %t3 = icmp ult i32 %t2, 144
38   %r = select i1 %t3, i32 %x, i32 %t1
39   ret i32 %r
41 define i32 @t1_ult_slt_0(i32 %x, i32 %replacement_low, i32 %replacement_high) {
42 ; CHECK-LABEL: @t1_ult_slt_0(
43 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], -16
44 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[X]], 127
45 ; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]]
46 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP2]], i32 [[REPLACEMENT_HIGH:%.*]], i32 [[TMP3]]
47 ; CHECK-NEXT:    ret i32 [[R]]
49   %t0 = icmp slt i32 %x, -16
50   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
51   %t2 = add i32 %x, 16
52   %t3 = icmp ult i32 %t2, 144
53   %r = select i1 %t3, i32 %x, i32 %t1
54   ret i32 %r
57 define i32 @t2_ult_sgt_128(i32 %x, i32 %replacement_low, i32 %replacement_high) {
58 ; CHECK-LABEL: @t2_ult_sgt_128(
59 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], -16
60 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[X]], 127
61 ; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]]
62 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP2]], i32 [[REPLACEMENT_HIGH:%.*]], i32 [[TMP3]]
63 ; CHECK-NEXT:    ret i32 [[R]]
65   %t0 = icmp sgt i32 %x, 127
66   %t1 = select i1 %t0, i32 %replacement_high, i32 %replacement_low
67   %t2 = add i32 %x, 16
68   %t3 = icmp ult i32 %t2, 144
69   %r = select i1 %t3, i32 %x, i32 %t1
70   ret i32 %r
72 define i32 @t3_ult_sgt_neg1(i32 %x, i32 %replacement_low, i32 %replacement_high) {
73 ; CHECK-LABEL: @t3_ult_sgt_neg1(
74 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], -16
75 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[X]], 127
76 ; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]]
77 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP2]], i32 [[REPLACEMENT_HIGH:%.*]], i32 [[TMP3]]
78 ; CHECK-NEXT:    ret i32 [[R]]
80   %t0 = icmp sgt i32 %x, -17
81   %t1 = select i1 %t0, i32 %replacement_high, i32 %replacement_low
82   %t2 = add i32 %x, 16
83   %t3 = icmp ult i32 %t2, 144
84   %r = select i1 %t3, i32 %x, i32 %t1
85   ret i32 %r
88 define i32 @t4_ugt_slt_128(i32 %x, i32 %replacement_low, i32 %replacement_high) {
89 ; CHECK-LABEL: @t4_ugt_slt_128(
90 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], -16
91 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[X]], 127
92 ; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]]
93 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP2]], i32 [[REPLACEMENT_HIGH:%.*]], i32 [[TMP3]]
94 ; CHECK-NEXT:    ret i32 [[R]]
96   %t0 = icmp slt i32 %x, 128
97   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
98   %t2 = add i32 %x, 16
99   %t3 = icmp ugt i32 %t2, 143
100   %r = select i1 %t3, i32 %t1, i32 %x
101   ret i32 %r
103 define i32 @t5_ugt_slt_0(i32 %x, i32 %replacement_low, i32 %replacement_high) {
104 ; CHECK-LABEL: @t5_ugt_slt_0(
105 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], -16
106 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[X]], 127
107 ; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]]
108 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP2]], i32 [[REPLACEMENT_HIGH:%.*]], i32 [[TMP3]]
109 ; CHECK-NEXT:    ret i32 [[R]]
111   %t0 = icmp slt i32 %x, -16
112   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
113   %t2 = add i32 %x, 16
114   %t3 = icmp ugt i32 %t2, 143
115   %r = select i1 %t3, i32 %t1, i32 %x
116   ret i32 %r
119 define i32 @t6_ugt_sgt_128(i32 %x, i32 %replacement_low, i32 %replacement_high) {
120 ; CHECK-LABEL: @t6_ugt_sgt_128(
121 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], -16
122 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[X]], 127
123 ; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]]
124 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP2]], i32 [[REPLACEMENT_HIGH:%.*]], i32 [[TMP3]]
125 ; CHECK-NEXT:    ret i32 [[R]]
127   %t0 = icmp sgt i32 %x, 127
128   %t1 = select i1 %t0, i32 %replacement_high, i32 %replacement_low
129   %t2 = add i32 %x, 16
130   %t3 = icmp ugt i32 %t2, 143
131   %r = select i1 %t3, i32 %t1, i32 %x
132   ret i32 %r
135 define i32 @t7_ugt_sgt_neg1(i32 %x, i32 %replacement_low, i32 %replacement_high) {
136 ; CHECK-LABEL: @t7_ugt_sgt_neg1(
137 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], -16
138 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[X]], 127
139 ; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]]
140 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP2]], i32 [[REPLACEMENT_HIGH:%.*]], i32 [[TMP3]]
141 ; CHECK-NEXT:    ret i32 [[R]]
143   %t0 = icmp sgt i32 %x, -17
144   %t1 = select i1 %t0, i32 %replacement_high, i32 %replacement_low
145   %t2 = add i32 %x, 16
146   %t3 = icmp ugt i32 %t2, 143
147   %r = select i1 %t3, i32 %t1, i32 %x
148   ret i32 %r
151 ;-------------------------------------------------------------------------------
153 ; So Ct0 can not be s> 128, or s< -16
155 define i32 @n8_ult_slt_129(i32 %x, i32 %replacement_low, i32 %replacement_high) {
156 ; CHECK-LABEL: @n8_ult_slt_129(
157 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 [[X:%.*]], 129
158 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
159 ; CHECK-NEXT:    [[T2:%.*]] = add i32 [[X]], 16
160 ; CHECK-NEXT:    [[T3:%.*]] = icmp ult i32 [[T2]], 144
161 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[T3]], i32 [[X]], i32 [[T1]]
162 ; CHECK-NEXT:    ret i32 [[R]]
164   %t0 = icmp slt i32 %x, 129
165   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
166   %t2 = add i32 %x, 16
167   %t3 = icmp ult i32 %t2, 144
168   %r = select i1 %t3, i32 %x, i32 %t1
169   ret i32 %r
172 define i32 @n9_ult_slt_neg17(i32 %x, i32 %replacement_low, i32 %replacement_high) {
173 ; CHECK-LABEL: @n9_ult_slt_neg17(
174 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 [[X:%.*]], -17
175 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
176 ; CHECK-NEXT:    [[T2:%.*]] = add i32 [[X]], 16
177 ; CHECK-NEXT:    [[T3:%.*]] = icmp ult i32 [[T2]], 144
178 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[T3]], i32 [[X]], i32 [[T1]]
179 ; CHECK-NEXT:    ret i32 [[R]]
181   %t0 = icmp slt i32 %x, -17
182   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
183   %t2 = add i32 %x, 16
184   %t3 = icmp ult i32 %t2, 144
185   %r = select i1 %t3, i32 %x, i32 %t1
186   ret i32 %r
189 ; Regression test for PR53252.
190 define i32 @n10_ugt_slt(i32 %x, i32 %replacement_low, i32 %replacement_high) {
191 ; CHECK-LABEL: @n10_ugt_slt(
192 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 [[X:%.*]], 0
193 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
194 ; CHECK-NEXT:    [[T2:%.*]] = icmp ugt i32 [[X]], 128
195 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[T2]], i32 [[X]], i32 [[T1]]
196 ; CHECK-NEXT:    ret i32 [[R]]
198   %t0 = icmp slt i32 %x, 0
199   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
200   %t2 = icmp ugt i32 %x, 128
201   %r = select i1 %t2, i32 %x, i32 %t1
202   ret i32 %r
205 define i32 @n11_uge_slt(i32 %x, i32 %replacement_low, i32 %replacement_high) {
206 ; CHECK-LABEL: @n11_uge_slt(
207 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 [[X:%.*]], 0
208 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
209 ; CHECK-NEXT:    [[T2:%.*]] = icmp ult i32 [[X]], 129
210 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[T2]], i32 [[T1]], i32 [[X]]
211 ; CHECK-NEXT:    ret i32 [[R]]
213   %t0 = icmp slt i32 %x, 0
214   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
215   %t2 = icmp ult i32 %x, 129
216   %r = select i1 %t2, i32 %t1, i32 %x
217   ret i32 %r
220 define i32 @n12_ule_slt(i32 %x, i32 %replacement_low, i32 %replacement_high) {
221 ; CHECK-LABEL: @n12_ule_slt(
222 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 [[X:%.*]], -1
223 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
224 ; CHECK-NEXT:    [[T2:%.*]] = icmp ugt i32 [[X]], 127
225 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[T2]], i32 [[T1]], i32 [[X]]
226 ; CHECK-NEXT:    ret i32 [[R]]
228   %t0 = icmp slt i32 %x, -1
229   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
230   %t2 = icmp ugt i32 %x, 127
231   %r = select i1 %t2, i32 %t1, i32 %x
232   ret i32 %r
235 ;-------------------------------------------------------------------------------
237 declare void @use32(i32)
238 declare void @use1(i1)
240 ; One-use restrictions: here the entire pattern needs to be one-use.
241 ; FIXME: if %t0 could be reused then it's less restrictive.
243 ; This one is ok.
244 define i32 @t10_oneuse0(i32 %x, i32 %replacement_low, i32 %replacement_high) {
245 ; CHECK-LABEL: @t10_oneuse0(
246 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 [[X:%.*]], 64
247 ; CHECK-NEXT:    call void @use1(i1 [[T0]])
248 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X]], -16
249 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[X]], 127
250 ; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]]
251 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP2]], i32 [[REPLACEMENT_HIGH:%.*]], i32 [[TMP3]]
252 ; CHECK-NEXT:    ret i32 [[R]]
254   %t0 = icmp slt i32 %x, 64
255   call void @use1(i1 %t0)
256   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
257   %t2 = add i32 %x, 16
258   %t3 = icmp ult i32 %t2, 144
259   %r = select i1 %t3, i32 %x, i32 %t1
260   ret i32 %r
262 define i32 @n11_oneuse1(i32 %x, i32 %replacement_low, i32 %replacement_high) {
263 ; CHECK-LABEL: @n11_oneuse1(
264 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 [[X:%.*]], 64
265 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
266 ; CHECK-NEXT:    call void @use32(i32 [[T1]])
267 ; CHECK-NEXT:    [[T2:%.*]] = add i32 [[X]], 16
268 ; CHECK-NEXT:    [[T3:%.*]] = icmp ult i32 [[T2]], 144
269 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[T3]], i32 [[X]], i32 [[T1]]
270 ; CHECK-NEXT:    ret i32 [[R]]
272   %t0 = icmp slt i32 %x, 64
273   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
274   call void @use32(i32 %t1)
275   %t2 = add i32 %x, 16
276   %t3 = icmp ult i32 %t2, 144
277   %r = select i1 %t3, i32 %x, i32 %t1
278   ret i32 %r
281 ; This one is ok.
282 define i32 @t12_oneuse2(i32 %x, i32 %replacement_low, i32 %replacement_high) {
283 ; CHECK-LABEL: @t12_oneuse2(
284 ; CHECK-NEXT:    [[T2:%.*]] = add i32 [[X:%.*]], 16
285 ; CHECK-NEXT:    call void @use32(i32 [[T2]])
286 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X]], -16
287 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[X]], 127
288 ; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]]
289 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP2]], i32 [[REPLACEMENT_HIGH:%.*]], i32 [[TMP3]]
290 ; CHECK-NEXT:    ret i32 [[R]]
292   %t0 = icmp slt i32 %x, 64
293   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
294   %t2 = add i32 %x, 16
295   call void @use32(i32 %t2)
296   %t3 = icmp ult i32 %t2, 144
297   %r = select i1 %t3, i32 %x, i32 %t1
298   ret i32 %r
301 define i32 @n13_oneuse3(i32 %x, i32 %replacement_low, i32 %replacement_high) {
302 ; CHECK-LABEL: @n13_oneuse3(
303 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 [[X:%.*]], 64
304 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
305 ; CHECK-NEXT:    [[T2:%.*]] = add i32 [[X]], 16
306 ; CHECK-NEXT:    [[T3:%.*]] = icmp ult i32 [[T2]], 144
307 ; CHECK-NEXT:    call void @use1(i1 [[T3]])
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   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
313   %t2 = add i32 %x, 16
314   %t3 = icmp ult i32 %t2, 144
315   call void @use1(i1 %t3)
316   %r = select i1 %t3, i32 %x, i32 %t1
317   ret i32 %r
320 define i32 @n14_oneuse4(i32 %x, i32 %replacement_low, i32 %replacement_high) {
321 ; CHECK-LABEL: @n14_oneuse4(
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:    call void @use32(i32 [[T1]])
326 ; CHECK-NEXT:    [[T2:%.*]] = add i32 [[X]], 16
327 ; CHECK-NEXT:    [[T3:%.*]] = icmp ult i32 [[T2]], 144
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   call void @use32(i32 %t1)
335   %t2 = add i32 %x, 16
336   %t3 = icmp ult i32 %t2, 144
337   %r = select i1 %t3, i32 %x, i32 %t1
338   ret i32 %r
340 define i32 @n15_oneuse5(i32 %x, i32 %replacement_low, i32 %replacement_high) {
341 ; CHECK-LABEL: @n15_oneuse5(
342 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 [[X:%.*]], 64
343 ; CHECK-NEXT:    call void @use1(i1 [[T0]])
344 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
345 ; CHECK-NEXT:    [[T2:%.*]] = add i32 [[X]], 16
346 ; CHECK-NEXT:    call void @use32(i32 [[T2]])
347 ; CHECK-NEXT:    [[T3:%.*]] = icmp ult i32 [[T2]], 144
348 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[T3]], i32 [[X]], i32 [[T1]]
349 ; CHECK-NEXT:    ret i32 [[R]]
351   %t0 = icmp slt i32 %x, 64
352   call void @use1(i1 %t0)
353   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
354   %t2 = add i32 %x, 16
355   call void @use32(i32 %t2)
356   %t3 = icmp ult i32 %t2, 144
357   %r = select i1 %t3, i32 %x, i32 %t1
358   ret i32 %r
360 define i32 @n16_oneuse6(i32 %x, i32 %replacement_low, i32 %replacement_high) {
361 ; CHECK-LABEL: @n16_oneuse6(
362 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 [[X:%.*]], 64
363 ; CHECK-NEXT:    call void @use1(i1 [[T0]])
364 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
365 ; CHECK-NEXT:    [[T2:%.*]] = add i32 [[X]], 16
366 ; CHECK-NEXT:    [[T3:%.*]] = icmp ult i32 [[T2]], 144
367 ; CHECK-NEXT:    call void @use1(i1 [[T3]])
368 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[T3]], i32 [[X]], i32 [[T1]]
369 ; CHECK-NEXT:    ret i32 [[R]]
371   %t0 = icmp slt i32 %x, 64
372   call void @use1(i1 %t0)
373   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
374   %t2 = add i32 %x, 16
375   %t3 = icmp ult i32 %t2, 144
376   call void @use1(i1 %t3)
377   %r = select i1 %t3, i32 %x, i32 %t1
378   ret i32 %r
381 define i32 @n17_oneuse7(i32 %x, i32 %replacement_low, i32 %replacement_high) {
382 ; CHECK-LABEL: @n17_oneuse7(
383 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 [[X:%.*]], 64
384 ; CHECK-NEXT:    call void @use1(i1 [[T0]])
385 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
386 ; CHECK-NEXT:    call void @use32(i32 [[T1]])
387 ; CHECK-NEXT:    [[T2:%.*]] = add i32 [[X]], 16
388 ; CHECK-NEXT:    call void @use32(i32 [[T2]])
389 ; CHECK-NEXT:    [[T3:%.*]] = icmp ult i32 [[T2]], 144
390 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[T3]], i32 [[X]], i32 [[T1]]
391 ; CHECK-NEXT:    ret i32 [[R]]
393   %t0 = icmp slt i32 %x, 64
394   call void @use1(i1 %t0)
395   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
396   call void @use32(i32 %t1)
397   %t2 = add i32 %x, 16
398   call void @use32(i32 %t2)
399   %t3 = icmp ult i32 %t2, 144
400   %r = select i1 %t3, i32 %x, i32 %t1
401   ret i32 %r
403 define i32 @n18_oneuse8(i32 %x, i32 %replacement_low, i32 %replacement_high) {
404 ; CHECK-LABEL: @n18_oneuse8(
405 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 [[X:%.*]], 64
406 ; CHECK-NEXT:    call void @use1(i1 [[T0]])
407 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
408 ; CHECK-NEXT:    call void @use32(i32 [[T1]])
409 ; CHECK-NEXT:    [[T2:%.*]] = add i32 [[X]], 16
410 ; CHECK-NEXT:    [[T3:%.*]] = icmp ult i32 [[T2]], 144
411 ; CHECK-NEXT:    call void @use1(i1 [[T3]])
412 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[T3]], i32 [[X]], i32 [[T1]]
413 ; CHECK-NEXT:    ret i32 [[R]]
415   %t0 = icmp slt i32 %x, 64
416   call void @use1(i1 %t0)
417   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
418   call void @use32(i32 %t1)
419   %t2 = add i32 %x, 16
420   %t3 = icmp ult i32 %t2, 144
421   call void @use1(i1 %t3)
422   %r = select i1 %t3, i32 %x, i32 %t1
423   ret i32 %r
426 define i32 @n19_oneuse9(i32 %x, i32 %replacement_low, i32 %replacement_high) {
427 ; CHECK-LABEL: @n19_oneuse9(
428 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 [[X:%.*]], 64
429 ; CHECK-NEXT:    call void @use1(i1 [[T0]])
430 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
431 ; CHECK-NEXT:    call void @use32(i32 [[T1]])
432 ; CHECK-NEXT:    [[T2:%.*]] = add i32 [[X]], 16
433 ; CHECK-NEXT:    call void @use32(i32 [[T2]])
434 ; CHECK-NEXT:    [[T3:%.*]] = icmp ult i32 [[T2]], 144
435 ; CHECK-NEXT:    call void @use1(i1 [[T3]])
436 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[T3]], i32 [[X]], i32 [[T1]]
437 ; CHECK-NEXT:    ret i32 [[R]]
439   %t0 = icmp slt i32 %x, 64
440   call void @use1(i1 %t0)
441   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
442   call void @use32(i32 %t1)
443   %t2 = add i32 %x, 16
444   call void @use32(i32 %t2)
445   %t3 = icmp ult i32 %t2, 144
446   call void @use1(i1 %t3)
447   %r = select i1 %t3, i32 %x, i32 %t1
448   ret i32 %r
451 ;-------------------------------------------------------------------------------
453 ; Vectors
455 define <2 x i32> @t20_ult_slt_vec_splat(<2 x i32> %x, <2 x i32> %replacement_low, <2 x i32> %replacement_high) {
456 ; CHECK-LABEL: @t20_ult_slt_vec_splat(
457 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt <2 x i32> [[X:%.*]], <i32 -16, i32 -16>
458 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt <2 x i32> [[X]], <i32 127, i32 127>
459 ; CHECK-NEXT:    [[TMP3:%.*]] = select <2 x i1> [[TMP1]], <2 x i32> [[REPLACEMENT_LOW:%.*]], <2 x i32> [[X]]
460 ; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[TMP2]], <2 x i32> [[REPLACEMENT_HIGH:%.*]], <2 x i32> [[TMP3]]
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 ult <2 x i32> %t2, <i32 144, i32 144>
467   %r = select <2 x i1> %t3, <2 x i32> %x, <2 x i32> %t1
468   ret <2 x i32> %r
470 define <2 x i32> @t21_ult_slt_vec_nonsplat(<2 x i32> %x, <2 x i32> %replacement_low, <2 x i32> %replacement_high) {
471 ; CHECK-LABEL: @t21_ult_slt_vec_nonsplat(
472 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt <2 x i32> [[X:%.*]], <i32 -16, i32 -8>
473 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt <2 x i32> [[X]], <i32 127, i32 255>
474 ; CHECK-NEXT:    [[TMP3:%.*]] = select <2 x i1> [[TMP1]], <2 x i32> [[REPLACEMENT_LOW:%.*]], <2 x i32> [[X]]
475 ; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[TMP2]], <2 x i32> [[REPLACEMENT_HIGH:%.*]], <2 x i32> [[TMP3]]
476 ; CHECK-NEXT:    ret <2 x i32> [[R]]
478   %t0 = icmp slt <2 x i32> %x, <i32 128, i32 64>
479   %t1 = select <2 x i1> %t0, <2 x i32> %replacement_low, <2 x i32> %replacement_high
480   %t2 = add <2 x i32> %x, <i32 16, i32 8>
481   %t3 = icmp ult <2 x i32> %t2, <i32 144, i32 264>
482   %r = select <2 x i1> %t3, <2 x i32> %x, <2 x i32> %t1
483   ret <2 x i32> %r
486 ; Non-canonical predicates
488 declare void @use2xi1(<2 x i1>)
490 declare void @use(<2 x i1>)
491 define <2 x i32> @t22_uge_slt(<2 x i32> %x, <2 x i32> %replacement_low, <2 x i32> %replacement_high) {
492 ; CHECK-LABEL: @t22_uge_slt(
493 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt <2 x i32> [[X:%.*]], <i32 128, i32 128>
494 ; CHECK-NEXT:    [[T1:%.*]] = select <2 x i1> [[T0]], <2 x i32> [[REPLACEMENT_LOW:%.*]], <2 x i32> [[REPLACEMENT_HIGH:%.*]]
495 ; CHECK-NEXT:    [[T2:%.*]] = add <2 x i32> [[X]], <i32 16, i32 16>
496 ; CHECK-NEXT:    [[T3:%.*]] = icmp uge <2 x i32> [[T2]], <i32 144, i32 0>
497 ; CHECK-NEXT:    call void @use2xi1(<2 x i1> [[T3]])
498 ; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[T3]], <2 x i32> [[T1]], <2 x i32> [[X]]
499 ; CHECK-NEXT:    ret <2 x i32> [[R]]
501   %t0 = icmp slt <2 x i32> %x, <i32 128, i32 128>
502   %t1 = select <2 x i1> %t0, <2 x i32> %replacement_low, <2 x i32> %replacement_high
503   %t2 = add <2 x i32> %x, <i32 16, i32 16>
504   %t3 = icmp uge <2 x i32> %t2, <i32 144, i32 0>
505   call void @use2xi1(<2 x i1> %t3)
506   %r = select <2 x i1> %t3, <2 x i32> %t1, <2 x i32> %x
507   ret <2 x i32> %r
510 define <2 x i32> @t23_ult_sge(<2 x i32> %x, <2 x i32> %replacement_low, <2 x i32> %replacement_high) {
511 ; CHECK-LABEL: @t23_ult_sge(
512 ; CHECK-NEXT:    [[T0:%.*]] = icmp sge <2 x i32> [[X:%.*]], <i32 128, i32 -2147483648>
513 ; CHECK-NEXT:    call void @use2xi1(<2 x i1> [[T0]])
514 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt <2 x i32> [[X]], <i32 -16, i32 -2147483648>
515 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt <2 x i32> [[X]], <i32 127, i32 2147483646>
516 ; CHECK-NEXT:    [[TMP3:%.*]] = select <2 x i1> [[TMP1]], <2 x i32> [[REPLACEMENT_LOW:%.*]], <2 x i32> [[X]]
517 ; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[TMP2]], <2 x i32> [[REPLACEMENT_HIGH:%.*]], <2 x i32> [[TMP3]]
518 ; CHECK-NEXT:    ret <2 x i32> [[R]]
520   %t0 = icmp sge <2 x i32> %x, <i32 128, i32 -2147483648>
521   call void @use2xi1(<2 x i1> %t0)
522   %t1 = select <2 x i1> %t0, <2 x i32> %replacement_high, <2 x i32> %replacement_low
523   %t2 = add <2 x i32> %x, <i32 16, i32 -2147483648>
524   %t3 = icmp ult <2 x i32> %t2, <i32 144, i32 -1>
525   %r = select <2 x i1> %t3, <2 x i32> %x, <2 x i32> %t1
526   ret <2 x i32> %r