xref: /llvm-project/llvm/test/Transforms/InstSimplify/select-abs.ll (revision bdf241cab35ee6c6c0a00e14711fb77e9ac49704)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -passes=instsimplify < %s | FileCheck %s
3
4declare <4 x i16> @llvm.abs.v4i16(<4 x i16>, i1 immarg)
5declare i32 @llvm.abs.i32(i32, i1 immarg)
6declare i64 @llvm.abs.i64(i64, i1 immarg)
7
8; check (a == 0) ? 0 : abs(a)
9
10define i32 @select_i32_eq0_abs_f(i32 %a) {
11; CHECK-LABEL: @select_i32_eq0_abs_f(
12; CHECK-NEXT:  entry:
13; CHECK-NEXT:    [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[A:%.*]], i1 false)
14; CHECK-NEXT:    ret i32 [[ABS]]
15;
16entry:
17  %cond = icmp eq i32 %a, 0
18  %abs = tail call i32 @llvm.abs.i32(i32 %a, i1 false)
19  %res = select i1 %cond, i32 0, i32 %abs
20  ret i32 %res
21}
22
23define i32 @select_i32_eq0_abs_t(i32 %a) {
24; CHECK-LABEL: @select_i32_eq0_abs_t(
25; CHECK-NEXT:  entry:
26; CHECK-NEXT:    [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[A:%.*]], i1 true)
27; CHECK-NEXT:    ret i32 [[ABS]]
28;
29entry:
30  %cond = icmp eq i32 %a, 0
31  %abs = tail call i32 @llvm.abs.i32(i32 %a, i1 true)
32  %res = select i1 %cond, i32 0, i32 %abs
33  ret i32 %res
34}
35
36; check (a == int_min) ? int_min : abs(a)
37
38define i32 @select_i32_eqINTMIN_abs_f(i32 %a) {
39; CHECK-LABEL: @select_i32_eqINTMIN_abs_f(
40; CHECK-NEXT:  entry:
41; CHECK-NEXT:    [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[A:%.*]], i1 false)
42; CHECK-NEXT:    ret i32 [[ABS]]
43;
44entry:
45  %cond = icmp eq i32 %a, -2147483648
46  %abs = tail call i32 @llvm.abs.i32(i32 %a, i1 false)
47  %res = select i1 %cond, i32 -2147483648, i32 %abs
48  ret i32 %res
49}
50
51; should not transform
52define i32 @select_i32_eqINTMIN_abs_t(i32 %a) {
53; CHECK-LABEL: @select_i32_eqINTMIN_abs_t(
54; CHECK-NEXT:  entry:
55; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[A:%.*]], -2147483648
56; CHECK-NEXT:    [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[A]], i1 true)
57; CHECK-NEXT:    [[RES:%.*]] = select i1 [[COND]], i32 -2147483648, i32 [[ABS]]
58; CHECK-NEXT:    ret i32 [[RES]]
59;
60entry:
61  %cond = icmp eq i32 %a, -2147483648
62  %abs = tail call i32 @llvm.abs.i32(i32 %a, i1 true)
63  %res = select i1 %cond, i32 -2147483648, i32 %abs
64  ret i32 %res
65}
66
67; check random values, like (a == -255) ? 255 : abs(a)
68define i32 @select_i32_eqneg255_abs_f(i32 %a) {
69; CHECK-LABEL: @select_i32_eqneg255_abs_f(
70; CHECK-NEXT:  entry:
71; CHECK-NEXT:    [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[A:%.*]], i1 false)
72; CHECK-NEXT:    ret i32 [[ABS]]
73;
74entry:
75  %cond = icmp eq i32 %a, -255
76  %abs = tail call i32 @llvm.abs.i32(i32 %a, i1 false)
77  %res = select i1 %cond, i32 255, i32 %abs
78  ret i32 %res
79}
80
81define i32 @select_i32_eqneg255_abs_t(i32 %a) {
82; CHECK-LABEL: @select_i32_eqneg255_abs_t(
83; CHECK-NEXT:  entry:
84; CHECK-NEXT:    [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[A:%.*]], i1 true)
85; CHECK-NEXT:    ret i32 [[ABS]]
86;
87entry:
88  %cond = icmp eq i32 %a, -255
89  %abs = tail call i32 @llvm.abs.i32(i32 %a, i1 true)
90  %res = select i1 %cond, i32 255, i32 %abs
91  ret i32 %res
92}
93
94define i32 @select_i32_eq65555_abs_f(i32 %a) {
95; CHECK-LABEL: @select_i32_eq65555_abs_f(
96; CHECK-NEXT:  entry:
97; CHECK-NEXT:    [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[A:%.*]], i1 false)
98; CHECK-NEXT:    ret i32 [[ABS]]
99;
100entry:
101  %cond = icmp eq i32 %a, 65555
102  %abs = tail call i32 @llvm.abs.i32(i32 %a, i1 false)
103  %res = select i1 %cond, i32 65555, i32 %abs
104  ret i32 %res
105}
106
107define i32 @select_i32_eq65555_abs_t(i32 %a) {
108; CHECK-LABEL: @select_i32_eq65555_abs_t(
109; CHECK-NEXT:  entry:
110; CHECK-NEXT:    [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[A:%.*]], i1 true)
111; CHECK-NEXT:    ret i32 [[ABS]]
112;
113entry:
114  %cond = icmp eq i32 %a, 65555
115  %abs = tail call i32 @llvm.abs.i32(i32 %a, i1 true)
116  %res = select i1 %cond, i32 65555, i32 %abs
117  ret i32 %res
118}
119
120
121; check random values, but the transform doesn't make sense, e.g.
122; (a == 255) ? -255 : abs(a)
123define i32 @bad_select_i32_eq255_abs_f(i32 %a) {
124; CHECK-LABEL: @bad_select_i32_eq255_abs_f(
125; CHECK-NEXT:  entry:
126; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[A:%.*]], 255
127; CHECK-NEXT:    [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[A]], i1 false)
128; CHECK-NEXT:    [[RES:%.*]] = select i1 [[COND]], i32 -255, i32 [[ABS]]
129; CHECK-NEXT:    ret i32 [[RES]]
130;
131entry:
132  %cond = icmp eq i32 %a, 255
133  %abs = tail call i32 @llvm.abs.i32(i32 %a, i1 false)
134  %res = select i1 %cond, i32 -255, i32 %abs
135  ret i32 %res
136}
137
138define i32 @bad_select_i32_eq255_abs_t(i32 %a) {
139; CHECK-LABEL: @bad_select_i32_eq255_abs_t(
140; CHECK-NEXT:  entry:
141; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[A:%.*]], 255
142; CHECK-NEXT:    [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[A]], i1 true)
143; CHECK-NEXT:    [[RES:%.*]] = select i1 [[COND]], i32 -255, i32 [[ABS]]
144; CHECK-NEXT:    ret i32 [[RES]]
145;
146entry:
147  %cond = icmp eq i32 %a, 255
148  %abs = tail call i32 @llvm.abs.i32(i32 %a, i1 true)
149  %res = select i1 %cond, i32 -255, i32 %abs
150  ret i32 %res
151}
152
153define i32 @bad_select_i32_eq65555_abs_f(i32 %a) {
154; CHECK-LABEL: @bad_select_i32_eq65555_abs_f(
155; CHECK-NEXT:  entry:
156; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[A:%.*]], -65555
157; CHECK-NEXT:    [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[A]], i1 false)
158; CHECK-NEXT:    [[RES:%.*]] = select i1 [[COND]], i32 65554, i32 [[ABS]]
159; CHECK-NEXT:    ret i32 [[RES]]
160;
161entry:
162  %cond = icmp eq i32 %a, -65555
163  %abs = tail call i32 @llvm.abs.i32(i32 %a, i1 false)
164  %res = select i1 %cond, i32 65554, i32 %abs
165  ret i32 %res
166}
167
168define i32 @bad_select_i32_eq65555_abs_t(i32 %a) {
169; CHECK-LABEL: @bad_select_i32_eq65555_abs_t(
170; CHECK-NEXT:  entry:
171; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[A:%.*]], -65555
172; CHECK-NEXT:    [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[A]], i1 true)
173; CHECK-NEXT:    [[RES:%.*]] = select i1 [[COND]], i32 65554, i32 [[ABS]]
174; CHECK-NEXT:    ret i32 [[RES]]
175;
176entry:
177  %cond = icmp eq i32 %a, -65555
178  %abs = tail call i32 @llvm.abs.i32(i32 %a, i1 true)
179  %res = select i1 %cond, i32 65554, i32 %abs
180  ret i32 %res
181}
182
183define i32 @select_i32_ne0_abs_f(i32 %a) {
184; CHECK-LABEL: @select_i32_ne0_abs_f(
185; CHECK-NEXT:  entry:
186; CHECK-NEXT:    [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[A:%.*]], i1 false)
187; CHECK-NEXT:    ret i32 [[ABS]]
188;
189entry:
190  %cond = icmp ne i32 %a, 0
191  %abs = tail call i32 @llvm.abs.i32(i32 %a, i1 false)
192  %res = select i1 %cond, i32 %abs, i32 0
193  ret i32 %res
194}
195
196define i32 @select_i32_ne0_abs_t(i32 %a) {
197; CHECK-LABEL: @select_i32_ne0_abs_t(
198; CHECK-NEXT:  entry:
199; CHECK-NEXT:    [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[A:%.*]], i1 true)
200; CHECK-NEXT:    ret i32 [[ABS]]
201;
202entry:
203  %cond = icmp ne i32 %a, 0
204  %abs = tail call i32 @llvm.abs.i32(i32 %a, i1 true)
205  %res = select i1 %cond, i32 %abs, i32 0
206  ret i32 %res
207}
208
209define i64 @select_i64_eq0_abs_t(i64 %a) {
210; CHECK-LABEL: @select_i64_eq0_abs_t(
211; CHECK-NEXT:  entry:
212; CHECK-NEXT:    [[ABS:%.*]] = tail call i64 @llvm.abs.i64(i64 [[A:%.*]], i1 true)
213; CHECK-NEXT:    ret i64 [[ABS]]
214;
215entry:
216  %cond = icmp eq i64 %a, 0
217  %abs = tail call i64 @llvm.abs.i64(i64 %a, i1 true)
218  %res = select i1 %cond, i64 0, i64 %abs
219  ret i64 %res
220}
221
222define i64 @select_i64_ne0_abs_t(i64 %a) {
223; CHECK-LABEL: @select_i64_ne0_abs_t(
224; CHECK-NEXT:  entry:
225; CHECK-NEXT:    [[ABS:%.*]] = tail call i64 @llvm.abs.i64(i64 [[A:%.*]], i1 true)
226; CHECK-NEXT:    ret i64 [[ABS]]
227;
228entry:
229  %cond = icmp ne i64 %a, 0
230  %abs = tail call i64 @llvm.abs.i64(i64 %a, i1 true)
231  %res = select i1 %cond, i64 %abs, i64 0
232  ret i64 %res
233}
234
235define <4 x i16> @select_v4i16_eq0_abs_t(<4 x i16> %a) {
236; CHECK-LABEL: @select_v4i16_eq0_abs_t(
237; CHECK-NEXT:  entry:
238; CHECK-NEXT:    [[ABS:%.*]] = tail call <4 x i16> @llvm.abs.v4i16(<4 x i16> [[A:%.*]], i1 true)
239; CHECK-NEXT:    ret <4 x i16> [[ABS]]
240;
241entry:
242  %cond = icmp eq <4 x i16> %a, <i16 0, i16 0, i16 0, i16 0>
243  %abs = tail call <4 x i16> @llvm.abs.v4i16(<4 x i16> %a, i1 true)
244  %res = select <4 x i1> %cond, <4 x i16>  <i16 0, i16 0, i16 0, i16 0>, <4 x i16> %abs
245  ret <4 x i16> %res
246}
247
248define <4 x i16> @select_v4i16_ne0_abs_t(<4 x i16> %a) {
249; CHECK-LABEL: @select_v4i16_ne0_abs_t(
250; CHECK-NEXT:  entry:
251; CHECK-NEXT:    [[ABS:%.*]] = tail call <4 x i16> @llvm.abs.v4i16(<4 x i16> [[A:%.*]], i1 true)
252; CHECK-NEXT:    ret <4 x i16> [[ABS]]
253;
254entry:
255  %cond = icmp ne <4 x i16> %a, <i16 0, i16 0, i16 0, i16 0>
256  %abs = tail call <4 x i16> @llvm.abs.v4i16(<4 x i16> %a, i1 true)
257  %res = select <4 x i1> %cond, <4 x i16> %abs, <4 x i16>  <i16 0, i16 0, i16 0, i16 0>
258  ret <4 x i16> %res
259}
260
261define <4 x i16> @select_v4i16_ne0_abs_t_with_undef(<4 x i16> %a) {
262; CHECK-LABEL: @select_v4i16_ne0_abs_t_with_undef(
263; CHECK-NEXT:  entry:
264; CHECK-NEXT:    [[COND:%.*]] = icmp ne <4 x i16> [[A:%.*]], zeroinitializer
265; CHECK-NEXT:    [[ABS:%.*]] = tail call <4 x i16> @llvm.abs.v4i16(<4 x i16> [[A]], i1 true)
266; CHECK-NEXT:    [[RES:%.*]] = select <4 x i1> [[COND]], <4 x i16> [[ABS]], <4 x i16> <i16 undef, i16 0, i16 0, i16 0>
267; CHECK-NEXT:    ret <4 x i16> [[RES]]
268;
269entry:
270  %cond = icmp ne <4 x i16> %a, <i16 0, i16 0, i16 0, i16 0>
271  %abs = tail call <4 x i16> @llvm.abs.v4i16(<4 x i16> %a, i1 true)
272  %res = select <4 x i1> %cond, <4 x i16> %abs, <4 x i16>  <i16 undef, i16 0, i16 0, i16 0>
273  ret <4 x i16> %res
274}
275
276define i32 @bad_select_i32_ne0_abs(i32 %a) {
277; CHECK-LABEL: @bad_select_i32_ne0_abs(
278; CHECK-NEXT:  entry:
279; CHECK-NEXT:    ret i32 0
280;
281entry:
282  %cond = icmp ne i32 %a, 0
283  %abs = tail call i32 @llvm.abs.i32(i32 %a, i1 false)
284  %res = select i1 %cond, i32 0, i32 %abs
285  ret i32 %res
286}
287
288define i32 @bad_select_i32_eq0_abs(i32 %a) {
289; CHECK-LABEL: @bad_select_i32_eq0_abs(
290; CHECK-NEXT:  entry:
291; CHECK-NEXT:    ret i32 0
292;
293entry:
294  %cond = icmp eq i32 %a, 0
295  %abs = tail call i32 @llvm.abs.i32(i32 %a, i1 false)
296  %res = select i1 %cond, i32 %abs, i32 0
297  ret i32 %res
298}
299
300define <4 x i16> @badsplat1_select_v4i16_ne0_abs(<4 x i16> %a) {
301; CHECK-LABEL: @badsplat1_select_v4i16_ne0_abs(
302; CHECK-NEXT:  entry:
303; CHECK-NEXT:    [[ABS:%.*]] = tail call <4 x i16> @llvm.abs.v4i16(<4 x i16> [[A:%.*]], i1 true)
304; CHECK-NEXT:    ret <4 x i16> [[ABS]]
305;
306entry:
307  %cond = icmp ne <4 x i16> %a, <i16 0, i16 1, i16 0, i16 0>
308  %abs = tail call <4 x i16> @llvm.abs.v4i16(<4 x i16> %a, i1 true)
309  %res = select <4 x i1> %cond, <4 x i16> %abs, <4 x i16>  <i16 0, i16 1, i16 0, i16 0>
310  ret <4 x i16> %res
311}
312
313define <4 x i16> @badsplat2_select_v4i16_ne0_abs(<4 x i16> %a) {
314; CHECK-LABEL: @badsplat2_select_v4i16_ne0_abs(
315; CHECK-NEXT:  entry:
316; CHECK-NEXT:    [[COND:%.*]] = icmp ne <4 x i16> [[A:%.*]], <i16 0, i16 undef, i16 0, i16 0>
317; CHECK-NEXT:    [[ABS:%.*]] = tail call <4 x i16> @llvm.abs.v4i16(<4 x i16> [[A]], i1 true)
318; CHECK-NEXT:    [[RES:%.*]] = select <4 x i1> [[COND]], <4 x i16> [[ABS]], <4 x i16> <i16 0, i16 1, i16 0, i16 0>
319; CHECK-NEXT:    ret <4 x i16> [[RES]]
320;
321entry:
322  %cond = icmp ne <4 x i16> %a, <i16 0, i16 undef, i16 0, i16 0>
323  %abs = tail call <4 x i16> @llvm.abs.v4i16(<4 x i16> %a, i1 true)
324  %res = select <4 x i1> %cond, <4 x i16> %abs, <4 x i16>  <i16 0, i16 1, i16 0, i16 0>
325  ret <4 x i16> %res
326}
327
328define <4 x i16> @badsplat3_select_v4i16_ne0_abs(<4 x i16> %a) {
329; CHECK-LABEL: @badsplat3_select_v4i16_ne0_abs(
330; CHECK-NEXT:  entry:
331; CHECK-NEXT:    [[COND:%.*]] = icmp ne <4 x i16> [[A:%.*]], zeroinitializer
332; CHECK-NEXT:    [[ABS:%.*]] = tail call <4 x i16> @llvm.abs.v4i16(<4 x i16> [[A]], i1 true)
333; CHECK-NEXT:    [[RES:%.*]] = select <4 x i1> [[COND]], <4 x i16> [[ABS]], <4 x i16> <i16 0, i16 1, i16 0, i16 0>
334; CHECK-NEXT:    ret <4 x i16> [[RES]]
335;
336entry:
337  %cond = icmp ne <4 x i16> %a, <i16 0, i16 0, i16 0, i16 0>
338  %abs = tail call <4 x i16> @llvm.abs.v4i16(<4 x i16> %a, i1 true)
339  %res = select <4 x i1> %cond, <4 x i16> %abs, <4 x i16>  <i16 0, i16 1, i16 0, i16 0>
340  ret <4 x i16> %res
341}
342