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