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