[SystemZ] Add zero-extending high-word loads (LLCH and LLHH)
[oota-llvm.git] / test / CodeGen / SystemZ / shift-08.ll
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.
6 define 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.
17 define 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.
28 define 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.
39 define 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.
51 define 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.
64 define 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.
79 define 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.
95 define 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.
109 define 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.
123 define 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.
137 define 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.
151 define 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.
165 define 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.
179 define 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 }