Tim Northover | e95c5b3 | 2015-02-24 17:22:34 +0000 | [diff] [blame] | 1 | ; RUN: llc -mtriple=armv7-linux-gnueabihf %s -o - | FileCheck %s |
| 2 | |
| 3 | ; [2 x i64] should be contiguous when split (e.g. we shouldn't try to align all |
| 4 | ; i32 components to 64 bits). Also makes sure i64 based types are properly |
| 5 | ; aligned on the stack. |
| 6 | define i64 @test_i64_contiguous_on_stack([8 x double], float, i32 %in, [2 x i64] %arg) nounwind { |
| 7 | ; CHECK-LABEL: test_i64_contiguous_on_stack: |
| 8 | ; CHECK-DAG: ldr [[LO0:r[0-9]+]], [sp, #8] |
| 9 | ; CHECK-DAG: ldr [[HI0:r[0-9]+]], [sp, #12] |
| 10 | ; CHECK-DAG: ldr [[LO1:r[0-9]+]], [sp, #16] |
| 11 | ; CHECK-DAG: ldr [[HI1:r[0-9]+]], [sp, #20] |
| 12 | ; CHECK: adds r0, [[LO0]], [[LO1]] |
| 13 | ; CHECK: adc r1, [[HI0]], [[HI1]] |
| 14 | |
| 15 | %val1 = extractvalue [2 x i64] %arg, 0 |
| 16 | %val2 = extractvalue [2 x i64] %arg, 1 |
| 17 | %sum = add i64 %val1, %val2 |
| 18 | ret i64 %sum |
| 19 | } |
| 20 | |
| 21 | ; [2 x i64] should try to use looks for 4 regs, not 8 (which might happen if the |
| 22 | ; i64 -> i32, i32 split wasn't handled correctly). |
| 23 | define i64 @test_2xi64_uses_4_regs([8 x double], float, [2 x i64] %arg) nounwind { |
| 24 | ; CHECK-LABEL: test_2xi64_uses_4_regs: |
| 25 | ; CHECK-DAG: mov r0, r2 |
| 26 | ; CHECK-DAG: mov r1, r3 |
| 27 | |
| 28 | %val = extractvalue [2 x i64] %arg, 1 |
| 29 | ret i64 %val |
| 30 | } |
| 31 | |
| 32 | ; An aggregate should be able to split between registers and stack if there is |
| 33 | ; nothing else on the stack. |
| 34 | define i32 @test_aggregates_split([8 x double], i32, [4 x i32] %arg) nounwind { |
| 35 | ; CHECK-LABEL: test_aggregates_split: |
| 36 | ; CHECK: ldr [[VAL3:r[0-9]+]], [sp] |
| 37 | ; CHECK: add r0, r1, [[VAL3]] |
| 38 | |
| 39 | %val0 = extractvalue [4 x i32] %arg, 0 |
| 40 | %val3 = extractvalue [4 x i32] %arg, 3 |
| 41 | %sum = add i32 %val0, %val3 |
| 42 | ret i32 %sum |
| 43 | } |
| 44 | |
| 45 | ; If an aggregate has to be moved entirely onto the stack, nothing should be |
| 46 | ; able to use r0-r3 any more. Also checks that [2 x i64] properly aligned when |
| 47 | ; it uses regs. |
| 48 | define i32 @test_no_int_backfilling([8 x double], float, i32, [2 x i64], i32 %arg) nounwind { |
| 49 | ; CHECK-LABEL: test_no_int_backfilling: |
| 50 | ; CHECK: ldr r0, [sp, #24] |
| 51 | ret i32 %arg |
| 52 | } |
| 53 | |
| 54 | ; Even if the argument was successfully allocated as reg block, there should be |
| 55 | ; no backfillig to r1. |
| 56 | define i32 @test_no_int_backfilling_regsonly(i32, [1 x i64], i32 %arg) { |
| 57 | ; CHECK-LABEL: test_no_int_backfilling_regsonly: |
| 58 | ; CHECK: ldr r0, [sp] |
| 59 | ret i32 %arg |
| 60 | } |
| 61 | |
| 62 | ; If an aggregate has to be moved entirely onto the stack, nothing should be |
| 63 | ; able to use r0-r3 any more. |
| 64 | define float @test_no_float_backfilling([7 x double], [4 x i32], i32, [4 x double], float %arg) nounwind { |
| 65 | ; CHECK-LABEL: test_no_float_backfilling: |
| 66 | ; CHECK: vldr s0, [sp, #40] |
| 67 | ret float %arg |
| 68 | } |
| 69 | |
| 70 | ; They're a bit pointless, but types like [N x i8] should work as well. |
| 71 | define i8 @test_i8_in_regs(i32, [3 x i8] %arg) { |
| 72 | ; CHECK-LABEL: test_i8_in_regs: |
| 73 | ; CHECK: add r0, r1, r3 |
| 74 | %val0 = extractvalue [3 x i8] %arg, 0 |
| 75 | %val2 = extractvalue [3 x i8] %arg, 2 |
| 76 | %sum = add i8 %val0, %val2 |
| 77 | ret i8 %sum |
| 78 | } |
| 79 | |
| 80 | define i16 @test_i16_split(i32, i32, [3 x i16] %arg) { |
| 81 | ; CHECK-LABEL: test_i16_split: |
| 82 | ; CHECK: ldrh [[VAL2:r[0-9]+]], [sp] |
| 83 | ; CHECK: add r0, r2, [[VAL2]] |
| 84 | %val0 = extractvalue [3 x i16] %arg, 0 |
| 85 | %val2 = extractvalue [3 x i16] %arg, 2 |
| 86 | %sum = add i16 %val0, %val2 |
| 87 | ret i16 %sum |
| 88 | } |
| 89 | |
| 90 | ; Beware: on the stack each i16 still gets a 32-bit slot, the array is not |
| 91 | ; packed. |
| 92 | define i16 @test_i16_forced_stack([8 x double], double, i32, i32, [3 x i16] %arg) { |
| 93 | ; CHECK-LABEL: test_i16_forced_stack: |
| 94 | ; CHECK-DAG: ldrh [[VAL0:r[0-9]+]], [sp, #8] |
| 95 | ; CHECK-DAG: ldrh [[VAL2:r[0-9]+]], [sp, #16] |
| 96 | ; CHECK: add r0, [[VAL0]], [[VAL2]] |
| 97 | %val0 = extractvalue [3 x i16] %arg, 0 |
| 98 | %val2 = extractvalue [3 x i16] %arg, 2 |
| 99 | %sum = add i16 %val0, %val2 |
| 100 | ret i16 %sum |
| 101 | } |