Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / test / CodeGen / SystemZ / shift-04.ll
blobc91a7292604c885992abe9f307642986bac18899
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) {
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
18 ; Check the high end of the defined RLL range.
19 define 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
30 ; We don't generate shifts by out-of-range values.
31 define 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
42 ; Check variable shifts.
43 define 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
55 ; Check shift amounts that have a constant term.
56 define 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
69 ; ...and again with a truncated 64-bit shift amount.
70 define 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
84 ; ...and again with a different truncation representation.
85 define 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
100 ; Check shift amounts that have the largest in-range constant term, and then
101 ; mask the amount.
102 define 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
115 ; Check the next value up, which without masking must use a separate
116 ; addition.
117 define 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
131 ; Check cases where 1 is subtracted from the shift amount.
132 define 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
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) {
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
160 ; Check the next value down, masking the amount removes the addition.
161 define 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
174 ; Check that we don't try to generate "indexed" shifts.
175 define 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
189 ; Check that the shift amount uses an address register.  It cannot be in %r0.
190 define i32 @f14(i32 %a, ptr %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, 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
201   ret i32 %or
204 ; Check another form of f5, which is the one produced by running f5 through
205 ; instcombine.
206 define 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
219 ; Likewise for f7.
220 define 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
235 ; Check cases where (-x & 31) is used instead of 32 - x.
236 define 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
241 entry:
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
250 ; ...and again with ((32 - x) & 31).
251 define 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
256 entry:
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
265 ; This is not a rotation.
266 define 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
277 entry:
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
286 ; Repeat f17 with an addition on the shift count.
287 define 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
292 entry:
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
302 ; ...and again with the InstCombine version.
303 define 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
308 entry:
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