blob: dd3b00a4bb0f4c7394d41af99122ac22a25f058e [file] [log] [blame]
Ulrich Weigandc3ec80f2018-04-30 17:54:28 +00001; 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: lgfi [[REG1:%r[0-9]+]], -2147483648
158; CHECK: sgr %r3, [[REG1]]
159; CHECK-DAG: stg %r3, 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