120
|
1 ; Test load and zero rightmost byte.
|
|
2 ;
|
|
3 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 | FileCheck %s
|
|
4
|
|
5 ; Check LZRF with no displacement.
|
|
6 define i32 @f1(i32 *%src) {
|
|
7 ; CHECK-LABEL: f1:
|
|
8 ; CHECK: lzrf %r2, 0(%r2)
|
|
9 ; CHECK: br %r14
|
|
10 %val = load i32, i32 *%src
|
|
11 %and = and i32 %val, 4294967040
|
|
12 ret i32 %and
|
|
13 }
|
|
14
|
|
15 ; Check the high end of the LZRF range.
|
|
16 define i32 @f2(i32 *%src) {
|
|
17 ; CHECK-LABEL: f2:
|
|
18 ; CHECK: lzrf %r2, 524284(%r2)
|
|
19 ; CHECK: br %r14
|
|
20 %ptr = getelementptr i32, i32 *%src, i64 131071
|
|
21 %val = load i32, i32 *%ptr
|
|
22 %and = and i32 %val, 4294967040
|
|
23 ret i32 %and
|
|
24 }
|
|
25
|
|
26 ; Check the next word up, which needs separate address logic.
|
|
27 ; Other sequences besides this one would be OK.
|
|
28 define i32 @f3(i32 *%src) {
|
|
29 ; CHECK-LABEL: f3:
|
|
30 ; CHECK: agfi %r2, 524288
|
|
31 ; CHECK: lzrf %r2, 0(%r2)
|
|
32 ; CHECK: br %r14
|
|
33 %ptr = getelementptr i32, i32 *%src, i64 131072
|
|
34 %val = load i32, i32 *%ptr
|
|
35 %and = and i32 %val, 4294967040
|
|
36 ret i32 %and
|
|
37 }
|
|
38
|
|
39 ; Check the high end of the negative LZRF range.
|
|
40 define i32 @f4(i32 *%src) {
|
|
41 ; CHECK-LABEL: f4:
|
|
42 ; CHECK: lzrf %r2, -4(%r2)
|
|
43 ; CHECK: br %r14
|
|
44 %ptr = getelementptr i32, i32 *%src, i64 -1
|
|
45 %val = load i32, i32 *%ptr
|
|
46 %and = and i32 %val, 4294967040
|
|
47 ret i32 %and
|
|
48 }
|
|
49
|
|
50 ; Check the low end of the LZRF range.
|
|
51 define i32 @f5(i32 *%src) {
|
|
52 ; CHECK-LABEL: f5:
|
|
53 ; CHECK: lzrf %r2, -524288(%r2)
|
|
54 ; CHECK: br %r14
|
|
55 %ptr = getelementptr i32, i32 *%src, i64 -131072
|
|
56 %val = load i32, i32 *%ptr
|
|
57 %and = and i32 %val, 4294967040
|
|
58 ret i32 %and
|
|
59 }
|
|
60
|
|
61 ; Check the next word down, which needs separate address logic.
|
|
62 ; Other sequences besides this one would be OK.
|
|
63 define i32 @f6(i32 *%src) {
|
|
64 ; CHECK-LABEL: f6:
|
|
65 ; CHECK: agfi %r2, -524292
|
|
66 ; CHECK: lzrf %r2, 0(%r2)
|
|
67 ; CHECK: br %r14
|
|
68 %ptr = getelementptr i32, i32 *%src, i64 -131073
|
|
69 %val = load i32, i32 *%ptr
|
|
70 %and = and i32 %val, 4294967040
|
|
71 ret i32 %and
|
|
72 }
|
|
73
|
|
74 ; Check that LZRF allows an index.
|
|
75 define i32 @f7(i64 %src, i64 %index) {
|
|
76 ; CHECK-LABEL: f7:
|
|
77 ; CHECK: lzrf %r2, 524287(%r3,%r2)
|
|
78 ; CHECK: br %r14
|
|
79 %add1 = add i64 %src, %index
|
|
80 %add2 = add i64 %add1, 524287
|
|
81 %ptr = inttoptr i64 %add2 to i32 *
|
|
82 %val = load i32 , i32 *%ptr
|
|
83 %and = and i32 %val, 4294967040
|
|
84 ret i32 %and
|
|
85 }
|
|
86
|
|
87 ; Check LZRG with no displacement.
|
|
88 define i64 @f8(i64 *%src) {
|
|
89 ; CHECK-LABEL: f8:
|
|
90 ; CHECK: lzrg %r2, 0(%r2)
|
|
91 ; CHECK: br %r14
|
|
92 %val = load i64, i64 *%src
|
|
93 %and = and i64 %val, 18446744073709551360
|
|
94 ret i64 %and
|
|
95 }
|
|
96
|
|
97 ; Check the high end of the LZRG range.
|
|
98 define i64 @f9(i64 *%src) {
|
|
99 ; CHECK-LABEL: f9:
|
|
100 ; CHECK: lzrg %r2, 524280(%r2)
|
|
101 ; CHECK: br %r14
|
|
102 %ptr = getelementptr i64, i64 *%src, i64 65535
|
|
103 %val = load i64, i64 *%ptr
|
|
104 %and = and i64 %val, 18446744073709551360
|
|
105 ret i64 %and
|
|
106 }
|
|
107
|
|
108 ; Check the next word up, which needs separate address logic.
|
|
109 ; Other sequences besides this one would be OK.
|
|
110 define i64 @f10(i64 *%src) {
|
|
111 ; CHECK-LABEL: f10:
|
|
112 ; CHECK: agfi %r2, 524288
|
|
113 ; CHECK: lzrg %r2, 0(%r2)
|
|
114 ; CHECK: br %r14
|
|
115 %ptr = getelementptr i64, i64 *%src, i64 65536
|
|
116 %val = load i64, i64 *%ptr
|
|
117 %and = and i64 %val, 18446744073709551360
|
|
118 ret i64 %and
|
|
119 }
|
|
120
|
|
121 ; Check the high end of the negative LZRG range.
|
|
122 define i64 @f11(i64 *%src) {
|
|
123 ; CHECK-LABEL: f11:
|
|
124 ; CHECK: lzrg %r2, -8(%r2)
|
|
125 ; CHECK: br %r14
|
|
126 %ptr = getelementptr i64, i64 *%src, i64 -1
|
|
127 %val = load i64, i64 *%ptr
|
|
128 %and = and i64 %val, 18446744073709551360
|
|
129 ret i64 %and
|
|
130 }
|
|
131
|
|
132 ; Check the low end of the LZRG range.
|
|
133 define i64 @f12(i64 *%src) {
|
|
134 ; CHECK-LABEL: f12:
|
|
135 ; CHECK: lzrg %r2, -524288(%r2)
|
|
136 ; CHECK: br %r14
|
|
137 %ptr = getelementptr i64, i64 *%src, i64 -65536
|
|
138 %val = load i64, i64 *%ptr
|
|
139 %and = and i64 %val, 18446744073709551360
|
|
140 ret i64 %and
|
|
141 }
|
|
142
|
|
143 ; Check the next word down, which needs separate address logic.
|
|
144 ; Other sequences besides this one would be OK.
|
|
145 define i64 @f13(i64 *%src) {
|
|
146 ; CHECK-LABEL: f13:
|
|
147 ; CHECK: agfi %r2, -524296
|
|
148 ; CHECK: lzrg %r2, 0(%r2)
|
|
149 ; CHECK: br %r14
|
|
150 %ptr = getelementptr i64, i64 *%src, i64 -65537
|
|
151 %val = load i64, i64 *%ptr
|
|
152 %and = and i64 %val, 18446744073709551360
|
|
153 ret i64 %and
|
|
154 }
|
|
155
|
|
156 ; Check that LZRG allows an index.
|
|
157 define i64 @f14(i64 %src, i64 %index) {
|
|
158 ; CHECK-LABEL: f14:
|
|
159 ; CHECK: lzrg %r2, 524287(%r3,%r2)
|
|
160 ; CHECK: br %r14
|
|
161 %add1 = add i64 %src, %index
|
|
162 %add2 = add i64 %add1, 524287
|
|
163 %ptr = inttoptr i64 %add2 to i64 *
|
|
164 %val = load i64 , i64 *%ptr
|
|
165 %and = and i64 %val, 18446744073709551360
|
|
166 ret i64 %and
|
|
167 }
|
|
168
|
|
169 ; Check LLZRGF with no displacement.
|
|
170 define i64 @f15(i32 *%src) {
|
|
171 ; CHECK-LABEL: f15:
|
|
172 ; CHECK: llzrgf %r2, 0(%r2)
|
|
173 ; CHECK: br %r14
|
|
174 %val = load i32, i32 *%src
|
|
175 %ext = zext i32 %val to i64
|
|
176 %and = and i64 %ext, 18446744073709551360
|
|
177 ret i64 %and
|
|
178 }
|
|
179
|
|
180 ; ... and the other way around.
|
|
181 define i64 @f16(i32 *%src) {
|
|
182 ; CHECK-LABEL: f16:
|
|
183 ; CHECK: llzrgf %r2, 0(%r2)
|
|
184 ; CHECK: br %r14
|
|
185 %val = load i32, i32 *%src
|
|
186 %and = and i32 %val, 4294967040
|
|
187 %ext = zext i32 %and to i64
|
|
188 ret i64 %ext
|
|
189 }
|
|
190
|
|
191 ; Check the high end of the LLZRGF range.
|
|
192 define i64 @f17(i32 *%src) {
|
|
193 ; CHECK-LABEL: f17:
|
|
194 ; CHECK: llzrgf %r2, 524284(%r2)
|
|
195 ; CHECK: br %r14
|
|
196 %ptr = getelementptr i32, i32 *%src, i64 131071
|
|
197 %val = load i32, i32 *%ptr
|
|
198 %and = and i32 %val, 4294967040
|
|
199 %ext = zext i32 %and to i64
|
|
200 ret i64 %ext
|
|
201 }
|
|
202
|
|
203 ; Check the next word up, which needs separate address logic.
|
|
204 ; Other sequences besides this one would be OK.
|
|
205 define i64 @f18(i32 *%src) {
|
|
206 ; CHECK-LABEL: f18:
|
|
207 ; CHECK: agfi %r2, 524288
|
|
208 ; CHECK: llzrgf %r2, 0(%r2)
|
|
209 ; CHECK: br %r14
|
|
210 %ptr = getelementptr i32, i32 *%src, i64 131072
|
|
211 %val = load i32, i32 *%ptr
|
|
212 %and = and i32 %val, 4294967040
|
|
213 %ext = zext i32 %and to i64
|
|
214 ret i64 %ext
|
|
215 }
|
|
216
|
|
217 ; Check the high end of the negative LLZRGF range.
|
|
218 define i64 @f19(i32 *%src) {
|
|
219 ; CHECK-LABEL: f19:
|
|
220 ; CHECK: llzrgf %r2, -4(%r2)
|
|
221 ; CHECK: br %r14
|
|
222 %ptr = getelementptr i32, i32 *%src, i64 -1
|
|
223 %val = load i32, i32 *%ptr
|
|
224 %and = and i32 %val, 4294967040
|
|
225 %ext = zext i32 %and to i64
|
|
226 ret i64 %ext
|
|
227 }
|
|
228
|
|
229 ; Check the low end of the LLZRGF range.
|
|
230 define i64 @f20(i32 *%src) {
|
|
231 ; CHECK-LABEL: f20:
|
|
232 ; CHECK: llzrgf %r2, -524288(%r2)
|
|
233 ; CHECK: br %r14
|
|
234 %ptr = getelementptr i32, i32 *%src, i64 -131072
|
|
235 %val = load i32, i32 *%ptr
|
|
236 %and = and i32 %val, 4294967040
|
|
237 %ext = zext i32 %and to i64
|
|
238 ret i64 %ext
|
|
239 }
|
|
240
|
|
241 ; Check the next word down, which needs separate address logic.
|
|
242 ; Other sequences besides this one would be OK.
|
|
243 define i64 @f21(i32 *%src) {
|
|
244 ; CHECK-LABEL: f21:
|
|
245 ; CHECK: agfi %r2, -524292
|
|
246 ; CHECK: llzrgf %r2, 0(%r2)
|
|
247 ; CHECK: br %r14
|
|
248 %ptr = getelementptr i32, i32 *%src, i64 -131073
|
|
249 %val = load i32, i32 *%ptr
|
|
250 %and = and i32 %val, 4294967040
|
|
251 %ext = zext i32 %and to i64
|
|
252 ret i64 %ext
|
|
253 }
|
|
254
|
|
255 ; Check that LLZRGF allows an index.
|
|
256 define i64 @f22(i64 %src, i64 %index) {
|
|
257 ; CHECK-LABEL: f22:
|
|
258 ; CHECK: llzrgf %r2, 524287(%r3,%r2)
|
|
259 ; CHECK: br %r14
|
|
260 %add1 = add i64 %src, %index
|
|
261 %add2 = add i64 %add1, 524287
|
|
262 %ptr = inttoptr i64 %add2 to i32 *
|
|
263 %val = load i32 , i32 *%ptr
|
|
264 %and = and i32 %val, 4294967040
|
|
265 %ext = zext i32 %and to i64
|
|
266 ret i64 %ext
|
|
267 }
|
|
268
|
|
269 ; Check that we still get a RISBGN if the source is in a register.
|
|
270 define i64 @f23(i32 %src) {
|
|
271 ; CHECK-LABEL: f23:
|
|
272 ; CHECK: risbgn %r2, %r2, 32, 183, 0
|
|
273 ; CHECK: br %r14
|
|
274 %and = and i32 %src, 4294967040
|
|
275 %ext = zext i32 %and to i64
|
|
276 ret i64 %ext
|
|
277 }
|
|
278
|