[Instrumentation] Fix a warning
[llvm-project.git] / llvm / test / CodeGen / AArch64 / arm64-ldxr-stxr.ll
blobb498611242d469d0dde2c84cd8cacaeab011f5f9
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
2 ; RUN: llc < %s -mtriple=arm64-linux-gnu | FileCheck %s --check-prefixes=CHECK,SDAG
3 ; RUN: llc < %s -global-isel -global-isel-abort=1 -pass-remarks-missed=gisel* -mtriple=arm64-linux-gnu 2>&1 | FileCheck %s --check-prefixes=CHECK,GISEL,FALLBACK
5 %0 = type { i64, i64 }
7 define dso_local i128 @f0(ptr %p) nounwind readonly {
8 ; CHECK-LABEL: f0:
9 ; CHECK:       // %bb.0: // %entry
10 ; CHECK-NEXT:    ldxp x0, x1, [x0]
11 ; CHECK-NEXT:    ret
12 entry:
13   %ldrexd = tail call %0 @llvm.aarch64.ldxp(ptr %p)
14   %0 = extractvalue %0 %ldrexd, 1
15   %1 = extractvalue %0 %ldrexd, 0
16   %2 = zext i64 %0 to i128
17   %3 = zext i64 %1 to i128
18   %shl = shl nuw i128 %2, 64
19   %4 = or i128 %shl, %3
20   ret i128 %4
23 define dso_local i32 @f1(ptr %ptr, i128 %val) nounwind {
24 ; CHECK-LABEL: f1:
25 ; CHECK:       // %bb.0: // %entry
26 ; CHECK-NEXT:    stxp w8, x2, x3, [x0]
27 ; CHECK-NEXT:    mov w0, w8
28 ; CHECK-NEXT:    ret
29 entry:
30   %tmp4 = trunc i128 %val to i64
31   %tmp6 = lshr i128 %val, 64
32   %tmp7 = trunc i128 %tmp6 to i64
33   %strexd = tail call i32 @llvm.aarch64.stxp(i64 %tmp4, i64 %tmp7, ptr %ptr)
34   ret i32 %strexd
37 declare %0 @llvm.aarch64.ldxp(ptr) nounwind
38 declare i32 @llvm.aarch64.stxp(i64, i64, ptr) nounwind
40 @var = dso_local global i64 0, align 8
42 ; FALLBACK-NOT: remark:{{.*}}test_load_i8
43 define dso_local void @test_load_i8(ptr %addr) {
44 ; SDAG-LABEL: test_load_i8:
45 ; SDAG:       // %bb.0:
46 ; SDAG-NEXT:    ldxrb w8, [x0]
47 ; SDAG-NEXT:    adrp x9, var
48 ; SDAG-NEXT:    str x8, [x9, :lo12:var]
49 ; SDAG-NEXT:    ret
51 ; GISEL-LABEL: test_load_i8:
52 ; GISEL:       // %bb.0:
53 ; GISEL-NEXT:    ldxrb w9, [x0]
54 ; GISEL-NEXT:    adrp x8, var
55 ; GISEL-NEXT:    and x9, x9, #0xff
56 ; GISEL-NEXT:    str x9, [x8, :lo12:var]
57 ; GISEL-NEXT:    ret
59   %val = call i64 @llvm.aarch64.ldxr.p0(ptr elementtype(i8) %addr)
60   %shortval = trunc i64 %val to i8
61   %extval = zext i8 %shortval to i64
62   store i64 %extval, ptr @var, align 8
63   ret void
66 ; FALLBACK-NOT: remark:{{.*}}test_load_i16
67 define dso_local void @test_load_i16(ptr %addr) {
68 ; SDAG-LABEL: test_load_i16:
69 ; SDAG:       // %bb.0:
70 ; SDAG-NEXT:    ldxrh w8, [x0]
71 ; SDAG-NEXT:    adrp x9, var
72 ; SDAG-NEXT:    str x8, [x9, :lo12:var]
73 ; SDAG-NEXT:    ret
75 ; GISEL-LABEL: test_load_i16:
76 ; GISEL:       // %bb.0:
77 ; GISEL-NEXT:    ldxrh w9, [x0]
78 ; GISEL-NEXT:    adrp x8, var
79 ; GISEL-NEXT:    and x9, x9, #0xffff
80 ; GISEL-NEXT:    str x9, [x8, :lo12:var]
81 ; GISEL-NEXT:    ret
83   %val = call i64 @llvm.aarch64.ldxr.p0(ptr elementtype(i16) %addr)
84   %shortval = trunc i64 %val to i16
85   %extval = zext i16 %shortval to i64
86   store i64 %extval, ptr @var, align 8
87   ret void
90 ; FALLBACK-NOT: remark:{{.*}}test_load_i32
91 define dso_local void @test_load_i32(ptr %addr) {
92 ; SDAG-LABEL: test_load_i32:
93 ; SDAG:       // %bb.0:
94 ; SDAG-NEXT:    ldxr w8, [x0]
95 ; SDAG-NEXT:    adrp x9, var
96 ; SDAG-NEXT:    str x8, [x9, :lo12:var]
97 ; SDAG-NEXT:    ret
99 ; GISEL-LABEL: test_load_i32:
100 ; GISEL:       // %bb.0:
101 ; GISEL-NEXT:    ldxr w9, [x0]
102 ; GISEL-NEXT:    adrp x8, var
103 ; GISEL-NEXT:    mov w9, w9
104 ; GISEL-NEXT:    str x9, [x8, :lo12:var]
105 ; GISEL-NEXT:    ret
107   %val = call i64 @llvm.aarch64.ldxr.p0(ptr elementtype(i32) %addr)
108   %shortval = trunc i64 %val to i32
109   %extval = zext i32 %shortval to i64
110   store i64 %extval, ptr @var, align 8
111   ret void
114 ; FALLBACK-NOT: remark:{{.*}}test_load_i64
115 define dso_local void @test_load_i64(ptr %addr) {
116 ; CHECK-LABEL: test_load_i64:
117 ; CHECK:       // %bb.0:
118 ; CHECK-NEXT:    ldxr x8, [x0]
119 ; CHECK-NEXT:    adrp x9, var
120 ; CHECK-NEXT:    str x8, [x9, :lo12:var]
121 ; CHECK-NEXT:    ret
123   %val = call i64 @llvm.aarch64.ldxr.p0(ptr elementtype(i64) %addr)
124   store i64 %val, ptr @var, align 8
125   ret void
129 declare i64 @llvm.aarch64.ldxr.p0(ptr) nounwind
131 ; FALLBACK-NOT: remark:{{.*}}test_store_i8
132 define dso_local i32 @test_store_i8(i32, i8 %val, ptr %addr) {
133 ; CHECK-LABEL: test_store_i8:
134 ; CHECK:       // %bb.0:
135 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
136 ; CHECK-NEXT:    stxrb w0, w1, [x2]
137 ; CHECK-NEXT:    ret
138   %extval = zext i8 %val to i64
139   %res = call i32 @llvm.aarch64.stxr.p0(i64 %extval, ptr elementtype(i8) %addr)
140   ret i32 %res
143 ; FALLBACK-NOT: remark:{{.*}}test_store_i16
144 define dso_local i32 @test_store_i16(i32, i16 %val, ptr %addr) {
145 ; CHECK-LABEL: test_store_i16:
146 ; CHECK:       // %bb.0:
147 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
148 ; CHECK-NEXT:    stxrh w0, w1, [x2]
149 ; CHECK-NEXT:    ret
150   %extval = zext i16 %val to i64
151   %res = call i32 @llvm.aarch64.stxr.p0(i64 %extval, ptr elementtype(i16) %addr)
152   ret i32 %res
155 ; FALLBACK-NOT: remark:{{.*}}test_store_i32
156 define dso_local i32 @test_store_i32(i32, i32 %val, ptr %addr) {
157 ; CHECK-LABEL: test_store_i32:
158 ; CHECK:       // %bb.0:
159 ; CHECK-NEXT:    stxr w0, w1, [x2]
160 ; CHECK-NEXT:    ret
161   %extval = zext i32 %val to i64
162   %res = call i32 @llvm.aarch64.stxr.p0(i64 %extval, ptr elementtype(i32) %addr)
163   ret i32 %res
166 ; FALLBACK-NOT: remark:{{.*}}test_store_i64
167 define dso_local i32 @test_store_i64(i32, i64 %val, ptr %addr) {
168 ; CHECK-LABEL: test_store_i64:
169 ; CHECK:       // %bb.0:
170 ; CHECK-NEXT:    stxr w0, x1, [x2]
171 ; CHECK-NEXT:    ret
172   %res = call i32 @llvm.aarch64.stxr.p0(i64 %val, ptr elementtype(i64) %addr)
173   ret i32 %res
176 declare i32 @llvm.aarch64.stxr.p0(i64, ptr) nounwind
178 define dso_local void @test_clear() {
179 ; CHECK-LABEL: test_clear:
180 ; CHECK:       // %bb.0:
181 ; CHECK-NEXT:    clrex
182 ; CHECK-NEXT:    ret
183   call void @llvm.aarch64.clrex()
184   ret void
187 declare void @llvm.aarch64.clrex() nounwind
189 define dso_local i128 @test_load_acquire_i128(ptr %p) nounwind readonly {
190 ; CHECK-LABEL: test_load_acquire_i128:
191 ; CHECK:       // %bb.0: // %entry
192 ; CHECK-NEXT:    ldaxp x0, x1, [x0]
193 ; CHECK-NEXT:    ret
194 entry:
195   %ldrexd = tail call %0 @llvm.aarch64.ldaxp(ptr %p)
196   %0 = extractvalue %0 %ldrexd, 1
197   %1 = extractvalue %0 %ldrexd, 0
198   %2 = zext i64 %0 to i128
199   %3 = zext i64 %1 to i128
200   %shl = shl nuw i128 %2, 64
201   %4 = or i128 %shl, %3
202   ret i128 %4
205 define dso_local i32 @test_store_release_i128(ptr %ptr, i128 %val) nounwind {
206 ; CHECK-LABEL: test_store_release_i128:
207 ; CHECK:       // %bb.0: // %entry
208 ; CHECK-NEXT:    stlxp w8, x2, x3, [x0]
209 ; CHECK-NEXT:    mov w0, w8
210 ; CHECK-NEXT:    ret
211 entry:
212   %tmp4 = trunc i128 %val to i64
213   %tmp6 = lshr i128 %val, 64
214   %tmp7 = trunc i128 %tmp6 to i64
215   %strexd = tail call i32 @llvm.aarch64.stlxp(i64 %tmp4, i64 %tmp7, ptr %ptr)
216   ret i32 %strexd
219 declare %0 @llvm.aarch64.ldaxp(ptr) nounwind
220 declare i32 @llvm.aarch64.stlxp(i64, i64, ptr) nounwind
222 ; FALLBACK-NOT: remark:{{.*}}test_load_acquire_i8
223 define dso_local void @test_load_acquire_i8(ptr %addr) {
224 ; SDAG-LABEL: test_load_acquire_i8:
225 ; SDAG:       // %bb.0:
226 ; SDAG-NEXT:    ldaxrb w8, [x0]
227 ; SDAG-NEXT:    adrp x9, var
228 ; SDAG-NEXT:    str x8, [x9, :lo12:var]
229 ; SDAG-NEXT:    ret
231 ; GISEL-LABEL: test_load_acquire_i8:
232 ; GISEL:       // %bb.0:
233 ; GISEL-NEXT:    ldaxrb w9, [x0]
234 ; GISEL-NEXT:    adrp x8, var
235 ; GISEL-NEXT:    and x9, x9, #0xff
236 ; GISEL-NEXT:    str x9, [x8, :lo12:var]
237 ; GISEL-NEXT:    ret
239   %val = call i64 @llvm.aarch64.ldaxr.p0(ptr elementtype(i8) %addr)
240   %shortval = trunc i64 %val to i8
241   %extval = zext i8 %shortval to i64
242   store i64 %extval, ptr @var, align 8
243   ret void
246 ; FALLBACK-NOT: remark:{{.*}}test_load_acquire_i16
247 define dso_local void @test_load_acquire_i16(ptr %addr) {
248 ; SDAG-LABEL: test_load_acquire_i16:
249 ; SDAG:       // %bb.0:
250 ; SDAG-NEXT:    ldaxrh w8, [x0]
251 ; SDAG-NEXT:    adrp x9, var
252 ; SDAG-NEXT:    str x8, [x9, :lo12:var]
253 ; SDAG-NEXT:    ret
255 ; GISEL-LABEL: test_load_acquire_i16:
256 ; GISEL:       // %bb.0:
257 ; GISEL-NEXT:    ldaxrh w9, [x0]
258 ; GISEL-NEXT:    adrp x8, var
259 ; GISEL-NEXT:    and x9, x9, #0xffff
260 ; GISEL-NEXT:    str x9, [x8, :lo12:var]
261 ; GISEL-NEXT:    ret
263   %val = call i64 @llvm.aarch64.ldaxr.p0(ptr elementtype(i16) %addr)
264   %shortval = trunc i64 %val to i16
265   %extval = zext i16 %shortval to i64
266   store i64 %extval, ptr @var, align 8
267   ret void
270 ; FALLBACK-NOT: remark:{{.*}}test_load_acquire_i32
271 define dso_local void @test_load_acquire_i32(ptr %addr) {
272 ; SDAG-LABEL: test_load_acquire_i32:
273 ; SDAG:       // %bb.0:
274 ; SDAG-NEXT:    ldaxr w8, [x0]
275 ; SDAG-NEXT:    adrp x9, var
276 ; SDAG-NEXT:    str x8, [x9, :lo12:var]
277 ; SDAG-NEXT:    ret
279 ; GISEL-LABEL: test_load_acquire_i32:
280 ; GISEL:       // %bb.0:
281 ; GISEL-NEXT:    ldaxr w9, [x0]
282 ; GISEL-NEXT:    adrp x8, var
283 ; GISEL-NEXT:    mov w9, w9
284 ; GISEL-NEXT:    str x9, [x8, :lo12:var]
285 ; GISEL-NEXT:    ret
287   %val = call i64 @llvm.aarch64.ldaxr.p0(ptr elementtype(i32) %addr)
288   %shortval = trunc i64 %val to i32
289   %extval = zext i32 %shortval to i64
290   store i64 %extval, ptr @var, align 8
291   ret void
294 ; FALLBACK-NOT: remark:{{.*}}test_load_acquire_i64
295 define dso_local void @test_load_acquire_i64(ptr %addr) {
296 ; CHECK-LABEL: test_load_acquire_i64:
297 ; CHECK:       // %bb.0:
298 ; CHECK-NEXT:    ldaxr x8, [x0]
299 ; CHECK-NEXT:    adrp x9, var
300 ; CHECK-NEXT:    str x8, [x9, :lo12:var]
301 ; CHECK-NEXT:    ret
303   %val = call i64 @llvm.aarch64.ldaxr.p0(ptr elementtype(i64) %addr)
304   store i64 %val, ptr @var, align 8
305   ret void
309 declare i64 @llvm.aarch64.ldaxr.p0(ptr) nounwind
311 ; FALLBACK-NOT: remark:{{.*}}test_store_release_i8
312 define dso_local i32 @test_store_release_i8(i32, i8 %val, ptr %addr) {
313 ; CHECK-LABEL: test_store_release_i8:
314 ; CHECK:       // %bb.0:
315 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
316 ; CHECK-NEXT:    stlxrb w0, w1, [x2]
317 ; CHECK-NEXT:    ret
318   %extval = zext i8 %val to i64
319   %res = call i32 @llvm.aarch64.stlxr.p0(i64 %extval, ptr elementtype(i8) %addr)
320   ret i32 %res
323 ; FALLBACK-NOT: remark:{{.*}}test_store_release_i16
324 define dso_local i32 @test_store_release_i16(i32, i16 %val, ptr %addr) {
325 ; CHECK-LABEL: test_store_release_i16:
326 ; CHECK:       // %bb.0:
327 ; CHECK-NEXT:    // kill: def $w1 killed $w1 def $x1
328 ; CHECK-NEXT:    stlxrh w0, w1, [x2]
329 ; CHECK-NEXT:    ret
330   %extval = zext i16 %val to i64
331   %res = call i32 @llvm.aarch64.stlxr.p0(i64 %extval, ptr elementtype(i16) %addr)
332   ret i32 %res
335 ; FALLBACK-NOT: remark:{{.*}}test_store_release_i32
336 define dso_local i32 @test_store_release_i32(i32, i32 %val, ptr %addr) {
337 ; CHECK-LABEL: test_store_release_i32:
338 ; CHECK:       // %bb.0:
339 ; CHECK-NEXT:    stlxr w0, w1, [x2]
340 ; CHECK-NEXT:    ret
341   %extval = zext i32 %val to i64
342   %res = call i32 @llvm.aarch64.stlxr.p0(i64 %extval, ptr elementtype(i32) %addr)
343   ret i32 %res
346 ; FALLBACK-NOT: remark:{{.*}}test_store_release_i64
347 define dso_local i32 @test_store_release_i64(i32, i64 %val, ptr %addr) {
348 ; CHECK-LABEL: test_store_release_i64:
349 ; CHECK:       // %bb.0:
350 ; CHECK-NEXT:    stlxr w0, x1, [x2]
351 ; CHECK-NEXT:    ret
352   %res = call i32 @llvm.aarch64.stlxr.p0(i64 %val, ptr elementtype(i64) %addr)
353   ret i32 %res
356 ; The stxp result cannot be allocated to the same register as the inputs.
357 define dso_local i32 @test_stxp_undef(ptr %p, i64 %x) nounwind {
358 ; CHECK-LABEL: test_stxp_undef:
359 ; CHECK:       // %bb.0:
360 ; CHECK-NEXT:    stxp w8, x9, x1, [x0]
361 ; CHECK-NEXT:    mov w0, w8
362 ; CHECK-NEXT:    ret
363   %res = call i32 @llvm.aarch64.stxp(i64 undef, i64 %x, ptr %p)
364   ret i32 %res
367 ; Same as previous test, but using inline asm.
368 define dso_local i32 @test_stxp_undef_inline_asm(ptr %p, i64 %x) nounwind {
369 ; CHECK-LABEL: test_stxp_undef_inline_asm:
370 ; CHECK:       // %bb.0:
371 ; CHECK-NEXT:    //APP
372 ; CHECK-NEXT:    stxp w8, x9, x1, [x0]
373 ; CHECK-NEXT:    //NO_APP
374 ; CHECK-NEXT:    mov w0, w8
375 ; CHECK-NEXT:    ret
376   %res = call i32 asm sideeffect "stxp ${0:w}, ${2}, ${3}, [${1}]", "=&r,r,r,r,~{memory}"(ptr %p, i64 undef, i64 %x)
377   ret i32 %res
380 declare i32 @llvm.aarch64.stlxr.p0(i64, ptr) nounwind
381 ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
382 ; FALLBACK: {{.*}}