[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / InstCombine / canonicalize-clamp-like-pattern-between-zero-and-positive-threshold.ll
blob73ca2977e178ff4ff49be729116558315b957a7a
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 65535 (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 65536 <= Ct0 <= 0.
26 define i32 @t0_ult_slt_65536(i32 %x, i32 %replacement_low, i32 %replacement_high) {
27 ; CHECK-LABEL: @t0_ult_slt_65536(
28 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 0
29 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[X]], 65535
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, 65536
35   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
36   %t2 = icmp ult i32 %x, 65536
37   %r = select i1 %t2, i32 %x, i32 %t1
38   ret i32 %r
40 define i32 @t1_ult_slt_0(i32 %x, i32 %replacement_low, i32 %replacement_high) {
41 ; CHECK-LABEL: @t1_ult_slt_0(
42 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 0
43 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[X]], 65535
44 ; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]]
45 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP2]], i32 [[REPLACEMENT_HIGH:%.*]], i32 [[TMP3]]
46 ; CHECK-NEXT:    ret i32 [[R]]
48   %t0 = icmp slt i32 %x, 0
49   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
50   %t2 = icmp ult i32 %x, 65536
51   %r = select i1 %t2, i32 %x, i32 %t1
52   ret i32 %r
55 define i32 @t2_ult_sgt_65536(i32 %x, i32 %replacement_low, i32 %replacement_high) {
56 ; CHECK-LABEL: @t2_ult_sgt_65536(
57 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 0
58 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[X]], 65535
59 ; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]]
60 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP2]], i32 [[REPLACEMENT_HIGH:%.*]], i32 [[TMP3]]
61 ; CHECK-NEXT:    ret i32 [[R]]
63   %t0 = icmp sgt i32 %x, 65535
64   %t1 = select i1 %t0, i32 %replacement_high, i32 %replacement_low
65   %t2 = icmp ult i32 %x, 65536
66   %r = select i1 %t2, i32 %x, i32 %t1
67   ret i32 %r
69 define i32 @t3_ult_sgt_neg1(i32 %x, i32 %replacement_low, i32 %replacement_high) {
70 ; CHECK-LABEL: @t3_ult_sgt_neg1(
71 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 0
72 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[X]], 65535
73 ; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]]
74 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP2]], i32 [[REPLACEMENT_HIGH:%.*]], i32 [[TMP3]]
75 ; CHECK-NEXT:    ret i32 [[R]]
77   %t0 = icmp sgt i32 %x, -1
78   %t1 = select i1 %t0, i32 %replacement_high, i32 %replacement_low
79   %t2 = icmp ult i32 %x, 65536
80   %r = select i1 %t2, i32 %x, i32 %t1
81   ret i32 %r
84 define i32 @t4_ugt_slt_65536(i32 %x, i32 %replacement_low, i32 %replacement_high) {
85 ; CHECK-LABEL: @t4_ugt_slt_65536(
86 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 0
87 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[X]], 65535
88 ; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]]
89 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP2]], i32 [[REPLACEMENT_HIGH:%.*]], i32 [[TMP3]]
90 ; CHECK-NEXT:    ret i32 [[R]]
92   %t0 = icmp slt i32 %x, 65536
93   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
94   %t2 = icmp ugt i32 %x, 65535
95   %r = select i1 %t2, i32 %t1, i32 %x
96   ret i32 %r
98 define i32 @t5_ugt_slt_0(i32 %x, i32 %replacement_low, i32 %replacement_high) {
99 ; CHECK-LABEL: @t5_ugt_slt_0(
100 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 0
101 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[X]], 65535
102 ; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]]
103 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP2]], i32 [[REPLACEMENT_HIGH:%.*]], i32 [[TMP3]]
104 ; CHECK-NEXT:    ret i32 [[R]]
106   %t0 = icmp slt i32 %x, 0
107   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
108   %t2 = icmp ugt i32 %x, 65535
109   %r = select i1 %t2, i32 %t1, i32 %x
110   ret i32 %r
113 define i32 @t6_ugt_sgt_65536(i32 %x, i32 %replacement_low, i32 %replacement_high) {
114 ; CHECK-LABEL: @t6_ugt_sgt_65536(
115 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 0
116 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[X]], 65535
117 ; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]]
118 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP2]], i32 [[REPLACEMENT_HIGH:%.*]], i32 [[TMP3]]
119 ; CHECK-NEXT:    ret i32 [[R]]
121   %t0 = icmp sgt i32 %x, 65535
122   %t1 = select i1 %t0, i32 %replacement_high, i32 %replacement_low
123   %t2 = icmp ugt i32 %x, 65535
124   %r = select i1 %t2, i32 %t1, i32 %x
125   ret i32 %r
127 define i32 @t7_ugt_sgt_neg1(i32 %x, i32 %replacement_low, i32 %replacement_high) {
128 ; CHECK-LABEL: @t7_ugt_sgt_neg1(
129 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 0
130 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[X]], 65535
131 ; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]]
132 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP2]], i32 [[REPLACEMENT_HIGH:%.*]], i32 [[TMP3]]
133 ; CHECK-NEXT:    ret i32 [[R]]
135   %t0 = icmp sgt i32 %x, -1
136   %t1 = select i1 %t0, i32 %replacement_high, i32 %replacement_low
137   %t2 = icmp ugt i32 %x, 65535
138   %r = select i1 %t2, i32 %t1, i32 %x
139   ret i32 %r
142 ;-------------------------------------------------------------------------------
144 ; So Ct0 can not be s> 65536, or s< 0
146 define i32 @n8_ult_slt_65537(i32 %x, i32 %replacement_low, i32 %replacement_high) {
147 ; CHECK-LABEL: @n8_ult_slt_65537(
148 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 [[X:%.*]], 65537
149 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
150 ; CHECK-NEXT:    [[T2:%.*]] = icmp ult i32 [[X]], 65536
151 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[T2]], i32 [[X]], i32 [[T1]]
152 ; CHECK-NEXT:    ret i32 [[R]]
154   %t0 = icmp slt i32 %x, 65537
155   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
156   %t2 = icmp ult i32 %x, 65536
157   %r = select i1 %t2, i32 %x, i32 %t1
158   ret i32 %r
160 define i32 @n9_ult_slt_neg1(i32 %x, i32 %replacement_low, i32 %replacement_high) {
161 ; CHECK-LABEL: @n9_ult_slt_neg1(
162 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 [[X:%.*]], -1
163 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
164 ; CHECK-NEXT:    [[T2:%.*]] = icmp ult i32 [[X]], 65536
165 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[T2]], i32 [[X]], i32 [[T1]]
166 ; CHECK-NEXT:    ret i32 [[R]]
168   %t0 = icmp slt i32 %x, -1
169   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
170   %t2 = icmp ult i32 %x, 65536
171   %r = select i1 %t2, i32 %x, i32 %t1
172   ret i32 %r
175 ;-------------------------------------------------------------------------------
177 declare void @use32(i32)
178 declare void @use1(i1)
180 ; One-use restrictions: here the entire pattern needs to be one-use.
181 ; FIXME: if %t0 could be reused then it's less restrictive.
183 define i32 @n10_oneuse0(i32 %x, i32 %replacement_low, i32 %replacement_high) {
184 ; CHECK-LABEL: @n10_oneuse0(
185 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 [[X:%.*]], 32768
186 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
187 ; CHECK-NEXT:    [[T2:%.*]] = icmp ult i32 [[X]], 65536
188 ; CHECK-NEXT:    call void @use1(i1 [[T2]])
189 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[T2]], i32 [[X]], i32 [[T1]]
190 ; CHECK-NEXT:    ret i32 [[R]]
192   %t0 = icmp slt i32 %x, 32768
193   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
194   %t2 = icmp ult i32 %x, 65536
195   call void @use1(i1 %t2)
196   %r = select i1 %t2, i32 %x, i32 %t1
197   ret i32 %r
199 define i32 @n11_oneuse1(i32 %x, i32 %replacement_low, i32 %replacement_high) {
200 ; CHECK-LABEL: @n11_oneuse1(
201 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 [[X:%.*]], 32768
202 ; CHECK-NEXT:    call void @use1(i1 [[T0]])
203 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
204 ; CHECK-NEXT:    [[T2:%.*]] = icmp ult i32 [[X]], 65536
205 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[T2]], i32 [[X]], i32 [[T1]]
206 ; CHECK-NEXT:    ret i32 [[R]]
208   %t0 = icmp slt i32 %x, 32768
209   call void @use1(i1 %t0)
210   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
211   %t2 = icmp ult i32 %x, 65536
212   %r = select i1 %t2, i32 %x, i32 %t1
213   ret i32 %r
215 define i32 @n12_oneuse2(i32 %x, i32 %replacement_low, i32 %replacement_high) {
216 ; CHECK-LABEL: @n12_oneuse2(
217 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 [[X:%.*]], 32768
218 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
219 ; CHECK-NEXT:    call void @use32(i32 [[T1]])
220 ; CHECK-NEXT:    [[T2:%.*]] = icmp ult i32 [[X]], 65536
221 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[T2]], i32 [[X]], i32 [[T1]]
222 ; CHECK-NEXT:    ret i32 [[R]]
224   %t0 = icmp slt i32 %x, 32768
225   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
226   call void @use32(i32 %t1)
227   %t2 = icmp ult i32 %x, 65536
228   %r = select i1 %t2, i32 %x, i32 %t1
229   ret i32 %r
232 define i32 @n13_oneuse3(i32 %x, i32 %replacement_low, i32 %replacement_high) {
233 ; CHECK-LABEL: @n13_oneuse3(
234 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 [[X:%.*]], 32768
235 ; CHECK-NEXT:    call void @use1(i1 [[T0]])
236 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
237 ; CHECK-NEXT:    [[T2:%.*]] = icmp ult i32 [[X]], 65536
238 ; CHECK-NEXT:    call void @use1(i1 [[T2]])
239 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[T2]], i32 [[X]], i32 [[T1]]
240 ; CHECK-NEXT:    ret i32 [[R]]
242   %t0 = icmp slt i32 %x, 32768
243   call void @use1(i1 %t0)
244   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
245   %t2 = icmp ult i32 %x, 65536
246   call void @use1(i1 %t2)
247   %r = select i1 %t2, i32 %x, i32 %t1
248   ret i32 %r
250 define i32 @n14_oneuse4(i32 %x, i32 %replacement_low, i32 %replacement_high) {
251 ; CHECK-LABEL: @n14_oneuse4(
252 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 [[X:%.*]], 32768
253 ; CHECK-NEXT:    call void @use1(i1 [[T0]])
254 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
255 ; CHECK-NEXT:    call void @use32(i32 [[T1]])
256 ; CHECK-NEXT:    [[T2:%.*]] = icmp ult i32 [[X]], 65536
257 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[T2]], i32 [[X]], i32 [[T1]]
258 ; CHECK-NEXT:    ret i32 [[R]]
260   %t0 = icmp slt i32 %x, 32768
261   call void @use1(i1 %t0)
262   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
263   call void @use32(i32 %t1)
264   %t2 = icmp ult i32 %x, 65536
265   %r = select i1 %t2, i32 %x, i32 %t1
266   ret i32 %r
268 define i32 @n15_oneuse5(i32 %x, i32 %replacement_low, i32 %replacement_high) {
269 ; CHECK-LABEL: @n15_oneuse5(
270 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 [[X:%.*]], 32768
271 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
272 ; CHECK-NEXT:    call void @use32(i32 [[T1]])
273 ; CHECK-NEXT:    [[T2:%.*]] = icmp ult i32 [[X]], 65536
274 ; CHECK-NEXT:    call void @use1(i1 [[T2]])
275 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[T2]], i32 [[X]], i32 [[T1]]
276 ; CHECK-NEXT:    ret i32 [[R]]
278   %t0 = icmp slt i32 %x, 32768
279   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
280   call void @use32(i32 %t1)
281   %t2 = icmp ult i32 %x, 65536
282   call void @use1(i1 %t2)
283   %r = select i1 %t2, i32 %x, i32 %t1
284   ret i32 %r
287 define i32 @n16_oneuse6(i32 %x, i32 %replacement_low, i32 %replacement_high) {
288 ; CHECK-LABEL: @n16_oneuse6(
289 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32 [[X:%.*]], 32768
290 ; CHECK-NEXT:    call void @use1(i1 [[T0]])
291 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]]
292 ; CHECK-NEXT:    call void @use32(i32 [[T1]])
293 ; CHECK-NEXT:    [[T2:%.*]] = icmp ult i32 [[X]], 65536
294 ; CHECK-NEXT:    call void @use1(i1 [[T2]])
295 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[T2]], i32 [[X]], i32 [[T1]]
296 ; CHECK-NEXT:    ret i32 [[R]]
298   %t0 = icmp slt i32 %x, 32768
299   call void @use1(i1 %t0)
300   %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high
301   call void @use32(i32 %t1)
302   %t2 = icmp ult i32 %x, 65536
303   call void @use1(i1 %t2)
304   %r = select i1 %t2, i32 %x, i32 %t1
305   ret i32 %r
308 ;-------------------------------------------------------------------------------
310 ; Vectors
312 define <2 x i32> @t17_ult_slt_vec_splat(<2 x i32> %x, <2 x i32> %replacement_low, <2 x i32> %replacement_high) {
313 ; CHECK-LABEL: @t17_ult_slt_vec_splat(
314 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt <2 x i32> [[X:%.*]], zeroinitializer
315 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt <2 x i32> [[X]], <i32 65535, i32 65535>
316 ; CHECK-NEXT:    [[TMP3:%.*]] = select <2 x i1> [[TMP1]], <2 x i32> [[REPLACEMENT_LOW:%.*]], <2 x i32> [[X]]
317 ; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[TMP2]], <2 x i32> [[REPLACEMENT_HIGH:%.*]], <2 x i32> [[TMP3]]
318 ; CHECK-NEXT:    ret <2 x i32> [[R]]
320   %t0 = icmp slt <2 x i32> %x, <i32 65536, i32 65536>
321   %t1 = select <2 x i1> %t0, <2 x i32> %replacement_low, <2 x i32> %replacement_high
322   %t2 = icmp ult <2 x i32> %x, <i32 65536, i32 65536>
323   %r = select <2 x i1> %t2, <2 x i32> %x, <2 x i32> %t1
324   ret <2 x i32> %r
326 define <2 x i32> @t18_ult_slt_vec_nonsplat(<2 x i32> %x, <2 x i32> %replacement_low, <2 x i32> %replacement_high) {
327 ; CHECK-LABEL: @t18_ult_slt_vec_nonsplat(
328 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt <2 x i32> [[X:%.*]], zeroinitializer
329 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt <2 x i32> [[X]], <i32 65535, i32 32767>
330 ; CHECK-NEXT:    [[TMP3:%.*]] = select <2 x i1> [[TMP1]], <2 x i32> [[REPLACEMENT_LOW:%.*]], <2 x i32> [[X]]
331 ; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[TMP2]], <2 x i32> [[REPLACEMENT_HIGH:%.*]], <2 x i32> [[TMP3]]
332 ; CHECK-NEXT:    ret <2 x i32> [[R]]
334   %t0 = icmp slt <2 x i32> %x, <i32 65536, i32 32768>
335   %t1 = select <2 x i1> %t0, <2 x i32> %replacement_low, <2 x i32> %replacement_high
336   %t2 = icmp ult <2 x i32> %x, <i32 65536, i32 32768>
337   %r = select <2 x i1> %t2, <2 x i32> %x, <2 x i32> %t1
338   ret <2 x i32> %r
341 define <3 x i32> @t19_ult_slt_vec_undef0(<3 x i32> %x, <3 x i32> %replacement_low, <3 x i32> %replacement_high) {
342 ; CHECK-LABEL: @t19_ult_slt_vec_undef0(
343 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt <3 x i32> [[X:%.*]], zeroinitializer
344 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt <3 x i32> [[X]], <i32 65535, i32 65535, i32 65535>
345 ; CHECK-NEXT:    [[TMP3:%.*]] = select <3 x i1> [[TMP1]], <3 x i32> [[REPLACEMENT_LOW:%.*]], <3 x i32> [[X]]
346 ; CHECK-NEXT:    [[R:%.*]] = select <3 x i1> [[TMP2]], <3 x i32> [[REPLACEMENT_HIGH:%.*]], <3 x i32> [[TMP3]]
347 ; CHECK-NEXT:    ret <3 x i32> [[R]]
349   %t0 = icmp slt <3 x i32> %x, <i32 65536, i32 undef, i32 65536>
350   %t1 = select <3 x i1> %t0, <3 x i32> %replacement_low, <3 x i32> %replacement_high
351   %t2 = icmp ult <3 x i32> %x, <i32 65536, i32 65536, i32 65536>
352   %r = select <3 x i1> %t2, <3 x i32> %x, <3 x i32> %t1
353   ret <3 x i32> %r
355 define <3 x i32> @t20_ult_slt_vec_undef1(<3 x i32> %x, <3 x i32> %replacement_low, <3 x i32> %replacement_high) {
356 ; CHECK-LABEL: @t20_ult_slt_vec_undef1(
357 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt <3 x i32> [[X:%.*]], zeroinitializer
358 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt <3 x i32> [[X]], <i32 65535, i32 65535, i32 65535>
359 ; CHECK-NEXT:    [[TMP3:%.*]] = select <3 x i1> [[TMP1]], <3 x i32> [[REPLACEMENT_LOW:%.*]], <3 x i32> [[X]]
360 ; CHECK-NEXT:    [[R:%.*]] = select <3 x i1> [[TMP2]], <3 x i32> [[REPLACEMENT_HIGH:%.*]], <3 x i32> [[TMP3]]
361 ; CHECK-NEXT:    ret <3 x i32> [[R]]
363   %t0 = icmp slt <3 x i32> %x, <i32 65536, i32 65537, i32 65536>
364   %t1 = select <3 x i1> %t0, <3 x i32> %replacement_low, <3 x i32> %replacement_high
365   %t2 = icmp ult <3 x i32> %x, <i32 65536, i32 undef, i32 65536>
366   %r = select <3 x i1> %t2, <3 x i32> %x, <3 x i32> %t1
367   ret <3 x i32> %r
369 define <3 x i32> @t21_ult_slt_vec_undef2(<3 x i32> %x, <3 x i32> %replacement_low, <3 x i32> %replacement_high) {
370 ; CHECK-LABEL: @t21_ult_slt_vec_undef2(
371 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt <3 x i32> [[X:%.*]], zeroinitializer
372 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt <3 x i32> [[X]], <i32 65535, i32 65535, i32 65535>
373 ; CHECK-NEXT:    [[TMP3:%.*]] = select <3 x i1> [[TMP1]], <3 x i32> [[REPLACEMENT_LOW:%.*]], <3 x i32> [[X]]
374 ; CHECK-NEXT:    [[R:%.*]] = select <3 x i1> [[TMP2]], <3 x i32> [[REPLACEMENT_HIGH:%.*]], <3 x i32> [[TMP3]]
375 ; CHECK-NEXT:    ret <3 x i32> [[R]]
377   %t0 = icmp slt <3 x i32> %x, <i32 65536, i32 undef, i32 65536>
378   %t1 = select <3 x i1> %t0, <3 x i32> %replacement_low, <3 x i32> %replacement_high
379   %t2 = icmp ult <3 x i32> %x, <i32 65536, i32 undef, i32 65536>
380   %r = select <3 x i1> %t2, <3 x i32> %x, <3 x i32> %t1
381   ret <3 x i32> %r
384 ;-------------------------------------------------------------------------------
386 define i32* @t22_pointers(i32* %x, i32* %replacement_low, i32* %replacement_high) {
387 ; CHECK-LABEL: @t22_pointers(
388 ; CHECK-NEXT:    [[T0:%.*]] = icmp slt i32* [[X:%.*]], inttoptr (i64 65536 to i32*)
389 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[T0]], i32* [[REPLACEMENT_LOW:%.*]], i32* [[REPLACEMENT_HIGH:%.*]]
390 ; CHECK-NEXT:    [[T2:%.*]] = icmp ult i32* [[X]], inttoptr (i64 65536 to i32*)
391 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[T2]], i32* [[X]], i32* [[T1]]
392 ; CHECK-NEXT:    ret i32* [[R]]
394   %t0 = icmp slt i32* %x, inttoptr (i64 65536 to i32*)
395   %t1 = select i1 %t0, i32* %replacement_low, i32* %replacement_high
396   %t2 = icmp ult i32* %x, inttoptr (i64 65536 to i32*)
397   %r = select i1 %t2, i32* %x, i32* %t1
398   ret i32* %r