8df26b26971a14aae6869cc79cec165f62228f24
[oota-llvm.git] / test / CodeGen / AArch64 / fast-isel-int-ext2.ll
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
8 define 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
17 bb2:
18   %4 = zext i8 %3 to i32
19   ret i32 %4
20 }
21
22 define 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
31 bb2:
32   %4 = zext i16 %3 to i32
33   ret i32 %4
34 }
35
36 define 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
45 bb2:
46   %4 = zext i8 %3 to i64
47   ret i64 %4
48 }
49
50 define 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
59 bb2:
60   %4 = zext i16 %3 to i64
61   ret i64 %4
62 }
63
64 define 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
73 bb2:
74   %4 = zext i32 %3 to i64
75   ret i64 %4
76 }
77
78 define 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
87 bb2:
88   %4 = sext i8 %3 to i32
89   ret i32 %4
90 }
91
92 define 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
101 bb2:
102   %4 = sext i16 %3 to i32
103   ret i32 %4
104 }
105
106 define 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
115 bb2:
116   %4 = sext i8 %3 to i64
117   ret i64 %4
118 }
119
120 define 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
129 bb2:
130   %4 = sext i16 %3 to i64
131   ret i64 %4
132 }
133
134 define 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
143 bb2:
144   %4 = sext i32 %3 to i64
145   ret i64 %4
146 }
147
148 ; Register
149 define 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
158 bb2:
159   %4 = zext i8 %3 to i32
160   ret i32 %4
161 }
162
163 define 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
172 bb2:
173   %4 = zext i16 %3 to i32
174   ret i32 %4
175 }
176
177 define 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
186 bb2:
187   %4 = zext i8 %3 to i64
188   ret i64 %4
189 }
190
191 define 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
200 bb2:
201   %4 = zext i16 %3 to i64
202   ret i64 %4
203 }
204
205 define 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
214 bb2:
215   %4 = zext i32 %3 to i64
216   ret i64 %4
217 }
218
219 define 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
228 bb2:
229   %4 = sext i8 %3 to i32
230   ret i32 %4
231 }
232
233 define 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
242 bb2:
243   %4 = sext i16 %3 to i32
244   ret i32 %4
245 }
246
247 define 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
256 bb2:
257   %4 = sext i8 %3 to i64
258   ret i64 %4
259 }
260
261 define 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
270 bb2:
271   %4 = sext i16 %3 to i64
272   ret i64 %4
273 }
274
275 define 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
284 bb2:
285   %4 = sext i32 %3 to i64
286   ret i64 %4
287 }
288
289 ; Extend
290 define 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
300 bb2:
301   %5 = zext i8 %4 to i32
302   ret i32 %5
303 }
304
305 define 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
315 bb2:
316   %5 = zext i16 %4 to i32
317   ret i32 %5
318 }
319
320 define 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
330 bb2:
331   %5 = zext i8 %4 to i64
332   ret i64 %5
333 }
334
335 define 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
345 bb2:
346   %5 = zext i16 %4 to i64
347   ret i64 %5
348 }
349
350 define 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
360 bb2:
361   %5 = zext i32 %4 to i64
362   ret i64 %5
363 }
364
365 define 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
375 bb2:
376   %5 = sext i8 %4 to i32
377   ret i32 %5
378 }
379
380 define 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
390 bb2:
391   %5 = sext i16 %4 to i32
392   ret i32 %5
393 }
394
395 define 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
405 bb2:
406   %5 = sext i8 %4 to i64
407   ret i64 %5
408 }
409
410 define 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
420 bb2:
421   %5 = sext i16 %4 to i64
422   ret i64 %5
423 }
424
425 define 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
435 bb2:
436   %5 = sext i32 %4 to i64
437   ret i64 %5
438 }
439