xref: /llvm-project/llvm/test/CodeGen/PowerPC/atomics-indexed.ll (revision a51712751c184ebe056718c938d2526693a31564)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=powerpc-unknown-linux-gnu -verify-machineinstrs -ppc-asm-full-reg-names | FileCheck %s --check-prefix=CHECK --check-prefix=PPC32
3; FIXME: -verify-machineinstrs currently fail on ppc64 (mismatched register/instruction).
4; This is already checked for in Atomics-64.ll
5; RUN: llc < %s -mcpu=ppc -mtriple=powerpc64-unknown-linux-gnu -ppc-asm-full-reg-names | FileCheck %s --check-prefix=CHECK --check-prefix=PPC64
6
7; In this file, we check that atomic load/store can make use of the indexed
8; versions of the instructions.
9
10; Indexed version of loads
11define i8 @load_x_i8_seq_cst(ptr %mem) {
12; PPC32-LABEL: load_x_i8_seq_cst:
13; PPC32:       # %bb.0:
14; PPC32-NEXT:    lis r4, 1
15; PPC32-NEXT:    sync
16; PPC32-NEXT:    ori r4, r4, 24464
17; PPC32-NEXT:    lbzx r3, r3, r4
18; PPC32-NEXT:    cmpw cr7, r3, r3
19; PPC32-NEXT:    bne- cr7, .+4
20; PPC32-NEXT:    isync
21; PPC32-NEXT:    blr
22;
23; PPC64-LABEL: load_x_i8_seq_cst:
24; PPC64:       # %bb.0:
25; PPC64-NEXT:    lis r4, 1
26; PPC64-NEXT:    sync
27; PPC64-NEXT:    ori r4, r4, 24464
28; PPC64-NEXT:    lbzx r3, r3, r4
29; PPC64-NEXT:    cmpd cr7, r3, r3
30; PPC64-NEXT:    bne- cr7, .+4
31; PPC64-NEXT:    isync
32; PPC64-NEXT:    blr
33  %ptr = getelementptr inbounds [100000 x i8], ptr %mem, i64 0, i64 90000
34  %val = load atomic i8, ptr %ptr seq_cst, align 1
35  ret i8 %val
36}
37define i16 @load_x_i16_acquire(ptr %mem) {
38; PPC32-LABEL: load_x_i16_acquire:
39; PPC32:       # %bb.0:
40; PPC32-NEXT:    lis r4, 2
41; PPC32-NEXT:    ori r4, r4, 48928
42; PPC32-NEXT:    lhzx r3, r3, r4
43; PPC32-NEXT:    cmpw cr7, r3, r3
44; PPC32-NEXT:    bne- cr7, .+4
45; PPC32-NEXT:    isync
46; PPC32-NEXT:    blr
47;
48; PPC64-LABEL: load_x_i16_acquire:
49; PPC64:       # %bb.0:
50; PPC64-NEXT:    lis r4, 2
51; PPC64-NEXT:    ori r4, r4, 48928
52; PPC64-NEXT:    lhzx r3, r3, r4
53; PPC64-NEXT:    cmpd cr7, r3, r3
54; PPC64-NEXT:    bne- cr7, .+4
55; PPC64-NEXT:    isync
56; PPC64-NEXT:    blr
57  %ptr = getelementptr inbounds [100000 x i16], ptr %mem, i64 0, i64 90000
58  %val = load atomic i16, ptr %ptr acquire, align 2
59  ret i16 %val
60}
61define i32 @load_x_i32_monotonic(ptr %mem) {
62; CHECK-LABEL: load_x_i32_monotonic:
63; CHECK:       # %bb.0:
64; CHECK-NEXT:    lis r4, 5
65; CHECK-NEXT:    ori r4, r4, 32320
66; CHECK-NEXT:    lwzx r3, r3, r4
67; CHECK-NEXT:    blr
68  %ptr = getelementptr inbounds [100000 x i32], ptr %mem, i64 0, i64 90000
69  %val = load atomic i32, ptr %ptr monotonic, align 4
70  ret i32 %val
71}
72define i64 @load_x_i64_unordered(ptr %mem) {
73; PPC32-LABEL: load_x_i64_unordered:
74; PPC32:       # %bb.0:
75; PPC32-NEXT:    mflr r0
76; PPC32-NEXT:    stwu r1, -16(r1)
77; PPC32-NEXT:    stw r0, 20(r1)
78; PPC32-NEXT:    .cfi_def_cfa_offset 16
79; PPC32-NEXT:    .cfi_offset lr, 4
80; PPC32-NEXT:    addi r3, r3, -896
81; PPC32-NEXT:    addis r3, r3, 11
82; PPC32-NEXT:    li r4, 0
83; PPC32-NEXT:    bl __atomic_load_8
84; PPC32-NEXT:    lwz r0, 20(r1)
85; PPC32-NEXT:    addi r1, r1, 16
86; PPC32-NEXT:    mtlr r0
87; PPC32-NEXT:    blr
88;
89; PPC64-LABEL: load_x_i64_unordered:
90; PPC64:       # %bb.0:
91; PPC64-NEXT:    lis r4, 10
92; PPC64-NEXT:    ori r4, r4, 64640
93; PPC64-NEXT:    ldx r3, r3, r4
94; PPC64-NEXT:    blr
95  %ptr = getelementptr inbounds [100000 x i64], ptr %mem, i64 0, i64 90000
96  %val = load atomic i64, ptr %ptr unordered, align 8
97  ret i64 %val
98}
99
100; Indexed version of stores
101define void @store_x_i8_seq_cst(ptr %mem) {
102; CHECK-LABEL: store_x_i8_seq_cst:
103; CHECK:       # %bb.0:
104; CHECK-NEXT:    lis r4, 1
105; CHECK-NEXT:    ori r4, r4, 24464
106; CHECK-NEXT:    li r5, 42
107; CHECK-NEXT:    sync
108; CHECK-NEXT:    stbx r5, r3, r4
109; CHECK-NEXT:    blr
110  %ptr = getelementptr inbounds [100000 x i8], ptr %mem, i64 0, i64 90000
111  store atomic i8 42, ptr %ptr seq_cst, align 1
112  ret void
113}
114define void @store_x_i16_release(ptr %mem) {
115; CHECK-LABEL: store_x_i16_release:
116; CHECK:       # %bb.0:
117; CHECK-NEXT:    lis r4, 2
118; CHECK-NEXT:    ori r4, r4, 48928
119; CHECK-NEXT:    li r5, 42
120; CHECK-NEXT:    lwsync
121; CHECK-NEXT:    sthx r5, r3, r4
122; CHECK-NEXT:    blr
123  %ptr = getelementptr inbounds [100000 x i16], ptr %mem, i64 0, i64 90000
124  store atomic i16 42, ptr %ptr release, align 2
125  ret void
126}
127define void @store_x_i32_monotonic(ptr %mem) {
128; CHECK-LABEL: store_x_i32_monotonic:
129; CHECK:       # %bb.0:
130; CHECK-NEXT:    lis r4, 5
131; CHECK-NEXT:    ori r4, r4, 32320
132; CHECK-NEXT:    li r5, 42
133; CHECK-NEXT:    stwx r5, r3, r4
134; CHECK-NEXT:    blr
135  %ptr = getelementptr inbounds [100000 x i32], ptr %mem, i64 0, i64 90000
136  store atomic i32 42, ptr %ptr monotonic, align 4
137  ret void
138}
139define void @store_x_i64_unordered(ptr %mem) {
140; PPC32-LABEL: store_x_i64_unordered:
141; PPC32:       # %bb.0:
142; PPC32-NEXT:    mflr r0
143; PPC32-NEXT:    stwu r1, -16(r1)
144; PPC32-NEXT:    stw r0, 20(r1)
145; PPC32-NEXT:    .cfi_def_cfa_offset 16
146; PPC32-NEXT:    .cfi_offset lr, 4
147; PPC32-NEXT:    addi r3, r3, -896
148; PPC32-NEXT:    addis r3, r3, 11
149; PPC32-NEXT:    li r5, 0
150; PPC32-NEXT:    li r6, 42
151; PPC32-NEXT:    li r7, 0
152; PPC32-NEXT:    bl __atomic_store_8
153; PPC32-NEXT:    lwz r0, 20(r1)
154; PPC32-NEXT:    addi r1, r1, 16
155; PPC32-NEXT:    mtlr r0
156; PPC32-NEXT:    blr
157;
158; PPC64-LABEL: store_x_i64_unordered:
159; PPC64:       # %bb.0:
160; PPC64-NEXT:    lis r4, 10
161; PPC64-NEXT:    ori r4, r4, 64640
162; PPC64-NEXT:    li r5, 42
163; PPC64-NEXT:    stdx r5, r3, r4
164; PPC64-NEXT:    blr
165  %ptr = getelementptr inbounds [100000 x i64], ptr %mem, i64 0, i64 90000
166  store atomic i64 42, ptr %ptr unordered, align 8
167  ret void
168}
169