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.  We could
102; mask the amount instead.
103define i64 @f8(i64 %a, i64 %amt) {
104; CHECK-LABEL: f8:
105; CHECK:       # %bb.0:
106; CHECK-NEXT:    rllg %r2, %r2, 524287(%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, which without masking must use a separate
162; addition.
163define i64 @f12(i64 %a, i64 %amt) {
164; CHECK-LABEL: f12:
165; CHECK:       # %bb.0:
166; CHECK-NEXT:    afi %r3, -524289
167; CHECK-NEXT:    rllg %r2, %r2, 0(%r3)
168; CHECK-NEXT:    br %r14
169  %suba = sub i64 %amt, 524289
170  %subb = sub i64 64, %suba
171  %parta = shl i64 %a, %suba
172  %partb = lshr i64 %a, %subb
173  %or = or i64 %parta, %partb
174  ret i64 %or
175}
176
177; Check that we don't try to generate "indexed" shifts.
178define i64 @f13(i64 %a, i64 %b, i64 %c) {
179; CHECK-LABEL: f13:
180; CHECK:       # %bb.0:
181; CHECK-NEXT:    agr %r3, %r4
182; CHECK-NEXT:    rllg %r2, %r2, 0(%r3)
183; CHECK-NEXT:    br %r14
184  %add = add i64 %b, %c
185  %sub = sub i64 64, %add
186  %parta = shl i64 %a, %add
187  %partb = lshr i64 %a, %sub
188  %or = or i64 %parta, %partb
189  ret i64 %or
190}
191
192; Check that the shift amount uses an address register.  It cannot be in %r0.
193define i64 @f14(i64 %a, i64 *%ptr) {
194; CHECK-LABEL: f14:
195; CHECK:       # %bb.0:
196; CHECK-NEXT:    l %r1, 4(%r3)
197; CHECK-NEXT:    rllg %r2, %r2, 0(%r1)
198; CHECK-NEXT:    br %r14
199  %amt = load i64, i64 *%ptr
200  %amtb = sub i64 64, %amt
201  %parta = shl i64 %a, %amt
202  %partb = lshr i64 %a, %amtb
203  %or = or i64 %parta, %partb
204  ret i64 %or
205}
206