1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -passes=instsimplify < %s | FileCheck %s
4 declare <4 x i16> @llvm.abs.v4i16(<4 x i16>, i1 immarg)
5 declare i32 @llvm.abs.i32(i32, i1 immarg)
6 declare i64 @llvm.abs.i64(i64, i1 immarg)
8 ; check (a == 0) ? 0 : abs(a)
10 define i32 @select_i32_eq0_abs_f(i32 %a) {
11 ; CHECK-LABEL: @select_i32_eq0_abs_f(
13 ; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[A:%.*]], i1 false)
14 ; CHECK-NEXT: ret i32 [[ABS]]
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
23 define i32 @select_i32_eq0_abs_t(i32 %a) {
24 ; CHECK-LABEL: @select_i32_eq0_abs_t(
26 ; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[A:%.*]], i1 true)
27 ; CHECK-NEXT: ret i32 [[ABS]]
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
36 ; check (a == int_min) ? int_min : abs(a)
38 define i32 @select_i32_eqINTMIN_abs_f(i32 %a) {
39 ; CHECK-LABEL: @select_i32_eqINTMIN_abs_f(
41 ; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[A:%.*]], i1 false)
42 ; CHECK-NEXT: ret i32 [[ABS]]
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
51 ; should not transform
52 define i32 @select_i32_eqINTMIN_abs_t(i32 %a) {
53 ; CHECK-LABEL: @select_i32_eqINTMIN_abs_t(
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]]
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
67 ; check random values, like (a == -255) ? 255 : abs(a)
68 define i32 @select_i32_eqneg255_abs_f(i32 %a) {
69 ; CHECK-LABEL: @select_i32_eqneg255_abs_f(
71 ; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[A:%.*]], i1 false)
72 ; CHECK-NEXT: ret i32 [[ABS]]
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
81 define i32 @select_i32_eqneg255_abs_t(i32 %a) {
82 ; CHECK-LABEL: @select_i32_eqneg255_abs_t(
84 ; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[A:%.*]], i1 true)
85 ; CHECK-NEXT: ret i32 [[ABS]]
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
94 define i32 @select_i32_eq65555_abs_f(i32 %a) {
95 ; CHECK-LABEL: @select_i32_eq65555_abs_f(
97 ; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[A:%.*]], i1 false)
98 ; CHECK-NEXT: ret i32 [[ABS]]
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
107 define i32 @select_i32_eq65555_abs_t(i32 %a) {
108 ; CHECK-LABEL: @select_i32_eq65555_abs_t(
110 ; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[A:%.*]], i1 true)
111 ; CHECK-NEXT: ret i32 [[ABS]]
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
121 ; check random values, but the transform doesn't make sense, e.g.
122 ; (a == 255) ? -255 : abs(a)
123 define i32 @bad_select_i32_eq255_abs_f(i32 %a) {
124 ; CHECK-LABEL: @bad_select_i32_eq255_abs_f(
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]]
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
138 define i32 @bad_select_i32_eq255_abs_t(i32 %a) {
139 ; CHECK-LABEL: @bad_select_i32_eq255_abs_t(
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]]
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
153 define i32 @bad_select_i32_eq65555_abs_f(i32 %a) {
154 ; CHECK-LABEL: @bad_select_i32_eq65555_abs_f(
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]]
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
168 define i32 @bad_select_i32_eq65555_abs_t(i32 %a) {
169 ; CHECK-LABEL: @bad_select_i32_eq65555_abs_t(
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]]
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
183 define i32 @select_i32_ne0_abs_f(i32 %a) {
184 ; CHECK-LABEL: @select_i32_ne0_abs_f(
186 ; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[A:%.*]], i1 false)
187 ; CHECK-NEXT: ret i32 [[ABS]]
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
196 define i32 @select_i32_ne0_abs_t(i32 %a) {
197 ; CHECK-LABEL: @select_i32_ne0_abs_t(
199 ; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[A:%.*]], i1 true)
200 ; CHECK-NEXT: ret i32 [[ABS]]
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
209 define i64 @select_i64_eq0_abs_t(i64 %a) {
210 ; CHECK-LABEL: @select_i64_eq0_abs_t(
212 ; CHECK-NEXT: [[ABS:%.*]] = tail call i64 @llvm.abs.i64(i64 [[A:%.*]], i1 true)
213 ; CHECK-NEXT: ret i64 [[ABS]]
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
222 define i64 @select_i64_ne0_abs_t(i64 %a) {
223 ; CHECK-LABEL: @select_i64_ne0_abs_t(
225 ; CHECK-NEXT: [[ABS:%.*]] = tail call i64 @llvm.abs.i64(i64 [[A:%.*]], i1 true)
226 ; CHECK-NEXT: ret i64 [[ABS]]
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
235 ; TODO: Handle vector cases?
236 define <4 x i16> @select_v4i16_eq0_abs_t(<4 x i16> %a) {
237 ; CHECK-LABEL: @select_v4i16_eq0_abs_t(
239 ; CHECK-NEXT: [[COND:%.*]] = icmp eq <4 x i16> [[A:%.*]], zeroinitializer
240 ; CHECK-NEXT: [[ABS:%.*]] = tail call <4 x i16> @llvm.abs.v4i16(<4 x i16> [[A]], i1 true)
241 ; CHECK-NEXT: [[RES:%.*]] = select <4 x i1> [[COND]], <4 x i16> zeroinitializer, <4 x i16> [[ABS]]
242 ; CHECK-NEXT: ret <4 x i16> [[RES]]
245 %cond = icmp eq <4 x i16> %a, <i16 0, i16 0, i16 0, i16 0>
246 %abs = tail call <4 x i16> @llvm.abs.v4i16(<4 x i16> %a, i1 true)
247 %res = select <4 x i1> %cond, <4 x i16> <i16 0, i16 0, i16 0, i16 0>, <4 x i16> %abs
251 define <4 x i16> @select_v4i16_ne0_abs_t(<4 x i16> %a) {
252 ; CHECK-LABEL: @select_v4i16_ne0_abs_t(
254 ; CHECK-NEXT: [[COND:%.*]] = icmp ne <4 x i16> [[A:%.*]], zeroinitializer
255 ; CHECK-NEXT: [[ABS:%.*]] = tail call <4 x i16> @llvm.abs.v4i16(<4 x i16> [[A]], i1 true)
256 ; CHECK-NEXT: [[RES:%.*]] = select <4 x i1> [[COND]], <4 x i16> [[ABS]], <4 x i16> zeroinitializer
257 ; CHECK-NEXT: ret <4 x i16> [[RES]]
260 %cond = icmp ne <4 x i16> %a, <i16 0, i16 0, i16 0, i16 0>
261 %abs = tail call <4 x i16> @llvm.abs.v4i16(<4 x i16> %a, i1 true)
262 %res = select <4 x i1> %cond, <4 x i16> %abs, <4 x i16> <i16 0, i16 0, i16 0, i16 0>
266 define <4 x i16> @select_v4i16_ne0_abs_t_with_undef(<4 x i16> %a) {
267 ; CHECK-LABEL: @select_v4i16_ne0_abs_t_with_undef(
269 ; CHECK-NEXT: [[COND:%.*]] = icmp ne <4 x i16> [[A:%.*]], zeroinitializer
270 ; CHECK-NEXT: [[ABS:%.*]] = tail call <4 x i16> @llvm.abs.v4i16(<4 x i16> [[A]], i1 true)
271 ; CHECK-NEXT: [[RES:%.*]] = select <4 x i1> [[COND]], <4 x i16> [[ABS]], <4 x i16> <i16 undef, i16 0, i16 0, i16 0>
272 ; CHECK-NEXT: ret <4 x i16> [[RES]]
275 %cond = icmp ne <4 x i16> %a, <i16 0, i16 0, i16 0, i16 0>
276 %abs = tail call <4 x i16> @llvm.abs.v4i16(<4 x i16> %a, i1 true)
277 %res = select <4 x i1> %cond, <4 x i16> %abs, <4 x i16> <i16 undef, i16 0, i16 0, i16 0>
281 define i32 @bad_select_i32_ne0_abs(i32 %a) {
282 ; CHECK-LABEL: @bad_select_i32_ne0_abs(
284 ; CHECK-NEXT: ret i32 0
287 %cond = icmp ne i32 %a, 0
288 %abs = tail call i32 @llvm.abs.i32(i32 %a, i1 false)
289 %res = select i1 %cond, i32 0, i32 %abs
293 define i32 @bad_select_i32_eq0_abs(i32 %a) {
294 ; CHECK-LABEL: @bad_select_i32_eq0_abs(
296 ; CHECK-NEXT: ret i32 0
299 %cond = icmp eq i32 %a, 0
300 %abs = tail call i32 @llvm.abs.i32(i32 %a, i1 false)
301 %res = select i1 %cond, i32 %abs, i32 0
305 define <4 x i16> @badsplat1_select_v4i16_ne0_abs(<4 x i16> %a) {
306 ; CHECK-LABEL: @badsplat1_select_v4i16_ne0_abs(
308 ; CHECK-NEXT: [[COND:%.*]] = icmp ne <4 x i16> [[A:%.*]], <i16 0, i16 1, i16 0, i16 0>
309 ; CHECK-NEXT: [[ABS:%.*]] = tail call <4 x i16> @llvm.abs.v4i16(<4 x i16> [[A]], i1 true)
310 ; CHECK-NEXT: [[RES:%.*]] = select <4 x i1> [[COND]], <4 x i16> [[ABS]], <4 x i16> <i16 0, i16 1, i16 0, i16 0>
311 ; CHECK-NEXT: ret <4 x i16> [[RES]]
314 %cond = icmp ne <4 x i16> %a, <i16 0, i16 1, i16 0, i16 0>
315 %abs = tail call <4 x i16> @llvm.abs.v4i16(<4 x i16> %a, i1 true)
316 %res = select <4 x i1> %cond, <4 x i16> %abs, <4 x i16> <i16 0, i16 1, i16 0, i16 0>
320 define <4 x i16> @badsplat2_select_v4i16_ne0_abs(<4 x i16> %a) {
321 ; CHECK-LABEL: @badsplat2_select_v4i16_ne0_abs(
323 ; CHECK-NEXT: [[COND:%.*]] = icmp ne <4 x i16> [[A:%.*]], <i16 0, i16 undef, i16 0, i16 0>
324 ; CHECK-NEXT: [[ABS:%.*]] = tail call <4 x i16> @llvm.abs.v4i16(<4 x i16> [[A]], i1 true)
325 ; CHECK-NEXT: [[RES:%.*]] = select <4 x i1> [[COND]], <4 x i16> [[ABS]], <4 x i16> <i16 0, i16 1, i16 0, i16 0>
326 ; CHECK-NEXT: ret <4 x i16> [[RES]]
329 %cond = icmp ne <4 x i16> %a, <i16 0, i16 undef, i16 0, i16 0>
330 %abs = tail call <4 x i16> @llvm.abs.v4i16(<4 x i16> %a, i1 true)
331 %res = select <4 x i1> %cond, <4 x i16> %abs, <4 x i16> <i16 0, i16 1, i16 0, i16 0>
335 define <4 x i16> @badsplat3_select_v4i16_ne0_abs(<4 x i16> %a) {
336 ; CHECK-LABEL: @badsplat3_select_v4i16_ne0_abs(
338 ; CHECK-NEXT: [[COND:%.*]] = icmp ne <4 x i16> [[A:%.*]], zeroinitializer
339 ; CHECK-NEXT: [[ABS:%.*]] = tail call <4 x i16> @llvm.abs.v4i16(<4 x i16> [[A]], i1 true)
340 ; CHECK-NEXT: [[RES:%.*]] = select <4 x i1> [[COND]], <4 x i16> [[ABS]], <4 x i16> <i16 0, i16 1, i16 0, i16 0>
341 ; CHECK-NEXT: ret <4 x i16> [[RES]]
344 %cond = icmp ne <4 x i16> %a, <i16 0, i16 0, i16 0, i16 0>
345 %abs = tail call <4 x i16> @llvm.abs.v4i16(<4 x i16> %a, i1 true)
346 %res = select <4 x i1> %cond, <4 x i16> %abs, <4 x i16> <i16 0, i16 1, i16 0, i16 0>