1; RUN: llc -mtriple=aarch64-apple-darwin -fast-isel -fast-isel-abort -aarch64-atomic-cfg-tidy=false -disable-cgp-branch-opts -verify-machineinstrs < %s | FileCheck %s
2
3;
4; Test folding of the sign-/zero-extend into the load instruction.
5;
6
7; Unscaled
8define i32 @load_unscaled_zext_i8_to_i32(i64 %a) {
9; CHECK-LABEL: load_unscaled_zext_i8_to_i32
10; CHECK:       ldurb w0, [x0, #-8]
11; CHECK-NOT:   uxtb
12  %1 = sub i64 %a, 8
13  %2 = inttoptr i64 %1 to i8*
14  %3 = load i8* %2
15  br label %bb2
16
17bb2:
18  %4 = zext i8 %3 to i32
19  ret i32 %4
20}
21
22define i32 @load_unscaled_zext_i16_to_i32(i64 %a) {
23; CHECK-LABEL: load_unscaled_zext_i16_to_i32
24; CHECK:       ldurh w0, [x0, #-8]
25; CHECK-NOT:   uxth
26  %1 = sub i64 %a, 8
27  %2 = inttoptr i64 %1 to i16*
28  %3 = load i16* %2
29  br label %bb2
30
31bb2:
32  %4 = zext i16 %3 to i32
33  ret i32 %4
34}
35
36define i64 @load_unscaled_zext_i8_to_i64(i64 %a) {
37; CHECK-LABEL: load_unscaled_zext_i8_to_i64
38; CHECK:       ldurb w0, [x0, #-8]
39; CHECK-NOT:   uxtb
40  %1 = sub i64 %a, 8
41  %2 = inttoptr i64 %1 to i8*
42  %3 = load i8* %2
43  br label %bb2
44
45bb2:
46  %4 = zext i8 %3 to i64
47  ret i64 %4
48}
49
50define i64 @load_unscaled_zext_i16_to_i64(i64 %a) {
51; CHECK-LABEL: load_unscaled_zext_i16_to_i64
52; CHECK:       ldurh w0, [x0, #-8]
53; CHECK-NOT:   uxth
54  %1 = sub i64 %a, 8
55  %2 = inttoptr i64 %1 to i16*
56  %3 = load i16* %2
57  br label %bb2
58
59bb2:
60  %4 = zext i16 %3 to i64
61  ret i64 %4
62}
63
64define i64 @load_unscaled_zext_i32_to_i64(i64 %a) {
65; CHECK-LABEL: load_unscaled_zext_i32_to_i64
66; CHECK:       ldur w0, [x0, #-8]
67; CHECK-NOT:   uxtw
68  %1 = sub i64 %a, 8
69  %2 = inttoptr i64 %1 to i32*
70  %3 = load i32* %2
71  br label %bb2
72
73bb2:
74  %4 = zext i32 %3 to i64
75  ret i64 %4
76}
77
78define i32 @load_unscaled_sext_i8_to_i32(i64 %a) {
79; CHECK-LABEL: load_unscaled_sext_i8_to_i32
80; CHECK:       ldursb w0, [x0, #-8]
81; CHECK-NOT:   sxtb
82  %1 = sub i64 %a, 8
83  %2 = inttoptr i64 %1 to i8*
84  %3 = load i8* %2
85  br label %bb2
86
87bb2:
88  %4 = sext i8 %3 to i32
89  ret i32 %4
90}
91
92define i32 @load_unscaled_sext_i16_to_i32(i64 %a) {
93; CHECK-LABEL: load_unscaled_sext_i16_to_i32
94; CHECK:       ldursh w0, [x0, #-8]
95; CHECK-NOT:   sxth
96  %1 = sub i64 %a, 8
97  %2 = inttoptr i64 %1 to i16*
98  %3 = load i16* %2
99  br label %bb2
100
101bb2:
102  %4 = sext i16 %3 to i32
103  ret i32 %4
104}
105
106define i64 @load_unscaled_sext_i8_to_i64(i64 %a) {
107; CHECK-LABEL: load_unscaled_sext_i8_to_i64
108; CHECK:       ldursb x0, [x0, #-8]
109; CHECK-NOT:   sxtb
110  %1 = sub i64 %a, 8
111  %2 = inttoptr i64 %1 to i8*
112  %3 = load i8* %2
113  br label %bb2
114
115bb2:
116  %4 = sext i8 %3 to i64
117  ret i64 %4
118}
119
120define i64 @load_unscaled_sext_i16_to_i64(i64 %a) {
121; CHECK-LABEL: load_unscaled_sext_i16_to_i64
122; CHECK:       ldursh x0, [x0, #-8]
123; CHECK-NOT:   sxth
124  %1 = sub i64 %a, 8
125  %2 = inttoptr i64 %1 to i16*
126  %3 = load i16* %2
127  br label %bb2
128
129bb2:
130  %4 = sext i16 %3 to i64
131  ret i64 %4
132}
133
134define i64 @load_unscaled_sext_i32_to_i64(i64 %a) {
135; CHECK-LABEL: load_unscaled_sext_i32_to_i64
136; CHECK:       ldursw x0, [x0, #-8]
137; CHECK-NOT:   sxtw
138  %1 = sub i64 %a, 8
139  %2 = inttoptr i64 %1 to i32*
140  %3 = load i32* %2
141  br label %bb2
142
143bb2:
144  %4 = sext i32 %3 to i64
145  ret i64 %4
146}
147
148; Register
149define i32 @load_register_zext_i8_to_i32(i64 %a, i64 %b) {
150; CHECK-LABEL: load_register_zext_i8_to_i32
151; CHECK:       ldrb w0, [x0, x1]
152; CHECK-NOT:   uxtb
153  %1 = add i64 %a, %b
154  %2 = inttoptr i64 %1 to i8*
155  %3 = load i8* %2
156  br label %bb2
157
158bb2:
159  %4 = zext i8 %3 to i32
160  ret i32 %4
161}
162
163define i32 @load_register_zext_i16_to_i32(i64 %a, i64 %b) {
164; CHECK-LABEL: load_register_zext_i16_to_i32
165; CHECK:       ldrh w0, [x0, x1]
166; CHECK-NOT:   uxth
167  %1 = add i64 %a, %b
168  %2 = inttoptr i64 %1 to i16*
169  %3 = load i16* %2
170  br label %bb2
171
172bb2:
173  %4 = zext i16 %3 to i32
174  ret i32 %4
175}
176
177define i64 @load_register_zext_i8_to_i64(i64 %a, i64 %b) {
178; CHECK-LABEL: load_register_zext_i8_to_i64
179; CHECK:       ldrb w0, [x0, x1]
180; CHECK-NOT:   uxtb
181  %1 = add i64 %a, %b
182  %2 = inttoptr i64 %1 to i8*
183  %3 = load i8* %2
184  br label %bb2
185
186bb2:
187  %4 = zext i8 %3 to i64
188  ret i64 %4
189}
190
191define i64 @load_register_zext_i16_to_i64(i64 %a, i64 %b) {
192; CHECK-LABEL: load_register_zext_i16_to_i64
193; CHECK:       ldrh w0, [x0, x1]
194; CHECK-NOT:   uxth
195  %1 = add i64 %a, %b
196  %2 = inttoptr i64 %1 to i16*
197  %3 = load i16* %2
198  br label %bb2
199
200bb2:
201  %4 = zext i16 %3 to i64
202  ret i64 %4
203}
204
205define i64 @load_register_zext_i32_to_i64(i64 %a, i64 %b) {
206; CHECK-LABEL: load_register_zext_i32_to_i64
207; CHECK:       ldr w0, [x0, x1]
208; CHECK-NOT:   uxtw
209  %1 = add i64 %a, %b
210  %2 = inttoptr i64 %1 to i32*
211  %3 = load i32* %2
212  br label %bb2
213
214bb2:
215  %4 = zext i32 %3 to i64
216  ret i64 %4
217}
218
219define i32 @load_register_sext_i8_to_i32(i64 %a, i64 %b) {
220; CHECK-LABEL: load_register_sext_i8_to_i32
221; CHECK:       ldrsb w0, [x0, x1]
222; CHECK-NOT:   sxtb
223  %1 = add i64 %a, %b
224  %2 = inttoptr i64 %1 to i8*
225  %3 = load i8* %2
226  br label %bb2
227
228bb2:
229  %4 = sext i8 %3 to i32
230  ret i32 %4
231}
232
233define i32 @load_register_sext_i16_to_i32(i64 %a, i64 %b) {
234; CHECK-LABEL: load_register_sext_i16_to_i32
235; CHECK:       ldrsh w0, [x0, x1]
236; CHECK-NOT:   sxth
237  %1 = add i64 %a, %b
238  %2 = inttoptr i64 %1 to i16*
239  %3 = load i16* %2
240  br label %bb2
241
242bb2:
243  %4 = sext i16 %3 to i32
244  ret i32 %4
245}
246
247define i64 @load_register_sext_i8_to_i64(i64 %a, i64 %b) {
248; CHECK-LABEL: load_register_sext_i8_to_i64
249; CHECK:       ldrsb x0, [x0, x1]
250; CHECK-NOT:   sxtb
251  %1 = add i64 %a, %b
252  %2 = inttoptr i64 %1 to i8*
253  %3 = load i8* %2
254  br label %bb2
255
256bb2:
257  %4 = sext i8 %3 to i64
258  ret i64 %4
259}
260
261define i64 @load_register_sext_i16_to_i64(i64 %a, i64 %b) {
262; CHECK-LABEL: load_register_sext_i16_to_i64
263; CHECK:       ldrsh x0, [x0, x1]
264; CHECK-NOT:   sxth
265  %1 = add i64 %a, %b
266  %2 = inttoptr i64 %1 to i16*
267  %3 = load i16* %2
268  br label %bb2
269
270bb2:
271  %4 = sext i16 %3 to i64
272  ret i64 %4
273}
274
275define i64 @load_register_sext_i32_to_i64(i64 %a, i64 %b) {
276; CHECK-LABEL: load_register_sext_i32_to_i64
277; CHECK:       ldrsw x0, [x0, x1]
278; CHECK-NOT:   sxtw
279  %1 = add i64 %a, %b
280  %2 = inttoptr i64 %1 to i32*
281  %3 = load i32* %2
282  br label %bb2
283
284bb2:
285  %4 = sext i32 %3 to i64
286  ret i64 %4
287}
288
289; Extend
290define i32 @load_extend_zext_i8_to_i32(i64 %a, i32 %b) {
291; CHECK-LABEL: load_extend_zext_i8_to_i32
292; CHECK:       ldrb w0, [x0, w1, sxtw]
293; CHECK-NOT:   uxtb
294  %1 = sext i32 %b to i64
295  %2 = add i64 %a, %1
296  %3 = inttoptr i64 %2 to i8*
297  %4 = load i8* %3
298  br label %bb2
299
300bb2:
301  %5 = zext i8 %4 to i32
302  ret i32 %5
303}
304
305define i32 @load_extend_zext_i16_to_i32(i64 %a, i32 %b) {
306; CHECK-LABEL: load_extend_zext_i16_to_i32
307; CHECK:       ldrh w0, [x0, w1, sxtw]
308; CHECK-NOT:   uxth
309  %1 = sext i32 %b to i64
310  %2 = add i64 %a, %1
311  %3 = inttoptr i64 %2 to i16*
312  %4 = load i16* %3
313  br label %bb2
314
315bb2:
316  %5 = zext i16 %4 to i32
317  ret i32 %5
318}
319
320define i64 @load_extend_zext_i8_to_i64(i64 %a, i32 %b) {
321; CHECK-LABEL: load_extend_zext_i8_to_i64
322; CHECK:       ldrb w0, [x0, w1, sxtw]
323; CHECK-NOT:   uxtb
324  %1 = sext i32 %b to i64
325  %2 = add i64 %a, %1
326  %3 = inttoptr i64 %2 to i8*
327  %4 = load i8* %3
328  br label %bb2
329
330bb2:
331  %5 = zext i8 %4 to i64
332  ret i64 %5
333}
334
335define i64 @load_extend_zext_i16_to_i64(i64 %a, i32 %b) {
336; CHECK-LABEL: load_extend_zext_i16_to_i64
337; CHECK:       ldrh w0, [x0, w1, sxtw]
338; CHECK-NOT:   uxth
339  %1 = sext i32 %b to i64
340  %2 = add i64 %a, %1
341  %3 = inttoptr i64 %2 to i16*
342  %4 = load i16* %3
343  br label %bb2
344
345bb2:
346  %5 = zext i16 %4 to i64
347  ret i64 %5
348}
349
350define i64 @load_extend_zext_i32_to_i64(i64 %a, i32 %b) {
351; CHECK-LABEL: load_extend_zext_i32_to_i64
352; CHECK:       ldr w0, [x0, w1, sxtw]
353; CHECK-NOT:   uxtw
354  %1 = sext i32 %b to i64
355  %2 = add i64 %a, %1
356  %3 = inttoptr i64 %2 to i32*
357  %4 = load i32* %3
358  br label %bb2
359
360bb2:
361  %5 = zext i32 %4 to i64
362  ret i64 %5
363}
364
365define i32 @load_extend_sext_i8_to_i32(i64 %a, i32 %b) {
366; CHECK-LABEL: load_extend_sext_i8_to_i32
367; CHECK:       ldrsb w0, [x0, w1, sxtw]
368; CHECK-NOT:   sxtb
369  %1 = sext i32 %b to i64
370  %2 = add i64 %a, %1
371  %3 = inttoptr i64 %2 to i8*
372  %4 = load i8* %3
373  br label %bb2
374
375bb2:
376  %5 = sext i8 %4 to i32
377  ret i32 %5
378}
379
380define i32 @load_extend_sext_i16_to_i32(i64 %a, i32 %b) {
381; CHECK-LABEL: load_extend_sext_i16_to_i32
382; CHECK:       ldrsh w0, [x0, w1, sxtw]
383; CHECK-NOT:   sxth
384  %1 = sext i32 %b to i64
385  %2 = add i64 %a, %1
386  %3 = inttoptr i64 %2 to i16*
387  %4 = load i16* %3
388  br label %bb2
389
390bb2:
391  %5 = sext i16 %4 to i32
392  ret i32 %5
393}
394
395define i64 @load_extend_sext_i8_to_i64(i64 %a, i32 %b) {
396; CHECK-LABEL: load_extend_sext_i8_to_i64
397; CHECK:       ldrsb x0, [x0, w1, sxtw]
398; CHECK-NOT:   sxtb
399  %1 = sext i32 %b to i64
400  %2 = add i64 %a, %1
401  %3 = inttoptr i64 %2 to i8*
402  %4 = load i8* %3
403  br label %bb2
404
405bb2:
406  %5 = sext i8 %4 to i64
407  ret i64 %5
408}
409
410define i64 @load_extend_sext_i16_to_i64(i64 %a, i32 %b) {
411; CHECK-LABEL: load_extend_sext_i16_to_i64
412; CHECK:       ldrsh x0, [x0, w1, sxtw]
413; CHECK-NOT:   sxth
414  %1 = sext i32 %b to i64
415  %2 = add i64 %a, %1
416  %3 = inttoptr i64 %2 to i16*
417  %4 = load i16* %3
418  br label %bb2
419
420bb2:
421  %5 = sext i16 %4 to i64
422  ret i64 %5
423}
424
425define i64 @load_extend_sext_i32_to_i64(i64 %a, i32 %b) {
426; CHECK-LABEL: load_extend_sext_i32_to_i64
427; CHECK:       ldrsw x0, [x0, w1, sxtw]
428; CHECK-NOT:   sxtw
429  %1 = sext i32 %b to i64
430  %2 = add i64 %a, %1
431  %3 = inttoptr i64 %2 to i32*
432  %4 = load i32* %3
433  br label %bb2
434
435bb2:
436  %5 = sext i32 %4 to i64
437  ret i64 %5
438}
439
440