1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3 ; RUN: opt < %s -passes=instcombine -use-constant-fp-for-fixed-length-splat -use-constant-int-for-fixed-length-splat -S | FileCheck %s
5 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
6 target triple = "x86_64-apple-darwin10.0.0"
8 declare void @use_vec(<2 x i64>)
10 ; Bitcasts between vectors and scalars are valid.
12 define i32 @test1(i64 %a) {
13 ; CHECK-LABEL: @test1(
14 ; CHECK-NEXT: ret i32 0
16 %t1 = bitcast i64 %a to <2 x i32>
17 %t2 = bitcast i64 %a to <2 x i32>
18 %t3 = xor <2 x i32> %t1, %t2
19 %t4 = extractelement <2 x i32> %t3, i32 0
23 ; Perform the bitwise logic in the source type of the operands to eliminate bitcasts.
25 define <2 x i32> @xor_two_vector_bitcasts(<1 x i64> %a, <1 x i64> %b) {
26 ; CHECK-LABEL: @xor_two_vector_bitcasts(
27 ; CHECK-NEXT: [[T31:%.*]] = xor <1 x i64> [[A:%.*]], [[B:%.*]]
28 ; CHECK-NEXT: [[T3:%.*]] = bitcast <1 x i64> [[T31]] to <2 x i32>
29 ; CHECK-NEXT: ret <2 x i32> [[T3]]
31 %t1 = bitcast <1 x i64> %a to <2 x i32>
32 %t2 = bitcast <1 x i64> %b to <2 x i32>
33 %t3 = xor <2 x i32> %t1, %t2
37 ; No change. Bitcasts are canonicalized above bitwise logic.
39 define <2 x i32> @xor_bitcast_vec_to_vec(<1 x i64> %a) {
40 ; CHECK-LABEL: @xor_bitcast_vec_to_vec(
41 ; CHECK-NEXT: [[T1:%.*]] = bitcast <1 x i64> [[A:%.*]] to <2 x i32>
42 ; CHECK-NEXT: [[T2:%.*]] = xor <2 x i32> [[T1]], <i32 1, i32 2>
43 ; CHECK-NEXT: ret <2 x i32> [[T2]]
45 %t1 = bitcast <1 x i64> %a to <2 x i32>
46 %t2 = xor <2 x i32> <i32 1, i32 2>, %t1
50 ; No change. Bitcasts are canonicalized above bitwise logic.
52 define i64 @and_bitcast_vec_to_int(<2 x i32> %a) {
53 ; CHECK-LABEL: @and_bitcast_vec_to_int(
54 ; CHECK-NEXT: [[T1:%.*]] = bitcast <2 x i32> [[A:%.*]] to i64
55 ; CHECK-NEXT: [[T2:%.*]] = and i64 [[T1]], 3
56 ; CHECK-NEXT: ret i64 [[T2]]
58 %t1 = bitcast <2 x i32> %a to i64
63 ; No change. Bitcasts are canonicalized above bitwise logic.
65 define <2 x i32> @or_bitcast_int_to_vec(i64 %a) {
66 ; CHECK-LABEL: @or_bitcast_int_to_vec(
67 ; CHECK-NEXT: [[T1:%.*]] = bitcast i64 [[A:%.*]] to <2 x i32>
68 ; CHECK-NEXT: [[T2:%.*]] = or <2 x i32> [[T1]], <i32 1, i32 2>
69 ; CHECK-NEXT: ret <2 x i32> [[T2]]
71 %t1 = bitcast i64 %a to <2 x i32>
72 %t2 = or <2 x i32> %t1, <i32 1, i32 2>
76 ; PR26702 - https://bugs.llvm.org//show_bug.cgi?id=26702
77 ; Bitcast is canonicalized above logic, so we can see the not-not pattern.
79 define <2 x i64> @is_negative(<4 x i32> %x) {
80 ; CHECK-LABEL: @is_negative(
81 ; CHECK-NEXT: [[X_LOBIT:%.*]] = ashr <4 x i32> [[X:%.*]], splat (i32 31)
82 ; CHECK-NEXT: [[NOTNOT:%.*]] = bitcast <4 x i32> [[X_LOBIT]] to <2 x i64>
83 ; CHECK-NEXT: ret <2 x i64> [[NOTNOT]]
85 %lobit = ashr <4 x i32> %x, <i32 31, i32 31, i32 31, i32 31>
86 %not = xor <4 x i32> %lobit, <i32 -1, i32 -1, i32 -1, i32 -1>
87 %bc = bitcast <4 x i32> %not to <2 x i64>
88 %notnot = xor <2 x i64> %bc, <i64 -1, i64 -1>
92 ; This variation has an extra bitcast at the end. This means that the 2nd xor
93 ; can be done in <4 x i32> to eliminate a bitcast regardless of canonicalizaion.
95 define <4 x i32> @is_negative_bonus_bitcast(<4 x i32> %x) {
96 ; CHECK-LABEL: @is_negative_bonus_bitcast(
97 ; CHECK-NEXT: [[X_LOBIT:%.*]] = ashr <4 x i32> [[X:%.*]], splat (i32 31)
98 ; CHECK-NEXT: ret <4 x i32> [[X_LOBIT]]
100 %lobit = ashr <4 x i32> %x, <i32 31, i32 31, i32 31, i32 31>
101 %not = xor <4 x i32> %lobit, <i32 -1, i32 -1, i32 -1, i32 -1>
102 %bc = bitcast <4 x i32> %not to <2 x i64>
103 %notnot = xor <2 x i64> %bc, <i64 -1, i64 -1>
104 %bc2 = bitcast <2 x i64> %notnot to <4 x i32>
108 ; Bitcasts are canonicalized above bitwise logic.
110 define <2 x i8> @canonicalize_bitcast_logic_with_constant(<4 x i4> %x) {
111 ; CHECK-LABEL: @canonicalize_bitcast_logic_with_constant(
112 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i4> [[X:%.*]] to <2 x i8>
113 ; CHECK-NEXT: [[B:%.*]] = and <2 x i8> [[TMP1]], splat (i8 -128)
114 ; CHECK-NEXT: ret <2 x i8> [[B]]
116 %a = and <4 x i4> %x, <i4 0, i4 8, i4 0, i4 8>
117 %b = bitcast <4 x i4> %a to <2 x i8>
121 ; PR27925 - https://llvm.org/bugs/show_bug.cgi?id=27925
123 define <4 x i32> @bitcasts_and_bitcast(<4 x i32> %a, <8 x i16> %b) {
124 ; CHECK-LABEL: @bitcasts_and_bitcast(
125 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x i16> [[B:%.*]] to <4 x i32>
126 ; CHECK-NEXT: [[BC3:%.*]] = and <4 x i32> [[A:%.*]], [[TMP1]]
127 ; CHECK-NEXT: ret <4 x i32> [[BC3]]
129 %bc1 = bitcast <4 x i32> %a to <2 x i64>
130 %bc2 = bitcast <8 x i16> %b to <2 x i64>
131 %and = and <2 x i64> %bc2, %bc1
132 %bc3 = bitcast <2 x i64> %and to <4 x i32>
136 define <4 x float> @bitcasts_and_bitcast_to_fp(<4 x float> %a, <8 x i16> %b) {
137 ; CHECK-LABEL: @bitcasts_and_bitcast_to_fp(
138 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x float> [[A:%.*]] to <8 x i16>
139 ; CHECK-NEXT: [[TMP2:%.*]] = and <8 x i16> [[B:%.*]], [[TMP1]]
140 ; CHECK-NEXT: [[BC3:%.*]] = bitcast <8 x i16> [[TMP2]] to <4 x float>
141 ; CHECK-NEXT: ret <4 x float> [[BC3]]
143 %bc1 = bitcast <4 x float> %a to <2 x i64>
144 %bc2 = bitcast <8 x i16> %b to <2 x i64>
145 %and = and <2 x i64> %bc2, %bc1
146 %bc3 = bitcast <2 x i64> %and to <4 x float>
150 define <2 x double> @bitcasts_or_bitcast_to_fp(<4 x float> %a, <8 x i16> %b) {
151 ; CHECK-LABEL: @bitcasts_or_bitcast_to_fp(
152 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x float> [[A:%.*]] to <8 x i16>
153 ; CHECK-NEXT: [[TMP2:%.*]] = or <8 x i16> [[B:%.*]], [[TMP1]]
154 ; CHECK-NEXT: [[BC3:%.*]] = bitcast <8 x i16> [[TMP2]] to <2 x double>
155 ; CHECK-NEXT: ret <2 x double> [[BC3]]
157 %bc1 = bitcast <4 x float> %a to <2 x i64>
158 %bc2 = bitcast <8 x i16> %b to <2 x i64>
159 %and = or <2 x i64> %bc1, %bc2
160 %bc3 = bitcast <2 x i64> %and to <2 x double>
161 ret <2 x double> %bc3
164 define <4 x float> @bitcasts_xor_bitcast_to_fp(<2 x double> %a, <8 x i16> %b) {
165 ; CHECK-LABEL: @bitcasts_xor_bitcast_to_fp(
166 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x double> [[A:%.*]] to <8 x i16>
167 ; CHECK-NEXT: [[TMP2:%.*]] = xor <8 x i16> [[B:%.*]], [[TMP1]]
168 ; CHECK-NEXT: [[BC3:%.*]] = bitcast <8 x i16> [[TMP2]] to <4 x float>
169 ; CHECK-NEXT: ret <4 x float> [[BC3]]
171 %bc1 = bitcast <8 x i16> %b to <2 x i64>
172 %bc2 = bitcast <2 x double> %a to <2 x i64>
173 %xor = xor <2 x i64> %bc2, %bc1
174 %bc3 = bitcast <2 x i64> %xor to <4 x float>
180 define <4 x float> @bitcasts_and_bitcast_to_fp_multiuse(<4 x float> %a, <8 x i16> %b) {
181 ; CHECK-LABEL: @bitcasts_and_bitcast_to_fp_multiuse(
182 ; CHECK-NEXT: [[BC1:%.*]] = bitcast <4 x float> [[A:%.*]] to <2 x i64>
183 ; CHECK-NEXT: [[BC2:%.*]] = bitcast <8 x i16> [[B:%.*]] to <2 x i64>
184 ; CHECK-NEXT: call void @use_vec(<2 x i64> [[BC2]])
185 ; CHECK-NEXT: [[AND:%.*]] = and <2 x i64> [[BC2]], [[BC1]]
186 ; CHECK-NEXT: [[BC3:%.*]] = bitcast <2 x i64> [[AND]] to <4 x float>
187 ; CHECK-NEXT: ret <4 x float> [[BC3]]
189 %bc1 = bitcast <4 x float> %a to <2 x i64>
190 %bc2 = bitcast <8 x i16> %b to <2 x i64>
191 call void @use_vec(<2 x i64> %bc2)
192 %and = and <2 x i64> %bc2, %bc1
193 %bc3 = bitcast <2 x i64> %and to <4 x float>
197 ; FIXME: Transform limited from changing vector op to integer op to avoid codegen problems.
199 define i128 @bitcast_or_bitcast(i128 %a, <2 x i64> %b) {
200 ; CHECK-LABEL: @bitcast_or_bitcast(
201 ; CHECK-NEXT: [[BC1:%.*]] = bitcast i128 [[A:%.*]] to <2 x i64>
202 ; CHECK-NEXT: [[OR:%.*]] = or <2 x i64> [[B:%.*]], [[BC1]]
203 ; CHECK-NEXT: [[BC2:%.*]] = bitcast <2 x i64> [[OR]] to i128
204 ; CHECK-NEXT: ret i128 [[BC2]]
206 %bc1 = bitcast i128 %a to <2 x i64>
207 %or = or <2 x i64> %b, %bc1
208 %bc2 = bitcast <2 x i64> %or to i128
212 ; FIXME: Transform limited from changing integer op to vector op to avoid codegen problems.
214 define <4 x i32> @bitcast_xor_bitcast(<4 x i32> %a, i128 %b) {
215 ; CHECK-LABEL: @bitcast_xor_bitcast(
216 ; CHECK-NEXT: [[BC1:%.*]] = bitcast <4 x i32> [[A:%.*]] to i128
217 ; CHECK-NEXT: [[XOR:%.*]] = xor i128 [[B:%.*]], [[BC1]]
218 ; CHECK-NEXT: [[BC2:%.*]] = bitcast i128 [[XOR]] to <4 x i32>
219 ; CHECK-NEXT: ret <4 x i32> [[BC2]]
221 %bc1 = bitcast <4 x i32> %a to i128
222 %xor = xor i128 %bc1, %b
223 %bc2 = bitcast i128 %xor to <4 x i32>
227 ; https://llvm.org/bugs/show_bug.cgi?id=6137#c6
229 define <4 x float> @bitcast_vector_select(<4 x float> %x, <2 x i64> %y, <4 x i1> %cmp) {
230 ; CHECK-LABEL: @bitcast_vector_select(
231 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i64> [[Y:%.*]] to <4 x float>
232 ; CHECK-NEXT: [[T7:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x float> [[X:%.*]], <4 x float> [[TMP1]]
233 ; CHECK-NEXT: ret <4 x float> [[T7]]
235 %t4 = bitcast <4 x float> %x to <4 x i32>
236 %t5 = bitcast <2 x i64> %y to <4 x i32>
237 %t6 = select <4 x i1> %cmp, <4 x i32> %t4, <4 x i32> %t5
238 %t7 = bitcast <4 x i32> %t6 to <4 x float>
242 define float @bitcast_scalar_select_of_scalars(float %x, i32 %y, i1 %cmp) {
243 ; CHECK-LABEL: @bitcast_scalar_select_of_scalars(
244 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32 [[Y:%.*]] to float
245 ; CHECK-NEXT: [[T7:%.*]] = select i1 [[CMP:%.*]], float [[X:%.*]], float [[TMP1]]
246 ; CHECK-NEXT: ret float [[T7]]
248 %t4 = bitcast float %x to i32
249 %t6 = select i1 %cmp, i32 %t4, i32 %y
250 %t7 = bitcast i32 %t6 to float
254 ; FIXME: We should change the select operand types to scalars, but we need to make
255 ; sure the backend can reverse that transform if needed.
257 define float @bitcast_scalar_select_type_mismatch1(float %x, <4 x i8> %y, i1 %cmp) {
258 ; CHECK-LABEL: @bitcast_scalar_select_type_mismatch1(
259 ; CHECK-NEXT: [[T4:%.*]] = bitcast float [[X:%.*]] to <4 x i8>
260 ; CHECK-NEXT: [[T6:%.*]] = select i1 [[CMP:%.*]], <4 x i8> [[T4]], <4 x i8> [[Y:%.*]]
261 ; CHECK-NEXT: [[T7:%.*]] = bitcast <4 x i8> [[T6]] to float
262 ; CHECK-NEXT: ret float [[T7]]
264 %t4 = bitcast float %x to <4 x i8>
265 %t6 = select i1 %cmp, <4 x i8> %t4, <4 x i8> %y
266 %t7 = bitcast <4 x i8> %t6 to float
270 ; FIXME: We should change the select operand types to vectors, but we need to make
271 ; sure the backend can reverse that transform if needed.
273 define <4 x i8> @bitcast_scalar_select_type_mismatch2(<4 x i8> %x, float %y, i1 %cmp) {
274 ; CHECK-LABEL: @bitcast_scalar_select_type_mismatch2(
275 ; CHECK-NEXT: [[T4:%.*]] = bitcast <4 x i8> [[X:%.*]] to float
276 ; CHECK-NEXT: [[T6:%.*]] = select i1 [[CMP:%.*]], float [[T4]], float [[Y:%.*]]
277 ; CHECK-NEXT: [[T7:%.*]] = bitcast float [[T6]] to <4 x i8>
278 ; CHECK-NEXT: ret <4 x i8> [[T7]]
280 %t4 = bitcast <4 x i8> %x to float
281 %t6 = select i1 %cmp, float %t4, float %y
282 %t7 = bitcast float %t6 to <4 x i8>
286 define <4 x float> @bitcast_scalar_select_of_vectors(<4 x float> %x, <2 x i64> %y, i1 %cmp) {
287 ; CHECK-LABEL: @bitcast_scalar_select_of_vectors(
288 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i64> [[Y:%.*]] to <4 x float>
289 ; CHECK-NEXT: [[T7:%.*]] = select i1 [[CMP:%.*]], <4 x float> [[X:%.*]], <4 x float> [[TMP1]]
290 ; CHECK-NEXT: ret <4 x float> [[T7]]
292 %t4 = bitcast <4 x float> %x to <4 x i32>
293 %t5 = bitcast <2 x i64> %y to <4 x i32>
294 %t6 = select i1 %cmp, <4 x i32> %t4, <4 x i32> %t5
295 %t7 = bitcast <4 x i32> %t6 to <4 x float>
299 ; Can't change the type of the vector select if the dest type is scalar.
301 define float @bitcast_vector_select_no_fold1(float %x, <2 x i16> %y, <4 x i1> %cmp) {
302 ; CHECK-LABEL: @bitcast_vector_select_no_fold1(
303 ; CHECK-NEXT: [[T4:%.*]] = bitcast float [[X:%.*]] to <4 x i8>
304 ; CHECK-NEXT: [[T5:%.*]] = bitcast <2 x i16> [[Y:%.*]] to <4 x i8>
305 ; CHECK-NEXT: [[T6:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x i8> [[T4]], <4 x i8> [[T5]]
306 ; CHECK-NEXT: [[T7:%.*]] = bitcast <4 x i8> [[T6]] to float
307 ; CHECK-NEXT: ret float [[T7]]
309 %t4 = bitcast float %x to <4 x i8>
310 %t5 = bitcast <2 x i16> %y to <4 x i8>
311 %t6 = select <4 x i1> %cmp, <4 x i8> %t4, <4 x i8> %t5
312 %t7 = bitcast <4 x i8> %t6 to float
316 ; Can't change the type of the vector select if the number of elements in the dest type is not the same.
318 define <2 x float> @bitcast_vector_select_no_fold2(<2 x float> %x, <4 x i16> %y, <8 x i1> %cmp) {
319 ; CHECK-LABEL: @bitcast_vector_select_no_fold2(
320 ; CHECK-NEXT: [[T4:%.*]] = bitcast <2 x float> [[X:%.*]] to <8 x i8>
321 ; CHECK-NEXT: [[T5:%.*]] = bitcast <4 x i16> [[Y:%.*]] to <8 x i8>
322 ; CHECK-NEXT: [[T6:%.*]] = select <8 x i1> [[CMP:%.*]], <8 x i8> [[T4]], <8 x i8> [[T5]]
323 ; CHECK-NEXT: [[T7:%.*]] = bitcast <8 x i8> [[T6]] to <2 x float>
324 ; CHECK-NEXT: ret <2 x float> [[T7]]
326 %t4 = bitcast <2 x float> %x to <8 x i8>
327 %t5 = bitcast <4 x i16> %y to <8 x i8>
328 %t6 = select <8 x i1> %cmp, <8 x i8> %t4, <8 x i8> %t5
329 %t7 = bitcast <8 x i8> %t6 to <2 x float>
333 ; Optimize bitcasts that are extracting low element of vector. This happens because of SRoA.
335 define float @test2(<2 x float> %A, <2 x i32> %B) {
336 ; CHECK-LABEL: @test2(
337 ; CHECK-NEXT: [[T24:%.*]] = extractelement <2 x float> [[A:%.*]], i64 0
338 ; CHECK-NEXT: [[BC:%.*]] = bitcast <2 x i32> [[B:%.*]] to <2 x float>
339 ; CHECK-NEXT: [[T4:%.*]] = extractelement <2 x float> [[BC]], i64 0
340 ; CHECK-NEXT: [[ADD:%.*]] = fadd float [[T24]], [[T4]]
341 ; CHECK-NEXT: ret float [[ADD]]
343 %t28 = bitcast <2 x float> %A to i64
344 %t23 = trunc i64 %t28 to i32
345 %t24 = bitcast i32 %t23 to float
347 %t = bitcast <2 x i32> %B to i64
348 %t2 = trunc i64 %t to i32
349 %t4 = bitcast i32 %t2 to float
351 %add = fadd float %t24, %t4
355 ; Optimize bitcasts that are extracting other elements of a vector. This happens because of SRoA.
357 define float @test3(<2 x float> %A, <2 x i64> %B) {
358 ; CHECK-LABEL: @test3(
359 ; CHECK-NEXT: [[T24:%.*]] = extractelement <2 x float> [[A:%.*]], i64 1
360 ; CHECK-NEXT: [[BC2:%.*]] = bitcast <2 x i64> [[B:%.*]] to <4 x float>
361 ; CHECK-NEXT: [[T4:%.*]] = extractelement <4 x float> [[BC2]], i64 2
362 ; CHECK-NEXT: [[ADD:%.*]] = fadd float [[T24]], [[T4]]
363 ; CHECK-NEXT: ret float [[ADD]]
365 %t28 = bitcast <2 x float> %A to i64
366 %t29 = lshr i64 %t28, 32
367 %t23 = trunc i64 %t29 to i32
368 %t24 = bitcast i32 %t23 to float
370 %t = bitcast <2 x i64> %B to i128
371 %t1 = lshr i128 %t, 64
372 %t2 = trunc i128 %t1 to i32
373 %t4 = bitcast i32 %t2 to float
375 %add = fadd float %t24, %t4
379 ; Both bitcasts are unnecessary; change the extractelement.
381 define float @bitcast_extelt1(<2 x float> %A) {
382 ; CHECK-LABEL: @bitcast_extelt1(
383 ; CHECK-NEXT: [[BC2:%.*]] = extractelement <2 x float> [[A:%.*]], i64 0
384 ; CHECK-NEXT: ret float [[BC2]]
386 %bc1 = bitcast <2 x float> %A to <2 x i32>
387 %ext = extractelement <2 x i32> %bc1, i32 0
388 %bc2 = bitcast i32 %ext to float
392 ; Second bitcast can be folded into the first.
394 define i64 @bitcast_extelt2(<4 x float> %A) {
395 ; CHECK-LABEL: @bitcast_extelt2(
396 ; CHECK-NEXT: [[BC:%.*]] = bitcast <4 x float> [[A:%.*]] to <2 x i64>
397 ; CHECK-NEXT: [[BC2:%.*]] = extractelement <2 x i64> [[BC]], i64 1
398 ; CHECK-NEXT: ret i64 [[BC2]]
400 %bc1 = bitcast <4 x float> %A to <2 x double>
401 %ext = extractelement <2 x double> %bc1, i32 1
402 %bc2 = bitcast double %ext to i64
406 define <2 x i32> @bitcast_extelt3(<2 x i32> %A) {
407 ; CHECK-LABEL: @bitcast_extelt3(
408 ; CHECK-NEXT: ret <2 x i32> [[A:%.*]]
410 %bc1 = bitcast <2 x i32> %A to <1 x i64>
411 %ext = extractelement <1 x i64> %bc1, i32 0
412 %bc2 = bitcast i64 %ext to <2 x i32>
416 ; Handle the case where the input is not a vector.
418 define double @bitcast_extelt4(i128 %A) {
419 ; CHECK-LABEL: @bitcast_extelt4(
420 ; CHECK-NEXT: [[EXT:%.*]] = trunc i128 [[A:%.*]] to i64
421 ; CHECK-NEXT: [[BC2:%.*]] = bitcast i64 [[EXT]] to double
422 ; CHECK-NEXT: ret double [[BC2]]
424 %bc1 = bitcast i128 %A to <2 x i64>
425 %ext = extractelement <2 x i64> %bc1, i32 0
426 %bc2 = bitcast i64 %ext to double
430 define <2 x i32> @bitcast_extelt5(<1 x i64> %A) {
431 ; CHECK-LABEL: @bitcast_extelt5(
432 ; CHECK-NEXT: [[BC:%.*]] = bitcast <1 x i64> [[A:%.*]] to <2 x i32>
433 ; CHECK-NEXT: ret <2 x i32> [[BC]]
435 %ext = extractelement <1 x i64> %A, i32 0
436 %bc = bitcast i64 %ext to <2 x i32>
440 define <2 x i32> @bitcast_extelt5_scalable(<vscale x 1 x i64> %A) {
441 ; CHECK-LABEL: @bitcast_extelt5_scalable(
442 ; CHECK-NEXT: [[EXT:%.*]] = extractelement <vscale x 1 x i64> [[A:%.*]], i64 0
443 ; CHECK-NEXT: [[BC:%.*]] = bitcast i64 [[EXT]] to <2 x i32>
444 ; CHECK-NEXT: ret <2 x i32> [[BC]]
446 %ext = extractelement <vscale x 1 x i64> %A, i32 0
447 %bc = bitcast i64 %ext to <2 x i32>
451 define <2 x i32> @bitcast_extelt6(<2 x i64> %A) {
452 ; CHECK-LABEL: @bitcast_extelt6(
453 ; CHECK-NEXT: [[EXT:%.*]] = extractelement <2 x i64> [[A:%.*]], i64 0
454 ; CHECK-NEXT: [[BC:%.*]] = bitcast i64 [[EXT]] to <2 x i32>
455 ; CHECK-NEXT: ret <2 x i32> [[BC]]
457 %ext = extractelement <2 x i64> %A, i32 0
458 %bc = bitcast i64 %ext to <2 x i32>
462 define double @bitcast_extelt7(<1 x i64> %A) {
463 ; CHECK-LABEL: @bitcast_extelt7(
464 ; CHECK-NEXT: [[BC1:%.*]] = bitcast <1 x i64> [[A:%.*]] to <1 x double>
465 ; CHECK-NEXT: [[BC:%.*]] = extractelement <1 x double> [[BC1]], i64 0
466 ; CHECK-NEXT: ret double [[BC]]
468 %ext = extractelement <1 x i64> %A, i32 0
469 %bc = bitcast i64 %ext to double
473 define double @bitcast_extelt8(<1 x i64> %A) {
474 ; CHECK-LABEL: @bitcast_extelt8(
475 ; CHECK-NEXT: [[BC1:%.*]] = bitcast <1 x i64> [[A:%.*]] to <1 x double>
476 ; CHECK-NEXT: [[BC:%.*]] = extractelement <1 x double> [[BC1]], i64 0
477 ; CHECK-NEXT: ret double [[BC]]
479 %bc = bitcast <1 x i64> %A to double
483 define <2 x i32> @test4(i32 %A, i32 %B){
484 ; CHECK-LABEL: @test4(
485 ; CHECK-NEXT: [[TMP1:%.*]] = insertelement <2 x i32> poison, i32 [[A:%.*]], i64 0
486 ; CHECK-NEXT: [[T43:%.*]] = insertelement <2 x i32> [[TMP1]], i32 [[B:%.*]], i64 1
487 ; CHECK-NEXT: ret <2 x i32> [[T43]]
489 %t38 = zext i32 %A to i64
490 %t32 = zext i32 %B to i64
491 %t33 = shl i64 %t32, 32
492 %ins35 = or i64 %t33, %t38
493 %t43 = bitcast i64 %ins35 to <2 x i32>
498 define <2 x float> @test5(float %A, float %B) {
499 ; CHECK-LABEL: @test5(
500 ; CHECK-NEXT: [[TMP1:%.*]] = insertelement <2 x float> poison, float [[A:%.*]], i64 0
501 ; CHECK-NEXT: [[T43:%.*]] = insertelement <2 x float> [[TMP1]], float [[B:%.*]], i64 1
502 ; CHECK-NEXT: ret <2 x float> [[T43]]
504 %t37 = bitcast float %A to i32
505 %t38 = zext i32 %t37 to i64
506 %t31 = bitcast float %B to i32
507 %t32 = zext i32 %t31 to i64
508 %t33 = shl i64 %t32, 32
509 %ins35 = or i64 %t33, %t38
510 %t43 = bitcast i64 %ins35 to <2 x float>
514 define <2 x float> @test6(float %A){
515 ; CHECK-LABEL: @test6(
516 ; CHECK-NEXT: [[T35:%.*]] = insertelement <2 x float> <float 4.200000e+01, float poison>, float [[A:%.*]], i64 1
517 ; CHECK-NEXT: ret <2 x float> [[T35]]
519 %t23 = bitcast float %A to i32
520 %t24 = zext i32 %t23 to i64
521 %t25 = shl i64 %t24, 32
522 %mask20 = or i64 %t25, 1109917696
523 %t35 = bitcast i64 %mask20 to <2 x float>
527 ; This test should not be optimized by OptimizeIntegerToVectorInsertions.
528 ; The bitcast from vector previously confused it.
529 define <2 x i64> @int2vec_insertion_bitcast_from_vec(i64 %x) {
530 ; CHECK-LABEL: @int2vec_insertion_bitcast_from_vec(
531 ; CHECK-NEXT: [[A:%.*]] = bitcast i64 [[X:%.*]] to <8 x i8>
532 ; CHECK-NEXT: [[B:%.*]] = zext <8 x i8> [[A]] to <8 x i16>
533 ; CHECK-NEXT: [[D:%.*]] = bitcast <8 x i16> [[B]] to <2 x i64>
534 ; CHECK-NEXT: ret <2 x i64> [[D]]
536 %a = bitcast i64 %x to <8 x i8>
537 %b = zext <8 x i8> %a to <8 x i16>
538 %c = bitcast <8 x i16> %b to i128
539 %d = bitcast i128 %c to <2 x i64>
543 define i64 @ISPC0(i64 %in) {
544 ; CHECK-LABEL: @ISPC0(
545 ; CHECK-NEXT: ret i64 0
547 %out = and i64 %in, xor (i64 bitcast (<4 x i16> <i16 -1, i16 -1, i16 -1, i16 -1> to i64), i64 -1)
552 define i64 @Vec2(i64 %in) {
553 ; CHECK-LABEL: @Vec2(
554 ; CHECK-NEXT: ret i64 0
556 %out = and i64 %in, xor (i64 bitcast (<4 x i16> <i16 0, i16 0, i16 0, i16 0> to i64), i64 0)
560 define i64 @All11(i64 %in) {
561 ; CHECK-LABEL: @All11(
562 ; CHECK-NEXT: ret i64 0
564 %out = and i64 %in, xor (i64 bitcast (<2 x float> bitcast (i64 -1 to <2 x float>) to i64), i64 -1)
569 define i32 @All111(i32 %in) {
570 ; CHECK-LABEL: @All111(
571 ; CHECK-NEXT: ret i32 0
573 %out = and i32 %in, xor (i32 bitcast (<1 x float> bitcast (i32 -1 to <1 x float>) to i32), i32 -1)
577 define <vscale x 1 x i32> @ScalableAll111(<vscale x 1 x i32> %in) {
578 ; CHECK-LABEL: @ScalableAll111(
579 ; CHECK-NEXT: ret <vscale x 1 x i32> [[IN:%.*]]
581 %out = and <vscale x 1 x i32> %in, bitcast (<vscale x 2 x i16> splat (i16 -1) to <vscale x 1 x i32>)
582 ret <vscale x 1 x i32> %out
585 define <2 x i16> @BitcastInsert(i32 %a) {
586 ; CHECK-LABEL: @BitcastInsert(
587 ; CHECK-NEXT: [[R:%.*]] = bitcast i32 [[A:%.*]] to <2 x i16>
588 ; CHECK-NEXT: ret <2 x i16> [[R]]
590 %v = insertelement <1 x i32> undef, i32 %a, i32 0
591 %r = bitcast <1 x i32> %v to <2 x i16>
596 define <2 x i64> @test7(ptr %arg) nounwind {
597 ; CHECK-LABEL: @test7(
598 ; CHECK-NEXT: [[LOAD:%.*]] = load <2 x i64>, ptr [[ARG:%.*]], align 16
599 ; CHECK-NEXT: ret <2 x i64> [[LOAD]]
601 %load = load <2 x i64>, ptr %arg, align 16
606 ; CHECK-LABEL: @test8(
607 ; CHECK-NEXT: ret i8 -85
609 %res = bitcast <8 x i1> <i1 true, i1 true, i1 false, i1 true, i1 false, i1 true, i1 false, i1 true> to i8
613 @g = internal unnamed_addr global i32 undef
615 define void @constant_fold_vector_to_double() {
616 ; CHECK-LABEL: @constant_fold_vector_to_double(
617 ; CHECK-NEXT: store volatile double 1.000000e+00, ptr undef, align 8
618 ; CHECK-NEXT: store volatile double 1.000000e+00, ptr undef, align 8
619 ; CHECK-NEXT: store volatile double 1.000000e+00, ptr undef, align 8
620 ; CHECK-NEXT: store volatile double 1.000000e+00, ptr undef, align 8
621 ; CHECK-NEXT: store volatile double 0xFFFFFFFFFFFFFFFF, ptr undef, align 8
622 ; CHECK-NEXT: store volatile double 0x162E000004D2, ptr undef, align 8
623 ; CHECK-NEXT: store volatile double bitcast (<2 x i32> <i32 1234, i32 ptrtoint (ptr @g to i32)> to double), ptr undef, align 8
624 ; CHECK-NEXT: store volatile double 0x400000003F800000, ptr undef, align 8
625 ; CHECK-NEXT: store volatile double 0.000000e+00, ptr undef, align 8
626 ; CHECK-NEXT: store volatile double 0.000000e+00, ptr undef, align 8
627 ; CHECK-NEXT: store volatile double 0.000000e+00, ptr undef, align 8
628 ; CHECK-NEXT: store volatile double 0.000000e+00, ptr undef, align 8
629 ; CHECK-NEXT: store volatile double 0.000000e+00, ptr undef, align 8
630 ; CHECK-NEXT: store volatile double 0.000000e+00, ptr undef, align 8
631 ; CHECK-NEXT: ret void
633 store volatile double bitcast (<1 x i64> <i64 4607182418800017408> to double), ptr undef
634 store volatile double bitcast (<2 x i32> <i32 0, i32 1072693248> to double), ptr undef
635 store volatile double bitcast (<4 x i16> <i16 0, i16 0, i16 0, i16 16368> to double), ptr undef
636 store volatile double bitcast (<8 x i8> <i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 240, i8 63> to double), ptr undef
638 store volatile double bitcast (<2 x i32> <i32 -1, i32 -1> to double), ptr undef
639 store volatile double bitcast (<2 x i32> <i32 1234, i32 5678> to double), ptr undef
641 store volatile double bitcast (<2 x i32> <i32 1234, i32 ptrtoint (ptr @g to i32)> to double), ptr undef
642 store volatile double bitcast (<2 x float> <float 1.0, float 2.0> to double), ptr undef
644 store volatile double bitcast (<2 x i32> zeroinitializer to double), ptr undef
645 store volatile double bitcast (<4 x i16> zeroinitializer to double), ptr undef
646 store volatile double bitcast (<8 x i8> zeroinitializer to double), ptr undef
647 store volatile double bitcast (<16 x i4> zeroinitializer to double), ptr undef
648 store volatile double bitcast (<32 x i2> zeroinitializer to double), ptr undef
649 store volatile double bitcast (<64 x i1> zeroinitializer to double), ptr undef
653 define void @constant_fold_vector_to_float() {
654 ; CHECK-LABEL: @constant_fold_vector_to_float(
655 ; CHECK-NEXT: store volatile float 1.000000e+00, ptr undef, align 4
656 ; CHECK-NEXT: store volatile float 1.000000e+00, ptr undef, align 4
657 ; CHECK-NEXT: store volatile float 1.000000e+00, ptr undef, align 4
658 ; CHECK-NEXT: store volatile float 1.000000e+00, ptr undef, align 4
659 ; CHECK-NEXT: ret void
661 store volatile float bitcast (<1 x i32> <i32 1065353216> to float), ptr undef
662 store volatile float bitcast (<2 x i16> <i16 0, i16 16256> to float), ptr undef
663 store volatile float bitcast (<4 x i8> <i8 0, i8 0, i8 128, i8 63> to float), ptr undef
664 store volatile float bitcast (<32 x i1> <i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 1, i1 1, i1 1, i1 1, i1 1, i1 1, i1 1, i1 0, i1 0> to float), ptr undef
669 define void @constant_fold_vector_to_half() {
670 ; CHECK-LABEL: @constant_fold_vector_to_half(
671 ; CHECK-NEXT: store volatile half 0xH4000, ptr undef, align 2
672 ; CHECK-NEXT: store volatile half 0xH4000, ptr undef, align 2
673 ; CHECK-NEXT: ret void
675 store volatile half bitcast (<2 x i8> <i8 0, i8 64> to half), ptr undef
676 store volatile half bitcast (<4 x i4> <i4 0, i4 0, i4 0, i4 4> to half), ptr undef
680 ; Ensure that we do not crash when looking at such a weird bitcast.
681 define ptr @bitcast_from_single_element_pointer_vector_to_pointer(<1 x ptr> %ptrvec) {
682 ; CHECK-LABEL: @bitcast_from_single_element_pointer_vector_to_pointer(
683 ; CHECK-NEXT: [[TMP1:%.*]] = extractelement <1 x ptr> [[PTRVEC:%.*]], i64 0
684 ; CHECK-NEXT: ret ptr [[TMP1]]
686 %ptr = bitcast <1 x ptr> %ptrvec to ptr
690 ; Sure that we calculate the correct shift.
691 define <4 x i32> @bitcast_shl(i32 %arg) {
692 ; CHECK-LABEL: @bitcast_shl(
693 ; CHECK-NEXT: [[I5:%.*]] = insertelement <4 x i32> <i32 0, i32 0, i32 65, i32 poison>, i32 [[ARG:%.*]], i64 3
694 ; CHECK-NEXT: ret <4 x i32> [[I5]]
696 %i = zext i32 %arg to i64
699 %i3 = zext i64 %i2 to i128
700 %i4 = shl i128 %i3, 64
701 %i5 = bitcast i128 %i4 to <4 x i32>
707 define ptr @select_bitcast_unsized_pointer(i1 %c) {
708 ; CHECK-LABEL: @select_bitcast_unsized_pointer(
709 ; CHECK-NEXT: [[S:%.*]] = select i1 [[C:%.*]], ptr @f1, ptr @f2
710 ; CHECK-NEXT: ret ptr [[S]]
712 %s = select i1 %c, ptr @f1, ptr @f2
716 define float @copysign_idiom_constant(float %x) {
717 ; CHECK-LABEL: @copysign_idiom_constant(
718 ; CHECK-NEXT: [[Y:%.*]] = call float @llvm.copysign.f32(float 1.000000e+00, float [[X:%.*]])
719 ; CHECK-NEXT: ret float [[Y]]
721 %bits = bitcast float %x to i32
722 %sign = and i32 %bits, -2147483648
723 %res = or i32 %sign, 1065353216
724 %y = bitcast i32 %res to float
728 define float @copysign_idiom(float %x, i32 %mag) {
729 ; CHECK-LABEL: @copysign_idiom(
730 ; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[MAG:%.*]], -1
731 ; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
732 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32 [[MAG]] to float
733 ; CHECK-NEXT: [[Y:%.*]] = call float @llvm.copysign.f32(float [[TMP1]], float [[X:%.*]])
734 ; CHECK-NEXT: ret float [[Y]]
736 %cond = icmp sgt i32 %mag, -1
737 call void @llvm.assume(i1 %cond)
739 %bits = bitcast float %x to i32
740 %sign = and i32 %bits, -2147483648
741 %res = or i32 %sign, %mag
742 %y = bitcast i32 %res to float
746 define float @copysign_idiom_commuted(float %x, i32 %magx) {
747 ; CHECK-LABEL: @copysign_idiom_commuted(
748 ; CHECK-NEXT: [[MAG:%.*]] = add i32 [[MAGX:%.*]], -1
749 ; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[MAG]], -1
750 ; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
751 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32 [[MAG]] to float
752 ; CHECK-NEXT: [[Y:%.*]] = call float @llvm.copysign.f32(float [[TMP1]], float [[X:%.*]])
753 ; CHECK-NEXT: ret float [[Y]]
755 %mag = add i32 %magx, -1 ; thwart complexity-based canonicalization
756 %cond = icmp sgt i32 %mag, -1
757 call void @llvm.assume(i1 %cond)
759 %bits = bitcast float %x to i32
760 %sign = and i32 %bits, -2147483648
761 %res = or i32 %mag, %sign
762 %y = bitcast i32 %res to float
766 define float @copysign_idiom_abs(float %x, float %mag) {
767 ; CHECK-LABEL: @copysign_idiom_abs(
768 ; CHECK-NEXT: [[Y:%.*]] = call float @llvm.copysign.f32(float [[MAG:%.*]], float [[X:%.*]])
769 ; CHECK-NEXT: ret float [[Y]]
771 %abs = call float @llvm.fabs.f32(float %mag)
772 %absbits = bitcast float %abs to i32
773 %bits = bitcast float %x to i32
774 %sign = and i32 %bits, -2147483648
775 %res = or i32 %sign, %absbits
776 %y = bitcast i32 %res to float
780 define double @copysign_idiom_f64(double %x, i64 %mag) {
781 ; CHECK-LABEL: @copysign_idiom_f64(
782 ; CHECK-NEXT: [[COND:%.*]] = icmp sgt i64 [[MAG:%.*]], -1
783 ; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
784 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast i64 [[MAG]] to double
785 ; CHECK-NEXT: [[Y:%.*]] = call double @llvm.copysign.f64(double [[TMP1]], double [[X:%.*]])
786 ; CHECK-NEXT: ret double [[Y]]
788 %cond = icmp sgt i64 %mag, -1
789 call void @llvm.assume(i1 %cond)
791 %bits = bitcast double %x to i64
792 %sign = and i64 %bits, -9223372036854775808
793 %res = or i64 %sign, %mag
794 %y = bitcast i64 %res to double
798 define <2 x float> @copysign_idiom_vec(<2 x float> %x) {
799 ; CHECK-LABEL: @copysign_idiom_vec(
800 ; CHECK-NEXT: [[Y:%.*]] = call <2 x float> @llvm.copysign.v2f32(<2 x float> splat (float 1.000000e+00), <2 x float> [[X:%.*]])
801 ; CHECK-NEXT: ret <2 x float> [[Y]]
803 %bits = bitcast <2 x float> %x to <2 x i32>
804 %sign = and <2 x i32> %bits, splat(i32 -2147483648)
805 %res = or <2 x i32> %sign, splat(i32 1065353216)
806 %y = bitcast <2 x i32> %res to <2 x float>
812 define float @copysign_idiom_without_nneg(float %x, i32 %mag) {
813 ; CHECK-LABEL: @copysign_idiom_without_nneg(
814 ; CHECK-NEXT: [[BITS:%.*]] = bitcast float [[X:%.*]] to i32
815 ; CHECK-NEXT: [[SIGN:%.*]] = and i32 [[BITS]], -2147483648
816 ; CHECK-NEXT: [[RES:%.*]] = or i32 [[SIGN]], [[MAG:%.*]]
817 ; CHECK-NEXT: [[Y:%.*]] = bitcast i32 [[RES]] to float
818 ; CHECK-NEXT: ret float [[Y]]
820 %bits = bitcast float %x to i32
821 %sign = and i32 %bits, -2147483648
822 %res = or i32 %sign, %mag
823 %y = bitcast i32 %res to float
827 define float @copysign_idiom_not_signmask(float %x, i32 %mag) {
828 ; CHECK-LABEL: @copysign_idiom_not_signmask(
829 ; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[MAG:%.*]], -1
830 ; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
831 ; CHECK-NEXT: [[BITS:%.*]] = bitcast float [[X:%.*]] to i32
832 ; CHECK-NEXT: [[SIGN:%.*]] = and i32 [[BITS]], -2147483647
833 ; CHECK-NEXT: [[RES:%.*]] = or i32 [[SIGN]], [[MAG]]
834 ; CHECK-NEXT: [[Y:%.*]] = bitcast i32 [[RES]] to float
835 ; CHECK-NEXT: ret float [[Y]]
837 %cond = icmp sgt i32 %mag, -1
838 call void @llvm.assume(i1 %cond)
840 %bits = bitcast float %x to i32
841 %sign = and i32 %bits, -2147483647
842 %res = or i32 %sign, %mag
843 %y = bitcast i32 %res to float
847 define float @copysign_idiom_constant_wrong_type1(<1 x i32> %x) {
848 ; CHECK-LABEL: @copysign_idiom_constant_wrong_type1(
849 ; CHECK-NEXT: [[TMP1:%.*]] = extractelement <1 x i32> [[X:%.*]], i64 0
850 ; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[TMP1]], -1
851 ; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
852 ; CHECK-NEXT: ret float 1.000000e+00
854 %bits = bitcast <1 x i32> %x to i32
855 %cond = icmp sgt i32 %bits, -1
856 call void @llvm.assume(i1 %cond)
858 %sign = and i32 %bits, -2147483648
859 %res = or i32 %sign, 1065353216
860 %y = bitcast i32 %res to float
864 define half @copysign_idiom_constant_wrong_type2(bfloat %x, i16 %mag) {
865 ; CHECK-LABEL: @copysign_idiom_constant_wrong_type2(
866 ; CHECK-NEXT: [[COND:%.*]] = icmp sgt i16 [[MAG:%.*]], -1
867 ; CHECK-NEXT: call void @llvm.assume(i1 [[COND]])
868 ; CHECK-NEXT: [[BITS:%.*]] = bitcast bfloat [[X:%.*]] to i16
869 ; CHECK-NEXT: [[SIGN:%.*]] = and i16 [[BITS]], -32768
870 ; CHECK-NEXT: [[RES:%.*]] = or disjoint i16 [[SIGN]], [[MAG]]
871 ; CHECK-NEXT: [[Y:%.*]] = bitcast i16 [[RES]] to half
872 ; CHECK-NEXT: ret half [[Y]]
874 %cond = icmp sgt i16 %mag, -1
875 call void @llvm.assume(i1 %cond)
877 %bits = bitcast bfloat %x to i16
878 %sign = and i16 %bits, -32768
879 %res = or i16 %sign, %mag
880 %y = bitcast i16 %res to half
884 define i16 @bitcast_undef_to_vector() {
885 ; CHECK-LABEL: @bitcast_undef_to_vector(
887 ; CHECK-NEXT: br label [[END:%.*]]
888 ; CHECK: unreachable:
889 ; CHECK-NEXT: br label [[END]]
891 ; CHECK-NEXT: ret i16 undef
896 unreachable: ; No predecessors!
897 %0 = extractvalue { i32, i32 } zeroinitializer, 1
900 end: ; preds = %unreachable, %entry
901 %1 = phi i32 [ %0, %unreachable ], [ undef, %entry ]
902 %2 = bitcast i32 %1 to <2 x i16>
903 %3 = extractelement <2 x i16> %2, i64 0