[NFC][RemoveDIs] Prefer iterators over inst-pointers in InstCombine
[llvm-project.git] / llvm / test / CodeGen / AArch64 / arm64-build-vector.ll
blobf9f57e662d6ae9545780596ee52ff4af2245f3ee
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=aarch64-eabi -mattr=+fullfp16,+bf16 | FileCheck %s
4 ; Check that building a vector from floats doesn't insert an unnecessary
5 ; copy for lane zero.
6 define <4 x float>  @foo(float %a, float %b, float %c, float %d) nounwind {
7 ; CHECK-LABEL: foo:
8 ; CHECK:       // %bb.0:
9 ; CHECK-NEXT:    // kill: def $s0 killed $s0 def $q0
10 ; CHECK-NEXT:    // kill: def $s1 killed $s1 def $q1
11 ; CHECK-NEXT:    // kill: def $s2 killed $s2 def $q2
12 ; CHECK-NEXT:    // kill: def $s3 killed $s3 def $q3
13 ; CHECK-NEXT:    mov v0.s[1], v1.s[0]
14 ; CHECK-NEXT:    mov v0.s[2], v2.s[0]
15 ; CHECK-NEXT:    mov v0.s[3], v3.s[0]
16 ; CHECK-NEXT:    ret
17   %1 = insertelement <4 x float> undef, float %a, i32 0
18   %2 = insertelement <4 x float> %1, float %b, i32 1
19   %3 = insertelement <4 x float> %2, float %c, i32 2
20   %4 = insertelement <4 x float> %3, float %d, i32 3
21   ret <4 x float> %4
24 define <8 x i16> @build_all_zero(<8 x i16> %a) #1 {
25 ; CHECK-LABEL: build_all_zero:
26 ; CHECK:       // %bb.0:
27 ; CHECK-NEXT:    mov w8, #44672
28 ; CHECK-NEXT:    fmov s1, w8
29 ; CHECK-NEXT:    mul v0.8h, v0.8h, v1.8h
30 ; CHECK-NEXT:    ret
31   %b = add <8 x i16> %a, <i16 -32768, i16 undef, i16 undef, i16 undef, i16 undef, i16 undef, i16 undef, i16 undef>
32   %c = mul <8 x i16> %b, <i16 -20864, i16 undef, i16 undef, i16 undef, i16 undef, i16 undef, i16 undef, i16 undef>
33   ret <8 x i16> %c
36 ; There is an optimization in DAG Combiner as following:
37 ;   fold (concat_vectors (BUILD_VECTOR A, B, ...), (BUILD_VECTOR C, D, ...))
38 ;        -> (BUILD_VECTOR A, B, ..., C, D, ...)
39 ; This case checks when A,B and C,D are different types, there should be no
40 ; assertion failure.
41 define <8 x i16> @concat_2_build_vector(<4 x i16> %in0) {
42 ; CHECK-LABEL: concat_2_build_vector:
43 ; CHECK:       // %bb.0:
44 ; CHECK-NEXT:    movi v0.2d, #0000000000000000
45 ; CHECK-NEXT:    ret
46   %vshl_n = shl <4 x i16> %in0, <i16 8, i16 8, i16 8, i16 8>
47   %vshl_n2 = shl <4 x i16> %vshl_n, <i16 9, i16 9, i16 9, i16 9>
48   %shuffle.i = shufflevector <4 x i16> %vshl_n2, <4 x i16> zeroinitializer, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
49   ret <8 x i16> %shuffle.i
52 ; The lowering of a widened f16 BUILD_VECTOR tries to optimize it by building
53 ; an equivalent integer vector and BITCAST-ing that. This case checks that
54 ; normalizing the vector generates a valid result. The choice of the
55 ; constant prevents earlier passes from replacing the BUILD_VECTOR.
56 define void @widen_f16_build_vector(ptr %addr) {
57 ; CHECK-LABEL: widen_f16_build_vector:
58 ; CHECK:       // %bb.0:
59 ; CHECK-NEXT:    mov w8, #13294
60 ; CHECK-NEXT:    movk w8, #13294, lsl #16
61 ; CHECK-NEXT:    str w8, [x0]
62 ; CHECK-NEXT:    ret
63   store <2 x half> <half 0xH33EE, half 0xH33EE>, ptr %addr, align 2
64   ret void
67 ; Check that a single element vector is constructed with a mov
68 define <1 x i64> @single_element_vector_i64(<1 x i64> %arg) {
69 ; CHECK-LABEL: single_element_vector_i64:
70 ; CHECK:       // %bb.0: // %entry
71 ; CHECK-NEXT:    mov w8, #1
72 ; CHECK-NEXT:    fmov d1, x8
73 ; CHECK-NEXT:    add d0, d0, d1
74 ; CHECK-NEXT:    ret
75 entry:
76   %add = add <1 x i64> %arg, <i64 1>
77   ret <1 x i64> %add
80 define <1 x double> @single_element_vector_double(<1 x double> %arg) {
81 ; CHECK-LABEL: single_element_vector_double:
82 ; CHECK:       // %bb.0: // %entry
83 ; CHECK-NEXT:    fmov d1, #1.00000000
84 ; CHECK-NEXT:    fadd d0, d0, d1
85 ; CHECK-NEXT:    ret
86 entry:
87   %add = fadd <1 x double> %arg, <double 1.0>
88   ret <1 x double> %add
91 ; Make sure BUILD_VECTOR does not get stuck in a loop trying to convert a
92 ; single element FP vector constant from a scalar to vector.
93 define <1 x double> @convert_single_fp_vector_constant(i1 %cmp) {
94 ; CHECK-LABEL: convert_single_fp_vector_constant:
95 ; CHECK:       // %bb.0: // %entry
96 ; CHECK-NEXT:    tst w0, #0x1
97 ; CHECK-NEXT:    mov x8, #4607182418800017408
98 ; CHECK-NEXT:    csetm x9, ne
99 ; CHECK-NEXT:    fmov d0, x8
100 ; CHECK-NEXT:    fmov d1, x9
101 ; CHECK-NEXT:    and v0.8b, v0.8b, v1.8b
102 ; CHECK-NEXT:    ret
103 entry:
104   %sel = select i1 %cmp, <1 x double> <double 1.000000e+00>, <1 x double> zeroinitializer
105   ret <1 x double> %sel
108 ; All Zero and All -Zero tests.
110 define <2 x double> @poszero_v2f64(<2 x double> %a) {
111 ; CHECK-LABEL: poszero_v2f64:
112 ; CHECK:       // %bb.0:
113 ; CHECK-NEXT:    movi v1.2d, #0000000000000000
114 ; CHECK-NEXT:    fadd v0.2d, v0.2d, v1.2d
115 ; CHECK-NEXT:    ret
116   %b = fadd <2 x double> %a, <double 0.0, double 0.0>
117   ret <2 x double> %b
120 define <2 x double> @negzero_v2f64(<2 x double> %a) {
121 ; CHECK-LABEL: negzero_v2f64:
122 ; CHECK:       // %bb.0:
123 ; CHECK-NEXT:    mov x8, #-9223372036854775808
124 ; CHECK-NEXT:    dup v1.2d, x8
125 ; CHECK-NEXT:    fmul v0.2d, v0.2d, v1.2d
126 ; CHECK-NEXT:    ret
127   %b = fmul <2 x double> %a, <double -0.0, double -0.0>
128   ret <2 x double> %b
131 define <1 x double> @poszero_v1f64(<1 x double> %a) {
132 ; CHECK-LABEL: poszero_v1f64:
133 ; CHECK:       // %bb.0:
134 ; CHECK-NEXT:    movi d1, #0000000000000000
135 ; CHECK-NEXT:    fadd d0, d0, d1
136 ; CHECK-NEXT:    ret
137   %b = fadd <1 x double> %a, <double 0.0>
138   ret <1 x double> %b
141 define <1 x double> @negzero_v1f64(<1 x double> %a) {
142 ; CHECK-LABEL: negzero_v1f64:
143 ; CHECK:       // %bb.0:
144 ; CHECK-NEXT:    mov x8, #-9223372036854775808
145 ; CHECK-NEXT:    fmov d1, x8
146 ; CHECK-NEXT:    fmul d0, d0, d1
147 ; CHECK-NEXT:    ret
148   %b = fmul <1 x double> %a, <double -0.0>
149   ret <1 x double> %b
152 define <4 x float> @poszero_v4f32(<4 x float> %a) {
153 ; CHECK-LABEL: poszero_v4f32:
154 ; CHECK:       // %bb.0:
155 ; CHECK-NEXT:    movi v1.2d, #0000000000000000
156 ; CHECK-NEXT:    fadd v0.4s, v0.4s, v1.4s
157 ; CHECK-NEXT:    ret
158   %b = fadd <4 x float> %a, <float 0.0, float 0.0, float 0.0, float 0.0>
159   ret <4 x float> %b
162 define <4 x float> @negzero_v4f32(<4 x float> %a) {
163 ; CHECK-LABEL: negzero_v4f32:
164 ; CHECK:       // %bb.0:
165 ; CHECK-NEXT:    movi v1.4s, #128, lsl #24
166 ; CHECK-NEXT:    fmul v0.4s, v0.4s, v1.4s
167 ; CHECK-NEXT:    ret
168   %b = fmul <4 x float> %a, <float -0.0, float -0.0, float -0.0, float -0.0>
169   ret <4 x float> %b
172 define <2 x float> @poszero_v2f32(<2 x float> %a) {
173 ; CHECK-LABEL: poszero_v2f32:
174 ; CHECK:       // %bb.0:
175 ; CHECK-NEXT:    movi d1, #0000000000000000
176 ; CHECK-NEXT:    fadd v0.2s, v0.2s, v1.2s
177 ; CHECK-NEXT:    ret
178   %b = fadd <2 x float> %a, <float 0.0, float 0.0>
179   ret <2 x float> %b
182 define <2 x float> @negzero_v2f32(<2 x float> %a) {
183 ; CHECK-LABEL: negzero_v2f32:
184 ; CHECK:       // %bb.0:
185 ; CHECK-NEXT:    movi v1.2s, #128, lsl #24
186 ; CHECK-NEXT:    fmul v0.2s, v0.2s, v1.2s
187 ; CHECK-NEXT:    ret
188   %b = fmul <2 x float> %a, <float -0.0, float -0.0>
189   ret <2 x float> %b
192 define <8 x half> @poszero_v8f16(<8 x half> %a) {
193 ; CHECK-LABEL: poszero_v8f16:
194 ; CHECK:       // %bb.0:
195 ; CHECK-NEXT:    movi v1.2d, #0000000000000000
196 ; CHECK-NEXT:    fadd v0.8h, v0.8h, v1.8h
197 ; CHECK-NEXT:    ret
198   %b = fadd <8 x half> %a, <half 0.0, half 0.0, half 0.0, half 0.0, half 0.0, half 0.0, half 0.0, half 0.0>
199   ret <8 x half> %b
202 define <8 x half> @negzero_v8f16(<8 x half> %a) {
203 ; CHECK-LABEL: negzero_v8f16:
204 ; CHECK:       // %bb.0:
205 ; CHECK-NEXT:    movi v1.8h, #128, lsl #8
206 ; CHECK-NEXT:    fmul v0.8h, v0.8h, v1.8h
207 ; CHECK-NEXT:    ret
208   %b = fmul <8 x half> %a, <half -0.0, half -0.0, half -0.0, half -0.0, half -0.0, half -0.0, half -0.0, half -0.0>
209   ret <8 x half> %b
212 define <4 x half> @poszero_v4f16(<4 x half> %a) {
213 ; CHECK-LABEL: poszero_v4f16:
214 ; CHECK:       // %bb.0:
215 ; CHECK-NEXT:    movi d1, #0000000000000000
216 ; CHECK-NEXT:    fadd v0.4h, v0.4h, v1.4h
217 ; CHECK-NEXT:    ret
218   %b = fadd <4 x half> %a, <half 0.0, half 0.0, half 0.0, half 0.0>
219   ret <4 x half> %b
222 define <4 x half> @negzero_v4f16(<4 x half> %a) {
223 ; CHECK-LABEL: negzero_v4f16:
224 ; CHECK:       // %bb.0:
225 ; CHECK-NEXT:    movi v1.4h, #128, lsl #8
226 ; CHECK-NEXT:    fmul v0.4h, v0.4h, v1.4h
227 ; CHECK-NEXT:    ret
228   %b = fmul <4 x half> %a, <half -0.0, half -0.0, half -0.0, half -0.0>
229   ret <4 x half> %b
232 define <8 x bfloat> @poszero_v8bf16(<8 x bfloat> %a) {
233 ; CHECK-LABEL: poszero_v8bf16:
234 ; CHECK:       // %bb.0:
235 ; CHECK-NEXT:    movi v0.2d, #0000000000000000
236 ; CHECK-NEXT:    ret
237   ret <8 x bfloat> <bfloat 0.0, bfloat 0.0, bfloat 0.0, bfloat 0.0, bfloat 0.0, bfloat 0.0, bfloat 0.0, bfloat 0.0>
240 define <8 x bfloat> @negzero_v8bf16(<8 x bfloat> %a) {
241 ; CHECK-LABEL: negzero_v8bf16:
242 ; CHECK:       // %bb.0:
243 ; CHECK-NEXT:    movi v0.8h, #128, lsl #8
244 ; CHECK-NEXT:    ret
245   ret <8 x bfloat> <bfloat -0.0, bfloat -0.0, bfloat -0.0, bfloat -0.0, bfloat -0.0, bfloat -0.0, bfloat -0.0, bfloat -0.0>
248 define <4 x bfloat> @poszero_v4bf16(<4 x bfloat> %a) {
249 ; CHECK-LABEL: poszero_v4bf16:
250 ; CHECK:       // %bb.0:
251 ; CHECK-NEXT:    movi d0, #0000000000000000
252 ; CHECK-NEXT:    ret
253   ret <4 x bfloat> <bfloat 0.0, bfloat 0.0, bfloat 0.0, bfloat 0.0>
256 define <4 x bfloat> @negzero_v4bf16(<4 x bfloat> %a) {
257 ; CHECK-LABEL: negzero_v4bf16:
258 ; CHECK:       // %bb.0:
259 ; CHECK-NEXT:    movi v0.4h, #128, lsl #8
260 ; CHECK-NEXT:    ret
261   ret <4 x bfloat> <bfloat -0.0, bfloat -0.0, bfloat -0.0, bfloat -0.0>