1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; Test 32-bit rotates left.
3;
4; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
5
6; Check the low end of the RLL range.
7define i32 @f1(i32 %a) {
8; CHECK-LABEL: f1:
9; CHECK:       # %bb.0:
10; CHECK-NEXT:    rll %r2, %r2, 1
11; CHECK-NEXT:    br %r14
12  %parta = shl i32 %a, 1
13  %partb = lshr i32 %a, 31
14  %or = or i32 %parta, %partb
15  ret i32 %or
16}
17
18; Check the high end of the defined RLL range.
19define i32 @f2(i32 %a) {
20; CHECK-LABEL: f2:
21; CHECK:       # %bb.0:
22; CHECK-NEXT:    rll %r2, %r2, 31
23; CHECK-NEXT:    br %r14
24  %parta = shl i32 %a, 31
25  %partb = lshr i32 %a, 1
26  %or = or i32 %parta, %partb
27  ret i32 %or
28}
29
30; We don't generate shifts by out-of-range values.
31define i32 @f3(i32 %a) {
32; CHECK-LABEL: f3:
33; CHECK:       # %bb.0:
34; CHECK-NEXT:    lhi %r2, -1
35; CHECK-NEXT:    br %r14
36  %parta = shl i32 %a, 32
37  %partb = lshr i32 %a, 0
38  %or = or i32 %parta, %partb
39  ret i32 %or
40}
41
42; Check variable shifts.
43define i32 @f4(i32 %a, i32 %amt) {
44; CHECK-LABEL: f4:
45; CHECK:       # %bb.0:
46; CHECK-NEXT:    rll %r2, %r2, 0(%r3)
47; CHECK-NEXT:    br %r14
48  %amtb = sub i32 32, %amt
49  %parta = shl i32 %a, %amt
50  %partb = lshr i32 %a, %amtb
51  %or = or i32 %parta, %partb
52  ret i32 %or
53}
54
55; Check shift amounts that have a constant term.
56define i32 @f5(i32 %a, i32 %amt) {
57; CHECK-LABEL: f5:
58; CHECK:       # %bb.0:
59; CHECK-NEXT:    rll %r2, %r2, 10(%r3)
60; CHECK-NEXT:    br %r14
61  %add = add i32 %amt, 10
62  %sub = sub i32 32, %add
63  %parta = shl i32 %a, %add
64  %partb = lshr i32 %a, %sub
65  %or = or i32 %parta, %partb
66  ret i32 %or
67}
68
69; ...and again with a truncated 64-bit shift amount.
70define i32 @f6(i32 %a, i64 %amt) {
71; CHECK-LABEL: f6:
72; CHECK:       # %bb.0:
73; CHECK-NEXT:    rll %r2, %r2, 10(%r3)
74; CHECK-NEXT:    br %r14
75  %add = add i64 %amt, 10
76  %addtrunc = trunc i64 %add to i32
77  %sub = sub i32 32, %addtrunc
78  %parta = shl i32 %a, %addtrunc
79  %partb = lshr i32 %a, %sub
80  %or = or i32 %parta, %partb
81  ret i32 %or
82}
83
84; ...and again with a different truncation representation.
85define i32 @f7(i32 %a, i64 %amt) {
86; CHECK-LABEL: f7:
87; CHECK:       # %bb.0:
88; CHECK-NEXT:    rll %r2, %r2, 10(%r3)
89; CHECK-NEXT:    br %r14
90  %add = add i64 %amt, 10
91  %sub = sub i64 32, %add
92  %addtrunc = trunc i64 %add to i32
93  %subtrunc = trunc i64 %sub to i32
94  %parta = shl i32 %a, %addtrunc
95  %partb = lshr i32 %a, %subtrunc
96  %or = or i32 %parta, %partb
97  ret i32 %or
98}
99
100; Check shift amounts that have the largest in-range constant term.  We could
101; mask the amount instead.
102define i32 @f8(i32 %a, i32 %amt) {
103; CHECK-LABEL: f8:
104; CHECK:       # %bb.0:
105; CHECK-NEXT:    rll %r2, %r2, 524287(%r3)
106; CHECK-NEXT:    br %r14
107  %add = add i32 %amt, 524287
108  %sub = sub i32 32, %add
109  %parta = shl i32 %a, %add
110  %partb = lshr i32 %a, %sub
111  %or = or i32 %parta, %partb
112  ret i32 %or
113}
114
115; Check the next value up, which without masking must use a separate
116; addition.
117define i32 @f9(i32 %a, i32 %amt) {
118; CHECK-LABEL: f9:
119; CHECK:       # %bb.0:
120; CHECK-NEXT:    afi %r3, 524288
121; CHECK-NEXT:    rll %r2, %r2, 0(%r3)
122; CHECK-NEXT:    br %r14
123  %add = add i32 %amt, 524288
124  %sub = sub i32 32, %add
125  %parta = shl i32 %a, %add
126  %partb = lshr i32 %a, %sub
127  %or = or i32 %parta, %partb
128  ret i32 %or
129}
130
131; Check cases where 1 is subtracted from the shift amount.
132define i32 @f10(i32 %a, i32 %amt) {
133; CHECK-LABEL: f10:
134; CHECK:       # %bb.0:
135; CHECK-NEXT:    rll %r2, %r2, -1(%r3)
136; CHECK-NEXT:    br %r14
137  %suba = sub i32 %amt, 1
138  %subb = sub i32 32, %suba
139  %parta = shl i32 %a, %suba
140  %partb = lshr i32 %a, %subb
141  %or = or i32 %parta, %partb
142  ret i32 %or
143}
144
145; Check the lowest value that can be subtracted from the shift amount.
146; Again, we could mask the shift amount instead.
147define i32 @f11(i32 %a, i32 %amt) {
148; CHECK-LABEL: f11:
149; CHECK:       # %bb.0:
150; CHECK-NEXT:    rll %r2, %r2, -524288(%r3)
151; CHECK-NEXT:    br %r14
152  %suba = sub i32 %amt, 524288
153  %subb = sub i32 32, %suba
154  %parta = shl i32 %a, %suba
155  %partb = lshr i32 %a, %subb
156  %or = or i32 %parta, %partb
157  ret i32 %or
158}
159
160; Check the next value down, which without masking must use a separate
161; addition.
162define i32 @f12(i32 %a, i32 %amt) {
163; CHECK-LABEL: f12:
164; CHECK:       # %bb.0:
165; CHECK-NEXT:    afi %r3, -524289
166; CHECK-NEXT:    rll %r2, %r2, 0(%r3)
167; CHECK-NEXT:    br %r14
168  %suba = sub i32 %amt, 524289
169  %subb = sub i32 32, %suba
170  %parta = shl i32 %a, %suba
171  %partb = lshr i32 %a, %subb
172  %or = or i32 %parta, %partb
173  ret i32 %or
174}
175
176; Check that we don't try to generate "indexed" shifts.
177define i32 @f13(i32 %a, i32 %b, i32 %c) {
178; CHECK-LABEL: f13:
179; CHECK:       # %bb.0:
180; CHECK-NEXT:    ar %r3, %r4
181; CHECK-NEXT:    rll %r2, %r2, 0(%r3)
182; CHECK-NEXT:    br %r14
183  %add = add i32 %b, %c
184  %sub = sub i32 32, %add
185  %parta = shl i32 %a, %add
186  %partb = lshr i32 %a, %sub
187  %or = or i32 %parta, %partb
188  ret i32 %or
189}
190
191; Check that the shift amount uses an address register.  It cannot be in %r0.
192define i32 @f14(i32 %a, i32 *%ptr) {
193; CHECK-LABEL: f14:
194; CHECK:       # %bb.0:
195; CHECK-NEXT:    l %r1, 0(%r3)
196; CHECK-NEXT:    rll %r2, %r2, 0(%r1)
197; CHECK-NEXT:    br %r14
198  %amt = load i32, i32 *%ptr
199  %amtb = sub i32 32, %amt
200  %parta = shl i32 %a, %amt
201  %partb = lshr i32 %a, %amtb
202  %or = or i32 %parta, %partb
203  ret i32 %or
204}
205
206; Check another form of f5, which is the one produced by running f5 through
207; instcombine.
208define i32 @f15(i32 %a, i32 %amt) {
209; CHECK-LABEL: f15:
210; CHECK:       # %bb.0:
211; CHECK-NEXT:    rll %r2, %r2, 10(%r3)
212; CHECK-NEXT:    br %r14
213  %add = add i32 %amt, 10
214  %sub = sub i32 22, %amt
215  %parta = shl i32 %a, %add
216  %partb = lshr i32 %a, %sub
217  %or = or i32 %parta, %partb
218  ret i32 %or
219}
220
221; Likewise for f7.
222define i32 @f16(i32 %a, i64 %amt) {
223; CHECK-LABEL: f16:
224; CHECK:       # %bb.0:
225; CHECK-NEXT:    rll %r2, %r2, 10(%r3)
226; CHECK-NEXT:    br %r14
227  %add = add i64 %amt, 10
228  %sub = sub i64 22, %amt
229  %addtrunc = trunc i64 %add to i32
230  %subtrunc = trunc i64 %sub to i32
231  %parta = shl i32 %a, %addtrunc
232  %partb = lshr i32 %a, %subtrunc
233  %or = or i32 %parta, %partb
234  ret i32 %or
235}
236
237; Check cases where (-x & 31) is used instead of 32 - x.
238define i32 @f17(i32 %x, i32 %y) {
239; CHECK-LABEL: f17:
240; CHECK:       # %bb.0: # %entry
241; CHECK-NEXT:    rll %r2, %r2, 0(%r3)
242; CHECK-NEXT:    br %r14
243entry:
244  %shl = shl i32 %x, %y
245  %sub = sub i32 0, %y
246  %and = and i32 %sub, 31
247  %shr = lshr i32 %x, %and
248  %or = or i32 %shr, %shl
249  ret i32 %or
250}
251
252; ...and again with ((32 - x) & 31).
253define i32 @f18(i32 %x, i32 %y) {
254; CHECK-LABEL: f18:
255; CHECK:       # %bb.0: # %entry
256; CHECK-NEXT:    rll %r2, %r2, 0(%r3)
257; CHECK-NEXT:    br %r14
258entry:
259  %shl = shl i32 %x, %y
260  %sub = sub i32 32, %y
261  %and = and i32 %sub, 31
262  %shr = lshr i32 %x, %and
263  %or = or i32 %shr, %shl
264  ret i32 %or
265}
266
267; This is not a rotation.
268define i32 @f19(i32 %x, i32 %y) {
269; CHECK-LABEL: f19:
270; CHECK:       # %bb.0: # %entry
271; CHECK-NEXT:    lr %r0, %r2
272; CHECK-NEXT:    sll %r0, 0(%r3)
273; CHECK-NEXT:    lhi %r1, 16
274; CHECK-NEXT:    sr %r1, %r3
275; CHECK-NEXT:    nill %r1, 31
276; CHECK-NEXT:    srl %r2, 0(%r1)
277; CHECK-NEXT:    or %r2, %r0
278; CHECK-NEXT:    br %r14
279entry:
280  %shl = shl i32 %x, %y
281  %sub = sub i32 16, %y
282  %and = and i32 %sub, 31
283  %shr = lshr i32 %x, %and
284  %or = or i32 %shr, %shl
285  ret i32 %or
286}
287
288; Repeat f17 with an addition on the shift count.
289define i32 @f20(i32 %x, i32 %y) {
290; CHECK-LABEL: f20:
291; CHECK:       # %bb.0: # %entry
292; CHECK-NEXT:    rll %r2, %r2, 199(%r3)
293; CHECK-NEXT:    br %r14
294entry:
295  %add = add i32 %y, 199
296  %shl = shl i32 %x, %add
297  %sub = sub i32 0, %add
298  %and = and i32 %sub, 31
299  %shr = lshr i32 %x, %and
300  %or = or i32 %shr, %shl
301  ret i32 %or
302}
303
304; ...and again with the InstCombine version.
305define i32 @f21(i32 %x, i32 %y) {
306; CHECK-LABEL: f21:
307; CHECK:       # %bb.0: # %entry
308; CHECK-NEXT:    rll %r2, %r2, 199(%r3)
309; CHECK-NEXT:    br %r14
310entry:
311  %add = add i32 %y, 199
312  %shl = shl i32 %x, %add
313  %sub = sub i32 -199, %y
314  %and = and i32 %sub, 31
315  %shr = lshr i32 %x, %and
316  %or = or i32 %shr, %shl
317  ret i32 %or
318}
319