1; RUN: llc < %s -mtriple=ve-unknown-unknown | FileCheck %s
2
3;;; Test atomicrmw operations
4
5@c = common global i8 0, align 4
6@s = common global i16 0, align 4
7@i = common global i32 0, align 4
8@l = common global i64 0, align 4
9
10; Function Attrs: norecurse nounwind
11define signext i8 @test_atomic_fetch_add_1() {
12; CHECK-LABEL: test_atomic_fetch_add_1:
13; CHECK:       # %bb.0: # %entry
14; CHECK-NEXT:    fencem 3
15; CHECK-NEXT:    lea %s0, c@lo
16; CHECK-NEXT:    and %s0, %s0, (32)0
17; CHECK-NEXT:    lea.sl %s0, c@hi(, %s0)
18; CHECK-NEXT:    and %s0, -4, %s0
19; CHECK-NEXT:    ldl.sx %s2, (, %s0)
20; CHECK-NEXT:    lea %s1, -256
21; CHECK-NEXT:    and %s1, %s1, (32)0
22; CHECK-NEXT:  .LBB{{[0-9]+}}_1: # %atomicrmw.start
23; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
24; CHECK-NEXT:    or %s3, 0, %s2
25; CHECK-NEXT:    adds.w.sx %s2, 1, %s2
26; CHECK-NEXT:    and %s2, %s2, (56)0
27; CHECK-NEXT:    and %s4, %s3, %s1
28; CHECK-NEXT:    or %s2, %s4, %s2
29; CHECK-NEXT:    cas.w %s2, (%s0), %s3
30; CHECK-NEXT:    brne.w %s2, %s3, .LBB{{[0-9]+}}_1
31; CHECK-NEXT:  # %bb.2: # %atomicrmw.end
32; CHECK-NEXT:    sll %s0, %s2, 56
33; CHECK-NEXT:    sra.l %s0, %s0, 56
34; CHECK-NEXT:    fencem 3
35; CHECK-NEXT:    b.l.t (, %s10)
36entry:
37  %0 = atomicrmw add i8* @c, i8 1 seq_cst
38  ret i8 %0
39}
40
41; Function Attrs: norecurse nounwind
42define signext i16 @test_atomic_fetch_sub_2() {
43; CHECK-LABEL: test_atomic_fetch_sub_2:
44; CHECK:       # %bb.0: # %entry
45; CHECK-NEXT:    fencem 3
46; CHECK-NEXT:    lea %s0, s@lo
47; CHECK-NEXT:    and %s0, %s0, (32)0
48; CHECK-NEXT:    lea.sl %s0, s@hi(, %s0)
49; CHECK-NEXT:    and %s0, -4, %s0
50; CHECK-NEXT:    ldl.sx %s2, (, %s0)
51; CHECK-NEXT:    lea %s1, -65536
52; CHECK-NEXT:    and %s1, %s1, (32)0
53; CHECK-NEXT:  .LBB{{[0-9]+}}_1: # %atomicrmw.start
54; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
55; CHECK-NEXT:    or %s3, 0, %s2
56; CHECK-NEXT:    adds.w.sx %s2, -1, %s2
57; CHECK-NEXT:    and %s2, %s2, (48)0
58; CHECK-NEXT:    and %s4, %s3, %s1
59; CHECK-NEXT:    or %s2, %s4, %s2
60; CHECK-NEXT:    cas.w %s2, (%s0), %s3
61; CHECK-NEXT:    brne.w %s2, %s3, .LBB{{[0-9]+}}_1
62; CHECK-NEXT:  # %bb.2: # %atomicrmw.end
63; CHECK-NEXT:    sll %s0, %s2, 48
64; CHECK-NEXT:    sra.l %s0, %s0, 48
65; CHECK-NEXT:    fencem 3
66; CHECK-NEXT:    b.l.t (, %s10)
67entry:
68  %0 = atomicrmw sub i16* @s, i16 1 seq_cst
69  ret i16 %0
70}
71
72; Function Attrs: norecurse nounwind
73define signext i32 @test_atomic_fetch_and_4() {
74; CHECK-LABEL: test_atomic_fetch_and_4:
75; CHECK:       # %bb.0: # %entry
76; CHECK-NEXT:    fencem 3
77; CHECK-NEXT:    lea %s0, i@lo
78; CHECK-NEXT:    and %s0, %s0, (32)0
79; CHECK-NEXT:    lea.sl %s0, i@hi(, %s0)
80; CHECK-NEXT:    ldl.sx %s1, (, %s0)
81; CHECK-NEXT:  .LBB{{[0-9]+}}_1: # %atomicrmw.start
82; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
83; CHECK-NEXT:    or %s2, 0, %s1
84; CHECK-NEXT:    and %s1, 1, %s2
85; CHECK-NEXT:    cas.w %s1, (%s0), %s2
86; CHECK-NEXT:    brne.w %s1, %s2, .LBB{{[0-9]+}}_1
87; CHECK-NEXT:  # %bb.2: # %atomicrmw.end
88; CHECK-NEXT:    adds.w.sx %s0, %s1, (0)1
89; CHECK-NEXT:    fencem 3
90; CHECK-NEXT:    b.l.t (, %s10)
91entry:
92  %0 = atomicrmw and i32* @i, i32 1 seq_cst
93  ret i32 %0
94}
95; Function Attrs: norecurse nounwind
96define i64 @test_atomic_fetch_or_8() {
97; CHECK-LABEL: test_atomic_fetch_or_8:
98; CHECK:       # %bb.0: # %entry
99; CHECK-NEXT:    fencem 3
100; CHECK-NEXT:    lea %s0, l@lo
101; CHECK-NEXT:    and %s0, %s0, (32)0
102; CHECK-NEXT:    lea.sl %s1, l@hi(, %s0)
103; CHECK-NEXT:    ld %s0, (, %s1)
104; CHECK-NEXT:  .LBB{{[0-9]+}}_1: # %atomicrmw.start
105; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
106; CHECK-NEXT:    or %s2, 0, %s0
107; CHECK-NEXT:    or %s0, 1, %s0
108; CHECK-NEXT:    cas.l %s0, (%s1), %s2
109; CHECK-NEXT:    brne.l %s0, %s2, .LBB{{[0-9]+}}_1
110; CHECK-NEXT:  # %bb.2: # %atomicrmw.end
111; CHECK-NEXT:    fencem 3
112; CHECK-NEXT:    b.l.t (, %s10)
113entry:
114  %0 = atomicrmw or i64* @l, i64 1 seq_cst
115  ret i64 %0
116}
117
118; Function Attrs: norecurse nounwind
119define signext i8 @test_atomic_fetch_xor_1() {
120; CHECK-LABEL: test_atomic_fetch_xor_1:
121; CHECK:       # %bb.0: # %entry
122; CHECK-NEXT:    fencem 3
123; CHECK-NEXT:    lea %s0, c@lo
124; CHECK-NEXT:    and %s0, %s0, (32)0
125; CHECK-NEXT:    lea.sl %s0, c@hi(, %s0)
126; CHECK-NEXT:    and %s1, -4, %s0
127; CHECK-NEXT:    ldl.sx %s0, (, %s1)
128; CHECK-NEXT:  .LBB{{[0-9]+}}_1: # %atomicrmw.start
129; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
130; CHECK-NEXT:    or %s2, 0, %s0
131; CHECK-NEXT:    xor %s0, 1, %s2
132; CHECK-NEXT:    cas.w %s0, (%s1), %s2
133; CHECK-NEXT:    brne.w %s0, %s2, .LBB{{[0-9]+}}_1
134; CHECK-NEXT:  # %bb.2: # %atomicrmw.end
135; CHECK-NEXT:    sll %s0, %s0, 56
136; CHECK-NEXT:    sra.l %s0, %s0, 56
137; CHECK-NEXT:    fencem 3
138; CHECK-NEXT:    b.l.t (, %s10)
139entry:
140  %0 = atomicrmw xor i8* @c, i8 1 seq_cst
141  ret i8 %0
142}
143
144; Function Attrs: norecurse nounwind
145define signext i16 @test_atomic_fetch_nand_2() {
146; CHECK-LABEL: test_atomic_fetch_nand_2:
147; CHECK:       # %bb.0: # %entry
148; CHECK-NEXT:    fencem 3
149; CHECK-NEXT:    lea %s0, s@lo
150; CHECK-NEXT:    and %s0, %s0, (32)0
151; CHECK-NEXT:    lea.sl %s0, s@hi(, %s0)
152; CHECK-NEXT:    and %s0, -4, %s0
153; CHECK-NEXT:    ldl.sx %s2, (, %s0)
154; CHECK-NEXT:    lea %s1, 65534
155; CHECK-NEXT:    lea %s3, -65536
156; CHECK-NEXT:    and %s3, %s3, (32)0
157; CHECK-NEXT:  .LBB{{[0-9]+}}_1: # %atomicrmw.start
158; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
159; CHECK-NEXT:    or %s4, 0, %s2
160; CHECK-NEXT:    xor %s2, -1, %s4
161; CHECK-NEXT:    or %s2, %s2, %s1
162; CHECK-NEXT:    and %s2, %s2, (48)0
163; CHECK-NEXT:    and %s5, %s4, %s3
164; CHECK-NEXT:    or %s2, %s5, %s2
165; CHECK-NEXT:    cas.w %s2, (%s0), %s4
166; CHECK-NEXT:    brne.w %s2, %s4, .LBB{{[0-9]+}}_1
167; CHECK-NEXT:  # %bb.2: # %atomicrmw.end
168; CHECK-NEXT:    sll %s0, %s2, 48
169; CHECK-NEXT:    sra.l %s0, %s0, 48
170; CHECK-NEXT:    fencem 3
171; CHECK-NEXT:    b.l.t (, %s10)
172entry:
173  %0 = atomicrmw nand i16* @s, i16 1 seq_cst
174  ret i16 %0
175}
176
177; Function Attrs: norecurse nounwind
178define signext i32 @test_atomic_fetch_max_4() {
179; CHECK-LABEL: test_atomic_fetch_max_4:
180; CHECK:       # %bb.0: # %entry
181; CHECK-NEXT:    fencem 3
182; CHECK-NEXT:    lea %s0, i@lo
183; CHECK-NEXT:    and %s0, %s0, (32)0
184; CHECK-NEXT:    lea.sl %s1, i@hi(, %s0)
185; CHECK-NEXT:    ldl.sx %s0, (, %s1)
186; CHECK-NEXT:    or %s2, 1, (0)1
187; CHECK-NEXT:  .LBB{{[0-9]+}}_1: # %atomicrmw.start
188; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
189; CHECK-NEXT:    or %s3, 0, %s0
190; CHECK-NEXT:    maxs.w.sx %s0, %s0, %s2
191; CHECK-NEXT:    cas.w %s0, (%s1), %s3
192; CHECK-NEXT:    brne.w %s0, %s3, .LBB{{[0-9]+}}_1
193; CHECK-NEXT:  # %bb.2: # %atomicrmw.end
194; CHECK-NEXT:    adds.w.sx %s0, %s0, (0)1
195; CHECK-NEXT:    fencem 3
196; CHECK-NEXT:    b.l.t (, %s10)
197entry:
198  %0 = atomicrmw max i32* @i, i32 1 seq_cst
199  ret i32 %0
200}
201
202; Function Attrs: norecurse nounwind
203define signext i32 @test_atomic_fetch_min_4() {
204; CHECK-LABEL: test_atomic_fetch_min_4:
205; CHECK:       # %bb.0: # %entry
206; CHECK-NEXT:    fencem 3
207; CHECK-NEXT:    lea %s0, i@lo
208; CHECK-NEXT:    and %s0, %s0, (32)0
209; CHECK-NEXT:    lea.sl %s0, i@hi(, %s0)
210; CHECK-NEXT:    ldl.sx %s1, (, %s0)
211; CHECK-NEXT:    or %s2, 2, (0)1
212; CHECK-NEXT:  .LBB{{[0-9]+}}_1: # %atomicrmw.start
213; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
214; CHECK-NEXT:    or %s3, 0, %s1
215; CHECK-NEXT:    cmps.w.sx %s4, %s1, %s2
216; CHECK-NEXT:    or %s1, 1, (0)1
217; CHECK-NEXT:    cmov.w.lt %s1, %s3, %s4
218; CHECK-NEXT:    cas.w %s1, (%s0), %s3
219; CHECK-NEXT:    brne.w %s1, %s3, .LBB{{[0-9]+}}_1
220; CHECK-NEXT:  # %bb.2: # %atomicrmw.end
221; CHECK-NEXT:    adds.w.sx %s0, %s1, (0)1
222; CHECK-NEXT:    fencem 3
223; CHECK-NEXT:    b.l.t (, %s10)
224entry:
225  %0 = atomicrmw min i32* @i, i32 1 seq_cst
226  ret i32 %0
227}
228
229; Function Attrs: norecurse nounwind
230define signext i32 @test_atomic_fetch_umax_4() {
231; CHECK-LABEL: test_atomic_fetch_umax_4:
232; CHECK:       # %bb.0: # %entry
233; CHECK-NEXT:    fencem 3
234; CHECK-NEXT:    lea %s0, i@lo
235; CHECK-NEXT:    and %s0, %s0, (32)0
236; CHECK-NEXT:    lea.sl %s0, i@hi(, %s0)
237; CHECK-NEXT:    ldl.sx %s1, (, %s0)
238; CHECK-NEXT:    or %s2, 1, (0)1
239; CHECK-NEXT:  .LBB{{[0-9]+}}_1: # %atomicrmw.start
240; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
241; CHECK-NEXT:    or %s3, 0, %s1
242; CHECK-NEXT:    cmpu.w %s4, %s1, %s2
243; CHECK-NEXT:    or %s1, 1, (0)1
244; CHECK-NEXT:    cmov.w.gt %s1, %s3, %s4
245; CHECK-NEXT:    cas.w %s1, (%s0), %s3
246; CHECK-NEXT:    brne.w %s1, %s3, .LBB{{[0-9]+}}_1
247; CHECK-NEXT:  # %bb.2: # %atomicrmw.end
248; CHECK-NEXT:    adds.w.sx %s0, %s1, (0)1
249; CHECK-NEXT:    fencem 3
250; CHECK-NEXT:    b.l.t (, %s10)
251entry:
252  %0 = atomicrmw umax i32* @i, i32 1 seq_cst
253  ret i32 %0
254}
255
256; Function Attrs: norecurse nounwind
257define signext i32 @test_atomic_fetch_umin_4() {
258; CHECK-LABEL: test_atomic_fetch_umin_4:
259; CHECK:       # %bb.0: # %entry
260; CHECK-NEXT:    fencem 3
261; CHECK-NEXT:    lea %s0, i@lo
262; CHECK-NEXT:    and %s0, %s0, (32)0
263; CHECK-NEXT:    lea.sl %s0, i@hi(, %s0)
264; CHECK-NEXT:    ldl.sx %s1, (, %s0)
265; CHECK-NEXT:    or %s2, 2, (0)1
266; CHECK-NEXT:  .LBB{{[0-9]+}}_1: # %atomicrmw.start
267; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
268; CHECK-NEXT:    or %s3, 0, %s1
269; CHECK-NEXT:    cmpu.w %s4, %s1, %s2
270; CHECK-NEXT:    or %s1, 1, (0)1
271; CHECK-NEXT:    cmov.w.lt %s1, %s3, %s4
272; CHECK-NEXT:    cas.w %s1, (%s0), %s3
273; CHECK-NEXT:    brne.w %s1, %s3, .LBB{{[0-9]+}}_1
274; CHECK-NEXT:  # %bb.2: # %atomicrmw.end
275; CHECK-NEXT:    adds.w.sx %s0, %s1, (0)1
276; CHECK-NEXT:    fencem 3
277; CHECK-NEXT:    b.l.t (, %s10)
278entry:
279  %0 = atomicrmw umin i32* @i, i32 1 seq_cst
280  ret i32 %0
281}
282