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