1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
2 ; RUN: llc -mtriple=aarch64 -mattr=+v8.9a -mattr=+rcpc3 < %s | FileCheck --check-prefixes=BOTH,RCPC3 %s
3 ; RUN: llc -mtriple=aarch64 -mattr=+v8.9a < %s | FileCheck --check-prefixes=BOTH,NO-RCPC3 %s
5 define hidden <2 x i64> @test_ldap1_2xi64_lane0(ptr nocapture noundef readonly %a, <2 x i64> noundef %b) local_unnamed_addr {
7 ; RCPC3-LABEL: test_ldap1_2xi64_lane0:
9 ; RCPC3-NEXT: ldap1 { v0.d }[0], [x0]
12 ; NO-RCPC3-LABEL: test_ldap1_2xi64_lane0:
14 ; NO-RCPC3-NEXT: ldapr x8, [x0]
15 ; NO-RCPC3-NEXT: mov v0.d[0], x8
17 %1 = load atomic i64, ptr %a acquire, align 8
18 %ldap1 = insertelement <2 x i64> %b, i64 %1, i64 0
22 define hidden <2 x i64> @test_ldap1_2xi64_lane1(ptr nocapture noundef readonly %a, <2 x i64> noundef %b) local_unnamed_addr {
24 ; RCPC3-LABEL: test_ldap1_2xi64_lane1:
26 ; RCPC3-NEXT: ldap1 { v0.d }[1], [x0]
29 ; NO-RCPC3-LABEL: test_ldap1_2xi64_lane1:
31 ; NO-RCPC3-NEXT: ldapr x8, [x0]
32 ; NO-RCPC3-NEXT: mov v0.d[1], x8
34 %1 = load atomic i64, ptr %a acquire, align 8
35 %ldap1 = insertelement <2 x i64> %b, i64 %1, i64 1
39 define hidden nofpclass(nan inf) <2 x double> @test_ldap1_2xdouble_lane0(ptr nocapture noundef readonly %a, <2 x double> noundef nofpclass(nan inf) %b) local_unnamed_addr {
41 ; RCPC3-LABEL: test_ldap1_2xdouble_lane0:
43 ; RCPC3-NEXT: ldap1 { v0.d }[0], [x0]
46 ; NO-RCPC3-LABEL: test_ldap1_2xdouble_lane0:
48 ; NO-RCPC3-NEXT: ldapr x8, [x0]
49 ; NO-RCPC3-NEXT: fmov d1, x8
50 ; NO-RCPC3-NEXT: mov v0.d[0], v1.d[0]
52 %1 = load atomic double, ptr %a acquire, align 8
53 %ldap1 = insertelement <2 x double> %b, double %1, i64 0
54 ret <2 x double> %ldap1
57 define hidden nofpclass(nan inf) <2 x double> @test_ldap1_2xdouble_lane1(ptr nocapture noundef readonly %a, <2 x double> noundef nofpclass(nan inf) %b) local_unnamed_addr {
59 ; RCPC3-LABEL: test_ldap1_2xdouble_lane1:
61 ; RCPC3-NEXT: ldap1 { v0.d }[1], [x0]
64 ; NO-RCPC3-LABEL: test_ldap1_2xdouble_lane1:
66 ; NO-RCPC3-NEXT: ldapr x8, [x0]
67 ; NO-RCPC3-NEXT: fmov d1, x8
68 ; NO-RCPC3-NEXT: mov v0.d[1], v1.d[0]
70 %1 = load atomic double, ptr %a acquire, align 8
71 %ldap1 = insertelement <2 x double> %b, double %1, i64 1
72 ret <2 x double> %ldap1
75 define hidden <1 x i64> @test_ldap1_1xi64_lane0(ptr nocapture noundef readonly %a, <1 x i64> noundef %b) local_unnamed_addr {
77 ; RCPC3-LABEL: test_ldap1_1xi64_lane0:
79 ; RCPC3-NEXT: ldap1 { v0.d }[0], [x0]
80 ; RCPC3-NEXT: // kill: def $d0 killed $d0 killed $q0
83 ; NO-RCPC3-LABEL: test_ldap1_1xi64_lane0:
85 ; NO-RCPC3-NEXT: ldapr x8, [x0]
86 ; NO-RCPC3-NEXT: fmov d0, x8
88 %1 = load atomic i64, ptr %a acquire, align 8
89 %ldap1 = insertelement <1 x i64> poison, i64 %1, i64 0
93 define hidden nofpclass(nan inf) <1 x double> @test_ldap1_1xdouble_lane0(ptr nocapture noundef readonly %a, <1 x double> noundef nofpclass(nan inf) %b) local_unnamed_addr {
95 ; RCPC3-LABEL: test_ldap1_1xdouble_lane0:
97 ; RCPC3-NEXT: ldap1 { v0.d }[0], [x0]
98 ; RCPC3-NEXT: // kill: def $d0 killed $d0 killed $q0
101 ; NO-RCPC3-LABEL: test_ldap1_1xdouble_lane0:
102 ; NO-RCPC3: // %bb.0:
103 ; NO-RCPC3-NEXT: ldapr x8, [x0]
104 ; NO-RCPC3-NEXT: fmov d0, x8
106 %1 = load atomic double, ptr %a acquire, align 8
107 %ldap1 = insertelement <1 x double> poison, double %1, i64 0
108 ret <1 x double> %ldap1
111 define hidden void @test_stl1_2xi64_lane0(ptr nocapture noundef writeonly %a, <2 x i64> noundef %b) local_unnamed_addr {
113 ; RCPC3-LABEL: test_stl1_2xi64_lane0:
115 ; RCPC3-NEXT: stl1 { v0.d }[0], [x0]
118 ; NO-RCPC3-LABEL: test_stl1_2xi64_lane0:
119 ; NO-RCPC3: // %bb.0:
120 ; NO-RCPC3-NEXT: fmov x8, d0
121 ; NO-RCPC3-NEXT: stlr x8, [x0]
123 %1 = extractelement <2 x i64> %b, i64 0
124 store atomic i64 %1, ptr %a release, align 8
128 define hidden void @test_stl1_2xi64_lane1(ptr nocapture noundef writeonly %a, <2 x i64> noundef %b) local_unnamed_addr {
130 ; RCPC3-LABEL: test_stl1_2xi64_lane1:
132 ; RCPC3-NEXT: stl1 { v0.d }[1], [x0]
135 ; NO-RCPC3-LABEL: test_stl1_2xi64_lane1:
136 ; NO-RCPC3: // %bb.0:
137 ; NO-RCPC3-NEXT: mov x8, v0.d[1]
138 ; NO-RCPC3-NEXT: stlr x8, [x0]
140 %1 = extractelement <2 x i64> %b, i64 1
141 store atomic i64 %1, ptr %a release, align 8
145 define hidden void @test_stl1_2xdouble_lane0(ptr nocapture noundef writeonly %a, <2 x double> noundef nofpclass(nan inf) %b) local_unnamed_addr {
147 ; RCPC3-LABEL: test_stl1_2xdouble_lane0:
149 ; RCPC3-NEXT: stl1 { v0.d }[0], [x0]
152 ; NO-RCPC3-LABEL: test_stl1_2xdouble_lane0:
153 ; NO-RCPC3: // %bb.0:
154 ; NO-RCPC3-NEXT: fmov x8, d0
155 ; NO-RCPC3-NEXT: stlr x8, [x0]
157 %1 = extractelement <2 x double> %b, i64 0
158 store atomic double %1, ptr %a release, align 8
162 define hidden void @test_stl1_2xdouble_lane1(ptr nocapture noundef writeonly %a, <2 x double> noundef nofpclass(nan inf) %b) local_unnamed_addr {
164 ; RCPC3-LABEL: test_stl1_2xdouble_lane1:
166 ; RCPC3-NEXT: stl1 { v0.d }[1], [x0]
169 ; NO-RCPC3-LABEL: test_stl1_2xdouble_lane1:
170 ; NO-RCPC3: // %bb.0:
171 ; NO-RCPC3-NEXT: mov d0, v0.d[1]
172 ; NO-RCPC3-NEXT: fmov x8, d0
173 ; NO-RCPC3-NEXT: stlr x8, [x0]
175 %1 = extractelement <2 x double> %b, i64 1
176 store atomic double %1, ptr %a release, align 8
180 define hidden void @test_stl1_1xi64_lane0(ptr nocapture noundef writeonly %a, <1 x i64> noundef %b) local_unnamed_addr {
182 ; RCPC3-LABEL: test_stl1_1xi64_lane0:
184 ; RCPC3-NEXT: // kill: def $d0 killed $d0 def $q0
185 ; RCPC3-NEXT: stl1 { v0.d }[0], [x0]
188 ; NO-RCPC3-LABEL: test_stl1_1xi64_lane0:
189 ; NO-RCPC3: // %bb.0:
190 ; NO-RCPC3-NEXT: // kill: def $d0 killed $d0 def $q0
191 ; NO-RCPC3-NEXT: fmov x8, d0
192 ; NO-RCPC3-NEXT: stlr x8, [x0]
194 %1 = extractelement <1 x i64> %b, i64 0
195 store atomic i64 %1, ptr %a release, align 8
199 define hidden void @test_stl1_1xdouble_lane0(ptr nocapture noundef writeonly %a, <1 x double> noundef nofpclass(nan inf) %b) local_unnamed_addr {
201 ; RCPC3-LABEL: test_stl1_1xdouble_lane0:
203 ; RCPC3-NEXT: // kill: def $d0 killed $d0 def $q0
204 ; RCPC3-NEXT: stl1 { v0.d }[0], [x0]
207 ; NO-RCPC3-LABEL: test_stl1_1xdouble_lane0:
208 ; NO-RCPC3: // %bb.0:
209 ; NO-RCPC3-NEXT: fmov x8, d0
210 ; NO-RCPC3-NEXT: stlr x8, [x0]
212 %1 = extractelement <1 x double> %b, i64 0
213 store atomic double %1, ptr %a release, align 8
217 ; The remaining tests do not have any particular RCPC3-specific codegen:
219 ; load-acquire a plain non-vector double value
220 define hidden double @test_double_load(ptr nocapture noundef readonly %a) local_unnamed_addr {
221 ; BOTH-LABEL: test_double_load:
223 ; BOTH-NEXT: ldapr x8, [x0]
224 ; BOTH-NEXT: fmov d0, x8
226 %1 = load atomic double, ptr %a acquire, align 8
230 ; store-release a plain non-vector double value
231 define hidden void @test_double_store(ptr nocapture noundef writeonly %a, double noundef %b) local_unnamed_addr {
232 ; BOTH-LABEL: test_double_store:
234 ; BOTH-NEXT: fmov x8, d0
235 ; BOTH-NEXT: stlr x8, [x0]
237 store atomic double %b, ptr %a release, align 8
241 ; load-acquire an i64, followed by a bitcast to a 64-bit vector
242 define hidden <2 x i32> @test_load_i64_bitcast_2xi32(ptr nocapture noundef readonly %a) local_unnamed_addr {
243 ; BOTH-LABEL: test_load_i64_bitcast_2xi32:
245 ; BOTH-NEXT: ldapr x8, [x0]
246 ; BOTH-NEXT: fmov d0, x8
248 %1 = load atomic i64, ptr %a acquire, align 8
249 %2 = bitcast i64 %1 to <2 x i32>
253 ; bitcast from a 64-bit vector, followed by a store-release of the i64
254 define hidden void @test_bitcast_2xi32_store_i64(ptr nocapture noundef readonly %a, <2 x i32> noundef %b) local_unnamed_addr {
255 ; BOTH-LABEL: test_bitcast_2xi32_store_i64:
257 ; BOTH-NEXT: fmov x8, d0
258 ; BOTH-NEXT: stlr x8, [x0]
260 %1 = bitcast <2 x i32> %b to i64
261 store atomic i64 %1, ptr %a release, align 8
265 ; (non-atomic) load a 64-bit vector
266 define hidden <2 x i32> @test_load_2xi32(ptr nocapture noundef readonly %a) local_unnamed_addr {
267 ; BOTH-LABEL: test_load_2xi32:
269 ; BOTH-NEXT: ldr d0, [x0]
271 %1 = load <2 x i32>, ptr %a, align 8
275 ; (non-atomic) store a 64-bit vector
276 define hidden void @test_store_2xi32(ptr nocapture noundef writeonly %a, <2 x i32> noundef %b) local_unnamed_addr {
277 ; BOTH-LABEL: test_store_2xi32:
279 ; BOTH-NEXT: str d0, [x0]
281 store <2 x i32> %b, ptr %a, align 8
285 ; (non-atomic) load a 64-bit vector
286 define hidden <1 x i64> @test_load_1xi64(ptr nocapture noundef readonly %a) local_unnamed_addr {
287 ; BOTH-LABEL: test_load_1xi64:
289 ; BOTH-NEXT: ldr d0, [x0]
291 %1 = load <1 x i64>, ptr %a, align 8
295 ; (non-atomic) store a 64-bit vector
296 define hidden void @test_store_1xi64(ptr nocapture noundef writeonly %a, <1 x i64> noundef %b) local_unnamed_addr {
297 ; BOTH-LABEL: test_store_1xi64:
299 ; BOTH-NEXT: str d0, [x0]
301 store <1 x i64> %b, ptr %a, align 8
305 ; (non-atomic) load a 64-bit value and insert into vector
306 define hidden <2 x i64> @test_load_insert_2xi64(ptr nocapture noundef readonly %a, <2 x i64> noundef %b) local_unnamed_addr {
307 ; BOTH-LABEL: test_load_insert_2xi64:
309 ; BOTH-NEXT: ld1 { v0.d }[0], [x0]
311 %1 = load i64, ptr %a, align 8
312 %2 = insertelement <2 x i64> %b, i64 %1, i64 0
316 ; extract from vector and (non-atomic) store a 64-bit value
317 define hidden void @test_extract_store_2xi64(ptr nocapture noundef writeonly %a, <2 x i64> noundef %b) local_unnamed_addr {
318 ; BOTH-LABEL: test_extract_store_2xi64:
320 ; BOTH-NEXT: st1 { v0.d }[1], [x0]
322 %1 = extractelement <2 x i64> %b, i64 1
323 store i64 %1, ptr %a, align 8