xref: /aosp_15_r20/external/llvm/test/CodeGen/SystemZ/risbg-01.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; Test sequences that can use RISBG with a zeroed first operand.
2*9880d681SAndroid Build Coastguard Worker; The tests here assume that RISBLG isn't available.
3*9880d681SAndroid Build Coastguard Worker;
4*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s
5*9880d681SAndroid Build Coastguard Worker
6*9880d681SAndroid Build Coastguard Worker; Test an extraction of bit 0 from a right-shifted value.
7*9880d681SAndroid Build Coastguard Workerdefine i32 @f1(i32 %foo) {
8*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f1:
9*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 63, 191, 54
10*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
11*9880d681SAndroid Build Coastguard Worker  %shr = lshr i32 %foo, 10
12*9880d681SAndroid Build Coastguard Worker  %and = and i32 %shr, 1
13*9880d681SAndroid Build Coastguard Worker  ret i32 %and
14*9880d681SAndroid Build Coastguard Worker}
15*9880d681SAndroid Build Coastguard Worker
16*9880d681SAndroid Build Coastguard Worker; ...and again with i64.
17*9880d681SAndroid Build Coastguard Workerdefine i64 @f2(i64 %foo) {
18*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f2:
19*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 63, 191, 54
20*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
21*9880d681SAndroid Build Coastguard Worker  %shr = lshr i64 %foo, 10
22*9880d681SAndroid Build Coastguard Worker  %and = and i64 %shr, 1
23*9880d681SAndroid Build Coastguard Worker  ret i64 %and
24*9880d681SAndroid Build Coastguard Worker}
25*9880d681SAndroid Build Coastguard Worker
26*9880d681SAndroid Build Coastguard Worker; Test an extraction of other bits from a right-shifted value.
27*9880d681SAndroid Build Coastguard Workerdefine i32 @f3(i32 %foo) {
28*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f3:
29*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 60, 189, 42
30*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
31*9880d681SAndroid Build Coastguard Worker  %shr = lshr i32 %foo, 22
32*9880d681SAndroid Build Coastguard Worker  %and = and i32 %shr, 12
33*9880d681SAndroid Build Coastguard Worker  ret i32 %and
34*9880d681SAndroid Build Coastguard Worker}
35*9880d681SAndroid Build Coastguard Worker
36*9880d681SAndroid Build Coastguard Worker; ...and again with i64.
37*9880d681SAndroid Build Coastguard Workerdefine i64 @f4(i64 %foo) {
38*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f4:
39*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 60, 189, 42
40*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
41*9880d681SAndroid Build Coastguard Worker  %shr = lshr i64 %foo, 22
42*9880d681SAndroid Build Coastguard Worker  %and = and i64 %shr, 12
43*9880d681SAndroid Build Coastguard Worker  ret i64 %and
44*9880d681SAndroid Build Coastguard Worker}
45*9880d681SAndroid Build Coastguard Worker
46*9880d681SAndroid Build Coastguard Worker; Test an extraction of most bits from a right-shifted value.
47*9880d681SAndroid Build Coastguard Worker; The range should be reduced to exclude the zeroed high bits.
48*9880d681SAndroid Build Coastguard Workerdefine i32 @f5(i32 %foo) {
49*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f5:
50*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 34, 188, 62
51*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
52*9880d681SAndroid Build Coastguard Worker  %shr = lshr i32 %foo, 2
53*9880d681SAndroid Build Coastguard Worker  %and = and i32 %shr, -8
54*9880d681SAndroid Build Coastguard Worker  ret i32 %and
55*9880d681SAndroid Build Coastguard Worker}
56*9880d681SAndroid Build Coastguard Worker
57*9880d681SAndroid Build Coastguard Worker; ...and again with i64.
58*9880d681SAndroid Build Coastguard Workerdefine i64 @f6(i64 %foo) {
59*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f6:
60*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 2, 188, 62
61*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
62*9880d681SAndroid Build Coastguard Worker  %shr = lshr i64 %foo, 2
63*9880d681SAndroid Build Coastguard Worker  %and = and i64 %shr, -8
64*9880d681SAndroid Build Coastguard Worker  ret i64 %and
65*9880d681SAndroid Build Coastguard Worker}
66*9880d681SAndroid Build Coastguard Worker
67*9880d681SAndroid Build Coastguard Worker; Try the next value up (mask ....1111001).  This needs a separate shift
68*9880d681SAndroid Build Coastguard Worker; and mask.
69*9880d681SAndroid Build Coastguard Workerdefine i32 @f7(i32 %foo) {
70*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f7:
71*9880d681SAndroid Build Coastguard Worker; CHECK: srl %r2, 2
72*9880d681SAndroid Build Coastguard Worker; CHECK: nill %r2, 65529
73*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
74*9880d681SAndroid Build Coastguard Worker  %shr = lshr i32 %foo, 2
75*9880d681SAndroid Build Coastguard Worker  %and = and i32 %shr, -7
76*9880d681SAndroid Build Coastguard Worker  ret i32 %and
77*9880d681SAndroid Build Coastguard Worker}
78*9880d681SAndroid Build Coastguard Worker
79*9880d681SAndroid Build Coastguard Worker; ...and again with i64.
80*9880d681SAndroid Build Coastguard Workerdefine i64 @f8(i64 %foo) {
81*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f8:
82*9880d681SAndroid Build Coastguard Worker; CHECK: srlg %r2, %r2, 2
83*9880d681SAndroid Build Coastguard Worker; CHECK: nill %r2, 65529
84*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
85*9880d681SAndroid Build Coastguard Worker  %shr = lshr i64 %foo, 2
86*9880d681SAndroid Build Coastguard Worker  %and = and i64 %shr, -7
87*9880d681SAndroid Build Coastguard Worker  ret i64 %and
88*9880d681SAndroid Build Coastguard Worker}
89*9880d681SAndroid Build Coastguard Worker
90*9880d681SAndroid Build Coastguard Worker; Test an extraction of bits from a left-shifted value.  The range should
91*9880d681SAndroid Build Coastguard Worker; be reduced to exclude the zeroed low bits.
92*9880d681SAndroid Build Coastguard Workerdefine i32 @f9(i32 %foo) {
93*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f9:
94*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 56, 189, 2
95*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
96*9880d681SAndroid Build Coastguard Worker  %shr = shl i32 %foo, 2
97*9880d681SAndroid Build Coastguard Worker  %and = and i32 %shr, 255
98*9880d681SAndroid Build Coastguard Worker  ret i32 %and
99*9880d681SAndroid Build Coastguard Worker}
100*9880d681SAndroid Build Coastguard Worker
101*9880d681SAndroid Build Coastguard Worker; ...and again with i64.
102*9880d681SAndroid Build Coastguard Workerdefine i64 @f10(i64 %foo) {
103*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f10:
104*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 56, 189, 2
105*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
106*9880d681SAndroid Build Coastguard Worker  %shr = shl i64 %foo, 2
107*9880d681SAndroid Build Coastguard Worker  %and = and i64 %shr, 255
108*9880d681SAndroid Build Coastguard Worker  ret i64 %and
109*9880d681SAndroid Build Coastguard Worker}
110*9880d681SAndroid Build Coastguard Worker
111*9880d681SAndroid Build Coastguard Worker; Try a wrap-around mask (mask ....111100001111).  This needs a separate shift
112*9880d681SAndroid Build Coastguard Worker; and mask.
113*9880d681SAndroid Build Coastguard Workerdefine i32 @f11(i32 %foo) {
114*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f11:
115*9880d681SAndroid Build Coastguard Worker; CHECK: sll %r2, 2
116*9880d681SAndroid Build Coastguard Worker; CHECK: nill %r2, 65295
117*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
118*9880d681SAndroid Build Coastguard Worker  %shr = shl i32 %foo, 2
119*9880d681SAndroid Build Coastguard Worker  %and = and i32 %shr, -241
120*9880d681SAndroid Build Coastguard Worker  ret i32 %and
121*9880d681SAndroid Build Coastguard Worker}
122*9880d681SAndroid Build Coastguard Worker
123*9880d681SAndroid Build Coastguard Worker; ...and again with i64.
124*9880d681SAndroid Build Coastguard Workerdefine i64 @f12(i64 %foo) {
125*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f12:
126*9880d681SAndroid Build Coastguard Worker; CHECK: sllg %r2, %r2, 2
127*9880d681SAndroid Build Coastguard Worker; CHECK: nill %r2, 65295
128*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
129*9880d681SAndroid Build Coastguard Worker  %shr = shl i64 %foo, 2
130*9880d681SAndroid Build Coastguard Worker  %and = and i64 %shr, -241
131*9880d681SAndroid Build Coastguard Worker  ret i64 %and
132*9880d681SAndroid Build Coastguard Worker}
133*9880d681SAndroid Build Coastguard Worker
134*9880d681SAndroid Build Coastguard Worker; Test an extraction from a rotated value, no mask wraparound.
135*9880d681SAndroid Build Coastguard Worker; This is equivalent to the lshr case, because the bits from the
136*9880d681SAndroid Build Coastguard Worker; shl are not used.
137*9880d681SAndroid Build Coastguard Workerdefine i32 @f13(i32 %foo) {
138*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f13:
139*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 56, 188, 46
140*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
141*9880d681SAndroid Build Coastguard Worker  %parta = shl i32 %foo, 14
142*9880d681SAndroid Build Coastguard Worker  %partb = lshr i32 %foo, 18
143*9880d681SAndroid Build Coastguard Worker  %rotl = or i32 %parta, %partb
144*9880d681SAndroid Build Coastguard Worker  %and = and i32 %rotl, 248
145*9880d681SAndroid Build Coastguard Worker  ret i32 %and
146*9880d681SAndroid Build Coastguard Worker}
147*9880d681SAndroid Build Coastguard Worker
148*9880d681SAndroid Build Coastguard Worker; ...and again with i64.
149*9880d681SAndroid Build Coastguard Workerdefine i64 @f14(i64 %foo) {
150*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f14:
151*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 56, 188, 14
152*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
153*9880d681SAndroid Build Coastguard Worker  %parta = shl i64 %foo, 14
154*9880d681SAndroid Build Coastguard Worker  %partb = lshr i64 %foo, 50
155*9880d681SAndroid Build Coastguard Worker  %rotl = or i64 %parta, %partb
156*9880d681SAndroid Build Coastguard Worker  %and = and i64 %rotl, 248
157*9880d681SAndroid Build Coastguard Worker  ret i64 %and
158*9880d681SAndroid Build Coastguard Worker}
159*9880d681SAndroid Build Coastguard Worker
160*9880d681SAndroid Build Coastguard Worker; Try a case in which only the bits from the shl are used.
161*9880d681SAndroid Build Coastguard Workerdefine i32 @f15(i32 %foo) {
162*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f15:
163*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 47, 177, 14
164*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
165*9880d681SAndroid Build Coastguard Worker  %parta = shl i32 %foo, 14
166*9880d681SAndroid Build Coastguard Worker  %partb = lshr i32 %foo, 18
167*9880d681SAndroid Build Coastguard Worker  %rotl = or i32 %parta, %partb
168*9880d681SAndroid Build Coastguard Worker  %and = and i32 %rotl, 114688
169*9880d681SAndroid Build Coastguard Worker  ret i32 %and
170*9880d681SAndroid Build Coastguard Worker}
171*9880d681SAndroid Build Coastguard Worker
172*9880d681SAndroid Build Coastguard Worker; ...and again with i64.
173*9880d681SAndroid Build Coastguard Workerdefine i64 @f16(i64 %foo) {
174*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f16:
175*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 47, 177, 14
176*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
177*9880d681SAndroid Build Coastguard Worker  %parta = shl i64 %foo, 14
178*9880d681SAndroid Build Coastguard Worker  %partb = lshr i64 %foo, 50
179*9880d681SAndroid Build Coastguard Worker  %rotl = or i64 %parta, %partb
180*9880d681SAndroid Build Coastguard Worker  %and = and i64 %rotl, 114688
181*9880d681SAndroid Build Coastguard Worker  ret i64 %and
182*9880d681SAndroid Build Coastguard Worker}
183*9880d681SAndroid Build Coastguard Worker
184*9880d681SAndroid Build Coastguard Worker; Test a 32-bit rotate in which both parts of the OR are needed.
185*9880d681SAndroid Build Coastguard Worker; This needs a separate shift and mask.
186*9880d681SAndroid Build Coastguard Workerdefine i32 @f17(i32 %foo) {
187*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f17:
188*9880d681SAndroid Build Coastguard Worker; CHECK: rll %r2, %r2, 4
189*9880d681SAndroid Build Coastguard Worker; CHECK: nilf %r2, 126
190*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
191*9880d681SAndroid Build Coastguard Worker  %parta = shl i32 %foo, 4
192*9880d681SAndroid Build Coastguard Worker  %partb = lshr i32 %foo, 28
193*9880d681SAndroid Build Coastguard Worker  %rotl = or i32 %parta, %partb
194*9880d681SAndroid Build Coastguard Worker  %and = and i32 %rotl, 126
195*9880d681SAndroid Build Coastguard Worker  ret i32 %and
196*9880d681SAndroid Build Coastguard Worker}
197*9880d681SAndroid Build Coastguard Worker
198*9880d681SAndroid Build Coastguard Worker; ...and for i64, where RISBG should do the rotate too.
199*9880d681SAndroid Build Coastguard Workerdefine i64 @f18(i64 %foo) {
200*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f18:
201*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 57, 190, 4
202*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
203*9880d681SAndroid Build Coastguard Worker  %parta = shl i64 %foo, 4
204*9880d681SAndroid Build Coastguard Worker  %partb = lshr i64 %foo, 60
205*9880d681SAndroid Build Coastguard Worker  %rotl = or i64 %parta, %partb
206*9880d681SAndroid Build Coastguard Worker  %and = and i64 %rotl, 126
207*9880d681SAndroid Build Coastguard Worker  ret i64 %and
208*9880d681SAndroid Build Coastguard Worker}
209*9880d681SAndroid Build Coastguard Worker
210*9880d681SAndroid Build Coastguard Worker; Test an arithmetic shift right in which some of the sign bits are kept.
211*9880d681SAndroid Build Coastguard Worker; This needs a separate shift and mask.
212*9880d681SAndroid Build Coastguard Workerdefine i32 @f19(i32 %foo) {
213*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f19:
214*9880d681SAndroid Build Coastguard Worker; CHECK: sra %r2, 28
215*9880d681SAndroid Build Coastguard Worker; CHECK: nilf %r2, 30
216*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
217*9880d681SAndroid Build Coastguard Worker  %shr = ashr i32 %foo, 28
218*9880d681SAndroid Build Coastguard Worker  %and = and i32 %shr, 30
219*9880d681SAndroid Build Coastguard Worker  ret i32 %and
220*9880d681SAndroid Build Coastguard Worker}
221*9880d681SAndroid Build Coastguard Worker
222*9880d681SAndroid Build Coastguard Worker; ...and again with i64.  In this case RISBG is the best way of doing the AND.
223*9880d681SAndroid Build Coastguard Workerdefine i64 @f20(i64 %foo) {
224*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f20:
225*9880d681SAndroid Build Coastguard Worker; CHECK: srag [[REG:%r[0-5]]], %r2, 60
226*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, [[REG]], 59, 190, 0
227*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
228*9880d681SAndroid Build Coastguard Worker  %shr = ashr i64 %foo, 60
229*9880d681SAndroid Build Coastguard Worker  %and = and i64 %shr, 30
230*9880d681SAndroid Build Coastguard Worker  ret i64 %and
231*9880d681SAndroid Build Coastguard Worker}
232*9880d681SAndroid Build Coastguard Worker
233*9880d681SAndroid Build Coastguard Worker; Now try an arithmetic right shift in which the sign bits aren't needed.
234*9880d681SAndroid Build Coastguard Worker; Introduce a second use of %shr so that the ashr doesn't decompose to
235*9880d681SAndroid Build Coastguard Worker; an lshr.
236*9880d681SAndroid Build Coastguard Workerdefine i32 @f21(i32 %foo, i32 *%dest) {
237*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f21:
238*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 60, 190, 36
239*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
240*9880d681SAndroid Build Coastguard Worker  %shr = ashr i32 %foo, 28
241*9880d681SAndroid Build Coastguard Worker  store i32 %shr, i32 *%dest
242*9880d681SAndroid Build Coastguard Worker  %and = and i32 %shr, 14
243*9880d681SAndroid Build Coastguard Worker  ret i32 %and
244*9880d681SAndroid Build Coastguard Worker}
245*9880d681SAndroid Build Coastguard Worker
246*9880d681SAndroid Build Coastguard Worker; ...and again with i64.
247*9880d681SAndroid Build Coastguard Workerdefine i64 @f22(i64 %foo, i64 *%dest) {
248*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f22:
249*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 60, 190, 4
250*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
251*9880d681SAndroid Build Coastguard Worker  %shr = ashr i64 %foo, 60
252*9880d681SAndroid Build Coastguard Worker  store i64 %shr, i64 *%dest
253*9880d681SAndroid Build Coastguard Worker  %and = and i64 %shr, 14
254*9880d681SAndroid Build Coastguard Worker  ret i64 %and
255*9880d681SAndroid Build Coastguard Worker}
256*9880d681SAndroid Build Coastguard Worker
257*9880d681SAndroid Build Coastguard Worker; Check that we use RISBG for shifted values even if the AND is a
258*9880d681SAndroid Build Coastguard Worker; natural zero extension.
259*9880d681SAndroid Build Coastguard Workerdefine i64 @f23(i64 %foo) {
260*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f23:
261*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 56, 191, 62
262*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
263*9880d681SAndroid Build Coastguard Worker  %shr = lshr i64 %foo, 2
264*9880d681SAndroid Build Coastguard Worker  %and = and i64 %shr, 255
265*9880d681SAndroid Build Coastguard Worker  ret i64 %and
266*9880d681SAndroid Build Coastguard Worker}
267*9880d681SAndroid Build Coastguard Worker
268*9880d681SAndroid Build Coastguard Worker; Test a case where the AND comes before a rotate.  This needs a separate
269*9880d681SAndroid Build Coastguard Worker; mask and rotate.
270*9880d681SAndroid Build Coastguard Workerdefine i32 @f24(i32 %foo) {
271*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f24:
272*9880d681SAndroid Build Coastguard Worker; CHECK: nilf %r2, 254
273*9880d681SAndroid Build Coastguard Worker; CHECK: rll %r2, %r2, 29
274*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
275*9880d681SAndroid Build Coastguard Worker  %and = and i32 %foo, 254
276*9880d681SAndroid Build Coastguard Worker  %parta = lshr i32 %and, 3
277*9880d681SAndroid Build Coastguard Worker  %partb = shl i32 %and, 29
278*9880d681SAndroid Build Coastguard Worker  %rotl = or i32 %parta, %partb
279*9880d681SAndroid Build Coastguard Worker  ret i32 %rotl
280*9880d681SAndroid Build Coastguard Worker}
281*9880d681SAndroid Build Coastguard Worker
282*9880d681SAndroid Build Coastguard Worker; ...and again with i64, where a single RISBG is enough.
283*9880d681SAndroid Build Coastguard Workerdefine i64 @f25(i64 %foo) {
284*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f25:
285*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 57, 187, 3
286*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
287*9880d681SAndroid Build Coastguard Worker  %and = and i64 %foo, 14
288*9880d681SAndroid Build Coastguard Worker  %parta = shl i64 %and, 3
289*9880d681SAndroid Build Coastguard Worker  %partb = lshr i64 %and, 61
290*9880d681SAndroid Build Coastguard Worker  %rotl = or i64 %parta, %partb
291*9880d681SAndroid Build Coastguard Worker  ret i64 %rotl
292*9880d681SAndroid Build Coastguard Worker}
293*9880d681SAndroid Build Coastguard Worker
294*9880d681SAndroid Build Coastguard Worker; Test a wrap-around case in which the AND comes before a rotate.
295*9880d681SAndroid Build Coastguard Worker; This again needs a separate mask and rotate.
296*9880d681SAndroid Build Coastguard Workerdefine i32 @f26(i32 %foo) {
297*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f26:
298*9880d681SAndroid Build Coastguard Worker; CHECK: rll %r2, %r2, 5
299*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
300*9880d681SAndroid Build Coastguard Worker  %and = and i32 %foo, -49
301*9880d681SAndroid Build Coastguard Worker  %parta = shl i32 %and, 5
302*9880d681SAndroid Build Coastguard Worker  %partb = lshr i32 %and, 27
303*9880d681SAndroid Build Coastguard Worker  %rotl = or i32 %parta, %partb
304*9880d681SAndroid Build Coastguard Worker  ret i32 %rotl
305*9880d681SAndroid Build Coastguard Worker}
306*9880d681SAndroid Build Coastguard Worker
307*9880d681SAndroid Build Coastguard Worker; ...and again with i64, where a single RISBG is OK.
308*9880d681SAndroid Build Coastguard Workerdefine i64 @f27(i64 %foo) {
309*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f27:
310*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 55, 180, 5
311*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
312*9880d681SAndroid Build Coastguard Worker  %and = and i64 %foo, -49
313*9880d681SAndroid Build Coastguard Worker  %parta = shl i64 %and, 5
314*9880d681SAndroid Build Coastguard Worker  %partb = lshr i64 %and, 59
315*9880d681SAndroid Build Coastguard Worker  %rotl = or i64 %parta, %partb
316*9880d681SAndroid Build Coastguard Worker  ret i64 %rotl
317*9880d681SAndroid Build Coastguard Worker}
318*9880d681SAndroid Build Coastguard Worker
319*9880d681SAndroid Build Coastguard Worker; Test a case where the AND comes before a shift left.
320*9880d681SAndroid Build Coastguard Workerdefine i32 @f28(i32 %foo) {
321*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f28:
322*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 32, 173, 17
323*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
324*9880d681SAndroid Build Coastguard Worker  %and = and i32 %foo, 32766
325*9880d681SAndroid Build Coastguard Worker  %shl = shl i32 %and, 17
326*9880d681SAndroid Build Coastguard Worker  ret i32 %shl
327*9880d681SAndroid Build Coastguard Worker}
328*9880d681SAndroid Build Coastguard Worker
329*9880d681SAndroid Build Coastguard Worker; ...and again with i64.
330*9880d681SAndroid Build Coastguard Workerdefine i64 @f29(i64 %foo) {
331*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f29:
332*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 0, 141, 49
333*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
334*9880d681SAndroid Build Coastguard Worker  %and = and i64 %foo, 32766
335*9880d681SAndroid Build Coastguard Worker  %shl = shl i64 %and, 49
336*9880d681SAndroid Build Coastguard Worker  ret i64 %shl
337*9880d681SAndroid Build Coastguard Worker}
338*9880d681SAndroid Build Coastguard Worker
339*9880d681SAndroid Build Coastguard Worker; Test the next shift up from f28, in which the mask should get shortened.
340*9880d681SAndroid Build Coastguard Workerdefine i32 @f30(i32 %foo) {
341*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f30:
342*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 32, 172, 18
343*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
344*9880d681SAndroid Build Coastguard Worker  %and = and i32 %foo, 32766
345*9880d681SAndroid Build Coastguard Worker  %shl = shl i32 %and, 18
346*9880d681SAndroid Build Coastguard Worker  ret i32 %shl
347*9880d681SAndroid Build Coastguard Worker}
348*9880d681SAndroid Build Coastguard Worker
349*9880d681SAndroid Build Coastguard Worker; ...and again with i64.
350*9880d681SAndroid Build Coastguard Workerdefine i64 @f31(i64 %foo) {
351*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f31:
352*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 0, 140, 50
353*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
354*9880d681SAndroid Build Coastguard Worker  %and = and i64 %foo, 32766
355*9880d681SAndroid Build Coastguard Worker  %shl = shl i64 %and, 50
356*9880d681SAndroid Build Coastguard Worker  ret i64 %shl
357*9880d681SAndroid Build Coastguard Worker}
358*9880d681SAndroid Build Coastguard Worker
359*9880d681SAndroid Build Coastguard Worker; Test a wrap-around case in which the shift left comes after the AND.
360*9880d681SAndroid Build Coastguard Worker; We can't use RISBG for the shift in that case.
361*9880d681SAndroid Build Coastguard Workerdefine i32 @f32(i32 %foo) {
362*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f32:
363*9880d681SAndroid Build Coastguard Worker; CHECK: sll %r2
364*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
365*9880d681SAndroid Build Coastguard Worker  %and = and i32 %foo, -7
366*9880d681SAndroid Build Coastguard Worker  %shl = shl i32 %and, 10
367*9880d681SAndroid Build Coastguard Worker  ret i32 %shl
368*9880d681SAndroid Build Coastguard Worker}
369*9880d681SAndroid Build Coastguard Worker
370*9880d681SAndroid Build Coastguard Worker; ...and again with i64.
371*9880d681SAndroid Build Coastguard Workerdefine i64 @f33(i64 %foo) {
372*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f33:
373*9880d681SAndroid Build Coastguard Worker; CHECK: sllg %r2
374*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
375*9880d681SAndroid Build Coastguard Worker  %and = and i64 %foo, -7
376*9880d681SAndroid Build Coastguard Worker  %shl = shl i64 %and, 10
377*9880d681SAndroid Build Coastguard Worker  ret i64 %shl
378*9880d681SAndroid Build Coastguard Worker}
379*9880d681SAndroid Build Coastguard Worker
380*9880d681SAndroid Build Coastguard Worker; Test a case where the AND comes before a shift right.
381*9880d681SAndroid Build Coastguard Workerdefine i32 @f34(i32 %foo) {
382*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f34:
383*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 57, 191, 55
384*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
385*9880d681SAndroid Build Coastguard Worker  %and = and i32 %foo, 65535
386*9880d681SAndroid Build Coastguard Worker  %shl = lshr i32 %and, 9
387*9880d681SAndroid Build Coastguard Worker  ret i32 %shl
388*9880d681SAndroid Build Coastguard Worker}
389*9880d681SAndroid Build Coastguard Worker
390*9880d681SAndroid Build Coastguard Worker; ...and again with i64.
391*9880d681SAndroid Build Coastguard Workerdefine i64 @f35(i64 %foo) {
392*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f35:
393*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 57, 191, 55
394*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
395*9880d681SAndroid Build Coastguard Worker  %and = and i64 %foo, 65535
396*9880d681SAndroid Build Coastguard Worker  %shl = lshr i64 %and, 9
397*9880d681SAndroid Build Coastguard Worker  ret i64 %shl
398*9880d681SAndroid Build Coastguard Worker}
399*9880d681SAndroid Build Coastguard Worker
400*9880d681SAndroid Build Coastguard Worker; Test a wrap-around case where the AND comes before a shift right.
401*9880d681SAndroid Build Coastguard Worker; We can't use RISBG for the shift in that case.
402*9880d681SAndroid Build Coastguard Workerdefine i32 @f36(i32 %foo) {
403*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f36:
404*9880d681SAndroid Build Coastguard Worker; CHECK: srl %r2
405*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
406*9880d681SAndroid Build Coastguard Worker  %and = and i32 %foo, -25
407*9880d681SAndroid Build Coastguard Worker  %shl = lshr i32 %and, 1
408*9880d681SAndroid Build Coastguard Worker  ret i32 %shl
409*9880d681SAndroid Build Coastguard Worker}
410*9880d681SAndroid Build Coastguard Worker
411*9880d681SAndroid Build Coastguard Worker; ...and again with i64.
412*9880d681SAndroid Build Coastguard Workerdefine i64 @f37(i64 %foo) {
413*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f37:
414*9880d681SAndroid Build Coastguard Worker; CHECK: srlg %r2
415*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
416*9880d681SAndroid Build Coastguard Worker  %and = and i64 %foo, -25
417*9880d681SAndroid Build Coastguard Worker  %shl = lshr i64 %and, 1
418*9880d681SAndroid Build Coastguard Worker  ret i64 %shl
419*9880d681SAndroid Build Coastguard Worker}
420*9880d681SAndroid Build Coastguard Worker
421*9880d681SAndroid Build Coastguard Worker; Test a combination involving a large ASHR and a shift left.  We can't
422*9880d681SAndroid Build Coastguard Worker; use RISBG there.
423*9880d681SAndroid Build Coastguard Workerdefine i64 @f38(i64 %foo) {
424*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f38:
425*9880d681SAndroid Build Coastguard Worker; CHECK: srag {{%r[0-5]}}
426*9880d681SAndroid Build Coastguard Worker; CHECK: sllg {{%r[0-5]}}
427*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
428*9880d681SAndroid Build Coastguard Worker  %ashr = ashr i64 %foo, 32
429*9880d681SAndroid Build Coastguard Worker  %shl = shl i64 %ashr, 5
430*9880d681SAndroid Build Coastguard Worker  ret i64 %shl
431*9880d681SAndroid Build Coastguard Worker}
432*9880d681SAndroid Build Coastguard Worker
433*9880d681SAndroid Build Coastguard Worker; Try a similar thing in which no shifted sign bits are kept.
434*9880d681SAndroid Build Coastguard Workerdefine i64 @f39(i64 %foo, i64 *%dest) {
435*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f39:
436*9880d681SAndroid Build Coastguard Worker; CHECK: srag [[REG:%r[01345]]], %r2, 35
437*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 33, 189, 31
438*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
439*9880d681SAndroid Build Coastguard Worker  %ashr = ashr i64 %foo, 35
440*9880d681SAndroid Build Coastguard Worker  store i64 %ashr, i64 *%dest
441*9880d681SAndroid Build Coastguard Worker  %shl = shl i64 %ashr, 2
442*9880d681SAndroid Build Coastguard Worker  %and = and i64 %shl, 2147483647
443*9880d681SAndroid Build Coastguard Worker  ret i64 %and
444*9880d681SAndroid Build Coastguard Worker}
445*9880d681SAndroid Build Coastguard Worker
446*9880d681SAndroid Build Coastguard Worker; ...and again with the next highest shift value, where one sign bit is kept.
447*9880d681SAndroid Build Coastguard Workerdefine i64 @f40(i64 %foo, i64 *%dest) {
448*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f40:
449*9880d681SAndroid Build Coastguard Worker; CHECK: srag [[REG:%r[01345]]], %r2, 36
450*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, [[REG]], 33, 189, 2
451*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
452*9880d681SAndroid Build Coastguard Worker  %ashr = ashr i64 %foo, 36
453*9880d681SAndroid Build Coastguard Worker  store i64 %ashr, i64 *%dest
454*9880d681SAndroid Build Coastguard Worker  %shl = shl i64 %ashr, 2
455*9880d681SAndroid Build Coastguard Worker  %and = and i64 %shl, 2147483647
456*9880d681SAndroid Build Coastguard Worker  ret i64 %and
457*9880d681SAndroid Build Coastguard Worker}
458*9880d681SAndroid Build Coastguard Worker
459*9880d681SAndroid Build Coastguard Worker; Check a case where the result is zero-extended.
460*9880d681SAndroid Build Coastguard Workerdefine i64 @f41(i32 %a) {
461*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f41
462*9880d681SAndroid Build Coastguard Worker; CHECK: risbg %r2, %r2, 36, 191, 62
463*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
464*9880d681SAndroid Build Coastguard Worker  %shl = shl i32 %a, 2
465*9880d681SAndroid Build Coastguard Worker  %shr = lshr i32 %shl, 4
466*9880d681SAndroid Build Coastguard Worker  %ext = zext i32 %shr to i64
467*9880d681SAndroid Build Coastguard Worker  ret i64 %ext
468*9880d681SAndroid Build Coastguard Worker}
469*9880d681SAndroid Build Coastguard Worker
470*9880d681SAndroid Build Coastguard Worker; In this case the sign extension is converted to a pair of 32-bit shifts,
471*9880d681SAndroid Build Coastguard Worker; which is then extended to 64 bits.  We previously used the wrong bit size
472*9880d681SAndroid Build Coastguard Worker; when testing whether the shifted-in bits of the shift right were significant.
473*9880d681SAndroid Build Coastguard Workerdefine i64 @f42(i1 %x) {
474*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f42:
475*9880d681SAndroid Build Coastguard Worker; CHECK: sll %r2, 31
476*9880d681SAndroid Build Coastguard Worker; CHECK: sra %r2, 31
477*9880d681SAndroid Build Coastguard Worker; CHECK: llgcr %r2, %r2
478*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
479*9880d681SAndroid Build Coastguard Worker  %ext = sext i1 %x to i8
480*9880d681SAndroid Build Coastguard Worker  %ext2 = zext i8 %ext to i64
481*9880d681SAndroid Build Coastguard Worker  ret i64 %ext2
482*9880d681SAndroid Build Coastguard Worker}
483*9880d681SAndroid Build Coastguard Worker
484*9880d681SAndroid Build Coastguard Worker; Check that we get the case where a 64-bit shift is used by a 32-bit and.
485*9880d681SAndroid Build Coastguard Workerdefine signext i32 @f43(i64 %x) {
486*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f43:
487*9880d681SAndroid Build Coastguard Worker; CHECK: risbg [[REG:%r[0-5]]], %r2, 32, 189, 52
488*9880d681SAndroid Build Coastguard Worker; CHECK: lgfr %r2, [[REG]]
489*9880d681SAndroid Build Coastguard Worker  %shr3 = lshr i64 %x, 12
490*9880d681SAndroid Build Coastguard Worker  %shr3.tr = trunc i64 %shr3 to i32
491*9880d681SAndroid Build Coastguard Worker  %conv = and i32 %shr3.tr, -4
492*9880d681SAndroid Build Coastguard Worker  ret i32 %conv
493*9880d681SAndroid Build Coastguard Worker}
494*9880d681SAndroid Build Coastguard Worker
495*9880d681SAndroid Build Coastguard Worker; Check that we don't get the case where the 32-bit and mask is not contiguous
496*9880d681SAndroid Build Coastguard Workerdefine signext i32 @f44(i64 %x) {
497*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f44:
498*9880d681SAndroid Build Coastguard Worker; CHECK: srlg [[REG:%r[0-5]]], %r2, 12
499*9880d681SAndroid Build Coastguard Worker  %shr4 = lshr i64 %x, 12
500*9880d681SAndroid Build Coastguard Worker  %conv = trunc i64 %shr4 to i32
501*9880d681SAndroid Build Coastguard Worker  %and = and i32 %conv, 10
502*9880d681SAndroid Build Coastguard Worker  ret i32 %and
503*9880d681SAndroid Build Coastguard Worker}
504