1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; Test 32-bit rotates left.
4 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
6 ; Check the low end of the RLL range.
7 define i32 @f1(i32 %a) {
10 ; CHECK-NEXT: rll %r2, %r2, 1
12 %parta = shl i32 %a, 1
13 %partb = lshr i32 %a, 31
14 %or = or i32 %parta, %partb
18 ; Check the high end of the defined RLL range.
19 define i32 @f2(i32 %a) {
22 ; CHECK-NEXT: rll %r2, %r2, 31
24 %parta = shl i32 %a, 31
25 %partb = lshr i32 %a, 1
26 %or = or i32 %parta, %partb
30 ; We don't generate shifts by out-of-range values.
31 define i32 @f3(i32 %a) {
34 ; CHECK-NEXT: lhi %r2, -1
36 %parta = shl i32 %a, 32
37 %partb = lshr i32 %a, 0
38 %or = or i32 %parta, %partb
42 ; Check variable shifts.
43 define i32 @f4(i32 %a, i32 %amt) {
46 ; CHECK-NEXT: rll %r2, %r2, 0(%r3)
48 %amtb = sub i32 32, %amt
49 %parta = shl i32 %a, %amt
50 %partb = lshr i32 %a, %amtb
51 %or = or i32 %parta, %partb
55 ; Check shift amounts that have a constant term.
56 define i32 @f5(i32 %a, i32 %amt) {
59 ; CHECK-NEXT: rll %r2, %r2, 10(%r3)
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
69 ; ...and again with a truncated 64-bit shift amount.
70 define i32 @f6(i32 %a, i64 %amt) {
73 ; CHECK-NEXT: rll %r2, %r2, 10(%r3)
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
84 ; ...and again with a different truncation representation.
85 define i32 @f7(i32 %a, i64 %amt) {
88 ; CHECK-NEXT: rll %r2, %r2, 10(%r3)
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
100 ; Check shift amounts that have the largest in-range constant term, and then
102 define i32 @f8(i32 %a, i32 %amt) {
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
115 ; Check the next value up, which without masking must use a separate
117 define i32 @f9(i32 %a, i32 %amt) {
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
131 ; Check cases where 1 is subtracted from the shift amount.
132 define i32 @f10(i32 %a, i32 %amt) {
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
145 ; Check the lowest value that can be subtracted from the shift amount.
146 ; Again, we could mask the shift amount instead.
147 define i32 @f11(i32 %a, i32 %amt) {
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
160 ; Check the next value down, masking the amount removes the addition.
161 define i32 @f12(i32 %a, i32 %amt) {
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
174 ; Check that we don't try to generate "indexed" shifts.
175 define i32 @f13(i32 %a, i32 %b, i32 %c) {
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
189 ; Check that the shift amount uses an address register. It cannot be in %r0.
190 define i32 @f14(i32 %a, ptr %ptr) {
193 ; CHECK-NEXT: l %r1, 0(%r3)
194 ; CHECK-NEXT: rll %r2, %r2, 0(%r1)
195 ; CHECK-NEXT: br %r14
196 %amt = load i32, ptr %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
204 ; Check another form of f5, which is the one produced by running f5 through
206 define i32 @f15(i32 %a, i32 %amt) {
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
220 define i32 @f16(i32 %a, i64 %amt) {
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
235 ; Check cases where (-x & 31) is used instead of 32 - x.
236 define i32 @f17(i32 %x, i32 %y) {
238 ; CHECK: # %bb.0: # %entry
239 ; CHECK-NEXT: rll %r2, %r2, 0(%r3)
240 ; CHECK-NEXT: br %r14
242 %shl = shl i32 %x, %y
244 %and = and i32 %sub, 31
245 %shr = lshr i32 %x, %and
246 %or = or i32 %shr, %shl
250 ; ...and again with ((32 - x) & 31).
251 define i32 @f18(i32 %x, i32 %y) {
253 ; CHECK: # %bb.0: # %entry
254 ; CHECK-NEXT: rll %r2, %r2, 0(%r3)
255 ; CHECK-NEXT: br %r14
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
265 ; This is not a rotation.
266 define i32 @f19(i32 %x, i32 %y) {
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
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
286 ; Repeat f17 with an addition on the shift count.
287 define i32 @f20(i32 %x, i32 %y) {
289 ; CHECK: # %bb.0: # %entry
290 ; CHECK-NEXT: rll %r2, %r2, 199(%r3)
291 ; CHECK-NEXT: br %r14
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
302 ; ...and again with the InstCombine version.
303 define i32 @f21(i32 %x, i32 %y) {
305 ; CHECK: # %bb.0: # %entry
306 ; CHECK-NEXT: rll %r2, %r2, 199(%r3)
307 ; CHECK-NEXT: br %r14
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