1*9880d681SAndroid Build Coastguard Worker; RUN: llc -mtriple=aarch64-apple-ios7.0 -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-DARWINPCS 2*9880d681SAndroid Build Coastguard Worker; RUN: llc -mtriple=aarch64-linux-gnu -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-AAPCS 3*9880d681SAndroid Build Coastguard Worker 4*9880d681SAndroid Build Coastguard Workerdeclare void @callee(...) 5*9880d681SAndroid Build Coastguard Worker 6*9880d681SAndroid Build Coastguard Workerdefine float @test_hfa_regs(float, [2 x float] %in) { 7*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_hfa_regs: 8*9880d681SAndroid Build Coastguard Worker; CHECK: fadd s0, s1, s2 9*9880d681SAndroid Build Coastguard Worker 10*9880d681SAndroid Build Coastguard Worker %lhs = extractvalue [2 x float] %in, 0 11*9880d681SAndroid Build Coastguard Worker %rhs = extractvalue [2 x float] %in, 1 12*9880d681SAndroid Build Coastguard Worker %sum = fadd float %lhs, %rhs 13*9880d681SAndroid Build Coastguard Worker ret float %sum 14*9880d681SAndroid Build Coastguard Worker} 15*9880d681SAndroid Build Coastguard Worker 16*9880d681SAndroid Build Coastguard Worker; Check that the array gets allocated to a contiguous block on the stack (rather 17*9880d681SAndroid Build Coastguard Worker; than the default of 2 8-byte slots). 18*9880d681SAndroid Build Coastguard Workerdefine float @test_hfa_block([7 x float], [2 x float] %in) { 19*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_hfa_block: 20*9880d681SAndroid Build Coastguard Worker; CHECK: ldp [[LHS:s[0-9]+]], [[RHS:s[0-9]+]], [sp] 21*9880d681SAndroid Build Coastguard Worker; CHECK: fadd s0, [[LHS]], [[RHS]] 22*9880d681SAndroid Build Coastguard Worker 23*9880d681SAndroid Build Coastguard Worker %lhs = extractvalue [2 x float] %in, 0 24*9880d681SAndroid Build Coastguard Worker %rhs = extractvalue [2 x float] %in, 1 25*9880d681SAndroid Build Coastguard Worker %sum = fadd float %lhs, %rhs 26*9880d681SAndroid Build Coastguard Worker ret float %sum 27*9880d681SAndroid Build Coastguard Worker} 28*9880d681SAndroid Build Coastguard Worker 29*9880d681SAndroid Build Coastguard Worker; Check that an HFA prevents backfilling of VFP registers (i.e. %rhs must go on 30*9880d681SAndroid Build Coastguard Worker; the stack rather than in s7). 31*9880d681SAndroid Build Coastguard Workerdefine float @test_hfa_block_consume([7 x float], [2 x float] %in, float %rhs) { 32*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_hfa_block_consume: 33*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: ldr [[LHS:s[0-9]+]], [sp] 34*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: ldr [[RHS:s[0-9]+]], [sp, #8] 35*9880d681SAndroid Build Coastguard Worker; CHECK: fadd s0, [[LHS]], [[RHS]] 36*9880d681SAndroid Build Coastguard Worker 37*9880d681SAndroid Build Coastguard Worker %lhs = extractvalue [2 x float] %in, 0 38*9880d681SAndroid Build Coastguard Worker %sum = fadd float %lhs, %rhs 39*9880d681SAndroid Build Coastguard Worker ret float %sum 40*9880d681SAndroid Build Coastguard Worker} 41*9880d681SAndroid Build Coastguard Worker 42*9880d681SAndroid Build Coastguard Workerdefine float @test_hfa_stackalign([8 x float], [1 x float], [2 x float] %in) { 43*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_hfa_stackalign: 44*9880d681SAndroid Build Coastguard Worker; CHECK-AAPCS: ldp [[LHS:s[0-9]+]], [[RHS:s[0-9]+]], [sp, #8] 45*9880d681SAndroid Build Coastguard Worker; CHECK-DARWINPCS: ldp [[LHS:s[0-9]+]], [[RHS:s[0-9]+]], [sp, #4] 46*9880d681SAndroid Build Coastguard Worker; CHECK: fadd s0, [[LHS]], [[RHS]] 47*9880d681SAndroid Build Coastguard Worker %lhs = extractvalue [2 x float] %in, 0 48*9880d681SAndroid Build Coastguard Worker %rhs = extractvalue [2 x float] %in, 1 49*9880d681SAndroid Build Coastguard Worker %sum = fadd float %lhs, %rhs 50*9880d681SAndroid Build Coastguard Worker ret float %sum 51*9880d681SAndroid Build Coastguard Worker} 52*9880d681SAndroid Build Coastguard Worker 53*9880d681SAndroid Build Coastguard Worker; An HFA that ends up on the stack should not have any effect on where 54*9880d681SAndroid Build Coastguard Worker; integer-based arguments go. 55*9880d681SAndroid Build Coastguard Workerdefine i64 @test_hfa_ignores_gprs([7 x float], [2 x float] %in, i64, i64 %res) { 56*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_hfa_ignores_gprs: 57*9880d681SAndroid Build Coastguard Worker; CHECK: mov x0, x1 58*9880d681SAndroid Build Coastguard Worker ret i64 %res 59*9880d681SAndroid Build Coastguard Worker} 60*9880d681SAndroid Build Coastguard Worker 61*9880d681SAndroid Build Coastguard Worker; [2 x float] should not be promoted to double by the Darwin varargs handling, 62*9880d681SAndroid Build Coastguard Worker; but should go in an 8-byte aligned slot. 63*9880d681SAndroid Build Coastguard Workerdefine void @test_varargs_stackalign() { 64*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_varargs_stackalign: 65*9880d681SAndroid Build Coastguard Worker; CHECK-DARWINPCS: stp {{w[0-9]+}}, {{w[0-9]+}}, [sp, #16] 66*9880d681SAndroid Build Coastguard Worker 67*9880d681SAndroid Build Coastguard Worker call void(...) @callee([3 x float] undef, [2 x float] [float 1.0, float 2.0]) 68*9880d681SAndroid Build Coastguard Worker ret void 69*9880d681SAndroid Build Coastguard Worker} 70*9880d681SAndroid Build Coastguard Worker 71*9880d681SAndroid Build Coastguard Workerdefine i64 @test_smallstruct_block([7 x i64], [2 x i64] %in) { 72*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_smallstruct_block: 73*9880d681SAndroid Build Coastguard Worker; CHECK: ldp [[LHS:x[0-9]+]], [[RHS:x[0-9]+]], [sp] 74*9880d681SAndroid Build Coastguard Worker; CHECK: add x0, [[LHS]], [[RHS]] 75*9880d681SAndroid Build Coastguard Worker %lhs = extractvalue [2 x i64] %in, 0 76*9880d681SAndroid Build Coastguard Worker %rhs = extractvalue [2 x i64] %in, 1 77*9880d681SAndroid Build Coastguard Worker %sum = add i64 %lhs, %rhs 78*9880d681SAndroid Build Coastguard Worker ret i64 %sum 79*9880d681SAndroid Build Coastguard Worker} 80*9880d681SAndroid Build Coastguard Worker 81*9880d681SAndroid Build Coastguard Worker; Check that a small struct prevents backfilling of registers (i.e. %rhs 82*9880d681SAndroid Build Coastguard Worker; must go on the stack rather than in x7). 83*9880d681SAndroid Build Coastguard Workerdefine i64 @test_smallstruct_block_consume([7 x i64], [2 x i64] %in, i64 %rhs) { 84*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_smallstruct_block_consume: 85*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: ldr [[LHS:x[0-9]+]], [sp] 86*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: ldr [[RHS:x[0-9]+]], [sp, #16] 87*9880d681SAndroid Build Coastguard Worker; CHECK: add x0, [[LHS]], [[RHS]] 88*9880d681SAndroid Build Coastguard Worker 89*9880d681SAndroid Build Coastguard Worker %lhs = extractvalue [2 x i64] %in, 0 90*9880d681SAndroid Build Coastguard Worker %sum = add i64 %lhs, %rhs 91*9880d681SAndroid Build Coastguard Worker ret i64 %sum 92*9880d681SAndroid Build Coastguard Worker} 93*9880d681SAndroid Build Coastguard Worker 94*9880d681SAndroid Build Coastguard Workerdefine <1 x i64> @test_v1i64_blocked([7 x double], [2 x <1 x i64>] %in) { 95*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_v1i64_blocked: 96*9880d681SAndroid Build Coastguard Worker; CHECK: ldr d0, [sp] 97*9880d681SAndroid Build Coastguard Worker %val = extractvalue [2 x <1 x i64>] %in, 0 98*9880d681SAndroid Build Coastguard Worker ret <1 x i64> %val 99*9880d681SAndroid Build Coastguard Worker} 100*9880d681SAndroid Build Coastguard Worker 101*9880d681SAndroid Build Coastguard Workerdefine <1 x double> @test_v1f64_blocked([7 x double], [2 x <1 x double>] %in) { 102*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_v1f64_blocked: 103*9880d681SAndroid Build Coastguard Worker; CHECK: ldr d0, [sp] 104*9880d681SAndroid Build Coastguard Worker %val = extractvalue [2 x <1 x double>] %in, 0 105*9880d681SAndroid Build Coastguard Worker ret <1 x double> %val 106*9880d681SAndroid Build Coastguard Worker} 107*9880d681SAndroid Build Coastguard Worker 108*9880d681SAndroid Build Coastguard Workerdefine <2 x i32> @test_v2i32_blocked([7 x double], [2 x <2 x i32>] %in) { 109*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_v2i32_blocked: 110*9880d681SAndroid Build Coastguard Worker; CHECK: ldr d0, [sp] 111*9880d681SAndroid Build Coastguard Worker %val = extractvalue [2 x <2 x i32>] %in, 0 112*9880d681SAndroid Build Coastguard Worker ret <2 x i32> %val 113*9880d681SAndroid Build Coastguard Worker} 114*9880d681SAndroid Build Coastguard Worker 115*9880d681SAndroid Build Coastguard Workerdefine <2 x float> @test_v2f32_blocked([7 x double], [2 x <2 x float>] %in) { 116*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_v2f32_blocked: 117*9880d681SAndroid Build Coastguard Worker; CHECK: ldr d0, [sp] 118*9880d681SAndroid Build Coastguard Worker %val = extractvalue [2 x <2 x float>] %in, 0 119*9880d681SAndroid Build Coastguard Worker ret <2 x float> %val 120*9880d681SAndroid Build Coastguard Worker} 121*9880d681SAndroid Build Coastguard Worker 122*9880d681SAndroid Build Coastguard Workerdefine <4 x i16> @test_v4i16_blocked([7 x double], [2 x <4 x i16>] %in) { 123*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_v4i16_blocked: 124*9880d681SAndroid Build Coastguard Worker; CHECK: ldr d0, [sp] 125*9880d681SAndroid Build Coastguard Worker %val = extractvalue [2 x <4 x i16>] %in, 0 126*9880d681SAndroid Build Coastguard Worker ret <4 x i16> %val 127*9880d681SAndroid Build Coastguard Worker} 128*9880d681SAndroid Build Coastguard Worker 129*9880d681SAndroid Build Coastguard Workerdefine <4 x half> @test_v4f16_blocked([7 x double], [2 x <4 x half>] %in) { 130*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_v4f16_blocked: 131*9880d681SAndroid Build Coastguard Worker; CHECK: ldr d0, [sp] 132*9880d681SAndroid Build Coastguard Worker %val = extractvalue [2 x <4 x half>] %in, 0 133*9880d681SAndroid Build Coastguard Worker ret <4 x half> %val 134*9880d681SAndroid Build Coastguard Worker} 135*9880d681SAndroid Build Coastguard Worker 136*9880d681SAndroid Build Coastguard Workerdefine <8 x i8> @test_v8i8_blocked([7 x double], [2 x <8 x i8>] %in) { 137*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_v8i8_blocked: 138*9880d681SAndroid Build Coastguard Worker; CHECK: ldr d0, [sp] 139*9880d681SAndroid Build Coastguard Worker %val = extractvalue [2 x <8 x i8>] %in, 0 140*9880d681SAndroid Build Coastguard Worker ret <8 x i8> %val 141*9880d681SAndroid Build Coastguard Worker} 142*9880d681SAndroid Build Coastguard Worker 143*9880d681SAndroid Build Coastguard Workerdefine <2 x i64> @test_v2i64_blocked([7 x double], [2 x <2 x i64>] %in) { 144*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_v2i64_blocked: 145*9880d681SAndroid Build Coastguard Worker; CHECK: ldr q0, [sp] 146*9880d681SAndroid Build Coastguard Worker %val = extractvalue [2 x <2 x i64>] %in, 0 147*9880d681SAndroid Build Coastguard Worker ret <2 x i64> %val 148*9880d681SAndroid Build Coastguard Worker} 149*9880d681SAndroid Build Coastguard Worker 150*9880d681SAndroid Build Coastguard Workerdefine <2 x double> @test_v2f64_blocked([7 x double], [2 x <2 x double>] %in) { 151*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_v2f64_blocked: 152*9880d681SAndroid Build Coastguard Worker; CHECK: ldr q0, [sp] 153*9880d681SAndroid Build Coastguard Worker %val = extractvalue [2 x <2 x double>] %in, 0 154*9880d681SAndroid Build Coastguard Worker ret <2 x double> %val 155*9880d681SAndroid Build Coastguard Worker} 156*9880d681SAndroid Build Coastguard Worker 157*9880d681SAndroid Build Coastguard Workerdefine <4 x i32> @test_v4i32_blocked([7 x double], [2 x <4 x i32>] %in) { 158*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_v4i32_blocked: 159*9880d681SAndroid Build Coastguard Worker; CHECK: ldr q0, [sp] 160*9880d681SAndroid Build Coastguard Worker %val = extractvalue [2 x <4 x i32>] %in, 0 161*9880d681SAndroid Build Coastguard Worker ret <4 x i32> %val 162*9880d681SAndroid Build Coastguard Worker} 163*9880d681SAndroid Build Coastguard Worker 164*9880d681SAndroid Build Coastguard Workerdefine <4 x float> @test_v4f32_blocked([7 x double], [2 x <4 x float>] %in) { 165*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_v4f32_blocked: 166*9880d681SAndroid Build Coastguard Worker; CHECK: ldr q0, [sp] 167*9880d681SAndroid Build Coastguard Worker %val = extractvalue [2 x <4 x float>] %in, 0 168*9880d681SAndroid Build Coastguard Worker ret <4 x float> %val 169*9880d681SAndroid Build Coastguard Worker} 170*9880d681SAndroid Build Coastguard Worker 171*9880d681SAndroid Build Coastguard Workerdefine <8 x i16> @test_v8i16_blocked([7 x double], [2 x <8 x i16>] %in) { 172*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_v8i16_blocked: 173*9880d681SAndroid Build Coastguard Worker; CHECK: ldr q0, [sp] 174*9880d681SAndroid Build Coastguard Worker %val = extractvalue [2 x <8 x i16>] %in, 0 175*9880d681SAndroid Build Coastguard Worker ret <8 x i16> %val 176*9880d681SAndroid Build Coastguard Worker} 177*9880d681SAndroid Build Coastguard Worker 178*9880d681SAndroid Build Coastguard Workerdefine <8 x half> @test_v8f16_blocked([7 x double], [2 x <8 x half>] %in) { 179*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_v8f16_blocked: 180*9880d681SAndroid Build Coastguard Worker; CHECK: ldr q0, [sp] 181*9880d681SAndroid Build Coastguard Worker %val = extractvalue [2 x <8 x half>] %in, 0 182*9880d681SAndroid Build Coastguard Worker ret <8 x half> %val 183*9880d681SAndroid Build Coastguard Worker} 184*9880d681SAndroid Build Coastguard Worker 185*9880d681SAndroid Build Coastguard Workerdefine <16 x i8> @test_v16i8_blocked([7 x double], [2 x <16 x i8>] %in) { 186*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_v16i8_blocked: 187*9880d681SAndroid Build Coastguard Worker; CHECK: ldr q0, [sp] 188*9880d681SAndroid Build Coastguard Worker %val = extractvalue [2 x <16 x i8>] %in, 0 189*9880d681SAndroid Build Coastguard Worker ret <16 x i8> %val 190*9880d681SAndroid Build Coastguard Worker} 191*9880d681SAndroid Build Coastguard Worker 192*9880d681SAndroid Build Coastguard Workerdefine half @test_f16_blocked([7 x double], [2 x half] %in) { 193*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_f16_blocked: 194*9880d681SAndroid Build Coastguard Worker; CHECK: ldr h0, [sp] 195*9880d681SAndroid Build Coastguard Worker %val = extractvalue [2 x half] %in, 0 196*9880d681SAndroid Build Coastguard Worker ret half %val 197*9880d681SAndroid Build Coastguard Worker} 198