1; Test 64-bit atomic minimum and maximum.  Here we match the z10 versions,
2; which can't use LOCGR.
3;
4; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s
5
6; Check signed minium.
7define i64 @f1(i64 %dummy, i64 *%src, i64 %b) {
8; CHECK-LABEL: f1:
9; CHECK: lg %r2, 0(%r3)
10; CHECK: [[LOOP:\.[^:]*]]:
11; CHECK: lgr [[NEW:%r[0-9]+]], %r2
12; CHECK: cgrjle %r2, %r4, [[KEEP:\..*]]
13; CHECK: lgr [[NEW]], %r4
14; CHECK: csg %r2, [[NEW]], 0(%r3)
15; CHECK: jl [[LOOP]]
16; CHECK: br %r14
17  %res = atomicrmw min i64 *%src, i64 %b seq_cst
18  ret i64 %res
19}
20
21; Check signed maximum.
22define i64 @f2(i64 %dummy, i64 *%src, i64 %b) {
23; CHECK-LABEL: f2:
24; CHECK: lg %r2, 0(%r3)
25; CHECK: [[LOOP:\.[^:]*]]:
26; CHECK: lgr [[NEW:%r[0-9]+]], %r2
27; CHECK: cgrjhe %r2, %r4, [[KEEP:\..*]]
28; CHECK: lgr [[NEW]], %r4
29; CHECK: csg %r2, [[NEW]], 0(%r3)
30; CHECK: jl [[LOOP]]
31; CHECK: br %r14
32  %res = atomicrmw max i64 *%src, i64 %b seq_cst
33  ret i64 %res
34}
35
36; Check unsigned minimum.
37define i64 @f3(i64 %dummy, i64 *%src, i64 %b) {
38; CHECK-LABEL: f3:
39; CHECK: lg %r2, 0(%r3)
40; CHECK: [[LOOP:\.[^:]*]]:
41; CHECK: lgr [[NEW:%r[0-9]+]], %r2
42; CHECK: clgrjle %r2, %r4, [[KEEP:\..*]]
43; CHECK: lgr [[NEW]], %r4
44; CHECK: csg %r2, [[NEW]], 0(%r3)
45; CHECK: jl [[LOOP]]
46; CHECK: br %r14
47  %res = atomicrmw umin i64 *%src, i64 %b seq_cst
48  ret i64 %res
49}
50
51; Check unsigned maximum.
52define i64 @f4(i64 %dummy, i64 *%src, i64 %b) {
53; CHECK-LABEL: f4:
54; CHECK: lg %r2, 0(%r3)
55; CHECK: [[LOOP:\.[^:]*]]:
56; CHECK: lgr [[NEW:%r[0-9]+]], %r2
57; CHECK: clgrjhe %r2, %r4, [[KEEP:\..*]]
58; CHECK: lgr [[NEW]], %r4
59; CHECK: csg %r2, [[NEW]], 0(%r3)
60; CHECK: jl [[LOOP]]
61; CHECK: br %r14
62  %res = atomicrmw umax i64 *%src, i64 %b seq_cst
63  ret i64 %res
64}
65
66; Check the high end of the aligned CSG range.
67define i64 @f5(i64 %dummy, i64 *%src, i64 %b) {
68; CHECK-LABEL: f5:
69; CHECK: lg %r2, 524280(%r3)
70; CHECK: csg %r2, {{%r[0-9]+}}, 524280(%r3)
71; CHECK: br %r14
72  %ptr = getelementptr i64 *%src, i64 65535
73  %res = atomicrmw min i64 *%ptr, i64 %b seq_cst
74  ret i64 %res
75}
76
77; Check the next doubleword up, which requires separate address logic.
78define i64 @f6(i64 %dummy, i64 *%src, i64 %b) {
79; CHECK-LABEL: f6:
80; CHECK: agfi %r3, 524288
81; CHECK: lg %r2, 0(%r3)
82; CHECK: csg %r2, {{%r[0-9]+}}, 0(%r3)
83; CHECK: br %r14
84  %ptr = getelementptr i64 *%src, i64 65536
85  %res = atomicrmw min i64 *%ptr, i64 %b seq_cst
86  ret i64 %res
87}
88
89; Check the low end of the CSG range.
90define i64 @f7(i64 %dummy, i64 *%src, i64 %b) {
91; CHECK-LABEL: f7:
92; CHECK: lg %r2, -524288(%r3)
93; CHECK: csg %r2, {{%r[0-9]+}}, -524288(%r3)
94; CHECK: br %r14
95  %ptr = getelementptr i64 *%src, i64 -65536
96  %res = atomicrmw min i64 *%ptr, i64 %b seq_cst
97  ret i64 %res
98}
99
100; Check the next doubleword down, which requires separate address logic.
101define i64 @f8(i64 %dummy, i64 *%src, i64 %b) {
102; CHECK-LABEL: f8:
103; CHECK: agfi %r3, -524296
104; CHECK: lg %r2, 0(%r3)
105; CHECK: csg %r2, {{%r[0-9]+}}, 0(%r3)
106; CHECK: br %r14
107  %ptr = getelementptr i64 *%src, i64 -65537
108  %res = atomicrmw min i64 *%ptr, i64 %b seq_cst
109  ret i64 %res
110}
111
112; Check that indexed addresses are not allowed.
113define i64 @f9(i64 %dummy, i64 %base, i64 %index, i64 %b) {
114; CHECK-LABEL: f9:
115; CHECK: agr %r3, %r4
116; CHECK: lg %r2, 0(%r3)
117; CHECK: csg %r2, {{%r[0-9]+}}, 0(%r3)
118; CHECK: br %r14
119  %add = add i64 %base, %index
120  %ptr = inttoptr i64 %add to i64 *
121  %res = atomicrmw min i64 *%ptr, i64 %b seq_cst
122  ret i64 %res
123}
124
125; Check that constants are handled.
126define i64 @f10(i64 %dummy, i64 *%ptr) {
127; CHECK-LABEL: f10:
128; CHECK: lghi [[LIMIT:%r[0-9]+]], 42
129; CHECK: lg %r2, 0(%r3)
130; CHECK: [[LOOP:\.[^:]*]]:
131; CHECK: lgr [[NEW:%r[0-9]+]], %r2
132; CHECK: cgrjle %r2, [[LIMIT]], [[KEEP:\..*]]
133; CHECK: lghi [[NEW]], 42
134; CHECK: csg %r2, [[NEW]], 0(%r3)
135; CHECK: jl [[LOOP]]
136; CHECK: br %r14
137  %res = atomicrmw min i64 *%ptr, i64 42 seq_cst
138  ret i64 %res
139}
140