1 ; Test 32-bit addition in which the second operand is a sign-extended
4 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
8 ; Check the low end of the AH range.
9 define zeroext i1 @f1(i32 %dummy, i32 %a, i16 *%src, i32 *%res) {
11 ; CHECK: ah %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
17 %half = load i16, i16 *%src
18 %b = sext i16 %half to i32
19 %t = call {i32, i1} @llvm.sadd.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, i32 *%res
26 ; Check the high end of the aligned AH range.
27 define zeroext i1 @f2(i32 %dummy, i32 %a, i16 *%src, i32 *%res) {
29 ; CHECK: ah %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
35 %ptr = getelementptr i16, i16 *%src, i64 2047
36 %half = load i16, i16 *%ptr
37 %b = sext i16 %half to i32
38 %t = call {i32, i1} @llvm.sadd.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, i32 *%res
45 ; Check the next halfword up, which should use AHY instead of AH.
46 define zeroext i1 @f3(i32 %dummy, i32 %a, i16 *%src, i32 *%res) {
48 ; CHECK: ahy %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
54 %ptr = getelementptr i16, i16 *%src, i64 2048
55 %half = load i16, i16 *%ptr
56 %b = sext i16 %half to i32
57 %t = call {i32, i1} @llvm.sadd.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, i32 *%res
64 ; Check the high end of the aligned AHY range.
65 define zeroext i1 @f4(i32 %dummy, i32 %a, i16 *%src, i32 *%res) {
67 ; CHECK: ahy %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
73 %ptr = getelementptr i16, i16 *%src, i64 262143
74 %half = load i16, i16 *%ptr
75 %b = sext i16 %half to i32
76 %t = call {i32, i1} @llvm.sadd.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, i32 *%res
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, i16 *%src, i32 *%res) {
87 ; CHECK: agfi %r4, 524288
88 ; CHECK: ah %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
94 %ptr = getelementptr i16, i16 *%src, i64 262144
95 %half = load i16, i16 *%ptr
96 %b = sext i16 %half to i32
97 %t = call {i32, i1} @llvm.sadd.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, i32 *%res
104 ; Check the high end of the negative aligned AHY range.
105 define zeroext i1 @f6(i32 %dummy, i32 %a, i16 *%src, i32 *%res) {
107 ; CHECK: ahy %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
113 %ptr = getelementptr i16, i16 *%src, i64 -1
114 %half = load i16, i16 *%ptr
115 %b = sext i16 %half to i32
116 %t = call {i32, i1} @llvm.sadd.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, i32 *%res
123 ; Check the low end of the AHY range.
124 define zeroext i1 @f7(i32 %dummy, i32 %a, i16 *%src, i32 *%res) {
126 ; CHECK: ahy %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
132 %ptr = getelementptr i16, i16 *%src, i64 -262144
133 %half = load i16, i16 *%ptr
134 %b = sext i16 %half to i32
135 %t = call {i32, i1} @llvm.sadd.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, i32 *%res
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, i16 *%src, i32 *%res) {
146 ; CHECK: agfi %r4, -524290
147 ; CHECK: ah %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
153 %ptr = getelementptr i16, i16 *%src, i64 -262145
154 %half = load i16, i16 *%ptr
155 %b = sext i16 %half to i32
156 %t = call {i32, i1} @llvm.sadd.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, i32 *%res
163 ; Check that AH allows an index.
164 define zeroext i1 @f9(i64 %src, i64 %index, i32 %a, i32 *%res) {
166 ; CHECK: ah %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
172 %add1 = add i64 %src, %index
173 %add2 = add i64 %add1, 4094
174 %ptr = inttoptr i64 %add2 to i16 *
175 %half = load i16, i16 *%ptr
176 %b = sext i16 %half to i32
177 %t = call {i32, i1} @llvm.sadd.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, i32 *%res
184 ; Check that AHY allows an index.
185 define zeroext i1 @f10(i64 %src, i64 %index, i32 %a, i32 *%res) {
187 ; CHECK: ahy %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
193 %add1 = add i64 %src, %index
194 %add2 = add i64 %add1, 4096
195 %ptr = inttoptr i64 %add2 to i16 *
196 %half = load i16, i16 *%ptr
197 %b = sext i16 %half to i32
198 %t = call {i32, i1} @llvm.sadd.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, i32 *%res
205 ; Check using the overflow result for a branch.
206 define void @f11(i32 %dummy, i32 %a, i16 *%src, i32 *%res) {
208 ; CHECK: ah %r3, 0(%r4)
209 ; CHECK: st %r3, 0(%r5)
212 %half = load i16, i16 *%src
213 %b = sext i16 %half to i32
214 %t = call {i32, i1} @llvm.sadd.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, i32 *%res
218 br i1 %obit, label %call, label %exit
228 ; ... and the same with the inverted direction.
229 define void @f12(i32 %dummy, i32 %a, i16 *%src, i32 *%res) {
231 ; CHECK: ah %r3, 0(%r4)
232 ; CHECK: st %r3, 0(%r5)
233 ; CHECK: jgno foo@PLT
235 %half = load i16, i16 *%src
236 %b = sext i16 %half to i32
237 %t = call {i32, i1} @llvm.sadd.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, i32 *%res
241 br i1 %obit, label %exit, label %call
252 declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone