• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, and then
101; mask the amount.
102define i32 @f8(i32 %a, i32 %amt) {
103; CHECK-LABEL: f8:
104; CHECK:       # %bb.0:
105; CHECK-NEXT:    rll %r2, %r2, -1(%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, masking the amount removes the addition.
161define i32 @f12(i32 %a, i32 %amt) {
162; CHECK-LABEL: f12:
163; CHECK:       # %bb.0:
164; CHECK-NEXT:    rll %r2, %r2, -1(%r3)
165; CHECK-NEXT:    br %r14
166  %suba = sub i32 %amt, 524289
167  %subb = sub i32 32, %suba
168  %parta = shl i32 %a, %suba
169  %partb = lshr i32 %a, %subb
170  %or = or i32 %parta, %partb
171  ret i32 %or
172}
173
174; Check that we don't try to generate "indexed" shifts.
175define i32 @f13(i32 %a, i32 %b, i32 %c) {
176; CHECK-LABEL: f13:
177; CHECK:       # %bb.0:
178; CHECK-NEXT:    ar %r3, %r4
179; CHECK-NEXT:    rll %r2, %r2, 0(%r3)
180; CHECK-NEXT:    br %r14
181  %add = add i32 %b, %c
182  %sub = sub i32 32, %add
183  %parta = shl i32 %a, %add
184  %partb = lshr i32 %a, %sub
185  %or = or i32 %parta, %partb
186  ret i32 %or
187}
188
189; Check that the shift amount uses an address register.  It cannot be in %r0.
190define i32 @f14(i32 %a, i32 *%ptr) {
191; CHECK-LABEL: f14:
192; CHECK:       # %bb.0:
193; CHECK-NEXT:    l %r1, 0(%r3)
194; CHECK-NEXT:    rll %r2, %r2, 0(%r1)
195; CHECK-NEXT:    br %r14
196  %amt = load i32, i32 *%ptr
197  %amtb = sub i32 32, %amt
198  %parta = shl i32 %a, %amt
199  %partb = lshr i32 %a, %amtb
200  %or = or i32 %parta, %partb
201  ret i32 %or
202}
203
204; Check another form of f5, which is the one produced by running f5 through
205; instcombine.
206define i32 @f15(i32 %a, i32 %amt) {
207; CHECK-LABEL: f15:
208; CHECK:       # %bb.0:
209; CHECK-NEXT:    rll %r2, %r2, 10(%r3)
210; CHECK-NEXT:    br %r14
211  %add = add i32 %amt, 10
212  %sub = sub i32 22, %amt
213  %parta = shl i32 %a, %add
214  %partb = lshr i32 %a, %sub
215  %or = or i32 %parta, %partb
216  ret i32 %or
217}
218
219; Likewise for f7.
220define i32 @f16(i32 %a, i64 %amt) {
221; CHECK-LABEL: f16:
222; CHECK:       # %bb.0:
223; CHECK-NEXT:    rll %r2, %r2, 10(%r3)
224; CHECK-NEXT:    br %r14
225  %add = add i64 %amt, 10
226  %sub = sub i64 22, %amt
227  %addtrunc = trunc i64 %add to i32
228  %subtrunc = trunc i64 %sub to i32
229  %parta = shl i32 %a, %addtrunc
230  %partb = lshr i32 %a, %subtrunc
231  %or = or i32 %parta, %partb
232  ret i32 %or
233}
234
235; Check cases where (-x & 31) is used instead of 32 - x.
236define i32 @f17(i32 %x, i32 %y) {
237; CHECK-LABEL: f17:
238; CHECK:       # %bb.0: # %entry
239; CHECK-NEXT:    rll %r2, %r2, 0(%r3)
240; CHECK-NEXT:    br %r14
241entry:
242  %shl = shl i32 %x, %y
243  %sub = sub i32 0, %y
244  %and = and i32 %sub, 31
245  %shr = lshr i32 %x, %and
246  %or = or i32 %shr, %shl
247  ret i32 %or
248}
249
250; ...and again with ((32 - x) & 31).
251define i32 @f18(i32 %x, i32 %y) {
252; CHECK-LABEL: f18:
253; CHECK:       # %bb.0: # %entry
254; CHECK-NEXT:    rll %r2, %r2, 0(%r3)
255; CHECK-NEXT:    br %r14
256entry:
257  %shl = shl i32 %x, %y
258  %sub = sub i32 32, %y
259  %and = and i32 %sub, 31
260  %shr = lshr i32 %x, %and
261  %or = or i32 %shr, %shl
262  ret i32 %or
263}
264
265; This is not a rotation.
266define i32 @f19(i32 %x, i32 %y) {
267; CHECK-LABEL: f19:
268; CHECK:       # %bb.0: # %entry
269; CHECK-NEXT:    lr %r0, %r2
270; CHECK-NEXT:    sll %r0, 0(%r3)
271; CHECK-NEXT:    lhi %r1, 16
272; CHECK-NEXT:    sr %r1, %r3
273; CHECK-NEXT:    nill %r1, 31
274; CHECK-NEXT:    srl %r2, 0(%r1)
275; CHECK-NEXT:    or %r2, %r0
276; CHECK-NEXT:    br %r14
277entry:
278  %shl = shl i32 %x, %y
279  %sub = sub i32 16, %y
280  %and = and i32 %sub, 31
281  %shr = lshr i32 %x, %and
282  %or = or i32 %shr, %shl
283  ret i32 %or
284}
285
286; Repeat f17 with an addition on the shift count.
287define i32 @f20(i32 %x, i32 %y) {
288; CHECK-LABEL: f20:
289; CHECK:       # %bb.0: # %entry
290; CHECK-NEXT:    rll %r2, %r2, 199(%r3)
291; CHECK-NEXT:    br %r14
292entry:
293  %add = add i32 %y, 199
294  %shl = shl i32 %x, %add
295  %sub = sub i32 0, %add
296  %and = and i32 %sub, 31
297  %shr = lshr i32 %x, %and
298  %or = or i32 %shr, %shl
299  ret i32 %or
300}
301
302; ...and again with the InstCombine version.
303define i32 @f21(i32 %x, i32 %y) {
304; CHECK-LABEL: f21:
305; CHECK:       # %bb.0: # %entry
306; CHECK-NEXT:    rll %r2, %r2, 199(%r3)
307; CHECK-NEXT:    br %r14
308entry:
309  %add = add i32 %y, 199
310  %shl = shl i32 %x, %add
311  %sub = sub i32 -199, %y
312  %and = and i32 %sub, 31
313  %shr = lshr i32 %x, %and
314  %or = or i32 %shr, %shl
315  ret i32 %or
316}
317