blob: 47283b50221cf3eef64431af3070abf49848eaab [file] [log] [blame]
Ulrich Weigand9e3577f2013-05-06 16:17:29 +00001; 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) {
Stephen Lind24ab202013-07-14 06:24:09 +00007; CHECK-LABEL: f1:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +00008; 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) {
Stephen Lind24ab202013-07-14 06:24:09 +000018; CHECK-LABEL: f2:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +000019; 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) {
Stephen Lind24ab202013-07-14 06:24:09 +000029; CHECK-LABEL: f3:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +000030; 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) {
Stephen Lind24ab202013-07-14 06:24:09 +000040; CHECK-LABEL: f4:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +000041; 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) {
Stephen Lind24ab202013-07-14 06:24:09 +000052; CHECK-LABEL: f5:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +000053; 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) {
Stephen Lind24ab202013-07-14 06:24:09 +000065; CHECK-LABEL: f6:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +000066; 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) {
Stephen Lind24ab202013-07-14 06:24:09 +000080; CHECK-LABEL: f7:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +000081; 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) {
Stephen Lind24ab202013-07-14 06:24:09 +000096; CHECK-LABEL: f8:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +000097; 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) {
Stephen Lind24ab202013-07-14 06:24:09 +0000110; CHECK-LABEL: f9:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000111; 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) {
Stephen Lind24ab202013-07-14 06:24:09 +0000124; CHECK-LABEL: f10:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000125; 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) {
Stephen Lind24ab202013-07-14 06:24:09 +0000138; CHECK-LABEL: f11:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000139; 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) {
Stephen Lind24ab202013-07-14 06:24:09 +0000152; CHECK-LABEL: f12:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000153; 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) {
Stephen Lind24ab202013-07-14 06:24:09 +0000166; CHECK-LABEL: f13:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000167; 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) {
Stephen Lind24ab202013-07-14 06:24:09 +0000180; CHECK-LABEL: f14:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000181; 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}