1; Test 64-bit subtraction in which the second operand is constant.
2;
3; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s
4; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
5
6declare i32 @foo()
7
8; Check subtractions of 1.
9define zeroext i1 @f1(i64 %dummy, i64 %a, i64 *%res) {
10; CHECK-LABEL: f1:
11; CHECK: aghi %r3, -1
12; CHECK-DAG: stg %r3, 0(%r4)
13; CHECK-DAG: ipm [[REG:%r[0-5]]]
14; CHECK-DAG: afi [[REG]], 1342177280
15; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33
16; CHECK: br %r14
17  %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 1)
18  %val = extractvalue {i64, i1} %t, 0
19  %obit = extractvalue {i64, i1} %t, 1
20  store i64 %val, i64 *%res
21  ret i1 %obit
22
23}
24
25; Check the high end of the SGHI range.
26define zeroext i1 @f2(i64 %dummy, i64 %a, i64 *%res) {
27; CHECK-LABEL: f2:
28; CHECK: aghi %r3, -32768
29; CHECK-DAG: stg %r3, 0(%r4)
30; CHECK-DAG: ipm [[REG:%r[0-5]]]
31; CHECK-DAG: afi [[REG]], 1342177280
32; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33
33; CHECK: br %r14
34  %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 32768)
35  %val = extractvalue {i64, i1} %t, 0
36  %obit = extractvalue {i64, i1} %t, 1
37  store i64 %val, i64 *%res
38  ret i1 %obit
39}
40
41; Check the next value up, which must use SGFI instead.
42define zeroext i1 @f3(i64 %dummy, i64 %a, i64 *%res) {
43; CHECK-LABEL: f3:
44; CHECK: agfi %r3, -32769
45; CHECK-DAG: stg %r3, 0(%r4)
46; CHECK-DAG: ipm [[REG:%r[0-5]]]
47; CHECK-DAG: afi [[REG]], 1342177280
48; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33
49; CHECK: br %r14
50  %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 32769)
51  %val = extractvalue {i64, i1} %t, 0
52  %obit = extractvalue {i64, i1} %t, 1
53  store i64 %val, i64 *%res
54  ret i1 %obit
55}
56
57; Check the high end of the SGFI range.
58define zeroext i1 @f4(i64 %dummy, i64 %a, i64 *%res) {
59; CHECK-LABEL: f4:
60; CHECK: agfi %r3, -2147483648
61; CHECK-DAG: stg %r3, 0(%r4)
62; CHECK-DAG: ipm [[REG:%r[0-5]]]
63; CHECK-DAG: afi [[REG]], 1342177280
64; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33
65; CHECK: br %r14
66  %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 2147483648)
67  %val = extractvalue {i64, i1} %t, 0
68  %obit = extractvalue {i64, i1} %t, 1
69  store i64 %val, i64 *%res
70  ret i1 %obit
71}
72
73; Check the next value up, which must be loaded into a register first.
74define zeroext i1 @f5(i64 %dummy, i64 %a, i64 *%res) {
75; CHECK-LABEL: f5:
76; CHECK: llilf [[REG1:%r[0-9]+]], 2147483649
77; CHECK: sgr %r3, [[REG1]]
78; CHECK-DAG: stg %r3, 0(%r4)
79; CHECK-DAG: ipm [[REG:%r[0-5]]]
80; CHECK-DAG: afi [[REG]], 1342177280
81; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33
82; CHECK: br %r14
83  %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 2147483649)
84  %val = extractvalue {i64, i1} %t, 0
85  %obit = extractvalue {i64, i1} %t, 1
86  store i64 %val, i64 *%res
87  ret i1 %obit
88}
89
90; Check the high end of the negative SGHI range.
91define zeroext i1 @f6(i64 %dummy, i64 %a, i64 *%res) {
92; CHECK-LABEL: f6:
93; CHECK: aghi %r3, 1
94; CHECK-DAG: stg %r3, 0(%r4)
95; CHECK-DAG: ipm [[REG:%r[0-5]]]
96; CHECK-DAG: afi [[REG]], 1342177280
97; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33
98; CHECK: br %r14
99  %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 -1)
100  %val = extractvalue {i64, i1} %t, 0
101  %obit = extractvalue {i64, i1} %t, 1
102  store i64 %val, i64 *%res
103  ret i1 %obit
104}
105
106; Check the low end of the SGHI range.
107define zeroext i1 @f7(i64 %dummy, i64 %a, i64 *%res) {
108; CHECK-LABEL: f7:
109; CHECK: aghi %r3, 32767
110; CHECK-DAG: stg %r3, 0(%r4)
111; CHECK-DAG: ipm [[REG:%r[0-5]]]
112; CHECK-DAG: afi [[REG]], 1342177280
113; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33
114; CHECK: br %r14
115  %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 -32767)
116  %val = extractvalue {i64, i1} %t, 0
117  %obit = extractvalue {i64, i1} %t, 1
118  store i64 %val, i64 *%res
119  ret i1 %obit
120}
121
122; Check the next value down, which must use SGFI instead.
123define zeroext i1 @f8(i64 %dummy, i64 %a, i64 *%res) {
124; CHECK-LABEL: f8:
125; CHECK: agfi %r3, 32768
126; CHECK-DAG: stg %r3, 0(%r4)
127; CHECK-DAG: ipm [[REG:%r[0-5]]]
128; CHECK-DAG: afi [[REG]], 1342177280
129; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33
130; CHECK: br %r14
131  %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 -32768)
132  %val = extractvalue {i64, i1} %t, 0
133  %obit = extractvalue {i64, i1} %t, 1
134  store i64 %val, i64 *%res
135  ret i1 %obit
136}
137
138; Check the low end of the SGFI range.
139define zeroext i1 @f9(i64 %dummy, i64 %a, i64 *%res) {
140; CHECK-LABEL: f9:
141; CHECK: agfi %r3, 2147483647
142; CHECK-DAG: stg %r3, 0(%r4)
143; CHECK-DAG: ipm [[REG:%r[0-5]]]
144; CHECK-DAG: afi [[REG]], 1342177280
145; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33
146; CHECK: br %r14
147  %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 -2147483647)
148  %val = extractvalue {i64, i1} %t, 0
149  %obit = extractvalue {i64, i1} %t, 1
150  store i64 %val, i64 *%res
151  ret i1 %obit
152}
153
154; Check the next value down, which must use register subtraction instead.
155define zeroext i1 @f10(i64 %dummy, i64 %a, i64 *%res) {
156; CHECK-LABEL: f10:
157; CHECK: llilh [[REG1:%r[0-9]+]], 32768
158; CHECK: agr [[REG1]], %r3
159; CHECK-DAG: stg [[REG1]], 0(%r4)
160; CHECK-DAG: ipm [[REG:%r[0-5]]]
161; CHECK-DAG: afi [[REG]], 1342177280
162; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33
163; CHECK: br %r14
164  %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 -2147483648)
165  %val = extractvalue {i64, i1} %t, 0
166  %obit = extractvalue {i64, i1} %t, 1
167  store i64 %val, i64 *%res
168  ret i1 %obit
169}
170
171; Check using the overflow result for a branch.
172define void @f11(i64 %dummy, i64 %a, i64 *%res) {
173; CHECK-LABEL: f11:
174; CHECK: aghi %r3, -1
175; CHECK: stg %r3, 0(%r4)
176; CHECK: {{jgo foo@PLT|bnor %r14}}
177; CHECK: {{br %r14|jg foo@PLT}}
178  %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 1)
179  %val = extractvalue {i64, i1} %t, 0
180  %obit = extractvalue {i64, i1} %t, 1
181  store i64 %val, i64 *%res
182  br i1 %obit, label %call, label %exit
183
184call:
185  tail call i32 @foo()
186  br label %exit
187
188exit:
189  ret void
190}
191
192; ... and the same with the inverted direction.
193define void @f12(i64 %dummy, i64 %a, i64 *%res) {
194; CHECK-LABEL: f12:
195; CHECK: aghi %r3, -1
196; CHECK: stg %r3, 0(%r4)
197; CHECK: {{jgno foo@PLT|bor %r14}}
198; CHECK: {{br %r14|jg foo@PLT}}
199  %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %a, i64 1)
200  %val = extractvalue {i64, i1} %t, 0
201  %obit = extractvalue {i64, i1} %t, 1
202  store i64 %val, i64 *%res
203  br i1 %obit, label %exit, label %call
204
205call:
206  tail call i32 @foo()
207  br label %exit
208
209exit:
210  ret void
211}
212
213declare {i64, i1} @llvm.ssub.with.overflow.i64(i64, i64) nounwind readnone
214
215