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.
6define 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.
16define 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.
28define 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.
40define 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.
51define 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.
63define 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.
75define 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.
88define 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.
98define 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.
110define 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.
122define 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.
133define 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.
145define 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.
157define 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.
170define 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.
181define 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.
192define 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.
205define 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.
218define 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.
230define 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.
243define 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.
256define 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.
270define 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
279