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