1 ; Test sequences that can use RISBG with a zeroed first operand.
3 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
5 ; Test an extraction of bit 0 from a right-shifted value.
6 define i32 @f1(i32 %foo) {
8 ; CHECK: risbg %r2, %r2, 63, 191, 54
10 %shr = lshr i32 %foo, 10
11 %and = and i32 %shr, 1
15 ; ...and again with i64.
16 define i64 @f2(i64 %foo) {
18 ; CHECK: risbg %r2, %r2, 63, 191, 54
20 %shr = lshr i64 %foo, 10
21 %and = and i64 %shr, 1
25 ; Test an extraction of other bits from a right-shifted value.
26 define i32 @f3(i32 %foo) {
28 ; CHECK: risbg %r2, %r2, 60, 189, 42
30 %shr = lshr i32 %foo, 22
31 %and = and i32 %shr, 12
35 ; ...and again with i64.
36 define i64 @f4(i64 %foo) {
38 ; CHECK: risbg %r2, %r2, 60, 189, 42
40 %shr = lshr i64 %foo, 22
41 %and = and i64 %shr, 12
45 ; Test an extraction of most bits from a right-shifted value.
46 ; The range should be reduced to exclude the zeroed high bits.
47 define i32 @f5(i32 %foo) {
49 ; CHECK: risbg %r2, %r2, 34, 188, 62
51 %shr = lshr i32 %foo, 2
52 %and = and i32 %shr, -8
56 ; ...and again with i64.
57 define i64 @f6(i64 %foo) {
59 ; CHECK: risbg %r2, %r2, 2, 188, 62
61 %shr = lshr i64 %foo, 2
62 %and = and i64 %shr, -8
66 ; Try the next value up (mask ....1111001). The mask itself is suitable
67 ; for RISBG, but the shift is still needed.
68 define i32 @f7(i32 %foo) {
71 ; CHECK: risbg %r2, %r2, 63, 188, 0
73 %shr = lshr i32 %foo, 2
74 %and = and i32 %shr, -7
78 ; ...and again with i64.
79 define i64 @f8(i64 %foo) {
81 ; CHECK: srlg [[REG:%r[0-5]]], %r2, 2
82 ; CHECK: risbg %r2, [[REG]], 63, 188, 0
84 %shr = lshr i64 %foo, 2
85 %and = and i64 %shr, -7
89 ; Test an extraction of bits from a left-shifted value. The range should
90 ; be reduced to exclude the zeroed low bits.
91 define i32 @f9(i32 %foo) {
93 ; CHECK: risbg %r2, %r2, 56, 189, 2
95 %shr = shl i32 %foo, 2
96 %and = and i32 %shr, 255
100 ; ...and again with i64.
101 define i64 @f10(i64 %foo) {
103 ; CHECK: risbg %r2, %r2, 56, 189, 2
105 %shr = shl i64 %foo, 2
106 %and = and i64 %shr, 255
110 ; Try a wrap-around mask (mask ....111100001111). The mask itself is suitable
111 ; for RISBG, but the shift is still needed.
112 define i32 @f11(i32 %foo) {
115 ; CHECK: risbg %r2, %r2, 60, 183, 0
117 %shr = shl i32 %foo, 2
118 %and = and i32 %shr, -241
122 ; ...and again with i64.
123 define i64 @f12(i64 %foo) {
125 ; CHECK: sllg [[REG:%r[0-5]]], %r2, 2
126 ; CHECK: risbg %r2, [[REG]], 60, 183, 0
128 %shr = shl i64 %foo, 2
129 %and = and i64 %shr, -241
133 ; Test an extraction from a rotated value, no mask wraparound.
134 ; This is equivalent to the lshr case, because the bits from the
136 define i32 @f13(i32 %foo) {
138 ; CHECK: risbg %r2, %r2, 56, 188, 46
140 %parta = shl i32 %foo, 14
141 %partb = lshr i32 %foo, 18
142 %rotl = or i32 %parta, %partb
143 %and = and i32 %rotl, 248
147 ; ...and again with i64.
148 define i64 @f14(i64 %foo) {
150 ; CHECK: risbg %r2, %r2, 56, 188, 14
152 %parta = shl i64 %foo, 14
153 %partb = lshr i64 %foo, 50
154 %rotl = or i64 %parta, %partb
155 %and = and i64 %rotl, 248
159 ; Try a case in which only the bits from the shl are used.
160 define i32 @f15(i32 %foo) {
162 ; CHECK: risbg %r2, %r2, 47, 177, 14
164 %parta = shl i32 %foo, 14
165 %partb = lshr i32 %foo, 18
166 %rotl = or i32 %parta, %partb
167 %and = and i32 %rotl, 114688
171 ; ...and again with i64.
172 define i64 @f16(i64 %foo) {
174 ; CHECK: risbg %r2, %r2, 47, 177, 14
176 %parta = shl i64 %foo, 14
177 %partb = lshr i64 %foo, 50
178 %rotl = or i64 %parta, %partb
179 %and = and i64 %rotl, 114688
183 ; Test a 32-bit rotate in which both parts of the OR are needed.
184 ; This needs a separate shift (although RISBLG would be better
186 define i32 @f17(i32 %foo) {
188 ; CHECK: rll [[REG:%r[0-5]]], %r2, 4
189 ; CHECK: risbg %r2, [[REG]], 57, 190, 0
191 %parta = shl i32 %foo, 4
192 %partb = lshr i32 %foo, 28
193 %rotl = or i32 %parta, %partb
194 %and = and i32 %rotl, 126
198 ; ...and for i64, where RISBG should do the rotate too.
199 define i64 @f18(i64 %foo) {
201 ; CHECK: risbg %r2, %r2, 57, 190, 4
203 %parta = shl i64 %foo, 4
204 %partb = lshr i64 %foo, 60
205 %rotl = or i64 %parta, %partb
206 %and = and i64 %rotl, 126
210 ; Test an arithmetic shift right in which some of the sign bits are kept.
211 ; The SRA is still needed.
212 define i32 @f19(i32 %foo) {
215 ; CHECK: risbg %r2, %r2, 59, 190, 0
217 %shr = ashr i32 %foo, 28
218 %and = and i32 %shr, 30
222 ; ...and again with i64.
223 define i64 @f20(i64 %foo) {
225 ; CHECK: srag [[REG:%r[0-5]]], %r2, 60
226 ; CHECK: risbg %r2, [[REG]], 59, 190, 0
228 %shr = ashr i64 %foo, 60
229 %and = and i64 %shr, 30
233 ; Now try an arithmetic right shift in which the sign bits aren't needed.
234 ; Introduce a second use of %shr so that the ashr doesn't decompose to
236 define i32 @f21(i32 %foo, i32 *%dest) {
238 ; CHECK: risbg %r2, %r2, 60, 190, 36
240 %shr = ashr i32 %foo, 28
241 store i32 %shr, i32 *%dest
242 %and = and i32 %shr, 14
246 ; ...and again with i64.
247 define i64 @f22(i64 %foo, i64 *%dest) {
249 ; CHECK: risbg %r2, %r2, 60, 190, 4
251 %shr = ashr i64 %foo, 60
252 store i64 %shr, i64 *%dest
253 %and = and i64 %shr, 14
257 ; Check that we use RISBG for shifted values even if the AND is a
258 ; natural zero extension.
259 define i64 @f23(i64 %foo) {
261 ; CHECK: risbg %r2, %r2, 56, 191, 62
263 %shr = lshr i64 %foo, 2
264 %and = and i64 %shr, 255
268 ; Test a case where the AND comes before a rotate.
269 define i32 @f24(i32 %foo) {
271 ; CHECK: risbg [[REG:%r[0-5]]], %r2, 60, 190, 0
272 ; CHECK: rll %r2, [[REG]], 3
274 %and = and i32 %foo, 14
275 %parta = shl i32 %and, 3
276 %partb = lshr i32 %and, 29
277 %rotl = or i32 %parta, %partb
281 ; ...and again with i64, where a single RISBG is enough.
282 define i64 @f25(i64 %foo) {
284 ; CHECK: risbg %r2, %r2, 57, 187, 3
286 %and = and i64 %foo, 14
287 %parta = shl i64 %and, 3
288 %partb = lshr i64 %and, 61
289 %rotl = or i64 %parta, %partb
293 ; Test a wrap-around case in which the rotate comes after the AND.
294 define i32 @f26(i32 %foo) {
296 ; CHECK: risbg [[REG:%r[0-5]]], %r2, 60, 185, 0
297 ; CHECK: rll %r2, [[REG]], 5
299 %and = and i32 %foo, -49
300 %parta = shl i32 %and, 5
301 %partb = lshr i32 %and, 27
302 %rotl = or i32 %parta, %partb
306 ; ...and again with i64, where a single RISBG is OK.
307 define i64 @f27(i64 %foo) {
309 ; CHECK: risbg %r2, %r2, 55, 180, 5
311 %and = and i64 %foo, -49
312 %parta = shl i64 %and, 5
313 %partb = lshr i64 %and, 59
314 %rotl = or i64 %parta, %partb
318 ; Test a case where the AND comes before a shift left.
319 define i32 @f28(i32 %foo) {
321 ; CHECK: risbg %r2, %r2, 32, 173, 17
323 %and = and i32 %foo, 32766
324 %shl = shl i32 %and, 17
328 ; ...and again with i64.
329 define i64 @f29(i64 %foo) {
331 ; CHECK: risbg %r2, %r2, 0, 141, 49
333 %and = and i64 %foo, 32766
334 %shl = shl i64 %and, 49
338 ; Test the next shift up from f28, in which the mask should get shortened.
339 define i32 @f30(i32 %foo) {
341 ; CHECK: risbg %r2, %r2, 32, 172, 18
343 %and = and i32 %foo, 32766
344 %shl = shl i32 %and, 18
348 ; ...and again with i64.
349 define i64 @f31(i64 %foo) {
351 ; CHECK: risbg %r2, %r2, 0, 140, 50
353 %and = and i64 %foo, 32766
354 %shl = shl i64 %and, 50
358 ; Test a wrap-around case in which the shift left comes after the AND.
359 ; We can't use RISBG for the shift in that case.
360 define i32 @f32(i32 %foo) {
364 %and = and i32 %foo, -7
365 %shl = shl i32 %and, 10
369 ; ...and again with i64.
370 define i64 @f33(i64 %foo) {
374 %and = and i64 %foo, -7
375 %shl = shl i64 %and, 10
379 ; Test a case where the AND comes before a shift right.
380 define i32 @f34(i32 %foo) {
382 ; CHECK: risbg %r2, %r2, 57, 191, 55
384 %and = and i32 %foo, 65535
385 %shl = lshr i32 %and, 9
389 ; ...and again with i64.
390 define i64 @f35(i64 %foo) {
392 ; CHECK: risbg %r2, %r2, 57, 191, 55
394 %and = and i64 %foo, 65535
395 %shl = lshr i64 %and, 9
399 ; Test a wrap-around case where the AND comes before a shift right.
400 ; We can't use RISBG for the shift in that case.
401 define i32 @f36(i32 %foo) {
405 %and = and i32 %foo, -25
406 %shl = lshr i32 %and, 1
410 ; ...and again with i64.
411 define i64 @f37(i64 %foo) {
415 %and = and i64 %foo, -25
416 %shl = lshr i64 %and, 1