xref: /llvm-project/llvm/test/CodeGen/SystemZ/shift-08.ll (revision a1710eb3cd5823c5d14899112ca3086acbdbe9cb)
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 RLLG range.
7define i64 @f1(i64 %a) {
8; CHECK-LABEL: f1:
9; CHECK:       # %bb.0:
10; CHECK-NEXT:    rllg %r2, %r2, 1
11; CHECK-NEXT:    br %r14
12  %parta = shl i64 %a, 1
13  %partb = lshr i64 %a, 63
14  %or = or i64 %parta, %partb
15  ret i64 %or
16}
17
18; Check the high end of the defined RLLG range.
19define i64 @f2(i64 %a) {
20; CHECK-LABEL: f2:
21; CHECK:       # %bb.0:
22; CHECK-NEXT:    rllg %r2, %r2, 63
23; CHECK-NEXT:    br %r14
24  %parta = shl i64 %a, 63
25  %partb = lshr i64 %a, 1
26  %or = or i64 %parta, %partb
27  ret i64 %or
28}
29
30; We don't generate shifts by out-of-range values.
31define i64 @f3(i64 %a) {
32; CHECK-LABEL: f3:
33; CHECK:       # %bb.0:
34; CHECK-NEXT:    lghi %r2, -1
35; CHECK-NEXT:    br %r14
36  %parta = shl i64 %a, 64
37  %partb = lshr i64 %a, 0
38  %or = or i64 %parta, %partb
39  ret i64 %or
40}
41
42; Check variable shifts.
43define i64 @f4(i64 %a, i64 %amt) {
44; CHECK-LABEL: f4:
45; CHECK:       # %bb.0:
46; CHECK-NEXT:    rllg %r2, %r2, 0(%r3)
47; CHECK-NEXT:    br %r14
48  %amtb = sub i64 64, %amt
49  %parta = shl i64 %a, %amt
50  %partb = lshr i64 %a, %amtb
51  %or = or i64 %parta, %partb
52  ret i64 %or
53}
54
55; Check shift amounts that have a constant term.
56define i64 @f5(i64 %a, i64 %amt) {
57; CHECK-LABEL: f5:
58; CHECK:       # %bb.0:
59; CHECK-NEXT:    rllg %r2, %r2, 10(%r3)
60; CHECK-NEXT:    br %r14
61  %add = add i64 %amt, 10
62  %sub = sub i64 64, %add
63  %parta = shl i64 %a, %add
64  %partb = lshr i64 %a, %sub
65  %or = or i64 %parta, %partb
66  ret i64 %or
67}
68
69; ...and again with a sign-extended 32-bit shift amount.
70define i64 @f6(i64 %a, i32 %amt) {
71; CHECK-LABEL: f6:
72; CHECK:       # %bb.0:
73; CHECK-NEXT:    rllg %r2, %r2, 10(%r3)
74; CHECK-NEXT:    br %r14
75  %add = add i32 %amt, 10
76  %sub = sub i32 64, %add
77  %addext = sext i32 %add to i64
78  %subext = sext i32 %sub to i64
79  %parta = shl i64 %a, %addext
80  %partb = lshr i64 %a, %subext
81  %or = or i64 %parta, %partb
82  ret i64 %or
83}
84
85; ...and now with a zero-extended 32-bit shift amount.
86define i64 @f7(i64 %a, i32 %amt) {
87; CHECK-LABEL: f7:
88; CHECK:       # %bb.0:
89; CHECK-NEXT:    rllg %r2, %r2, 10(%r3)
90; CHECK-NEXT:    br %r14
91  %add = add i32 %amt, 10
92  %sub = sub i32 64, %add
93  %addext = zext i32 %add to i64
94  %subext = zext i32 %sub to i64
95  %parta = shl i64 %a, %addext
96  %partb = lshr i64 %a, %subext
97  %or = or i64 %parta, %partb
98  ret i64 %or
99}
100
101; Check shift amounts that have the largest in-range constant term, and then
102; mask the amount.
103define i64 @f8(i64 %a, i64 %amt) {
104; CHECK-LABEL: f8:
105; CHECK:       # %bb.0:
106; CHECK-NEXT:    rllg %r2, %r2, -1(%r3)
107; CHECK-NEXT:    br %r14
108  %add = add i64 %amt, 524287
109  %sub = sub i64 64, %add
110  %parta = shl i64 %a, %add
111  %partb = lshr i64 %a, %sub
112  %or = or i64 %parta, %partb
113  ret i64 %or
114}
115
116; Check the next value up, which without masking must use a separate
117; addition.
118define i64 @f9(i64 %a, i64 %amt) {
119; CHECK-LABEL: f9:
120; CHECK:       # %bb.0:
121; CHECK-NEXT:    afi %r3, 524288
122; CHECK-NEXT:    rllg %r2, %r2, 0(%r3)
123; CHECK-NEXT:    br %r14
124  %add = add i64 %amt, 524288
125  %sub = sub i64 64, %add
126  %parta = shl i64 %a, %add
127  %partb = lshr i64 %a, %sub
128  %or = or i64 %parta, %partb
129  ret i64 %or
130}
131
132; Check cases where 1 is subtracted from the shift amount.
133define i64 @f10(i64 %a, i64 %amt) {
134; CHECK-LABEL: f10:
135; CHECK:       # %bb.0:
136; CHECK-NEXT:    rllg %r2, %r2, -1(%r3)
137; CHECK-NEXT:    br %r14
138  %suba = sub i64 %amt, 1
139  %subb = sub i64 64, %suba
140  %parta = shl i64 %a, %suba
141  %partb = lshr i64 %a, %subb
142  %or = or i64 %parta, %partb
143  ret i64 %or
144}
145
146; Check the lowest value that can be subtracted from the shift amount.
147; Again, we could mask the shift amount instead.
148define i64 @f11(i64 %a, i64 %amt) {
149; CHECK-LABEL: f11:
150; CHECK:       # %bb.0:
151; CHECK-NEXT:    rllg %r2, %r2, -524288(%r3)
152; CHECK-NEXT:    br %r14
153  %suba = sub i64 %amt, 524288
154  %subb = sub i64 64, %suba
155  %parta = shl i64 %a, %suba
156  %partb = lshr i64 %a, %subb
157  %or = or i64 %parta, %partb
158  ret i64 %or
159}
160
161; Check the next value down, masking the amount removes the addition.
162define i64 @f12(i64 %a, i64 %amt) {
163; CHECK-LABEL: f12:
164; CHECK:       # %bb.0:
165; CHECK-NEXT:    rllg %r2, %r2, -1(%r3)
166; CHECK-NEXT:    br %r14
167  %suba = sub i64 %amt, 524289
168  %subb = sub i64 64, %suba
169  %parta = shl i64 %a, %suba
170  %partb = lshr i64 %a, %subb
171  %or = or i64 %parta, %partb
172  ret i64 %or
173}
174
175; Check that we don't try to generate "indexed" shifts.
176define i64 @f13(i64 %a, i64 %b, i64 %c) {
177; CHECK-LABEL: f13:
178; CHECK:       # %bb.0:
179; CHECK-NEXT:    agr %r3, %r4
180; CHECK-NEXT:    rllg %r2, %r2, 0(%r3)
181; CHECK-NEXT:    br %r14
182  %add = add i64 %b, %c
183  %sub = sub i64 64, %add
184  %parta = shl i64 %a, %add
185  %partb = lshr i64 %a, %sub
186  %or = or i64 %parta, %partb
187  ret i64 %or
188}
189
190; Check that the shift amount uses an address register.  It cannot be in %r0.
191define i64 @f14(i64 %a, ptr %ptr) {
192; CHECK-LABEL: f14:
193; CHECK:       # %bb.0:
194; CHECK-NEXT:    l %r1, 4(%r3)
195; CHECK-NEXT:    rllg %r2, %r2, 0(%r1)
196; CHECK-NEXT:    br %r14
197  %amt = load i64, ptr %ptr
198  %amtb = sub i64 64, %amt
199  %parta = shl i64 %a, %amt
200  %partb = lshr i64 %a, %amtb
201  %or = or i64 %parta, %partb
202  ret i64 %or
203}
204