xref: /aosp_15_r20/external/llvm/test/CodeGen/SystemZ/rnsbg-01.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; Test sequences that can use RNSBG.
2*9880d681SAndroid Build Coastguard Worker;
3*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
4*9880d681SAndroid Build Coastguard Worker
5*9880d681SAndroid Build Coastguard Worker; Test a simple mask, which is a wrap-around case.
6*9880d681SAndroid Build Coastguard Workerdefine i32 @f1(i32 %a, i32 %b) {
7*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f1:
8*9880d681SAndroid Build Coastguard Worker; CHECK: rnsbg %r2, %r3, 59, 56, 0
9*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
10*9880d681SAndroid Build Coastguard Worker  %orb = or i32 %b, 96
11*9880d681SAndroid Build Coastguard Worker  %and = and i32 %a, %orb
12*9880d681SAndroid Build Coastguard Worker  ret i32 %and
13*9880d681SAndroid Build Coastguard Worker}
14*9880d681SAndroid Build Coastguard Worker
15*9880d681SAndroid Build Coastguard Worker; ...and again with i64.
16*9880d681SAndroid Build Coastguard Workerdefine i64 @f2(i64 %a, i64 %b) {
17*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f2:
18*9880d681SAndroid Build Coastguard Worker; CHECK: rnsbg %r2, %r3, 59, 56, 0
19*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
20*9880d681SAndroid Build Coastguard Worker  %orb = or i64 %b, 96
21*9880d681SAndroid Build Coastguard Worker  %and = and i64 %a, %orb
22*9880d681SAndroid Build Coastguard Worker  ret i64 %and
23*9880d681SAndroid Build Coastguard Worker}
24*9880d681SAndroid Build Coastguard Worker
25*9880d681SAndroid Build Coastguard Worker; Test a case where no wraparound is needed.
26*9880d681SAndroid Build Coastguard Workerdefine i32 @f3(i32 %a, i32 %b) {
27*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f3:
28*9880d681SAndroid Build Coastguard Worker; CHECK: rnsbg %r2, %r3, 58, 61, 0
29*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
30*9880d681SAndroid Build Coastguard Worker  %orb = or i32 %b, -61
31*9880d681SAndroid Build Coastguard Worker  %and = and i32 %a, %orb
32*9880d681SAndroid Build Coastguard Worker  ret i32 %and
33*9880d681SAndroid Build Coastguard Worker}
34*9880d681SAndroid Build Coastguard Worker
35*9880d681SAndroid Build Coastguard Worker; ...and again with i64.
36*9880d681SAndroid Build Coastguard Workerdefine i64 @f4(i64 %a, i64 %b) {
37*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f4:
38*9880d681SAndroid Build Coastguard Worker; CHECK: rnsbg %r2, %r3, 58, 61, 0
39*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
40*9880d681SAndroid Build Coastguard Worker  %orb = or i64 %b, -61
41*9880d681SAndroid Build Coastguard Worker  %and = and i64 %a, %orb
42*9880d681SAndroid Build Coastguard Worker  ret i64 %and
43*9880d681SAndroid Build Coastguard Worker}
44*9880d681SAndroid Build Coastguard Worker
45*9880d681SAndroid Build Coastguard Worker; Test a case with just a left shift.  This can't use RNSBG.
46*9880d681SAndroid Build Coastguard Workerdefine i32 @f6(i32 %a, i32 %b) {
47*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f6:
48*9880d681SAndroid Build Coastguard Worker; CHECK: sll {{%r[0-5]}}
49*9880d681SAndroid Build Coastguard Worker; CHECK: nr {{%r[0-5]}}
50*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
51*9880d681SAndroid Build Coastguard Worker  %shrb = shl i32 %b, 20
52*9880d681SAndroid Build Coastguard Worker  %and = and i32 %a, %shrb
53*9880d681SAndroid Build Coastguard Worker  ret i32 %and
54*9880d681SAndroid Build Coastguard Worker}
55*9880d681SAndroid Build Coastguard Worker
56*9880d681SAndroid Build Coastguard Worker; ...and again with i64.
57*9880d681SAndroid Build Coastguard Workerdefine i64 @f7(i64 %a, i64 %b) {
58*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f7:
59*9880d681SAndroid Build Coastguard Worker; CHECK: sllg {{%r[0-5]}}
60*9880d681SAndroid Build Coastguard Worker; CHECK: ngr {{%r[0-5]}}
61*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
62*9880d681SAndroid Build Coastguard Worker  %shrb = shl i64 %b, 20
63*9880d681SAndroid Build Coastguard Worker  %and = and i64 %a, %shrb
64*9880d681SAndroid Build Coastguard Worker  ret i64 %and
65*9880d681SAndroid Build Coastguard Worker}
66*9880d681SAndroid Build Coastguard Worker
67*9880d681SAndroid Build Coastguard Worker; Test a case with just a rotate.  This can't use RNSBG.
68*9880d681SAndroid Build Coastguard Workerdefine i32 @f8(i32 %a, i32 %b) {
69*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f8:
70*9880d681SAndroid Build Coastguard Worker; CHECK: rll {{%r[0-5]}}
71*9880d681SAndroid Build Coastguard Worker; CHECK: nr {{%r[0-5]}}
72*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
73*9880d681SAndroid Build Coastguard Worker  %shlb = shl i32 %b, 22
74*9880d681SAndroid Build Coastguard Worker  %shrb = lshr i32 %b, 10
75*9880d681SAndroid Build Coastguard Worker  %rotlb = or i32 %shlb, %shrb
76*9880d681SAndroid Build Coastguard Worker  %and = and i32 %a, %rotlb
77*9880d681SAndroid Build Coastguard Worker  ret i32 %and
78*9880d681SAndroid Build Coastguard Worker}
79*9880d681SAndroid Build Coastguard Worker
80*9880d681SAndroid Build Coastguard Worker; ...and again with i64, which can.
81*9880d681SAndroid Build Coastguard Workerdefine i64 @f9(i64 %a, i64 %b) {
82*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f9:
83*9880d681SAndroid Build Coastguard Worker; CHECK: rnsbg %r2, %r3, 0, 63, 44
84*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
85*9880d681SAndroid Build Coastguard Worker  %shlb = shl i64 %b, 44
86*9880d681SAndroid Build Coastguard Worker  %shrb = lshr i64 %b, 20
87*9880d681SAndroid Build Coastguard Worker  %rotlb = or i64 %shlb, %shrb
88*9880d681SAndroid Build Coastguard Worker  %and = and i64 %a, %rotlb
89*9880d681SAndroid Build Coastguard Worker  ret i64 %and
90*9880d681SAndroid Build Coastguard Worker}
91*9880d681SAndroid Build Coastguard Worker
92*9880d681SAndroid Build Coastguard Worker; Test a case with a left shift and OR, where the OR covers all shifted bits.
93*9880d681SAndroid Build Coastguard Worker; We can do the whole thing using RNSBG.
94*9880d681SAndroid Build Coastguard Workerdefine i32 @f10(i32 %a, i32 %b) {
95*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f10:
96*9880d681SAndroid Build Coastguard Worker; CHECK: rnsbg %r2, %r3, 32, 56, 7
97*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
98*9880d681SAndroid Build Coastguard Worker  %shlb = shl i32 %b, 7
99*9880d681SAndroid Build Coastguard Worker  %orb = or i32 %shlb, 127
100*9880d681SAndroid Build Coastguard Worker  %and = and i32 %a, %orb
101*9880d681SAndroid Build Coastguard Worker  ret i32 %and
102*9880d681SAndroid Build Coastguard Worker}
103*9880d681SAndroid Build Coastguard Worker
104*9880d681SAndroid Build Coastguard Worker; ...and again with i64.
105*9880d681SAndroid Build Coastguard Workerdefine i64 @f11(i64 %a, i64 %b) {
106*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f11:
107*9880d681SAndroid Build Coastguard Worker; CHECK: rnsbg %r2, %r3, 0, 56, 7
108*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
109*9880d681SAndroid Build Coastguard Worker  %shlb = shl i64 %b, 7
110*9880d681SAndroid Build Coastguard Worker  %orb = or i64 %shlb, 127
111*9880d681SAndroid Build Coastguard Worker  %and = and i64 %a, %orb
112*9880d681SAndroid Build Coastguard Worker  ret i64 %and
113*9880d681SAndroid Build Coastguard Worker}
114*9880d681SAndroid Build Coastguard Worker
115*9880d681SAndroid Build Coastguard Worker; Test a case with a left shift and OR, where the OR doesn't cover all
116*9880d681SAndroid Build Coastguard Worker; shifted bits.  We can't use RNSBG for the shift, but we can for the OR
117*9880d681SAndroid Build Coastguard Worker; and AND.
118*9880d681SAndroid Build Coastguard Workerdefine i32 @f12(i32 %a, i32 %b) {
119*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f12:
120*9880d681SAndroid Build Coastguard Worker; CHECK: sll %r3, 7
121*9880d681SAndroid Build Coastguard Worker; CHECK: rnsbg %r2, %r3, 32, 57, 0
122*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
123*9880d681SAndroid Build Coastguard Worker  %shlb = shl i32 %b, 7
124*9880d681SAndroid Build Coastguard Worker  %orb = or i32 %shlb, 63
125*9880d681SAndroid Build Coastguard Worker  %and = and i32 %a, %orb
126*9880d681SAndroid Build Coastguard Worker  ret i32 %and
127*9880d681SAndroid Build Coastguard Worker}
128*9880d681SAndroid Build Coastguard Worker
129*9880d681SAndroid Build Coastguard Worker; ...and again with i64.
130*9880d681SAndroid Build Coastguard Workerdefine i64 @f13(i64 %a, i64 %b) {
131*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f13:
132*9880d681SAndroid Build Coastguard Worker; CHECK: sllg [[REG:%r[01345]]], %r3, 7
133*9880d681SAndroid Build Coastguard Worker; CHECK: rnsbg %r2, [[REG]], 0, 57, 0
134*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
135*9880d681SAndroid Build Coastguard Worker  %shlb = shl i64 %b, 7
136*9880d681SAndroid Build Coastguard Worker  %orb = or i64 %shlb, 63
137*9880d681SAndroid Build Coastguard Worker  %and = and i64 %a, %orb
138*9880d681SAndroid Build Coastguard Worker  ret i64 %and
139*9880d681SAndroid Build Coastguard Worker}
140*9880d681SAndroid Build Coastguard Worker
141*9880d681SAndroid Build Coastguard Worker; Test a case with a right shift and OR, where the OR covers all the shifted
142*9880d681SAndroid Build Coastguard Worker; bits.  The whole thing can be done using RNSBG.
143*9880d681SAndroid Build Coastguard Workerdefine i32 @f14(i32 %a, i32 %b) {
144*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f14:
145*9880d681SAndroid Build Coastguard Worker; CHECK: rnsbg %r2, %r3, 60, 63, 37
146*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
147*9880d681SAndroid Build Coastguard Worker  %shrb = lshr i32 %b, 27
148*9880d681SAndroid Build Coastguard Worker  %orb = or i32 %shrb, -16
149*9880d681SAndroid Build Coastguard Worker  %and = and i32 %a, %orb
150*9880d681SAndroid Build Coastguard Worker  ret i32 %and
151*9880d681SAndroid Build Coastguard Worker}
152*9880d681SAndroid Build Coastguard Worker
153*9880d681SAndroid Build Coastguard Worker; ...and again with i64.
154*9880d681SAndroid Build Coastguard Workerdefine i64 @f15(i64 %a, i64 %b) {
155*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f15:
156*9880d681SAndroid Build Coastguard Worker; CHECK: rnsbg %r2, %r3, 60, 63, 5
157*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
158*9880d681SAndroid Build Coastguard Worker  %shrb = lshr i64 %b, 59
159*9880d681SAndroid Build Coastguard Worker  %orb = or i64 %shrb, -16
160*9880d681SAndroid Build Coastguard Worker  %and = and i64 %a, %orb
161*9880d681SAndroid Build Coastguard Worker  ret i64 %and
162*9880d681SAndroid Build Coastguard Worker}
163*9880d681SAndroid Build Coastguard Worker
164*9880d681SAndroid Build Coastguard Worker; Test a case with a right shift and OR, where the OR doesn't cover all the
165*9880d681SAndroid Build Coastguard Worker; shifted bits.  The shift needs to be done separately, but the OR and AND
166*9880d681SAndroid Build Coastguard Worker; can use RNSBG.
167*9880d681SAndroid Build Coastguard Workerdefine i32 @f16(i32 %a, i32 %b) {
168*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f16:
169*9880d681SAndroid Build Coastguard Worker; CHECK: srl %r3, 29
170*9880d681SAndroid Build Coastguard Worker; CHECK: rnsbg %r2, %r3, 60, 63, 0
171*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
172*9880d681SAndroid Build Coastguard Worker  %shrb = lshr i32 %b, 29
173*9880d681SAndroid Build Coastguard Worker  %orb = or i32 %shrb, -16
174*9880d681SAndroid Build Coastguard Worker  %and = and i32 %a, %orb
175*9880d681SAndroid Build Coastguard Worker  ret i32 %and
176*9880d681SAndroid Build Coastguard Worker}
177*9880d681SAndroid Build Coastguard Worker
178*9880d681SAndroid Build Coastguard Worker; ...and again with i64.
179*9880d681SAndroid Build Coastguard Workerdefine i64 @f17(i64 %a, i64 %b) {
180*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f17:
181*9880d681SAndroid Build Coastguard Worker; CHECK: srlg [[REG:%r[01345]]], %r3, 61
182*9880d681SAndroid Build Coastguard Worker; CHECK: rnsbg %r2, [[REG]], 60, 63, 0
183*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
184*9880d681SAndroid Build Coastguard Worker  %shrb = lshr i64 %b, 61
185*9880d681SAndroid Build Coastguard Worker  %orb = or i64 %shrb, -16
186*9880d681SAndroid Build Coastguard Worker  %and = and i64 %a, %orb
187*9880d681SAndroid Build Coastguard Worker  ret i64 %and
188*9880d681SAndroid Build Coastguard Worker}
189*9880d681SAndroid Build Coastguard Worker
190*9880d681SAndroid Build Coastguard Worker; Test a combination involving an ASHR in which the sign bits matter.
191*9880d681SAndroid Build Coastguard Worker; We can't use RNSBG for the ASHR in that case, but we can for the rest.
192*9880d681SAndroid Build Coastguard Workerdefine i32 @f18(i32 %a, i32 %b, i32 *%dest) {
193*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f18:
194*9880d681SAndroid Build Coastguard Worker; CHECK: sra %r3, 4
195*9880d681SAndroid Build Coastguard Worker; CHECK: rnsbg %r2, %r3, 32, 62, 1
196*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
197*9880d681SAndroid Build Coastguard Worker  %ashrb = ashr i32 %b, 4
198*9880d681SAndroid Build Coastguard Worker  store i32 %ashrb, i32 *%dest
199*9880d681SAndroid Build Coastguard Worker  %shlb = shl i32 %ashrb, 1
200*9880d681SAndroid Build Coastguard Worker  %orb = or i32 %shlb, 1
201*9880d681SAndroid Build Coastguard Worker  %and = and i32 %a, %orb
202*9880d681SAndroid Build Coastguard Worker  ret i32 %and
203*9880d681SAndroid Build Coastguard Worker}
204*9880d681SAndroid Build Coastguard Worker
205*9880d681SAndroid Build Coastguard Worker; ...and again with i64.
206*9880d681SAndroid Build Coastguard Workerdefine i64 @f19(i64 %a, i64 %b, i64 *%dest) {
207*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f19:
208*9880d681SAndroid Build Coastguard Worker; CHECK: srag [[REG:%r[0145]]], %r3, 34
209*9880d681SAndroid Build Coastguard Worker; CHECK: rnsbg %r2, [[REG]], 0, 62, 1
210*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
211*9880d681SAndroid Build Coastguard Worker  %ashrb = ashr i64 %b, 34
212*9880d681SAndroid Build Coastguard Worker  store i64 %ashrb, i64 *%dest
213*9880d681SAndroid Build Coastguard Worker  %shlb = shl i64 %ashrb, 1
214*9880d681SAndroid Build Coastguard Worker  %orb = or i64 %shlb, 1
215*9880d681SAndroid Build Coastguard Worker  %and = and i64 %a, %orb
216*9880d681SAndroid Build Coastguard Worker  ret i64 %and
217*9880d681SAndroid Build Coastguard Worker}
218*9880d681SAndroid Build Coastguard Worker
219*9880d681SAndroid Build Coastguard Worker; Test a combination involving an ASHR in which the sign bits don't matter.
220*9880d681SAndroid Build Coastguard Workerdefine i32 @f20(i32 %a, i32 %b, i32 *%dest) {
221*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f20:
222*9880d681SAndroid Build Coastguard Worker; CHECK: rnsbg %r2, %r3, 48, 62, 48
223*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
224*9880d681SAndroid Build Coastguard Worker  %ashrb = ashr i32 %b, 17
225*9880d681SAndroid Build Coastguard Worker  store i32 %ashrb, i32 *%dest
226*9880d681SAndroid Build Coastguard Worker  %shlb = shl i32 %ashrb, 1
227*9880d681SAndroid Build Coastguard Worker  %orb = or i32 %shlb, -65535
228*9880d681SAndroid Build Coastguard Worker  %and = and i32 %a, %orb
229*9880d681SAndroid Build Coastguard Worker  ret i32 %and
230*9880d681SAndroid Build Coastguard Worker}
231*9880d681SAndroid Build Coastguard Worker
232*9880d681SAndroid Build Coastguard Worker; ...and again with i64.
233*9880d681SAndroid Build Coastguard Workerdefine i64 @f21(i64 %a, i64 %b, i64 *%dest) {
234*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f21:
235*9880d681SAndroid Build Coastguard Worker; CHECK: rnsbg %r2, %r3, 48, 62, 16
236*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
237*9880d681SAndroid Build Coastguard Worker  %ashrb = ashr i64 %b, 49
238*9880d681SAndroid Build Coastguard Worker  store i64 %ashrb, i64 *%dest
239*9880d681SAndroid Build Coastguard Worker  %shlb = shl i64 %ashrb, 1
240*9880d681SAndroid Build Coastguard Worker  %orb = or i64 %shlb, -65535
241*9880d681SAndroid Build Coastguard Worker  %and = and i64 %a, %orb
242*9880d681SAndroid Build Coastguard Worker  ret i64 %and
243*9880d681SAndroid Build Coastguard Worker}
244*9880d681SAndroid Build Coastguard Worker
245*9880d681SAndroid Build Coastguard Worker; Test a case with a shift, OR, and rotate where the OR covers all shifted bits.
246*9880d681SAndroid Build Coastguard Workerdefine i64 @f22(i64 %a, i64 %b) {
247*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f22:
248*9880d681SAndroid Build Coastguard Worker; CHECK: rnsbg %r2, %r3, 60, 54, 9
249*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
250*9880d681SAndroid Build Coastguard Worker  %shlb = shl i64 %b, 5
251*9880d681SAndroid Build Coastguard Worker  %orb = or i64 %shlb, 31
252*9880d681SAndroid Build Coastguard Worker  %shlorb = shl i64 %orb, 4
253*9880d681SAndroid Build Coastguard Worker  %shrorb = lshr i64 %orb, 60
254*9880d681SAndroid Build Coastguard Worker  %rotlorb = or i64 %shlorb, %shrorb
255*9880d681SAndroid Build Coastguard Worker  %and = and i64 %a, %rotlorb
256*9880d681SAndroid Build Coastguard Worker  ret i64 %and
257*9880d681SAndroid Build Coastguard Worker}
258*9880d681SAndroid Build Coastguard Worker
259*9880d681SAndroid Build Coastguard Worker; Check the handling of zext and AND, which isn't suitable for RNSBG.
260*9880d681SAndroid Build Coastguard Workerdefine i64 @f23(i64 %a, i32 %b) {
261*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f23:
262*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: rnsbg
263*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
264*9880d681SAndroid Build Coastguard Worker  %add = add i32 %b, 1
265*9880d681SAndroid Build Coastguard Worker  %ext = zext i32 %add to i64
266*9880d681SAndroid Build Coastguard Worker  %and = and i64 %a, %ext
267*9880d681SAndroid Build Coastguard Worker  ret i64 %and
268*9880d681SAndroid Build Coastguard Worker}
269