1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 ; If we have a relational comparison with a constant, and said comparison is
5 ; used in a select, and there is a constant in select, see if we can make
6 ; those constants match.
8 ; We can't ever get non-canonical scalar predicates.
10 ; Likewise, while we can get non-canonical vector predicates, there must be an
11 ; extra use on that `icmp`, which precludes the fold from happening.
13 ;------------------------------------------------------------------------------;
14 ; Canonical scalar predicates
15 ;------------------------------------------------------------------------------;
17 !0 = !{!"branch_weights", i32 2000, i32 1}
19 define i32 @p0_ult_65536(i32 %x, i32 %y) {
20 ; CHECK-LABEL: @p0_ult_65536(
21 ; CHECK-NEXT: [[T_INV:%.*]] = icmp ugt i32 [[X:%.*]], 65535
22 ; CHECK-NEXT: [[R:%.*]] = select i1 [[T_INV]], i32 65535, i32 [[Y:%.*]], !prof [[PROF0:![0-9]+]]
23 ; CHECK-NEXT: ret i32 [[R]]
25 %t = icmp ult i32 %x, 65536
26 %r = select i1 %t, i32 %y, i32 65535, !prof !0
29 define i32 @p1_ugt(i32 %x, i32 %y) {
30 ; CHECK-LABEL: @p1_ugt(
31 ; CHECK-NEXT: [[T_INV:%.*]] = icmp ult i32 [[X:%.*]], 65535
32 ; CHECK-NEXT: [[R:%.*]] = select i1 [[T_INV]], i32 65535, i32 [[Y:%.*]]
33 ; CHECK-NEXT: ret i32 [[R]]
35 %t = icmp ugt i32 %x, 65534
36 %r = select i1 %t, i32 %y, i32 65535
39 define i32 @p2_slt_65536(i32 %x, i32 %y) {
40 ; CHECK-LABEL: @p2_slt_65536(
41 ; CHECK-NEXT: [[T_INV:%.*]] = icmp sgt i32 [[X:%.*]], 65535
42 ; CHECK-NEXT: [[R:%.*]] = select i1 [[T_INV]], i32 65535, i32 [[Y:%.*]]
43 ; CHECK-NEXT: ret i32 [[R]]
45 %t = icmp slt i32 %x, 65536
46 %r = select i1 %t, i32 %y, i32 65535
49 define i32 @p3_sgt(i32 %x, i32 %y) {
50 ; CHECK-LABEL: @p3_sgt(
51 ; CHECK-NEXT: [[T_INV:%.*]] = icmp slt i32 [[X:%.*]], 65535
52 ; CHECK-NEXT: [[R:%.*]] = select i1 [[T_INV]], i32 65535, i32 [[Y:%.*]]
53 ; CHECK-NEXT: ret i32 [[R]]
55 %t = icmp sgt i32 %x, 65534
56 %r = select i1 %t, i32 %y, i32 65535
60 ;------------------------------------------------------------------------------;
62 ;------------------------------------------------------------------------------;
64 define <2 x i32> @p4_vec_splat_ult_65536(<2 x i32> %x, <2 x i32> %y) {
65 ; CHECK-LABEL: @p4_vec_splat_ult_65536(
66 ; CHECK-NEXT: [[T_INV:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 65535, i32 65535>
67 ; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[T_INV]], <2 x i32> <i32 65535, i32 65535>, <2 x i32> [[Y:%.*]]
68 ; CHECK-NEXT: ret <2 x i32> [[R]]
70 %t = icmp ult <2 x i32> %x, <i32 65536, i32 65536>
71 %r = select <2 x i1> %t, <2 x i32> %y, <2 x i32> <i32 65535, i32 65535>
74 define <2 x i32> @p5_vec_splat_ugt(<2 x i32> %x, <2 x i32> %y) {
75 ; CHECK-LABEL: @p5_vec_splat_ugt(
76 ; CHECK-NEXT: [[T_INV:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 65535, i32 65535>
77 ; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[T_INV]], <2 x i32> <i32 65535, i32 65535>, <2 x i32> [[Y:%.*]]
78 ; CHECK-NEXT: ret <2 x i32> [[R]]
80 %t = icmp ugt <2 x i32> %x, <i32 65534, i32 65534>
81 %r = select <2 x i1> %t, <2 x i32> %y, <2 x i32> <i32 65535, i32 65535>
84 define <2 x i32> @p6_vec_splat_slt_65536(<2 x i32> %x, <2 x i32> %y) {
85 ; CHECK-LABEL: @p6_vec_splat_slt_65536(
86 ; CHECK-NEXT: [[T_INV:%.*]] = icmp sgt <2 x i32> [[X:%.*]], <i32 65535, i32 65535>
87 ; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[T_INV]], <2 x i32> <i32 65535, i32 65535>, <2 x i32> [[Y:%.*]]
88 ; CHECK-NEXT: ret <2 x i32> [[R]]
90 %t = icmp slt <2 x i32> %x, <i32 65536, i32 65536>
91 %r = select <2 x i1> %t, <2 x i32> %y, <2 x i32> <i32 65535, i32 65535>
94 define <2 x i32> @p7_vec_splat_sgt(<2 x i32> %x, <2 x i32> %y) {
95 ; CHECK-LABEL: @p7_vec_splat_sgt(
96 ; CHECK-NEXT: [[T_INV:%.*]] = icmp slt <2 x i32> [[X:%.*]], <i32 65535, i32 65535>
97 ; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[T_INV]], <2 x i32> <i32 65535, i32 65535>, <2 x i32> [[Y:%.*]]
98 ; CHECK-NEXT: ret <2 x i32> [[R]]
100 %t = icmp sgt <2 x i32> %x, <i32 65534, i32 65534>
101 %r = select <2 x i1> %t, <2 x i32> %y, <2 x i32> <i32 65535, i32 65535>
107 define <2 x i32> @p8_vec_nonsplat_undef0(<2 x i32> %x, <2 x i32> %y) {
108 ; CHECK-LABEL: @p8_vec_nonsplat_undef0(
109 ; CHECK-NEXT: [[T_INV:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 65535, i32 65535>
110 ; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[T_INV]], <2 x i32> <i32 65535, i32 65535>, <2 x i32> [[Y:%.*]]
111 ; CHECK-NEXT: ret <2 x i32> [[R]]
113 %t = icmp ult <2 x i32> %x, <i32 65536, i32 undef>
114 %r = select <2 x i1> %t, <2 x i32> %y, <2 x i32> <i32 65535, i32 65535>
117 define <2 x i32> @p9_vec_nonsplat_undef1(<2 x i32> %x, <2 x i32> %y) {
118 ; CHECK-LABEL: @p9_vec_nonsplat_undef1(
119 ; CHECK-NEXT: [[T_INV:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 65535, i32 65535>
120 ; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[T_INV]], <2 x i32> <i32 65535, i32 undef>, <2 x i32> [[Y:%.*]]
121 ; CHECK-NEXT: ret <2 x i32> [[R]]
123 %t = icmp ult <2 x i32> %x, <i32 65536, i32 65536>
124 %r = select <2 x i1> %t, <2 x i32> %y, <2 x i32> <i32 65535, i32 undef>
127 define <2 x i32> @p10_vec_nonsplat_undef2(<2 x i32> %x, <2 x i32> %y) {
128 ; CHECK-LABEL: @p10_vec_nonsplat_undef2(
129 ; CHECK-NEXT: [[T_INV:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 65535, i32 65535>
130 ; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[T_INV]], <2 x i32> <i32 65535, i32 undef>, <2 x i32> [[Y:%.*]]
131 ; CHECK-NEXT: ret <2 x i32> [[R]]
133 %t = icmp ult <2 x i32> %x, <i32 65536, i32 undef>
134 %r = select <2 x i1> %t, <2 x i32> %y, <2 x i32> <i32 65535, i32 undef>
140 define <2 x i32> @p11_vec_nonsplat(<2 x i32> %x, <2 x i32> %y) {
141 ; CHECK-LABEL: @p11_vec_nonsplat(
142 ; CHECK-NEXT: [[T_INV:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 65535, i32 32767>
143 ; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[T_INV]], <2 x i32> <i32 65535, i32 32767>, <2 x i32> [[Y:%.*]]
144 ; CHECK-NEXT: ret <2 x i32> [[R]]
146 %t = icmp ult <2 x i32> %x, <i32 65536, i32 32768>
147 %r = select <2 x i1> %t, <2 x i32> %y, <2 x i32> <i32 65535, i32 32767>
151 ;------------------------------------------------------------------------------;
152 ; Extra uses prevent the fold.
153 ;------------------------------------------------------------------------------;
155 declare void @use1(i1)
157 define i32 @n12_extrause(i32 %x, i32 %y) {
158 ; CHECK-LABEL: @n12_extrause(
159 ; CHECK-NEXT: [[T:%.*]] = icmp ult i32 [[X:%.*]], 65536
160 ; CHECK-NEXT: call void @use1(i1 [[T]])
161 ; CHECK-NEXT: [[R:%.*]] = select i1 [[T]], i32 [[Y:%.*]], i32 65535
162 ; CHECK-NEXT: ret i32 [[R]]
164 %t = icmp ult i32 %x, 65536
165 call void @use1(i1 %t)
166 %r = select i1 %t, i32 %y, i32 65535
170 ;------------------------------------------------------------------------------;
172 ;------------------------------------------------------------------------------;
174 ; We don't care if the constant in select is true value or false value
175 define i32 @p13_commutativity0(i32 %x, i32 %y) {
176 ; CHECK-LABEL: @p13_commutativity0(
177 ; CHECK-NEXT: [[T_INV:%.*]] = icmp ugt i32 [[X:%.*]], 65535
178 ; CHECK-NEXT: [[R:%.*]] = select i1 [[T_INV]], i32 [[Y:%.*]], i32 65535
179 ; CHECK-NEXT: ret i32 [[R]]
181 %t = icmp ult i32 %x, 65536
182 %r = select i1 %t, i32 65535, i32 %y
186 ; Which means, if both possibilities are constants, we must check both of them.
187 define i32 @p14_commutativity1(i32 %x, i32 %y) {
188 ; CHECK-LABEL: @p14_commutativity1(
189 ; CHECK-NEXT: [[T_INV:%.*]] = icmp ugt i32 [[X:%.*]], 65535
190 ; CHECK-NEXT: [[R:%.*]] = select i1 [[T_INV]], i32 42, i32 65535
191 ; CHECK-NEXT: ret i32 [[R]]
193 %t = icmp ult i32 %x, 65536
194 %r = select i1 %t, i32 65535, i32 42
197 define i32 @p15_commutativity2(i32 %x, i32 %y) {
198 ; CHECK-LABEL: @p15_commutativity2(
199 ; CHECK-NEXT: [[T_INV:%.*]] = icmp ugt i32 [[X:%.*]], 65535
200 ; CHECK-NEXT: [[R:%.*]] = select i1 [[T_INV]], i32 65535, i32 42
201 ; CHECK-NEXT: ret i32 [[R]]
203 %t = icmp ult i32 %x, 65536
204 %r = select i1 %t, i32 42, i32 65535
208 ;------------------------------------------------------------------------------;
210 ;------------------------------------------------------------------------------;
212 ; For vectors, make sure we handle edge cases correctly
213 define <2 x i32> @n17_ult_zero(<2 x i32> %x, <2 x i32> %y) {
214 ; CHECK-LABEL: @n17_ult_zero(
215 ; CHECK-NEXT: [[T:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 65536, i32 0>
216 ; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[T]], <2 x i32> [[Y:%.*]], <2 x i32> <i32 65535, i32 -1>
217 ; CHECK-NEXT: ret <2 x i32> [[R]]
219 %t = icmp ult <2 x i32> %x, <i32 65536, i32 0>
220 %r = select <2 x i1> %t, <2 x i32> %y, <2 x i32> <i32 65535, i32 -1>
223 define <2 x i32> @n18_ugt_allones(<2 x i32> %x, <2 x i32> %y) {
224 ; CHECK-LABEL: @n18_ugt_allones(
225 ; CHECK-NEXT: [[T:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 65534, i32 -1>
226 ; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[T]], <2 x i32> [[Y:%.*]], <2 x i32> <i32 65535, i32 0>
227 ; CHECK-NEXT: ret <2 x i32> [[R]]
229 %t = icmp ugt <2 x i32> %x, <i32 65534, i32 -1>
230 %r = select <2 x i1> %t, <2 x i32> %y, <2 x i32> <i32 65535, i32 0>
233 define <2 x i32> @n19_slt_int_min(<2 x i32> %x, <2 x i32> %y) {
234 ; CHECK-LABEL: @n19_slt_int_min(
235 ; CHECK-NEXT: [[T:%.*]] = icmp slt <2 x i32> [[X:%.*]], <i32 65536, i32 -2147483648>
236 ; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[T]], <2 x i32> [[Y:%.*]], <2 x i32> <i32 65535, i32 2147483647>
237 ; CHECK-NEXT: ret <2 x i32> [[R]]
239 %t = icmp slt <2 x i32> %x, <i32 65536, i32 -2147483648>
240 %r = select <2 x i1> %t, <2 x i32> %y, <2 x i32> <i32 65535, i32 2147483647>
243 define <2 x i32> @n20_sgt_int_max(<2 x i32> %x, <2 x i32> %y) {
244 ; CHECK-LABEL: @n20_sgt_int_max(
245 ; CHECK-NEXT: [[T:%.*]] = icmp sgt <2 x i32> [[X:%.*]], <i32 65534, i32 2147483647>
246 ; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[T]], <2 x i32> [[Y:%.*]], <2 x i32> <i32 65535, i32 -2147483648>
247 ; CHECK-NEXT: ret <2 x i32> [[R]]
249 %t = icmp sgt <2 x i32> %x, <i32 65534, i32 2147483647>
250 %r = select <2 x i1> %t, <2 x i32> %y, <2 x i32> <i32 65535, i32 -2147483648>
254 ; We don't do anything for non-relational comparisons.
255 define i32 @n21_equality(i32 %x, i32 %y) {
256 ; CHECK-LABEL: @n21_equality(
257 ; CHECK-NEXT: [[T:%.*]] = icmp eq i32 [[X:%.*]], -2147483648
258 ; CHECK-NEXT: [[R:%.*]] = select i1 [[T]], i32 2147483647, i32 [[Y:%.*]]
259 ; CHECK-NEXT: ret i32 [[R]]
261 %t = icmp eq i32 %x, -2147483648
262 %r = select i1 %t, i32 2147483647, i32 %y
266 ; There is nothing special about sign-bit-tests, we can fold them.
267 define i32 @t22_sign_check(i32 %x, i32 %y) {
268 ; CHECK-LABEL: @t22_sign_check(
269 ; CHECK-NEXT: [[T_INV:%.*]] = icmp sgt i32 [[X:%.*]], -1
270 ; CHECK-NEXT: [[R:%.*]] = select i1 [[T_INV]], i32 [[Y:%.*]], i32 -1
271 ; CHECK-NEXT: ret i32 [[R]]
273 %t = icmp slt i32 %x, 0
274 %r = select i1 %t, i32 -1, i32 %y
277 define i32 @t22_sign_check2(i32 %x, i32 %y) {
278 ; CHECK-LABEL: @t22_sign_check2(
279 ; CHECK-NEXT: [[T_INV:%.*]] = icmp slt i32 [[X:%.*]], 0
280 ; CHECK-NEXT: [[R:%.*]] = select i1 [[T_INV]], i32 [[Y:%.*]], i32 0
281 ; CHECK-NEXT: ret i32 [[R]]
283 %t = icmp sgt i32 %x, -1
284 %r = select i1 %t, i32 0, i32 %y
288 ; If the types don't match we currently don't do anything.
289 define i32 @n23_type_mismatch(i64 %x, i32 %y) {
290 ; CHECK-LABEL: @n23_type_mismatch(
291 ; CHECK-NEXT: [[T:%.*]] = icmp ult i64 [[X:%.*]], 65536
292 ; CHECK-NEXT: [[R:%.*]] = select i1 [[T]], i32 [[Y:%.*]], i32 65535
293 ; CHECK-NEXT: ret i32 [[R]]
295 %t = icmp ult i64 %x, 65536
296 %r = select i1 %t, i32 %y, i32 65535
300 ; Don't do wrong tranform
301 define i32 @n24_ult_65534(i32 %x, i32 %y) {
302 ; CHECK-LABEL: @n24_ult_65534(
303 ; CHECK-NEXT: [[T:%.*]] = icmp ult i32 [[X:%.*]], 65534
304 ; CHECK-NEXT: [[R:%.*]] = select i1 [[T]], i32 [[Y:%.*]], i32 65535
305 ; CHECK-NEXT: ret i32 [[R]]
307 %t = icmp ult i32 %x, 65534
308 %r = select i1 %t, i32 %y, i32 65535
312 ; If we already have a match, it's good enough.
313 define i32 @n25_all_good0(i32 %x, i32 %y) {
314 ; CHECK-LABEL: @n25_all_good0(
315 ; CHECK-NEXT: [[T:%.*]] = icmp ult i32 [[X:%.*]], 65536
316 ; CHECK-NEXT: [[R:%.*]] = select i1 [[T]], i32 65535, i32 65536
317 ; CHECK-NEXT: ret i32 [[R]]
319 %t = icmp ult i32 %x, 65536
320 %r = select i1 %t, i32 65535, i32 65536
323 define i32 @n26_all_good1(i32 %x, i32 %y) {
324 ; CHECK-LABEL: @n26_all_good1(
325 ; CHECK-NEXT: [[T:%.*]] = icmp ult i32 [[X:%.*]], 65536
326 ; CHECK-NEXT: [[R:%.*]] = select i1 [[T]], i32 65536, i32 65535
327 ; CHECK-NEXT: ret i32 [[R]]
329 %t = icmp ult i32 %x, 65536
330 %r = select i1 %t, i32 65536, i32 65535
334 ; https://llvm.org/PR52684
335 ; Do not infinite loop by opposing 'ult' canonicalization.
337 define i32 @ult_inf_loop(i32 %x) {
338 ; CHECK-LABEL: @ult_inf_loop(
339 ; CHECK-NEXT: [[ADD:%.*]] = add i32 [[X:%.*]], -1
340 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD]], 2
341 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 1, i32 -3
342 ; CHECK-NEXT: ret i32 [[SEL]]
344 %add = add i32 %x, -1
345 %cmp = icmp ult i32 %add, 2
346 %sel = select i1 %cmp, i32 1, i32 -3
350 define <2 x i32> @ult_inf_loop_vec(<2 x i32> %x) {
351 ; CHECK-LABEL: @ult_inf_loop_vec(
352 ; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[X:%.*]], <i32 38, i32 38>
353 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult <2 x i32> [[TMP1]], <i32 -4, i32 -4>
354 ; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i32> <i32 -5, i32 -5>, <2 x i32> <i32 3, i32 3>
355 ; CHECK-NEXT: ret <2 x i32> [[SEL]]
357 %add = add <2 x i32> %x, <i32 42, i32 42>
358 %cmp = icmp ugt <2 x i32> %add, <i32 3, i32 3>
359 %sel = select <2 x i1> %cmp, <2 x i32> <i32 -5, i32 -5>, <2 x i32> <i32 3, i32 3>
363 ; CHECK: !0 = !{!"branch_weights", i32 1, i32 2000}