Revert " [LoongArch][ISel] Check the number of sign bits in `PatGprGpr_32` (#107432)"
[llvm-project.git] / llvm / test / CodeGen / SystemZ / int-ssub-02.ll
blobf3bc92c1d697f95329b3d907f7981573107a9845
1 ; Test 32-bit subtraction in which the second operand is a sign-extended
2 ; i16 memory value.
4 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
6 declare i32 @foo()
8 ; Check the low end of the SH range.
9 define zeroext i1 @f1(i32 %dummy, i32 %a, ptr %src, ptr %res) {
10 ; CHECK-LABEL: f1:
11 ; CHECK: sh %r3, 0(%r4)
12 ; CHECK-DAG: st %r3, 0(%r5)
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   %half = load i16, ptr %src
18   %b = sext i16 %half to i32
19   %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %a, i32 %b)
20   %val = extractvalue {i32, i1} %t, 0
21   %obit = extractvalue {i32, i1} %t, 1
22   store i32 %val, ptr %res
23   ret i1 %obit
26 ; Check the high end of the aligned SH range.
27 define zeroext i1 @f2(i32 %dummy, i32 %a, ptr %src, ptr %res) {
28 ; CHECK-LABEL: f2:
29 ; CHECK: sh %r3, 4094(%r4)
30 ; CHECK-DAG: st %r3, 0(%r5)
31 ; CHECK-DAG: ipm [[REG:%r[0-5]]]
32 ; CHECK-DAG: afi [[REG]], 1342177280
33 ; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33
34 ; CHECK: br %r14
35   %ptr = getelementptr i16, ptr %src, i64 2047
36   %half = load i16, ptr %ptr
37   %b = sext i16 %half to i32
38   %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %a, i32 %b)
39   %val = extractvalue {i32, i1} %t, 0
40   %obit = extractvalue {i32, i1} %t, 1
41   store i32 %val, ptr %res
42   ret i1 %obit
45 ; Check the next halfword up, which should use SHY instead of SH.
46 define zeroext i1 @f3(i32 %dummy, i32 %a, ptr %src, ptr %res) {
47 ; CHECK-LABEL: f3:
48 ; CHECK: shy %r3, 4096(%r4)
49 ; CHECK-DAG: st %r3, 0(%r5)
50 ; CHECK-DAG: ipm [[REG:%r[0-5]]]
51 ; CHECK-DAG: afi [[REG]], 1342177280
52 ; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33
53 ; CHECK: br %r14
54   %ptr = getelementptr i16, ptr %src, i64 2048
55   %half = load i16, ptr %ptr
56   %b = sext i16 %half to i32
57   %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %a, i32 %b)
58   %val = extractvalue {i32, i1} %t, 0
59   %obit = extractvalue {i32, i1} %t, 1
60   store i32 %val, ptr %res
61   ret i1 %obit
64 ; Check the high end of the aligned SHY range.
65 define zeroext i1 @f4(i32 %dummy, i32 %a, ptr %src, ptr %res) {
66 ; CHECK-LABEL: f4:
67 ; CHECK: shy %r3, 524286(%r4)
68 ; CHECK-DAG: st %r3, 0(%r5)
69 ; CHECK-DAG: ipm [[REG:%r[0-5]]]
70 ; CHECK-DAG: afi [[REG]], 1342177280
71 ; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33
72 ; CHECK: br %r14
73   %ptr = getelementptr i16, ptr %src, i64 262143
74   %half = load i16, ptr %ptr
75   %b = sext i16 %half to i32
76   %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %a, i32 %b)
77   %val = extractvalue {i32, i1} %t, 0
78   %obit = extractvalue {i32, i1} %t, 1
79   store i32 %val, ptr %res
80   ret i1 %obit
83 ; Check the next halfword up, which needs separate address logic.
84 ; Other sequences besides this one would be OK.
85 define zeroext i1 @f5(i32 %dummy, i32 %a, ptr %src, ptr %res) {
86 ; CHECK-LABEL: f5:
87 ; CHECK: agfi %r4, 524288
88 ; CHECK: sh %r3, 0(%r4)
89 ; CHECK-DAG: st %r3, 0(%r5)
90 ; CHECK-DAG: ipm [[REG:%r[0-5]]]
91 ; CHECK-DAG: afi [[REG]], 1342177280
92 ; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33
93 ; CHECK: br %r14
94   %ptr = getelementptr i16, ptr %src, i64 262144
95   %half = load i16, ptr %ptr
96   %b = sext i16 %half to i32
97   %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %a, i32 %b)
98   %val = extractvalue {i32, i1} %t, 0
99   %obit = extractvalue {i32, i1} %t, 1
100   store i32 %val, ptr %res
101   ret i1 %obit
104 ; Check the high end of the negative aligned SHY range.
105 define zeroext i1 @f6(i32 %dummy, i32 %a, ptr %src, ptr %res) {
106 ; CHECK-LABEL: f6:
107 ; CHECK: shy %r3, -2(%r4)
108 ; CHECK-DAG: st %r3, 0(%r5)
109 ; CHECK-DAG: ipm [[REG:%r[0-5]]]
110 ; CHECK-DAG: afi [[REG]], 1342177280
111 ; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33
112 ; CHECK: br %r14
113   %ptr = getelementptr i16, ptr %src, i64 -1
114   %half = load i16, ptr %ptr
115   %b = sext i16 %half to i32
116   %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %a, i32 %b)
117   %val = extractvalue {i32, i1} %t, 0
118   %obit = extractvalue {i32, i1} %t, 1
119   store i32 %val, ptr %res
120   ret i1 %obit
123 ; Check the low end of the SHY range.
124 define zeroext i1 @f7(i32 %dummy, i32 %a, ptr %src, ptr %res) {
125 ; CHECK-LABEL: f7:
126 ; CHECK: shy %r3, -524288(%r4)
127 ; CHECK-DAG: st %r3, 0(%r5)
128 ; CHECK-DAG: ipm [[REG:%r[0-5]]]
129 ; CHECK-DAG: afi [[REG]], 1342177280
130 ; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33
131 ; CHECK: br %r14
132   %ptr = getelementptr i16, ptr %src, i64 -262144
133   %half = load i16, ptr %ptr
134   %b = sext i16 %half to i32
135   %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %a, i32 %b)
136   %val = extractvalue {i32, i1} %t, 0
137   %obit = extractvalue {i32, i1} %t, 1
138   store i32 %val, ptr %res
139   ret i1 %obit
142 ; Check the next halfword down, which needs separate address logic.
143 ; Other sequences besides this one would be OK.
144 define zeroext i1 @f8(i32 %dummy, i32 %a, ptr %src, ptr %res) {
145 ; CHECK-LABEL: f8:
146 ; CHECK: agfi %r4, -524290
147 ; CHECK: sh %r3, 0(%r4)
148 ; CHECK-DAG: st %r3, 0(%r5)
149 ; CHECK-DAG: ipm [[REG:%r[0-5]]]
150 ; CHECK-DAG: afi [[REG]], 1342177280
151 ; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33
152 ; CHECK: br %r14
153   %ptr = getelementptr i16, ptr %src, i64 -262145
154   %half = load i16, ptr %ptr
155   %b = sext i16 %half to i32
156   %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %a, i32 %b)
157   %val = extractvalue {i32, i1} %t, 0
158   %obit = extractvalue {i32, i1} %t, 1
159   store i32 %val, ptr %res
160   ret i1 %obit
163 ; Check that SH allows an index.
164 define zeroext i1 @f9(i64 %src, i64 %index, i32 %a, ptr %res) {
165 ; CHECK-LABEL: f9:
166 ; CHECK: sh %r4, 4094({{%r3,%r2|%r2,%r3}})
167 ; CHECK-DAG: st %r4, 0(%r5)
168 ; CHECK-DAG: ipm [[REG:%r[0-5]]]
169 ; CHECK-DAG: afi [[REG]], 1342177280
170 ; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33
171 ; CHECK: br %r14
172   %add1 = add i64 %src, %index
173   %add2 = add i64 %add1, 4094
174   %ptr = inttoptr i64 %add2 to ptr
175   %half = load i16, ptr %ptr
176   %b = sext i16 %half to i32
177   %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %a, i32 %b)
178   %val = extractvalue {i32, i1} %t, 0
179   %obit = extractvalue {i32, i1} %t, 1
180   store i32 %val, ptr %res
181   ret i1 %obit
184 ; Check that SHY allows an index.
185 define zeroext i1 @f10(i64 %src, i64 %index, i32 %a, ptr %res) {
186 ; CHECK-LABEL: f10:
187 ; CHECK: shy %r4, 4096({{%r3,%r2|%r2,%r3}})
188 ; CHECK-DAG: st %r4, 0(%r5)
189 ; CHECK-DAG: ipm [[REG:%r[0-5]]]
190 ; CHECK-DAG: afi [[REG]], 1342177280
191 ; CHECK-DAG: risbg %r2, [[REG]], 63, 191, 33
192 ; CHECK: br %r14
193   %add1 = add i64 %src, %index
194   %add2 = add i64 %add1, 4096
195   %ptr = inttoptr i64 %add2 to ptr
196   %half = load i16, ptr %ptr
197   %b = sext i16 %half to i32
198   %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %a, i32 %b)
199   %val = extractvalue {i32, i1} %t, 0
200   %obit = extractvalue {i32, i1} %t, 1
201   store i32 %val, ptr %res
202   ret i1 %obit
205 ; Check using the overflow result for a branch.
206 define void @f11(i32 %dummy, i32 %a, ptr %src, ptr %res) {
207 ; CHECK-LABEL: f11:
208 ; CHECK: sh %r3, 0(%r4)
209 ; CHECK: st %r3, 0(%r5)
210 ; CHECK: jgo foo@PLT
211 ; CHECK: br %r14
212   %half = load i16, ptr %src
213   %b = sext i16 %half to i32
214   %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %a, i32 %b)
215   %val = extractvalue {i32, i1} %t, 0
216   %obit = extractvalue {i32, i1} %t, 1
217   store i32 %val, ptr %res
218   br i1 %obit, label %call, label %exit
220 call:
221   tail call i32 @foo()
222   br label %exit
224 exit:
225   ret void
228 ; ... and the same with the inverted direction.
229 define void @f12(i32 %dummy, i32 %a, ptr %src, ptr %res) {
230 ; CHECK-LABEL: f12:
231 ; CHECK: sh %r3, 0(%r4)
232 ; CHECK: st %r3, 0(%r5)
233 ; CHECK: jgno foo@PLT
234 ; CHECK: br %r14
235   %half = load i16, ptr %src
236   %b = sext i16 %half to i32
237   %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %a, i32 %b)
238   %val = extractvalue {i32, i1} %t, 0
239   %obit = extractvalue {i32, i1} %t, 1
240   store i32 %val, ptr %res
241   br i1 %obit, label %exit, label %call
243 call:
244   tail call i32 @foo()
245   br label %exit
247 exit:
248   ret void
252 declare {i32, i1} @llvm.ssub.with.overflow.i32(i32, i32) nounwind readnone