xref: /llvm-project/llvm/test/CodeGen/AArch64/neon-truncstore.ll (revision 0b4688403672264ab451992a3461a0df113c3bd7)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -verify-machineinstrs -mtriple=aarch64-none-linux-gnu -mattr=+neon | FileCheck %s
3
4; A vector TruncStore can not be selected.
5; Test a trunc IR and a vector store IR can be selected correctly.
6
7define void @v2i64_v2i32(<2 x i64> %a, ptr %result) {
8; CHECK-LABEL: v2i64_v2i32:
9; CHECK:       // %bb.0:
10; CHECK-NEXT:    xtn v0.2s, v0.2d
11; CHECK-NEXT:    str d0, [x0]
12; CHECK-NEXT:    ret
13  %b = trunc <2 x i64> %a to <2 x i32>
14  store <2 x i32> %b, ptr %result
15  ret void
16}
17
18define void @v4i64_v4i32(<4 x i64> %a, ptr %result) {
19; CHECK-LABEL: v4i64_v4i32:
20; CHECK:       // %bb.0:
21; CHECK-NEXT:    uzp1 v0.4s, v0.4s, v1.4s
22; CHECK-NEXT:    str q0, [x0]
23; CHECK-NEXT:    ret
24  %b = trunc <4 x i64> %a to <4 x i32>
25  store <4 x i32> %b, ptr %result
26  ret void
27}
28
29define void @v8i64_v8i32(<8 x i64> %a, ptr %result) {
30; CHECK-LABEL: v8i64_v8i32:
31; CHECK:       // %bb.0:
32; CHECK-NEXT:    uzp1 v2.4s, v2.4s, v3.4s
33; CHECK-NEXT:    uzp1 v0.4s, v0.4s, v1.4s
34; CHECK-NEXT:    stp q0, q2, [x0]
35; CHECK-NEXT:    ret
36  %b = trunc <8 x i64> %a to <8 x i32>
37  store <8 x i32> %b, ptr %result
38  ret void
39}
40
41define void @v2i32_v2i16(<2 x i32> %a, ptr %result) {
42; CHECK-LABEL: v2i32_v2i16:
43; CHECK:       // %bb.0:
44; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
45; CHECK-NEXT:    mov w8, v0.s[1]
46; CHECK-NEXT:    fmov w9, s0
47; CHECK-NEXT:    strh w9, [x0]
48; CHECK-NEXT:    strh w8, [x0, #2]
49; CHECK-NEXT:    ret
50  %b = trunc <2 x i32> %a to <2 x i16>
51  store <2 x i16> %b, ptr %result
52  ret void
53}
54
55define void @v4i32_v4i16(<4 x i32> %a, ptr %result) {
56; CHECK-LABEL: v4i32_v4i16:
57; CHECK:       // %bb.0:
58; CHECK-NEXT:    xtn v0.4h, v0.4s
59; CHECK-NEXT:    str d0, [x0]
60; CHECK-NEXT:    ret
61  %b = trunc <4 x i32> %a to <4 x i16>
62  store <4 x i16> %b, ptr %result
63  ret void
64}
65
66define void @v8i32_v8i16(<8 x i32> %a, ptr %result) {
67; CHECK-LABEL: v8i32_v8i16:
68; CHECK:       // %bb.0:
69; CHECK-NEXT:    uzp1 v0.8h, v0.8h, v1.8h
70; CHECK-NEXT:    str q0, [x0]
71; CHECK-NEXT:    ret
72  %b = trunc <8 x i32> %a to <8 x i16>
73  store <8 x i16> %b, ptr %result
74  ret void
75}
76
77define void @v16i32_v16i16(<16 x i32> %a, ptr %result) {
78; CHECK-LABEL: v16i32_v16i16:
79; CHECK:       // %bb.0:
80; CHECK-NEXT:    uzp1 v2.8h, v2.8h, v3.8h
81; CHECK-NEXT:    uzp1 v0.8h, v0.8h, v1.8h
82; CHECK-NEXT:    stp q0, q2, [x0]
83; CHECK-NEXT:    ret
84  %b = trunc <16 x i32> %a to <16 x i16>
85  store <16 x i16> %b, ptr %result
86  ret void
87}
88
89define void @v2i32_v2i8(<2 x i32> %a, ptr %result) {
90; CHECK-LABEL: v2i32_v2i8:
91; CHECK:       // %bb.0:
92; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
93; CHECK-NEXT:    mov w8, v0.s[1]
94; CHECK-NEXT:    fmov w9, s0
95; CHECK-NEXT:    strb w9, [x0]
96; CHECK-NEXT:    strb w8, [x0, #1]
97; CHECK-NEXT:    ret
98  %b = trunc <2 x i32> %a to <2 x i8>
99  store <2 x i8> %b, ptr %result
100  ret void
101}
102
103define void @v4i32_v4i8(<4 x i32> %a, ptr %result) {
104; CHECK-LABEL: v4i32_v4i8:
105; CHECK:       // %bb.0:
106; CHECK-NEXT:    xtn v0.4h, v0.4s
107; CHECK-NEXT:    uzp1 v0.8b, v0.8b, v0.8b
108; CHECK-NEXT:    str s0, [x0]
109; CHECK-NEXT:    ret
110  %b = trunc <4 x i32> %a to <4 x i8>
111  store <4 x i8> %b, ptr %result
112  ret void
113}
114
115define void @v8i32_v8i8(<8 x i32> %a, ptr %result) {
116; CHECK-LABEL: v8i32_v8i8:
117; CHECK:       // %bb.0:
118; CHECK-NEXT:    uzp1 v0.8h, v0.8h, v1.8h
119; CHECK-NEXT:    xtn v0.8b, v0.8h
120; CHECK-NEXT:    str d0, [x0]
121; CHECK-NEXT:    ret
122  %b = trunc <8 x i32> %a to <8 x i8>
123  store <8 x i8> %b, ptr %result
124  ret void
125}
126
127define void @v16i32_v16i8(<16 x i32> %a, ptr %result) {
128; CHECK-LABEL: v16i32_v16i8:
129; CHECK:       // %bb.0:
130; CHECK-NEXT:    uzp1 v2.8h, v2.8h, v3.8h
131; CHECK-NEXT:    uzp1 v0.8h, v0.8h, v1.8h
132; CHECK-NEXT:    uzp1 v0.16b, v0.16b, v2.16b
133; CHECK-NEXT:    str q0, [x0]
134; CHECK-NEXT:    ret
135  %b = trunc <16 x i32> %a to <16 x i8>
136  store <16 x i8> %b, ptr %result
137  ret void
138}
139
140define void @v32i32_v32i8(<32 x i32> %a, ptr %result) {
141; CHECK-LABEL: v32i32_v32i8:
142; CHECK:       // %bb.0:
143; CHECK-NEXT:    uzp1 v6.8h, v6.8h, v7.8h
144; CHECK-NEXT:    uzp1 v4.8h, v4.8h, v5.8h
145; CHECK-NEXT:    uzp1 v2.8h, v2.8h, v3.8h
146; CHECK-NEXT:    uzp1 v0.8h, v0.8h, v1.8h
147; CHECK-NEXT:    uzp1 v1.16b, v4.16b, v6.16b
148; CHECK-NEXT:    uzp1 v0.16b, v0.16b, v2.16b
149; CHECK-NEXT:    stp q0, q1, [x0]
150; CHECK-NEXT:    ret
151  %b = trunc <32 x i32> %a to <32 x i8>
152  store <32 x i8> %b, ptr %result
153  ret void
154}
155
156define void @v2i16_v2i8(<2 x i16> %a, ptr %result) {
157; CHECK-LABEL: v2i16_v2i8:
158; CHECK:       // %bb.0:
159; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
160; CHECK-NEXT:    mov w8, v0.s[1]
161; CHECK-NEXT:    fmov w9, s0
162; CHECK-NEXT:    strb w9, [x0]
163; CHECK-NEXT:    strb w8, [x0, #1]
164; CHECK-NEXT:    ret
165  %b = trunc <2 x i16> %a to <2 x i8>
166  store <2 x i8> %b, ptr %result
167  ret void
168}
169
170define void @v4i16_v4i8(<4 x i16> %a, ptr %result) {
171; CHECK-LABEL: v4i16_v4i8:
172; CHECK:       // %bb.0:
173; CHECK-NEXT:    uzp1 v0.8b, v0.8b, v0.8b
174; CHECK-NEXT:    str s0, [x0]
175; CHECK-NEXT:    ret
176  %b = trunc <4 x i16> %a to <4 x i8>
177  store <4 x i8> %b, ptr %result
178  ret void
179}
180
181define void @v8i16_v8i8(<8 x i16> %a, ptr %result) {
182; CHECK-LABEL: v8i16_v8i8:
183; CHECK:       // %bb.0:
184; CHECK-NEXT:    xtn v0.8b, v0.8h
185; CHECK-NEXT:    str d0, [x0]
186; CHECK-NEXT:    ret
187  %b = trunc <8 x i16> %a to <8 x i8>
188  store <8 x i8> %b, ptr %result
189  ret void
190}
191
192define void @v16i16_v16i8(<16 x i16> %a, ptr %result) {
193; CHECK-LABEL: v16i16_v16i8:
194; CHECK:       // %bb.0:
195; CHECK-NEXT:    uzp1 v0.16b, v0.16b, v1.16b
196; CHECK-NEXT:    str q0, [x0]
197; CHECK-NEXT:    ret
198  %b = trunc <16 x i16> %a to <16 x i8>
199  store <16 x i8> %b, ptr %result
200  ret void
201}
202
203define void @v32i16_v32i8(<32 x i16> %a, ptr %result) {
204; CHECK-LABEL: v32i16_v32i8:
205; CHECK:       // %bb.0:
206; CHECK-NEXT:    uzp1 v2.16b, v2.16b, v3.16b
207; CHECK-NEXT:    uzp1 v0.16b, v0.16b, v1.16b
208; CHECK-NEXT:    stp q0, q2, [x0]
209; CHECK-NEXT:    ret
210  %b = trunc <32 x i16> %a to <32 x i8>
211  store <32 x i8> %b, ptr %result
212  ret void
213}
214