xref: /llvm-project/llvm/test/CodeGen/SystemZ/atomicrmw-minmax-04.ll (revision 435ba72afda756183a1ddc7a3a160152ad630951)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
2; Test 64-bit atomic minimum and maximum.  Here we match the z10 versions,
3; which can't use LOCGR.
4;
5; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s
6
7; Todo: If-converter no longer producing CondReturns (with AtomicExpand pass).
8
9; Check signed minimum.
10define i64 @f1(i64 %dummy, ptr %src, i64 %b) {
11; CHECK-LABEL: f1:
12; CHECK:       # %bb.0:
13; CHECK-NEXT:    lg %r2, 0(%r3)
14; CHECK-NEXT:    j .LBB0_2
15; CHECK-NEXT:  .LBB0_1: # %atomicrmw.start
16; CHECK-NEXT:    # in Loop: Header=BB0_2 Depth=1
17; CHECK-NEXT:    csg %r2, %r0, 0(%r3)
18; CHECK-NEXT:    je .LBB0_4
19; CHECK-NEXT:  .LBB0_2: # %atomicrmw.start
20; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
21; CHECK-NEXT:    lgr %r0, %r2
22; CHECK-NEXT:    cgrjle %r2, %r4, .LBB0_1
23; CHECK-NEXT:  # %bb.3: # %atomicrmw.start
24; CHECK-NEXT:    # in Loop: Header=BB0_2 Depth=1
25; CHECK-NEXT:    lgr %r0, %r4
26; CHECK-NEXT:    j .LBB0_1
27; CHECK-NEXT:  .LBB0_4: # %atomicrmw.end
28; CHECK-NEXT:    br %r14
29  %res = atomicrmw min ptr %src, i64 %b seq_cst
30  ret i64 %res
31}
32
33; Check signed maximum.
34define i64 @f2(i64 %dummy, ptr %src, i64 %b) {
35; CHECK-LABEL: f2:
36; CHECK:       # %bb.0:
37; CHECK-NEXT:    lg %r2, 0(%r3)
38; CHECK-NEXT:    j .LBB1_2
39; CHECK-NEXT:  .LBB1_1: # %atomicrmw.start
40; CHECK-NEXT:    # in Loop: Header=BB1_2 Depth=1
41; CHECK-NEXT:    csg %r2, %r0, 0(%r3)
42; CHECK-NEXT:    je .LBB1_4
43; CHECK-NEXT:  .LBB1_2: # %atomicrmw.start
44; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
45; CHECK-NEXT:    lgr %r0, %r2
46; CHECK-NEXT:    cgrjh %r2, %r4, .LBB1_1
47; CHECK-NEXT:  # %bb.3: # %atomicrmw.start
48; CHECK-NEXT:    # in Loop: Header=BB1_2 Depth=1
49; CHECK-NEXT:    lgr %r0, %r4
50; CHECK-NEXT:    j .LBB1_1
51; CHECK-NEXT:  .LBB1_4: # %atomicrmw.end
52; CHECK-NEXT:    br %r14
53  %res = atomicrmw max ptr %src, i64 %b seq_cst
54  ret i64 %res
55}
56
57; Check unsigned minimum.
58define i64 @f3(i64 %dummy, ptr %src, i64 %b) {
59; CHECK-LABEL: f3:
60; CHECK:       # %bb.0:
61; CHECK-NEXT:    lg %r2, 0(%r3)
62; CHECK-NEXT:    j .LBB2_2
63; CHECK-NEXT:  .LBB2_1: # %atomicrmw.start
64; CHECK-NEXT:    # in Loop: Header=BB2_2 Depth=1
65; CHECK-NEXT:    csg %r2, %r0, 0(%r3)
66; CHECK-NEXT:    je .LBB2_4
67; CHECK-NEXT:  .LBB2_2: # %atomicrmw.start
68; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
69; CHECK-NEXT:    lgr %r0, %r2
70; CHECK-NEXT:    clgrjle %r2, %r4, .LBB2_1
71; CHECK-NEXT:  # %bb.3: # %atomicrmw.start
72; CHECK-NEXT:    # in Loop: Header=BB2_2 Depth=1
73; CHECK-NEXT:    lgr %r0, %r4
74; CHECK-NEXT:    j .LBB2_1
75; CHECK-NEXT:  .LBB2_4: # %atomicrmw.end
76; CHECK-NEXT:    br %r14
77  %res = atomicrmw umin ptr %src, i64 %b seq_cst
78  ret i64 %res
79}
80
81; Check unsigned maximum.
82define i64 @f4(i64 %dummy, ptr %src, i64 %b) {
83; CHECK-LABEL: f4:
84; CHECK:       # %bb.0:
85; CHECK-NEXT:    lg %r2, 0(%r3)
86; CHECK-NEXT:    j .LBB3_2
87; CHECK-NEXT:  .LBB3_1: # %atomicrmw.start
88; CHECK-NEXT:    # in Loop: Header=BB3_2 Depth=1
89; CHECK-NEXT:    csg %r2, %r0, 0(%r3)
90; CHECK-NEXT:    je .LBB3_4
91; CHECK-NEXT:  .LBB3_2: # %atomicrmw.start
92; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
93; CHECK-NEXT:    lgr %r0, %r2
94; CHECK-NEXT:    clgrjh %r2, %r4, .LBB3_1
95; CHECK-NEXT:  # %bb.3: # %atomicrmw.start
96; CHECK-NEXT:    # in Loop: Header=BB3_2 Depth=1
97; CHECK-NEXT:    lgr %r0, %r4
98; CHECK-NEXT:    j .LBB3_1
99; CHECK-NEXT:  .LBB3_4: # %atomicrmw.end
100; CHECK-NEXT:    br %r14
101  %res = atomicrmw umax ptr %src, i64 %b seq_cst
102  ret i64 %res
103}
104
105; Check the high end of the aligned CSG range.
106define i64 @f5(i64 %dummy, ptr %src, i64 %b) {
107; CHECK-LABEL: f5:
108; CHECK:       # %bb.0:
109; CHECK-NEXT:    lg %r2, 524280(%r3)
110; CHECK-NEXT:    j .LBB4_2
111; CHECK-NEXT:  .LBB4_1: # %atomicrmw.start
112; CHECK-NEXT:    # in Loop: Header=BB4_2 Depth=1
113; CHECK-NEXT:    csg %r2, %r0, 524280(%r3)
114; CHECK-NEXT:    je .LBB4_4
115; CHECK-NEXT:  .LBB4_2: # %atomicrmw.start
116; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
117; CHECK-NEXT:    lgr %r0, %r2
118; CHECK-NEXT:    cgrjle %r2, %r4, .LBB4_1
119; CHECK-NEXT:  # %bb.3: # %atomicrmw.start
120; CHECK-NEXT:    # in Loop: Header=BB4_2 Depth=1
121; CHECK-NEXT:    lgr %r0, %r4
122; CHECK-NEXT:    j .LBB4_1
123; CHECK-NEXT:  .LBB4_4: # %atomicrmw.end
124; CHECK-NEXT:    br %r14
125  %ptr = getelementptr i64, ptr %src, i64 65535
126  %res = atomicrmw min ptr %ptr, i64 %b seq_cst
127  ret i64 %res
128}
129
130; Check the next doubleword up, which requires separate address logic.
131define i64 @f6(i64 %dummy, ptr %src, i64 %b) {
132; CHECK-LABEL: f6:
133; CHECK:       # %bb.0:
134; CHECK-NEXT:    agfi %r3, 524288
135; CHECK-NEXT:    lg %r2, 0(%r3)
136; CHECK-NEXT:    j .LBB5_2
137; CHECK-NEXT:  .LBB5_1: # %atomicrmw.start
138; CHECK-NEXT:    # in Loop: Header=BB5_2 Depth=1
139; CHECK-NEXT:    csg %r2, %r0, 0(%r3)
140; CHECK-NEXT:    je .LBB5_4
141; CHECK-NEXT:  .LBB5_2: # %atomicrmw.start
142; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
143; CHECK-NEXT:    lgr %r0, %r2
144; CHECK-NEXT:    cgrjle %r2, %r4, .LBB5_1
145; CHECK-NEXT:  # %bb.3: # %atomicrmw.start
146; CHECK-NEXT:    # in Loop: Header=BB5_2 Depth=1
147; CHECK-NEXT:    lgr %r0, %r4
148; CHECK-NEXT:    j .LBB5_1
149; CHECK-NEXT:  .LBB5_4: # %atomicrmw.end
150; CHECK-NEXT:    br %r14
151  %ptr = getelementptr i64, ptr %src, i64 65536
152  %res = atomicrmw min ptr %ptr, i64 %b seq_cst
153  ret i64 %res
154}
155
156; Check the low end of the CSG range.
157define i64 @f7(i64 %dummy, ptr %src, i64 %b) {
158; CHECK-LABEL: f7:
159; CHECK:       # %bb.0:
160; CHECK-NEXT:    lg %r2, -524288(%r3)
161; CHECK-NEXT:    j .LBB6_2
162; CHECK-NEXT:  .LBB6_1: # %atomicrmw.start
163; CHECK-NEXT:    # in Loop: Header=BB6_2 Depth=1
164; CHECK-NEXT:    csg %r2, %r0, -524288(%r3)
165; CHECK-NEXT:    je .LBB6_4
166; CHECK-NEXT:  .LBB6_2: # %atomicrmw.start
167; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
168; CHECK-NEXT:    lgr %r0, %r2
169; CHECK-NEXT:    cgrjle %r2, %r4, .LBB6_1
170; CHECK-NEXT:  # %bb.3: # %atomicrmw.start
171; CHECK-NEXT:    # in Loop: Header=BB6_2 Depth=1
172; CHECK-NEXT:    lgr %r0, %r4
173; CHECK-NEXT:    j .LBB6_1
174; CHECK-NEXT:  .LBB6_4: # %atomicrmw.end
175; CHECK-NEXT:    br %r14
176  %ptr = getelementptr i64, ptr %src, i64 -65536
177  %res = atomicrmw min ptr %ptr, i64 %b seq_cst
178  ret i64 %res
179}
180
181; Check the next doubleword down, which requires separate address logic.
182define i64 @f8(i64 %dummy, ptr %src, i64 %b) {
183; CHECK-LABEL: f8:
184; CHECK:       # %bb.0:
185; CHECK-NEXT:    agfi %r3, -524296
186; CHECK-NEXT:    lg %r2, 0(%r3)
187; CHECK-NEXT:    j .LBB7_2
188; CHECK-NEXT:  .LBB7_1: # %atomicrmw.start
189; CHECK-NEXT:    # in Loop: Header=BB7_2 Depth=1
190; CHECK-NEXT:    csg %r2, %r0, 0(%r3)
191; CHECK-NEXT:    je .LBB7_4
192; CHECK-NEXT:  .LBB7_2: # %atomicrmw.start
193; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
194; CHECK-NEXT:    lgr %r0, %r2
195; CHECK-NEXT:    cgrjle %r2, %r4, .LBB7_1
196; CHECK-NEXT:  # %bb.3: # %atomicrmw.start
197; CHECK-NEXT:    # in Loop: Header=BB7_2 Depth=1
198; CHECK-NEXT:    lgr %r0, %r4
199; CHECK-NEXT:    j .LBB7_1
200; CHECK-NEXT:  .LBB7_4: # %atomicrmw.end
201; CHECK-NEXT:    br %r14
202  %ptr = getelementptr i64, ptr %src, i64 -65537
203  %res = atomicrmw min ptr %ptr, i64 %b seq_cst
204  ret i64 %res
205}
206
207; Check that indexed addresses are not allowed.
208define i64 @f9(i64 %dummy, i64 %base, i64 %index, i64 %b) {
209; CHECK-LABEL: f9:
210; CHECK:       # %bb.0:
211; CHECK-NEXT:    lg %r2, 0(%r4,%r3)
212; CHECK-NEXT:    agr %r3, %r4
213; CHECK-NEXT:    j .LBB8_2
214; CHECK-NEXT:  .LBB8_1: # %atomicrmw.start
215; CHECK-NEXT:    # in Loop: Header=BB8_2 Depth=1
216; CHECK-NEXT:    csg %r2, %r0, 0(%r3)
217; CHECK-NEXT:    je .LBB8_4
218; CHECK-NEXT:  .LBB8_2: # %atomicrmw.start
219; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
220; CHECK-NEXT:    lgr %r0, %r2
221; CHECK-NEXT:    cgrjle %r2, %r5, .LBB8_1
222; CHECK-NEXT:  # %bb.3: # %atomicrmw.start
223; CHECK-NEXT:    # in Loop: Header=BB8_2 Depth=1
224; CHECK-NEXT:    lgr %r0, %r5
225; CHECK-NEXT:    j .LBB8_1
226; CHECK-NEXT:  .LBB8_4: # %atomicrmw.end
227; CHECK-NEXT:    br %r14
228  %add = add i64 %base, %index
229  %ptr = inttoptr i64 %add to ptr
230  %res = atomicrmw min ptr %ptr, i64 %b seq_cst
231  ret i64 %res
232}
233
234; Check that constants are handled.
235define i64 @f10(i64 %dummy, ptr %ptr) {
236; CHECK-LABEL: f10:
237; CHECK:       # %bb.0:
238; CHECK-NEXT:    lg %r2, 0(%r3)
239; CHECK-NEXT:    j .LBB9_2
240; CHECK-NEXT:  .LBB9_1: # %atomicrmw.start
241; CHECK-NEXT:    # in Loop: Header=BB9_2 Depth=1
242; CHECK-NEXT:    csg %r2, %r0, 0(%r3)
243; CHECK-NEXT:    je .LBB9_4
244; CHECK-NEXT:  .LBB9_2: # %atomicrmw.start
245; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
246; CHECK-NEXT:    lgr %r0, %r2
247; CHECK-NEXT:    cgijl %r2, 43, .LBB9_1
248; CHECK-NEXT:  # %bb.3: # %atomicrmw.start
249; CHECK-NEXT:    # in Loop: Header=BB9_2 Depth=1
250; CHECK-NEXT:    lghi %r0, 42
251; CHECK-NEXT:    j .LBB9_1
252; CHECK-NEXT:  .LBB9_4: # %atomicrmw.end
253; CHECK-NEXT:    br %r14
254  %res = atomicrmw min ptr %ptr, i64 42 seq_cst
255  ret i64 %res
256}
257