[FastISel][AArch64] Followup commit for 218031 to handle negative offsets too.
[oota-llvm.git] / test / CodeGen / AArch64 / fast-isel-addressing-modes.ll
1 ; RUN: llc -mtriple=aarch64-apple-darwin                             -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK --check-prefix=SDAG
2 ; RUN: llc -mtriple=aarch64-apple-darwin -fast-isel -fast-isel-abort -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK --check-prefix=FAST
3
4 ; Load / Store Base Register only
5 define zeroext i1 @load_breg_i1(i1* %a) {
6 ; CHECK-LABEL: load_breg_i1
7 ; CHECK:       ldrb {{w[0-9]+}}, [x0]
8   %1 = load i1* %a
9   ret i1 %1
10 }
11
12 define zeroext i8 @load_breg_i8(i8* %a) {
13 ; CHECK-LABEL: load_breg_i8
14 ; CHECK:       ldrb {{w[0-9]+}}, [x0]
15   %1 = load i8* %a
16   ret i8 %1
17 }
18
19 define zeroext i16 @load_breg_i16(i16* %a) {
20 ; CHECK-LABEL: load_breg_i16
21 ; CHECK:       ldrh {{w[0-9]+}}, [x0]
22   %1 = load i16* %a
23   ret i16 %1
24 }
25
26 define i32 @load_breg_i32(i32* %a) {
27 ; CHECK-LABEL: load_breg_i32
28 ; CHECK:       ldr {{w[0-9]+}}, [x0]
29   %1 = load i32* %a
30   ret i32 %1
31 }
32
33 define i64 @load_breg_i64(i64* %a) {
34 ; CHECK-LABEL: load_breg_i64
35 ; CHECK:       ldr {{x[0-9]+}}, [x0]
36   %1 = load i64* %a
37   ret i64 %1
38 }
39
40 define float @load_breg_f32(float* %a) {
41 ; CHECK-LABEL: load_breg_f32
42 ; CHECK:       ldr {{s[0-9]+}}, [x0]
43   %1 = load float* %a
44   ret float %1
45 }
46
47 define double @load_breg_f64(double* %a) {
48 ; CHECK-LABEL: load_breg_f64
49 ; CHECK:       ldr {{d[0-9]+}}, [x0]
50   %1 = load double* %a
51   ret double %1
52 }
53
54 define void @store_breg_i1(i1* %a) {
55 ; CHECK-LABEL: store_breg_i1
56 ; CHECK:       strb wzr, [x0]
57   store i1 0, i1* %a
58   ret void
59 }
60
61 define void @store_breg_i1_2(i1* %a) {
62 ; CHECK-LABEL: store_breg_i1_2
63 ; CHECK:       strb {{w[0-9]+}}, [x0]
64   store i1 true, i1* %a
65   ret void
66 }
67
68 define void @store_breg_i8(i8* %a) {
69 ; CHECK-LABEL: store_breg_i8
70 ; CHECK:       strb wzr, [x0]
71   store i8 0, i8* %a
72   ret void
73 }
74
75 define void @store_breg_i16(i16* %a) {
76 ; CHECK-LABEL: store_breg_i16
77 ; CHECK:       strh wzr, [x0]
78   store i16 0, i16* %a
79   ret void
80 }
81
82 define void @store_breg_i32(i32* %a) {
83 ; CHECK-LABEL: store_breg_i32
84 ; CHECK:       str wzr, [x0]
85   store i32 0, i32* %a
86   ret void
87 }
88
89 define void @store_breg_i64(i64* %a) {
90 ; CHECK-LABEL: store_breg_i64
91 ; CHECK:       str xzr, [x0]
92   store i64 0, i64* %a
93   ret void
94 }
95
96 define void @store_breg_f32(float* %a) {
97 ; CHECK-LABEL: store_breg_f32
98 ; CHECK:       str wzr, [x0]
99   store float 0.0, float* %a
100   ret void
101 }
102
103 define void @store_breg_f64(double* %a) {
104 ; CHECK-LABEL: store_breg_f64
105 ; CHECK:       str xzr, [x0]
106   store double 0.0, double* %a
107   ret void
108 }
109
110 ; Load Immediate
111 define i32 @load_immoff_1() {
112 ; CHECK-LABEL: load_immoff_1
113 ; CHECK:       orr {{w|x}}[[REG:[0-9]+]], {{wzr|xzr}}, #0x80
114 ; CHECK:       ldr {{w[0-9]+}}, {{\[}}x[[REG]]{{\]}}
115   %1 = inttoptr i64 128 to i32*
116   %2 = load i32* %1
117   ret i32 %2
118 }
119
120 ; Load / Store Base Register + Immediate Offset
121 ; Max supported negative offset
122 define i32 @load_breg_immoff_1(i64 %a) {
123 ; CHECK-LABEL: load_breg_immoff_1
124 ; CHECK:       ldur {{w[0-9]+}}, [x0, #-256]
125   %1 = add i64 %a, -256
126   %2 = inttoptr i64 %1 to i32*
127   %3 = load i32* %2
128   ret i32 %3
129 }
130
131 ; Min not-supported negative offset
132 define i32 @load_breg_immoff_2(i64 %a) {
133 ; CHECK-LABEL: load_breg_immoff_2
134 ; CHECK:       sub [[REG:x[0-9]+]], x0, #257
135 ; CHECK-NEXT:  ldr {{w[0-9]+}}, {{\[}}[[REG]]{{\]}}
136   %1 = add i64 %a, -257
137   %2 = inttoptr i64 %1 to i32*
138   %3 = load i32* %2
139   ret i32 %3
140 }
141
142 ; Max supported unscaled offset
143 define i32 @load_breg_immoff_3(i64 %a) {
144 ; CHECK-LABEL: load_breg_immoff_3
145 ; CHECK:       ldur {{w[0-9]+}}, [x0, #255]
146   %1 = add i64 %a, 255
147   %2 = inttoptr i64 %1 to i32*
148   %3 = load i32* %2
149   ret i32 %3
150 }
151
152 ; Min un-supported unscaled offset
153 define i32 @load_breg_immoff_4(i64 %a) {
154 ; CHECK-LABEL: load_breg_immoff_4
155 ; CHECK:       add [[REG:x[0-9]+]], x0, #257
156 ; CHECK-NEXT:  ldr {{w[0-9]+}}, {{\[}}[[REG]]{{\]}}
157   %1 = add i64 %a, 257
158   %2 = inttoptr i64 %1 to i32*
159   %3 = load i32* %2
160   ret i32 %3
161 }
162
163 ; Max supported scaled offset
164 define i32 @load_breg_immoff_5(i64 %a) {
165 ; CHECK-LABEL: load_breg_immoff_5
166 ; CHECK:       ldr {{w[0-9]+}}, [x0, #16380]
167   %1 = add i64 %a, 16380
168   %2 = inttoptr i64 %1 to i32*
169   %3 = load i32* %2
170   ret i32 %3
171 }
172
173 ; Min un-supported scaled offset
174 define i32 @load_breg_immoff_6(i64 %a) {
175 ; CHECK-LABEL: load_breg_immoff_6
176 ; CHECK:       add [[REG:x[0-9]+]], x0, #4, lsl #12
177 ; CHECK-NEXT:  ldr {{w[0-9]+}}, {{\[}}[[REG]]{{\]}}
178   %1 = add i64 %a, 16384
179   %2 = inttoptr i64 %1 to i32*
180   %3 = load i32* %2
181   ret i32 %3
182 }
183
184 ; Max supported negative offset
185 define void @store_breg_immoff_1(i64 %a) {
186 ; CHECK-LABEL: store_breg_immoff_1
187 ; CHECK:       stur wzr, [x0, #-256]
188   %1 = add i64 %a, -256
189   %2 = inttoptr i64 %1 to i32*
190   store i32 0, i32* %2
191   ret void
192 }
193
194 ; Min not-supported negative offset
195 define void @store_breg_immoff_2(i64 %a) {
196 ; CHECK-LABEL: store_breg_immoff_2
197 ; CHECK:       sub [[REG:x[0-9]+]], x0, #257
198 ; CHECK-NEXT:  str wzr, {{\[}}[[REG]]{{\]}}
199   %1 = add i64 %a, -257
200   %2 = inttoptr i64 %1 to i32*
201   store i32 0, i32* %2
202   ret void
203 }
204
205 ; Max supported unscaled offset
206 define void @store_breg_immoff_3(i64 %a) {
207 ; CHECK-LABEL: store_breg_immoff_3
208 ; CHECK:       stur wzr, [x0, #255]
209   %1 = add i64 %a, 255
210   %2 = inttoptr i64 %1 to i32*
211   store i32 0, i32* %2
212   ret void
213 }
214
215 ; Min un-supported unscaled offset
216 define void @store_breg_immoff_4(i64 %a) {
217 ; CHECK-LABEL: store_breg_immoff_4
218 ; CHECK:       add [[REG:x[0-9]+]], x0, #257
219 ; CHECK-NEXT:  str wzr, {{\[}}[[REG]]{{\]}}
220   %1 = add i64 %a, 257
221   %2 = inttoptr i64 %1 to i32*
222   store i32 0, i32* %2
223   ret void
224 }
225
226 ; Max supported scaled offset
227 define void @store_breg_immoff_5(i64 %a) {
228 ; CHECK-LABEL: store_breg_immoff_5
229 ; CHECK:       str wzr, [x0, #16380]
230   %1 = add i64 %a, 16380
231   %2 = inttoptr i64 %1 to i32*
232   store i32 0, i32* %2
233   ret void
234 }
235
236 ; Min un-supported scaled offset
237 define void @store_breg_immoff_6(i64 %a) {
238 ; CHECK-LABEL: store_breg_immoff_6
239 ; CHECK:       add [[REG:x[0-9]+]], x0, #4, lsl #12
240 ; CHECK-NEXT:  str wzr, {{\[}}[[REG]]{{\]}}
241   %1 = add i64 %a, 16384
242   %2 = inttoptr i64 %1 to i32*
243   store i32 0, i32* %2
244   ret void
245 }
246
247 define i64 @load_breg_immoff_7(i64 %a) {
248 ; CHECK-LABEL: load_breg_immoff_7
249 ; CHECK:       ldr {{x[0-9]+}}, [x0, #48]
250   %1 = add i64 %a, 48
251   %2 = inttoptr i64 %1 to i64*
252   %3 = load i64* %2
253   ret i64 %3
254 }
255
256 ; Flip add operands
257 define i64 @load_breg_immoff_8(i64 %a) {
258 ; CHECK-LABEL: load_breg_immoff_8
259 ; CHECK:       ldr {{x[0-9]+}}, [x0, #48]
260   %1 = add i64 48, %a
261   %2 = inttoptr i64 %1 to i64*
262   %3 = load i64* %2
263   ret i64 %3
264 }
265
266 ; Load Base Register + Register Offset
267 define i64 @load_breg_offreg_1(i64 %a, i64 %b) {
268 ; CHECK-LABEL: load_breg_offreg_1
269 ; CHECK:       ldr {{x[0-9]+}}, [x0, x1]
270   %1 = add i64 %a, %b
271   %2 = inttoptr i64 %1 to i64*
272   %3 = load i64* %2
273   ret i64 %3
274 }
275
276 ; Flip add operands
277 define i64 @load_breg_offreg_2(i64 %a, i64 %b) {
278 ; CHECK-LABEL: load_breg_offreg_2
279 ; CHECK:       ldr {{x[0-9]+}}, [x1, x0]
280   %1 = add i64 %b, %a
281   %2 = inttoptr i64 %1 to i64*
282   %3 = load i64* %2
283   ret i64 %3
284 }
285
286 ; Load Base Register + Register Offset + Immediate Offset
287 define i64 @load_breg_offreg_immoff_1(i64 %a, i64 %b) {
288 ; CHECK-LABEL: load_breg_offreg_immoff_1
289 ; CHECK:       add [[REG:x[0-9]+]], x0, x1
290 ; CHECK-NEXT:  ldr x0, {{\[}}[[REG]], #48{{\]}}
291   %1 = add i64 %a, %b
292   %2 = add i64 %1, 48
293   %3 = inttoptr i64 %2 to i64*
294   %4 = load i64* %3
295   ret i64 %4
296 }
297
298 define i64 @load_breg_offreg_immoff_2(i64 %a, i64 %b) {
299 ; SDAG-LABEL: load_breg_offreg_immoff_2
300 ; SDAG:       add [[REG1:x[0-9]+]], x0, x1
301 ; SDAG-NEXT:  add [[REG2:x[0-9]+]], [[REG1]], #15, lsl #12
302 ; SDAG-NEXT:  ldr x0, {{\[}}[[REG2]]{{\]}}
303 ; FAST-LABEL: load_breg_offreg_immoff_2
304 ; FAST:       add [[REG:x[0-9]+]], x0, #15, lsl #12
305 ; FAST-NEXT:  ldr x0, {{\[}}[[REG]], x1{{\]}}
306   %1 = add i64 %a, %b
307   %2 = add i64 %1, 61440
308   %3 = inttoptr i64 %2 to i64*
309   %4 = load i64* %3
310   ret i64 %4
311 }
312
313 ; Load Scaled Register Offset
314 define i32 @load_shift_offreg_1(i64 %a) {
315 ; CHECK-LABEL: load_shift_offreg_1
316 ; CHECK:       lsl [[REG:x[0-9]+]], x0, #2
317 ; CHECK:       ldr {{w[0-9]+}}, {{\[}}[[REG]]{{\]}}
318   %1 = shl i64 %a, 2
319   %2 = inttoptr i64 %1 to i32*
320   %3 = load i32* %2
321   ret i32 %3
322 }
323
324 define i32 @load_mul_offreg_1(i64 %a) {
325 ; CHECK-LABEL: load_mul_offreg_1
326 ; CHECK:       lsl [[REG:x[0-9]+]], x0, #2
327 ; CHECK:       ldr {{w[0-9]+}}, {{\[}}[[REG]]{{\]}}
328   %1 = mul i64 %a, 4
329   %2 = inttoptr i64 %1 to i32*
330   %3 = load i32* %2
331   ret i32 %3
332 }
333
334 ; Load Base Register + Scaled Register Offset
335 define i32 @load_breg_shift_offreg_1(i64 %a, i64 %b) {
336 ; CHECK-LABEL: load_breg_shift_offreg_1
337 ; CHECK:       ldr {{w[0-9]+}}, [x1, x0, lsl #2]
338   %1 = shl i64 %a, 2
339   %2 = add i64 %1, %b
340   %3 = inttoptr i64 %2 to i32*
341   %4 = load i32* %3
342   ret i32 %4
343 }
344
345 define i32 @load_breg_shift_offreg_2(i64 %a, i64 %b) {
346 ; CHECK-LABEL: load_breg_shift_offreg_2
347 ; CHECK:       ldr {{w[0-9]+}}, [x1, x0, lsl #2]
348   %1 = shl i64 %a, 2
349   %2 = add i64 %b, %1
350   %3 = inttoptr i64 %2 to i32*
351   %4 = load i32* %3
352   ret i32 %4
353 }
354
355 define i32 @load_breg_shift_offreg_3(i64 %a, i64 %b) {
356 ; SDAG-LABEL: load_breg_shift_offreg_3
357 ; SDAG:       lsl [[REG:x[0-9]+]], x0, #2
358 ; SDAG-NEXT:  ldr {{w[0-9]+}}, {{\[}}[[REG]], x1, lsl #2{{\]}}
359 ; FAST-LABEL: load_breg_shift_offreg_3
360 ; FAST:       lsl [[REG:x[0-9]+]], x1, #2
361 ; FAST-NEXT:  ldr {{w[0-9]+}}, {{\[}}[[REG]], x0, lsl #2{{\]}}
362   %1 = shl i64 %a, 2
363   %2 = shl i64 %b, 2
364   %3 = add i64 %1, %2
365   %4 = inttoptr i64 %3 to i32*
366   %5 = load i32* %4
367   ret i32 %5
368 }
369
370 define i32 @load_breg_shift_offreg_4(i64 %a, i64 %b) {
371 ; SDAG-LABEL: load_breg_shift_offreg_4
372 ; SDAG:       lsl [[REG:x[0-9]+]], x1, #2
373 ; SDAG-NEXT:  ldr {{w[0-9]+}}, {{\[}}[[REG]], x0, lsl #2{{\]}}
374 ; FAST-LABEL: load_breg_shift_offreg_4
375 ; FAST:       lsl [[REG:x[0-9]+]], x0, #2
376 ; FAST-NEXT:  ldr {{w[0-9]+}}, {{\[}}[[REG]], x1, lsl #2{{\]}}
377   %1 = shl i64 %a, 2
378   %2 = shl i64 %b, 2
379   %3 = add i64 %2, %1
380   %4 = inttoptr i64 %3 to i32*
381   %5 = load i32* %4
382   ret i32 %5
383 }
384
385 define i32 @load_breg_shift_offreg_5(i64 %a, i64 %b) {
386 ; SDAG-LABEL: load_breg_shift_offreg_5
387 ; SDAG:       lsl [[REG:x[0-9]+]], x1, #3
388 ; SDAG-NEXT:  ldr {{w[0-9]+}}, {{\[}}[[REG]], x0, lsl #2{{\]}}
389 ; FAST-LABEL: load_breg_shift_offreg_5
390 ; FAST:       lsl [[REG:x[0-9]+]], x1, #3
391 ; FAST-NEXT:  ldr {{w[0-9]+}}, {{\[}}[[REG]], x0, lsl #2{{\]}}
392   %1 = shl i64 %a, 2
393   %2 = shl i64 %b, 3
394   %3 = add i64 %1, %2
395   %4 = inttoptr i64 %3 to i32*
396   %5 = load i32* %4
397   ret i32 %5
398 }
399
400 define i32 @load_breg_mul_offreg_1(i64 %a, i64 %b) {
401 ; CHECK-LABEL: load_breg_mul_offreg_1
402 ; CHECK:       ldr {{w[0-9]+}}, [x1, x0, lsl #2]
403   %1 = mul i64 %a, 4
404   %2 = add i64 %1, %b
405   %3 = inttoptr i64 %2 to i32*
406   %4 = load i32* %3
407   ret i32 %4
408 }
409
410 define zeroext i8 @load_breg_and_offreg_1(i64 %a, i64 %b) {
411 ; CHECK-LABEL: load_breg_and_offreg_1
412 ; CHECK:       ldrb {{w[0-9]+}}, [x1, w0, uxtw]
413   %1 = and i64 %a, 4294967295
414   %2 = add i64 %1, %b
415   %3 = inttoptr i64 %2 to i8*
416   %4 = load i8* %3
417   ret i8 %4
418 }
419
420 define zeroext i16 @load_breg_and_offreg_2(i64 %a, i64 %b) {
421 ; CHECK-LABEL: load_breg_and_offreg_2
422 ; CHECK:       ldrh {{w[0-9]+}}, [x1, w0, uxtw #1]
423   %1 = and i64 %a, 4294967295
424   %2 = shl i64 %1, 1
425   %3 = add i64 %2, %b
426   %4 = inttoptr i64 %3 to i16*
427   %5 = load i16* %4
428   ret i16 %5
429 }
430
431 define i32 @load_breg_and_offreg_3(i64 %a, i64 %b) {
432 ; CHECK-LABEL: load_breg_and_offreg_3
433 ; CHECK:       ldr {{w[0-9]+}}, [x1, w0, uxtw #2]
434   %1 = and i64 %a, 4294967295
435   %2 = shl i64 %1, 2
436   %3 = add i64 %2, %b
437   %4 = inttoptr i64 %3 to i32*
438   %5 = load i32* %4
439   ret i32 %5
440 }
441
442 define i64 @load_breg_and_offreg_4(i64 %a, i64 %b) {
443 ; CHECK-LABEL: load_breg_and_offreg_4
444 ; CHECK:       ldr {{x[0-9]+}}, [x1, w0, uxtw #3]
445   %1 = and i64 %a, 4294967295
446   %2 = shl i64 %1, 3
447   %3 = add i64 %2, %b
448   %4 = inttoptr i64 %3 to i64*
449   %5 = load i64* %4
450   ret i64 %5
451 }
452
453 ; Load Base Register + Scaled Register Offset + Sign/Zero extension
454 define i32 @load_breg_zext_shift_offreg_1(i32 %a, i64 %b) {
455 ; CHECK-LABEL: load_breg_zext_shift_offreg_1
456 ; CHECK:       ldr {{w[0-9]+}}, [x1, w0, uxtw #2]
457   %1 = zext i32 %a to i64
458   %2 = shl i64 %1, 2
459   %3 = add i64 %2, %b
460   %4 = inttoptr i64 %3 to i32*
461   %5 = load i32* %4
462   ret i32 %5
463 }
464
465 define i32 @load_breg_zext_shift_offreg_2(i32 %a, i64 %b) {
466 ; CHECK-LABEL: load_breg_zext_shift_offreg_2
467 ; CHECK:       ldr {{w[0-9]+}}, [x1, w0, uxtw #2]
468   %1 = zext i32 %a to i64
469   %2 = shl i64 %1, 2
470   %3 = add i64 %b, %2
471   %4 = inttoptr i64 %3 to i32*
472   %5 = load i32* %4
473   ret i32 %5
474 }
475
476 define i32 @load_breg_zext_mul_offreg_1(i32 %a, i64 %b) {
477 ; CHECK-LABEL: load_breg_zext_mul_offreg_1
478 ; CHECK:       ldr {{w[0-9]+}}, [x1, w0, uxtw #2]
479   %1 = zext i32 %a to i64
480   %2 = mul i64 %1, 4
481   %3 = add i64 %2, %b
482   %4 = inttoptr i64 %3 to i32*
483   %5 = load i32* %4
484   ret i32 %5
485 }
486
487 define i32 @load_breg_sext_shift_offreg_1(i32 %a, i64 %b) {
488 ; CHECK-LABEL: load_breg_sext_shift_offreg_1
489 ; CHECK:       ldr {{w[0-9]+}}, [x1, w0, sxtw #2]
490   %1 = sext i32 %a to i64
491   %2 = shl i64 %1, 2
492   %3 = add i64 %2, %b
493   %4 = inttoptr i64 %3 to i32*
494   %5 = load i32* %4
495   ret i32 %5
496 }
497
498 define i32 @load_breg_sext_shift_offreg_2(i32 %a, i64 %b) {
499 ; CHECK-LABEL: load_breg_sext_shift_offreg_2
500 ; CHECK:       ldr {{w[0-9]+}}, [x1, w0, sxtw #2]
501   %1 = sext i32 %a to i64
502   %2 = shl i64 %1, 2
503   %3 = add i64 %b, %2
504   %4 = inttoptr i64 %3 to i32*
505   %5 = load i32* %4
506   ret i32 %5
507 }
508
509 define i32 @load_breg_sext_mul_offreg_1(i32 %a, i64 %b) {
510 ; CHECK-LABEL: load_breg_sext_mul_offreg_1
511 ; CHECK:       ldr {{w[0-9]+}}, [x1, w0, sxtw #2]
512   %1 = sext i32 %a to i64
513   %2 = mul i64 %1, 4
514   %3 = add i64 %2, %b
515   %4 = inttoptr i64 %3 to i32*
516   %5 = load i32* %4
517   ret i32 %5
518 }
519
520 ; Load Scaled Register Offset + Immediate Offset + Sign/Zero extension
521 define i64 @load_sext_shift_offreg_imm1(i32 %a) {
522 ; CHECK-LABEL: load_sext_shift_offreg_imm1
523 ; CHECK:       sbfiz [[REG:x[0-9]+]], {{x[0-9]+}}, #3, #32
524 ; CHECK-NEXT:  ldr {{x[0-9]+}}, {{\[}}[[REG]], #8{{\]}}
525   %1 = sext i32 %a to i64
526   %2 = shl i64 %1, 3
527   %3 = add i64 %2, 8
528   %4 = inttoptr i64 %3 to i64*
529   %5 = load i64* %4
530   ret i64 %5
531 }
532
533 ; Load Base Register + Scaled Register Offset + Immediate Offset + Sign/Zero extension
534 define i64 @load_breg_sext_shift_offreg_imm1(i32 %a, i64 %b) {
535 ; CHECK-LABEL: load_breg_sext_shift_offreg_imm1
536 ; CHECK:       add [[REG:x[0-9]+]], x1, w0, sxtw #3
537 ; CHECK-NEXT:  ldr {{x[0-9]+}}, {{\[}}[[REG]], #8{{\]}}
538   %1 = sext i32 %a to i64
539   %2 = shl i64 %1, 3
540   %3 = add i64 %b, %2
541   %4 = add i64 %3, 8
542   %5 = inttoptr i64 %4 to i64*
543   %6 = load i64* %5
544   ret i64 %6
545 }
546
547 ; Test that the kill flag is not set - the machine instruction verifier does that for us.
548 define i64 @kill_reg(i64 %a) {
549   %1 = sub i64 %a, 8
550   %2 = add i64 %1, 96
551   %3 = inttoptr i64 %2 to i64*
552   %4 = load i64* %3
553   %5 = add i64 %2, %4
554   ret i64 %5
555 }
556