1 ; RUN: llc -mtriple arm-unknown -mattr=+vfp2,+v4t -global-isel -stop-after=irtranslator -verify-machineinstrs %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=LITTLE 2 ; RUN: llc -mtriple armeb-unknown -mattr=+vfp2,+v4t -global-isel -global-isel-abort=0 -stop-after=irtranslator -verify-machineinstrs %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=BIG 3 ; XFAIL: armeb 4 5 declare arm_aapcscc i32* @simple_reg_params_target(i32, i32*) 6 7 define arm_aapcscc i32* @test_call_simple_reg_params(i32 *%a, i32 %b) { 8 ; CHECK-LABEL: name: test_call_simple_reg_params 9 ; CHECK-DAG: [[AVREG:%[0-9]+]]:_(p0) = COPY $r0 10 ; CHECK-DAG: [[BVREG:%[0-9]+]]:_(s32) = COPY $r1 11 ; CHECK: ADJCALLSTACKDOWN 0, 0, 14, $noreg, implicit-def $sp, implicit $sp 12 ; CHECK-DAG: $r0 = COPY [[BVREG]] 13 ; CHECK-DAG: $r1 = COPY [[AVREG]] 14 ; CHECK: BL @simple_reg_params_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit-def $r0 15 ; CHECK: [[RVREG:%[0-9]+]]:_(p0) = COPY $r0 16 ; CHECK: ADJCALLSTACKUP 0, 0, 14, $noreg, implicit-def $sp, implicit $sp 17 ; CHECK: $r0 = COPY [[RVREG]] 18 ; CHECK: BX_RET 14, $noreg, implicit $r0 19 entry: 20 %r = notail call arm_aapcscc i32 *@simple_reg_params_target(i32 %b, i32 *%a) 21 ret i32 *%r 22 } 23 24 declare arm_aapcscc i32* @simple_stack_params_target(i32, i32*, i32, i32*, i32, i32*) 25 26 define arm_aapcscc i32* @test_call_simple_stack_params(i32 *%a, i32 %b) { 27 ; CHECK-LABEL: name: test_call_simple_stack_params 28 ; CHECK-DAG: [[AVREG:%[0-9]+]]:_(p0) = COPY $r0 29 ; CHECK-DAG: [[BVREG:%[0-9]+]]:_(s32) = COPY $r1 30 ; CHECK: ADJCALLSTACKDOWN 8, 0, 14, $noreg, implicit-def $sp, implicit $sp 31 ; CHECK-DAG: $r0 = COPY [[BVREG]] 32 ; CHECK-DAG: $r1 = COPY [[AVREG]] 33 ; CHECK-DAG: $r2 = COPY [[BVREG]] 34 ; CHECK-DAG: $r3 = COPY [[AVREG]] 35 ; CHECK: [[SP1:%[0-9]+]]:_(p0) = COPY $sp 36 ; CHECK: [[OFF1:%[0-9]+]]:_(s32) = G_CONSTANT i32 0 37 ; CHECK: [[FI1:%[0-9]+]]:_(p0) = G_GEP [[SP1]], [[OFF1]](s32) 38 ; CHECK: G_STORE [[BVREG]](s32), [[FI1]](p0){{.*}}store 4 39 ; CHECK: [[SP2:%[0-9]+]]:_(p0) = COPY $sp 40 ; CHECK: [[OFF2:%[0-9]+]]:_(s32) = G_CONSTANT i32 4 41 ; CHECK: [[FI2:%[0-9]+]]:_(p0) = G_GEP [[SP2]], [[OFF2]](s32) 42 ; CHECK: G_STORE [[AVREG]](p0), [[FI2]](p0){{.*}}store 4 43 ; CHECK: BL @simple_stack_params_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit $r2, implicit $r3, implicit-def $r0 44 ; CHECK: [[RVREG:%[0-9]+]]:_(p0) = COPY $r0 45 ; CHECK: ADJCALLSTACKUP 8, 0, 14, $noreg, implicit-def $sp, implicit $sp 46 ; CHECK: $r0 = COPY [[RVREG]] 47 ; CHECK: BX_RET 14, $noreg, implicit $r0 48 entry: 49 %r = notail call arm_aapcscc i32 *@simple_stack_params_target(i32 %b, i32 *%a, i32 %b, i32 *%a, i32 %b, i32 *%a) 50 ret i32 *%r 51 } 52 53 declare arm_aapcscc signext i16 @ext_target(i8 signext, i8 zeroext, i16 signext, i16 zeroext, i8 signext, i8 zeroext, i16 signext, i16 zeroext, i1 zeroext) 54 55 define arm_aapcscc signext i16 @test_call_ext_params(i8 %a, i16 %b, i1 %c) { 56 ; CHECK-LABEL: name: test_call_ext_params 57 ; CHECK-DAG: [[R0VREG:%[0-9]+]]:_(s32) = COPY $r0 58 ; CHECK-DAG: [[AVREG:%[0-9]+]]:_(s8) = G_TRUNC [[R0VREG]] 59 ; CHECK-DAG: [[R1VREG:%[0-9]+]]:_(s32) = COPY $r1 60 ; CHECK-DAG: [[BVREG:%[0-9]+]]:_(s16) = G_TRUNC [[R1VREG]] 61 ; CHECK-DAG: [[R2VREG:%[0-9]+]]:_(s32) = COPY $r2 62 ; CHECK-DAG: [[CVREG:%[0-9]+]]:_(s1) = G_TRUNC [[R2VREG]] 63 ; CHECK: ADJCALLSTACKDOWN 20, 0, 14, $noreg, implicit-def $sp, implicit $sp 64 ; CHECK: [[SEXTA:%[0-9]+]]:_(s32) = G_SEXT [[AVREG]](s8) 65 ; CHECK: $r0 = COPY [[SEXTA]] 66 ; CHECK: [[ZEXTA:%[0-9]+]]:_(s32) = G_ZEXT [[AVREG]](s8) 67 ; CHECK: $r1 = COPY [[ZEXTA]] 68 ; CHECK: [[SEXTB:%[0-9]+]]:_(s32) = G_SEXT [[BVREG]](s16) 69 ; CHECK: $r2 = COPY [[SEXTB]] 70 ; CHECK: [[ZEXTB:%[0-9]+]]:_(s32) = G_ZEXT [[BVREG]](s16) 71 ; CHECK: $r3 = COPY [[ZEXTB]] 72 ; CHECK: [[SP1:%[0-9]+]]:_(p0) = COPY $sp 73 ; CHECK: [[OFF1:%[0-9]+]]:_(s32) = G_CONSTANT i32 0 74 ; CHECK: [[FI1:%[0-9]+]]:_(p0) = G_GEP [[SP1]], [[OFF1]](s32) 75 ; CHECK: [[SEXTA2:%[0-9]+]]:_(s32) = G_SEXT [[AVREG]] 76 ; CHECK: G_STORE [[SEXTA2]](s32), [[FI1]](p0){{.*}}store 4 77 ; CHECK: [[SP2:%[0-9]+]]:_(p0) = COPY $sp 78 ; CHECK: [[OFF2:%[0-9]+]]:_(s32) = G_CONSTANT i32 4 79 ; CHECK: [[FI2:%[0-9]+]]:_(p0) = G_GEP [[SP2]], [[OFF2]](s32) 80 ; CHECK: [[ZEXTA2:%[0-9]+]]:_(s32) = G_ZEXT [[AVREG]] 81 ; CHECK: G_STORE [[ZEXTA2]](s32), [[FI2]](p0){{.*}}store 4 82 ; CHECK: [[SP3:%[0-9]+]]:_(p0) = COPY $sp 83 ; CHECK: [[OFF3:%[0-9]+]]:_(s32) = G_CONSTANT i32 8 84 ; CHECK: [[FI3:%[0-9]+]]:_(p0) = G_GEP [[SP3]], [[OFF3]](s32) 85 ; CHECK: [[SEXTB2:%[0-9]+]]:_(s32) = G_SEXT [[BVREG]] 86 ; CHECK: G_STORE [[SEXTB2]](s32), [[FI3]](p0){{.*}}store 4 87 ; CHECK: [[SP4:%[0-9]+]]:_(p0) = COPY $sp 88 ; CHECK: [[OFF4:%[0-9]+]]:_(s32) = G_CONSTANT i32 12 89 ; CHECK: [[FI4:%[0-9]+]]:_(p0) = G_GEP [[SP4]], [[OFF4]](s32) 90 ; CHECK: [[ZEXTB2:%[0-9]+]]:_(s32) = G_ZEXT [[BVREG]] 91 ; CHECK: G_STORE [[ZEXTB2]](s32), [[FI4]](p0){{.*}}store 4 92 ; CHECK: [[SP5:%[0-9]+]]:_(p0) = COPY $sp 93 ; CHECK: [[OFF5:%[0-9]+]]:_(s32) = G_CONSTANT i32 16 94 ; CHECK: [[FI5:%[0-9]+]]:_(p0) = G_GEP [[SP5]], [[OFF5]](s32) 95 ; CHECK: [[ZEXTC:%[0-9]+]]:_(s32) = G_ZEXT [[CVREG]] 96 ; CHECK: G_STORE [[ZEXTC]](s32), [[FI5]](p0){{.*}}store 4 97 ; CHECK: BL @ext_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit $r2, implicit $r3, implicit-def $r0 98 ; CHECK: [[R0VREG:%[0-9]+]]:_(s32) = COPY $r0 99 ; CHECK: [[RVREG:%[0-9]+]]:_(s16) = G_TRUNC [[R0VREG]] 100 ; CHECK: ADJCALLSTACKUP 20, 0, 14, $noreg, implicit-def $sp, implicit $sp 101 ; CHECK: [[RExtVREG:%[0-9]+]]:_(s32) = G_SEXT [[RVREG]] 102 ; CHECK: $r0 = COPY [[RExtVREG]] 103 ; CHECK: BX_RET 14, $noreg, implicit $r0 104 entry: 105 %r = notail call arm_aapcscc signext i16 @ext_target(i8 signext %a, i8 zeroext %a, i16 signext %b, i16 zeroext %b, i8 signext %a, i8 zeroext %a, i16 signext %b, i16 zeroext %b, i1 zeroext %c) 106 ret i16 %r 107 } 108 109 declare arm_aapcs_vfpcc double @vfpcc_fp_target(float, double) 110 111 define arm_aapcs_vfpcc double @test_call_vfpcc_fp_params(double %a, float %b) { 112 ; CHECK-LABEL: name: test_call_vfpcc_fp_params 113 ; CHECK-DAG: [[AVREG:%[0-9]+]]:_(s64) = COPY $d0 114 ; CHECK-DAG: [[BVREG:%[0-9]+]]:_(s32) = COPY $s2 115 ; CHECK: ADJCALLSTACKDOWN 0, 0, 14, $noreg, implicit-def $sp, implicit $sp 116 ; CHECK-DAG: $s0 = COPY [[BVREG]] 117 ; CHECK-DAG: $d1 = COPY [[AVREG]] 118 ; CHECK: BL @vfpcc_fp_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $s0, implicit $d1, implicit-def $d0 119 ; CHECK: [[RVREG:%[0-9]+]]:_(s64) = COPY $d0 120 ; CHECK: ADJCALLSTACKUP 0, 0, 14, $noreg, implicit-def $sp, implicit $sp 121 ; CHECK: $d0 = COPY [[RVREG]] 122 ; CHECK: BX_RET 14, $noreg, implicit $d0 123 entry: 124 %r = notail call arm_aapcs_vfpcc double @vfpcc_fp_target(float %b, double %a) 125 ret double %r 126 } 127 128 declare arm_aapcscc double @aapcscc_fp_target(float, double, float, double) 129 130 define arm_aapcscc double @test_call_aapcs_fp_params(double %a, float %b) { 131 ; CHECK-LABEL: name: test_call_aapcs_fp_params 132 ; CHECK-DAG: [[A1:%[0-9]+]]:_(s32) = COPY $r0 133 ; CHECK-DAG: [[A2:%[0-9]+]]:_(s32) = COPY $r1 134 ; LITTLE-DAG: [[AVREG:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[A1]](s32), [[A2]](s32) 135 ; BIG-DAG: [[AVREG:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[A2]](s32), [[A1]](s32) 136 ; CHECK-DAG: [[BVREG:%[0-9]+]]:_(s32) = COPY $r2 137 ; CHECK: ADJCALLSTACKDOWN 16, 0, 14, $noreg, implicit-def $sp, implicit $sp 138 ; CHECK-DAG: $r0 = COPY [[BVREG]] 139 ; CHECK-DAG: [[A1:%[0-9]+]]:_(s32), [[A2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[AVREG]](s64) 140 ; LITTLE-DAG: $r2 = COPY [[A1]] 141 ; LITTLE-DAG: $r3 = COPY [[A2]] 142 ; BIG-DAG: $r2 = COPY [[A2]] 143 ; BIG-DAG: $r3 = COPY [[A1]] 144 ; CHECK: [[SP1:%[0-9]+]]:_(p0) = COPY $sp 145 ; CHECK: [[OFF1:%[0-9]+]]:_(s32) = G_CONSTANT i32 0 146 ; CHECK: [[FI1:%[0-9]+]]:_(p0) = G_GEP [[SP1]], [[OFF1]](s32) 147 ; CHECK: G_STORE [[BVREG]](s32), [[FI1]](p0){{.*}}store 4 148 ; CHECK: [[SP2:%[0-9]+]]:_(p0) = COPY $sp 149 ; CHECK: [[OFF2:%[0-9]+]]:_(s32) = G_CONSTANT i32 8 150 ; CHECK: [[FI2:%[0-9]+]]:_(p0) = G_GEP [[SP2]], [[OFF2]](s32) 151 ; CHECK: G_STORE [[AVREG]](s64), [[FI2]](p0){{.*}}store 8 152 ; CHECK: BL @aapcscc_fp_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r2, implicit $r3, implicit-def $r0, implicit-def $r1 153 ; CHECK-DAG: [[R1:%[0-9]+]]:_(s32) = COPY $r0 154 ; CHECK-DAG: [[R2:%[0-9]+]]:_(s32) = COPY $r1 155 ; LITTLE: [[RVREG:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[R1]](s32), [[R2]](s32) 156 ; BIG: [[RVREG:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[R2]](s32), [[R1]](s32) 157 ; CHECK: ADJCALLSTACKUP 16, 0, 14, $noreg, implicit-def $sp, implicit $sp 158 ; CHECK: [[R1:%[0-9]+]]:_(s32), [[R2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[RVREG]](s64) 159 ; LITTLE-DAG: $r0 = COPY [[R1]] 160 ; LITTLE-DAG: $r1 = COPY [[R2]] 161 ; BIG-DAG: $r0 = COPY [[R2]] 162 ; BIG-DAG: $r1 = COPY [[R1]] 163 ; CHECK: BX_RET 14, $noreg, implicit $r0, implicit $r1 164 entry: 165 %r = notail call arm_aapcscc double @aapcscc_fp_target(float %b, double %a, float %b, double %a) 166 ret double %r 167 } 168 169 declare arm_aapcscc float @different_call_conv_target(float) 170 171 define arm_aapcs_vfpcc float @test_call_different_call_conv(float %x) { 172 ; CHECK-LABEL: name: test_call_different_call_conv 173 ; CHECK: [[X:%[0-9]+]]:_(s32) = COPY $s0 174 ; CHECK: ADJCALLSTACKDOWN 0, 0, 14, $noreg, implicit-def $sp, implicit $sp 175 ; CHECK: $r0 = COPY [[X]] 176 ; CHECK: BL @different_call_conv_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit-def $r0 177 ; CHECK: [[R:%[0-9]+]]:_(s32) = COPY $r0 178 ; CHECK: ADJCALLSTACKUP 0, 0, 14, $noreg, implicit-def $sp, implicit $sp 179 ; CHECK: $s0 = COPY [[R]] 180 ; CHECK: BX_RET 14, $noreg, implicit $s0 181 entry: 182 %r = notail call arm_aapcscc float @different_call_conv_target(float %x) 183 ret float %r 184 } 185 186 declare arm_aapcscc [3 x i32] @tiny_int_arrays_target([2 x i32]) 187 188 define arm_aapcscc [3 x i32] @test_tiny_int_arrays([2 x i32] %arr) { 189 ; CHECK-LABEL: name: test_tiny_int_arrays 190 ; CHECK: liveins: $r0, $r1 191 ; CHECK: [[R0:%[0-9]+]]:_(s32) = COPY $r0 192 ; CHECK: [[R1:%[0-9]+]]:_(s32) = COPY $r1 193 ; CHECK: [[ARG_ARR:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[R0]](s32), [[R1]](s32) 194 ; CHECK: [[EXT1:%[0-9]+]]:_(s32) = G_EXTRACT [[ARG_ARR]](s64), 0 195 ; CHECK: [[EXT2:%[0-9]+]]:_(s32) = G_EXTRACT [[ARG_ARR]](s64), 32 196 ; CHECK: [[IMPDEF:%[0-9]+]]:_(s64) = G_IMPLICIT_DEF 197 ; CHECK: [[INS1:%[0-9]+]]:_(s64) = G_INSERT [[IMPDEF]], [[EXT1]](s32), 0 198 ; CHECK: [[INS2:%[0-9]+]]:_(s64) = G_INSERT [[INS1]], [[EXT2]](s32), 32 199 ; CHECK: ADJCALLSTACKDOWN 0, 0, 14, $noreg, implicit-def $sp, implicit $sp 200 ; CHECK: [[R0:%[0-9]+]]:_(s32), [[R1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[INS2]](s64) 201 ; CHECK: $r0 = COPY [[R0]] 202 ; CHECK: $r1 = COPY [[R1]] 203 ; CHECK: BL @tiny_int_arrays_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit-def $r0, implicit-def $r1 204 ; CHECK: [[R0:%[0-9]+]]:_(s32) = COPY $r0 205 ; CHECK: [[R1:%[0-9]+]]:_(s32) = COPY $r1 206 ; CHECK: [[R2:%[0-9]+]]:_(s32) = COPY $r2 207 ; CHECK: [[RES_ARR:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[R0]](s32), [[R1]](s32), [[R2]](s32) 208 ; CHECK: ADJCALLSTACKUP 0, 0, 14, $noreg, implicit-def $sp, implicit $sp 209 ; CHECK: [[EXT3:%[0-9]+]]:_(s32) = G_EXTRACT [[RES_ARR]](s96), 0 210 ; CHECK: [[EXT4:%[0-9]+]]:_(s32) = G_EXTRACT [[RES_ARR]](s96), 32 211 ; CHECK: [[EXT5:%[0-9]+]]:_(s32) = G_EXTRACT [[RES_ARR]](s96), 64 212 ; CHECK: [[IMPDEF2:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF 213 ; CHECK: [[INS3:%[0-9]+]]:_(s96) = G_INSERT [[IMPDEF2]], [[EXT3]](s32), 0 214 ; CHECK: [[INS4:%[0-9]+]]:_(s96) = G_INSERT [[INS3]], [[EXT4]](s32), 32 215 ; CHECK: [[INS5:%[0-9]+]]:_(s96) = G_INSERT [[INS4]], [[EXT5]](s32), 64 216 ; CHECK: [[R0:%[0-9]+]]:_(s32), [[R1:%[0-9]+]]:_(s32), [[R2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[INS5]](s96) 217 ; FIXME: This doesn't seem correct with regard to the AAPCS docs (which say 218 ; that composite types larger than 4 bytes should be passed through memory), 219 ; but it's what DAGISel does. We should fix it in the common code for both. 220 ; CHECK: $r0 = COPY [[R0]] 221 ; CHECK: $r1 = COPY [[R1]] 222 ; CHECK: $r2 = COPY [[R2]] 223 ; CHECK: BX_RET 14, $noreg, implicit $r0, implicit $r1, implicit $r2 224 entry: 225 %r = notail call arm_aapcscc [3 x i32] @tiny_int_arrays_target([2 x i32] %arr) 226 ret [3 x i32] %r 227 } 228 229 declare arm_aapcscc void @multiple_int_arrays_target([2 x i32], [2 x i32]) 230 231 define arm_aapcscc void @test_multiple_int_arrays([2 x i32] %arr0, [2 x i32] %arr1) { 232 ; CHECK-LABEL: name: test_multiple_int_arrays 233 ; CHECK: liveins: $r0, $r1 234 ; CHECK: [[R0:%[0-9]+]]:_(s32) = COPY $r0 235 ; CHECK: [[R1:%[0-9]+]]:_(s32) = COPY $r1 236 ; CHECK: [[R2:%[0-9]+]]:_(s32) = COPY $r2 237 ; CHECK: [[R3:%[0-9]+]]:_(s32) = COPY $r3 238 ; CHECK: [[ARG_ARR0:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[R0]](s32), [[R1]](s32) 239 ; CHECK: [[ARG_ARR1:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[R2]](s32), [[R3]](s32) 240 ; CHECK: [[EXT1:%[0-9]+]]:_(s32) = G_EXTRACT [[ARG_ARR0]](s64), 0 241 ; CHECK: [[EXT2:%[0-9]+]]:_(s32) = G_EXTRACT [[ARG_ARR0]](s64), 32 242 ; CHECK: [[EXT3:%[0-9]+]]:_(s32) = G_EXTRACT [[ARG_ARR1]](s64), 0 243 ; CHECK: [[EXT4:%[0-9]+]]:_(s32) = G_EXTRACT [[ARG_ARR1]](s64), 32 244 ; CHECK: [[IMPDEF:%[0-9]+]]:_(s64) = G_IMPLICIT_DEF 245 ; CHECK: [[INS1:%[0-9]+]]:_(s64) = G_INSERT [[IMPDEF]], [[EXT1]](s32), 0 246 ; CHECK: [[INS2:%[0-9]+]]:_(s64) = G_INSERT [[INS1]], [[EXT2]](s32), 32 247 ; CHECK: [[IMPDEF2:%[0-9]+]]:_(s64) = G_IMPLICIT_DEF 248 ; CHECK: [[INS3:%[0-9]+]]:_(s64) = G_INSERT [[IMPDEF2]], [[EXT3]](s32), 0 249 ; CHECK: [[INS4:%[0-9]+]]:_(s64) = G_INSERT [[INS3]], [[EXT4]](s32), 32 250 ; CHECK: ADJCALLSTACKDOWN 0, 0, 14, $noreg, implicit-def $sp, implicit $sp 251 ; CHECK: [[R0:%[0-9]+]]:_(s32), [[R1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[INS2]](s64) 252 ; CHECK: [[R2:%[0-9]+]]:_(s32), [[R3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[INS4]](s64) 253 ; CHECK: $r0 = COPY [[R0]] 254 ; CHECK: $r1 = COPY [[R1]] 255 ; CHECK: $r2 = COPY [[R2]] 256 ; CHECK: $r3 = COPY [[R3]] 257 ; CHECK: BL @multiple_int_arrays_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit $r2, implicit $r3 258 ; CHECK: ADJCALLSTACKUP 0, 0, 14, $noreg, implicit-def $sp, implicit $sp 259 ; CHECK: BX_RET 14, $noreg 260 entry: 261 notail call arm_aapcscc void @multiple_int_arrays_target([2 x i32] %arr0, [2 x i32] %arr1) 262 ret void 263 } 264 265 declare arm_aapcscc void @large_int_arrays_target([20 x i32]) 266 267 define arm_aapcscc void @test_large_int_arrays([20 x i32] %arr) { 268 ; CHECK-LABEL: name: test_large_int_arrays 269 ; CHECK: fixedStack: 270 ; The parameters live in separate stack locations, one for each element that 271 ; doesn't fit in the registers. 272 ; CHECK-DAG: id: [[FIRST_STACK_ID:[0-9]+]], type: default, offset: 0, size: 4, 273 ; CHECK-DAG: id: [[LAST_STACK_ID:[-0]+]], type: default, offset: 60, size: 4 274 ; CHECK: liveins: $r0, $r1, $r2, $r3 275 ; CHECK-DAG: [[R0:%[0-9]+]]:_(s32) = COPY $r0 276 ; CHECK-DAG: [[R1:%[0-9]+]]:_(s32) = COPY $r1 277 ; CHECK-DAG: [[R2:%[0-9]+]]:_(s32) = COPY $r2 278 ; CHECK-DAG: [[R3:%[0-9]+]]:_(s32) = COPY $r3 279 ; CHECK: [[FIRST_STACK_ELEMENT_FI:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[FIRST_STACK_ID]] 280 ; CHECK: [[FIRST_STACK_ELEMENT:%[0-9]+]]:_(s32) = G_LOAD [[FIRST_STACK_ELEMENT_FI]]{{.*}}load 4 from %fixed-stack.[[FIRST_STACK_ID]] 281 ; CHECK: [[LAST_STACK_ELEMENT_FI:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[LAST_STACK_ID]] 282 ; CHECK: [[LAST_STACK_ELEMENT:%[0-9]+]]:_(s32) = G_LOAD [[LAST_STACK_ELEMENT_FI]]{{.*}}load 4 from %fixed-stack.[[LAST_STACK_ID]] 283 ; CHECK: [[ARG_ARR:%[0-9]+]]:_(s640) = G_MERGE_VALUES [[R0]](s32), [[R1]](s32), [[R2]](s32), [[R3]](s32), [[FIRST_STACK_ELEMENT]](s32), {{.*}}, [[LAST_STACK_ELEMENT]](s32) 284 ; CHECK: [[INS:%[0-9]+]]:_(s640) = G_INSERT {{.*}}, {{.*}}(s32), 608 285 ; CHECK: ADJCALLSTACKDOWN 64, 0, 14, $noreg, implicit-def $sp, implicit $sp 286 ; CHECK: [[R0:%[0-9]+]]:_(s32), [[R1:%[0-9]+]]:_(s32), [[R2:%[0-9]+]]:_(s32), [[R3:%[0-9]+]]:_(s32), [[FIRST_STACK_ELEMENT:%[0-9]+]]:_(s32), {{.*}}, [[LAST_STACK_ELEMENT:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[INS]](s640) 287 ; CHECK: $r0 = COPY [[R0]] 288 ; CHECK: $r1 = COPY [[R1]] 289 ; CHECK: $r2 = COPY [[R2]] 290 ; CHECK: $r3 = COPY [[R3]] 291 ; CHECK: [[SP:%[0-9]+]]:_(p0) = COPY $sp 292 ; CHECK: [[OFF_FIRST_ELEMENT:%[0-9]+]]:_(s32) = G_CONSTANT i32 0 293 ; CHECK: [[FIRST_STACK_ARG_ADDR:%[0-9]+]]:_(p0) = G_GEP [[SP]], [[OFF_FIRST_ELEMENT]](s32) 294 ; CHECK: G_STORE [[FIRST_STACK_ELEMENT]](s32), [[FIRST_STACK_ARG_ADDR]]{{.*}}store 4 295 ; Match the second-to-last offset, so we can get the correct SP for the last element 296 ; CHECK: G_CONSTANT i32 56 297 ; CHECK: [[SP:%[0-9]+]]:_(p0) = COPY $sp 298 ; CHECK: [[OFF_LAST_ELEMENT:%[0-9]+]]:_(s32) = G_CONSTANT i32 60 299 ; CHECK: [[LAST_STACK_ARG_ADDR:%[0-9]+]]:_(p0) = G_GEP [[SP]], [[OFF_LAST_ELEMENT]](s32) 300 ; CHECK: G_STORE [[LAST_STACK_ELEMENT]](s32), [[LAST_STACK_ARG_ADDR]]{{.*}}store 4 301 ; CHECK: BL @large_int_arrays_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit $r2, implicit $r3 302 ; CHECK: ADJCALLSTACKUP 64, 0, 14, $noreg, implicit-def $sp, implicit $sp 303 ; CHECK: BX_RET 14, $noreg 304 entry: 305 notail call arm_aapcscc void @large_int_arrays_target([20 x i32] %arr) 306 ret void 307 } 308 309 declare arm_aapcscc [2 x float] @fp_arrays_aapcs_target([3 x double]) 310 311 define arm_aapcscc [2 x float] @test_fp_arrays_aapcs([3 x double] %arr) { 312 ; CHECK-LABEL: name: test_fp_arrays_aapcs 313 ; CHECK: fixedStack: 314 ; CHECK: id: [[ARR2_ID:[0-9]+]], type: default, offset: 0, size: 8, 315 ; CHECK: liveins: $r0, $r1, $r2, $r3 316 ; CHECK: [[ARR0_0:%[0-9]+]]:_(s32) = COPY $r0 317 ; CHECK: [[ARR0_1:%[0-9]+]]:_(s32) = COPY $r1 318 ; LITTLE: [[ARR0:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[ARR0_0]](s32), [[ARR0_1]](s32) 319 ; BIG: [[ARR0:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[ARR0_1]](s32), [[ARR0_0]](s32) 320 ; CHECK: [[ARR1_0:%[0-9]+]]:_(s32) = COPY $r2 321 ; CHECK: [[ARR1_1:%[0-9]+]]:_(s32) = COPY $r3 322 ; LITTLE: [[ARR1:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[ARR1_0]](s32), [[ARR1_1]](s32) 323 ; BIG: [[ARR1:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[ARR1_1]](s32), [[ARR1_0]](s32) 324 ; CHECK: [[ARR2_FI:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[ARR2_ID]] 325 ; CHECK: [[ARR2:%[0-9]+]]:_(s64) = G_LOAD [[ARR2_FI]]{{.*}}load 8 from %fixed-stack.[[ARR2_ID]] 326 ; CHECK: [[ARR_MERGED:%[0-9]+]]:_(s192) = G_MERGE_VALUES [[ARR0]](s64), [[ARR1]](s64), [[ARR2]](s64) 327 ; CHECK: [[EXT1:%[0-9]+]]:_(s64) = G_EXTRACT [[ARR_MERGED]](s192), 0 328 ; CHECK: [[EXT2:%[0-9]+]]:_(s64) = G_EXTRACT [[ARR_MERGED]](s192), 64 329 ; CHECK: [[EXT3:%[0-9]+]]:_(s64) = G_EXTRACT [[ARR_MERGED]](s192), 128 330 ; CHECK: [[IMPDEF:%[0-9]+]]:_(s192) = G_IMPLICIT_DEF 331 ; CHECK: [[INS1:%[0-9]+]]:_(s192) = G_INSERT [[IMPDEF]], [[EXT1]](s64), 0 332 ; CHECK: [[INS2:%[0-9]+]]:_(s192) = G_INSERT [[INS1]], [[EXT2]](s64), 64 333 ; CHECK: [[INS3:%[0-9]+]]:_(s192) = G_INSERT [[INS2]], [[EXT3]](s64), 128 334 ; CHECK: ADJCALLSTACKDOWN 8, 0, 14, $noreg, implicit-def $sp, implicit $sp 335 ; CHECK: [[ARR0:%[0-9]+]]:_(s64), [[ARR1:%[0-9]+]]:_(s64), [[ARR2:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[INS3]](s192) 336 ; CHECK: [[ARR0_0:%[0-9]+]]:_(s32), [[ARR0_1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[ARR0]](s64) 337 ; LITTLE: $r0 = COPY [[ARR0_0]](s32) 338 ; LITTLE: $r1 = COPY [[ARR0_1]](s32) 339 ; BIG: $r0 = COPY [[ARR0_1]](s32) 340 ; BIG: $r1 = COPY [[ARR0_0]](s32) 341 ; CHECK: [[ARR1_0:%[0-9]+]]:_(s32), [[ARR1_1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[ARR1]](s64) 342 ; LITTLE: $r2 = COPY [[ARR1_0]](s32) 343 ; LITTLE: $r3 = COPY [[ARR1_1]](s32) 344 ; BIG: $r2 = COPY [[ARR1_1]](s32) 345 ; BIG: $r3 = COPY [[ARR1_0]](s32) 346 ; CHECK: [[SP:%[0-9]+]]:_(p0) = COPY $sp 347 ; CHECK: [[ARR2_OFFSET:%[0-9]+]]:_(s32) = G_CONSTANT i32 0 348 ; CHECK: [[ARR2_ADDR:%[0-9]+]]:_(p0) = G_GEP [[SP]], [[ARR2_OFFSET]](s32) 349 ; CHECK: G_STORE [[ARR2]](s64), [[ARR2_ADDR]](p0){{.*}}store 8 350 ; CHECK: BL @fp_arrays_aapcs_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit $r2, implicit $r3, implicit-def $r0, implicit-def $r1 351 ; CHECK: [[R0:%[0-9]+]]:_(s32) = COPY $r0 352 ; CHECK: [[R1:%[0-9]+]]:_(s32) = COPY $r1 353 ; CHECK: [[R_MERGED:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[R0]](s32), [[R1]](s32) 354 ; CHECK: ADJCALLSTACKUP 8, 0, 14, $noreg, implicit-def $sp, implicit $sp 355 ; CHECK: [[EXT4:%[0-9]+]]:_(s32) = G_EXTRACT [[R_MERGED]](s64), 0 356 ; CHECK: [[EXT5:%[0-9]+]]:_(s32) = G_EXTRACT [[R_MERGED]](s64), 32 357 ; CHECK: [[IMPDEF2:%[0-9]+]]:_(s64) = G_IMPLICIT_DEF 358 ; CHECK: [[INS4:%[0-9]+]]:_(s64) = G_INSERT [[IMPDEF2]], [[EXT4]](s32), 0 359 ; CHECK: [[INS5:%[0-9]+]]:_(s64) = G_INSERT [[INS4]], [[EXT5]](s32), 32 360 ; CHECK: [[R0:%[0-9]+]]:_(s32), [[R1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[INS5]](s64) 361 ; CHECK: $r0 = COPY [[R0]] 362 ; CHECK: $r1 = COPY [[R1]] 363 ; CHECK: BX_RET 14, $noreg, implicit $r0, implicit $r1 364 entry: 365 %r = notail call arm_aapcscc [2 x float] @fp_arrays_aapcs_target([3 x double] %arr) 366 ret [2 x float] %r 367 } 368 369 declare arm_aapcs_vfpcc [4 x float] @fp_arrays_aapcs_vfp_target([3 x double], [3 x float], [4 x double]) 370 371 define arm_aapcs_vfpcc [4 x float] @test_fp_arrays_aapcs_vfp([3 x double] %x, [3 x float] %y, [4 x double] %z) { 372 ; CHECK-LABEL: name: test_fp_arrays_aapcs_vfp 373 ; CHECK: fixedStack: 374 ; CHECK-DAG: id: [[Z0_ID:[0-9]+]], type: default, offset: 0, size: 8, 375 ; CHECK-DAG: id: [[Z1_ID:[0-9]+]], type: default, offset: 8, size: 8, 376 ; CHECK-DAG: id: [[Z2_ID:[0-9]+]], type: default, offset: 16, size: 8, 377 ; CHECK-DAG: id: [[Z3_ID:[0-9]+]], type: default, offset: 24, size: 8, 378 ; CHECK: liveins: $d0, $d1, $d2, $s6, $s7, $s8 379 ; CHECK: [[X0:%[0-9]+]]:_(s64) = COPY $d0 380 ; CHECK: [[X1:%[0-9]+]]:_(s64) = COPY $d1 381 ; CHECK: [[X2:%[0-9]+]]:_(s64) = COPY $d2 382 ; CHECK: [[Y0:%[0-9]+]]:_(s32) = COPY $s6 383 ; CHECK: [[Y1:%[0-9]+]]:_(s32) = COPY $s7 384 ; CHECK: [[Y2:%[0-9]+]]:_(s32) = COPY $s8 385 ; CHECK: [[Z0_FI:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[Z0_ID]] 386 ; CHECK: [[Z0:%[0-9]+]]:_(s64) = G_LOAD [[Z0_FI]]{{.*}}load 8 387 ; CHECK: [[Z1_FI:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[Z1_ID]] 388 ; CHECK: [[Z1:%[0-9]+]]:_(s64) = G_LOAD [[Z1_FI]]{{.*}}load 8 389 ; CHECK: [[Z2_FI:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[Z2_ID]] 390 ; CHECK: [[Z2:%[0-9]+]]:_(s64) = G_LOAD [[Z2_FI]]{{.*}}load 8 391 ; CHECK: [[Z3_FI:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[Z3_ID]] 392 ; CHECK: [[Z3:%[0-9]+]]:_(s64) = G_LOAD [[Z3_FI]]{{.*}}load 8 393 ; CHECK: [[X_ARR:%[0-9]+]]:_(s192) = G_MERGE_VALUES [[X0]](s64), [[X1]](s64), [[X2]](s64) 394 ; CHECK: [[Y_ARR:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[Y0]](s32), [[Y1]](s32), [[Y2]](s32) 395 ; CHECK: [[Z_ARR:%[0-9]+]]:_(s256) = G_MERGE_VALUES [[Z0]](s64), [[Z1]](s64), [[Z2]](s64), [[Z3]](s64) 396 ; CHECK: [[EXT1:%[0-9]+]]:_(s64) = G_EXTRACT [[X_ARR]](s192), 0 397 ; CHECK: [[EXT2:%[0-9]+]]:_(s64) = G_EXTRACT [[X_ARR]](s192), 64 398 ; CHECK: [[EXT3:%[0-9]+]]:_(s64) = G_EXTRACT [[X_ARR]](s192), 128 399 ; CHECK: [[EXT4:%[0-9]+]]:_(s32) = G_EXTRACT [[Y_ARR]](s96), 0 400 ; CHECK: [[EXT5:%[0-9]+]]:_(s32) = G_EXTRACT [[Y_ARR]](s96), 32 401 ; CHECK: [[EXT6:%[0-9]+]]:_(s32) = G_EXTRACT [[Y_ARR]](s96), 64 402 ; CHECK: [[EXT7:%[0-9]+]]:_(s64) = G_EXTRACT [[Z_ARR]](s256), 0 403 ; CHECK: [[EXT8:%[0-9]+]]:_(s64) = G_EXTRACT [[Z_ARR]](s256), 64 404 ; CHECK: [[EXT9:%[0-9]+]]:_(s64) = G_EXTRACT [[Z_ARR]](s256), 128 405 ; CHECK: [[EXT10:%[0-9]+]]:_(s64) = G_EXTRACT [[Z_ARR]](s256), 192 406 ; CHECK: [[IMPDEF:%[0-9]+]]:_(s192) = G_IMPLICIT_DEF 407 ; CHECK: [[INS1:%[0-9]+]]:_(s192) = G_INSERT [[IMPDEF]], [[EXT1]](s64), 0 408 ; CHECK: [[INS2:%[0-9]+]]:_(s192) = G_INSERT [[INS1]], [[EXT2]](s64), 64 409 ; CHECK: [[INS3:%[0-9]+]]:_(s192) = G_INSERT [[INS2]], [[EXT3]](s64), 128 410 ; CHECK: [[IMPDEF2:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF 411 ; CHECK: [[INS4:%[0-9]+]]:_(s96) = G_INSERT [[IMPDEF2]], [[EXT4]](s32), 0 412 ; CHECK: [[INS5:%[0-9]+]]:_(s96) = G_INSERT [[INS4]], [[EXT5]](s32), 32 413 ; CHECK: [[INS6:%[0-9]+]]:_(s96) = G_INSERT [[INS5]], [[EXT6]](s32), 64 414 ; CHECK: [[IMPDEF3:%[0-9]+]]:_(s256) = G_IMPLICIT_DEF 415 ; CHECK: [[INS7:%[0-9]+]]:_(s256) = G_INSERT [[IMPDEF3]], [[EXT7]](s64), 0 416 ; CHECK: [[INS8:%[0-9]+]]:_(s256) = G_INSERT [[INS7]], [[EXT8]](s64), 64 417 ; CHECK: [[INS9:%[0-9]+]]:_(s256) = G_INSERT [[INS8]], [[EXT9]](s64), 128 418 ; CHECK: [[INS10:%[0-9]+]]:_(s256) = G_INSERT [[INS9]], [[EXT10]](s64), 192 419 ; CHECK: ADJCALLSTACKDOWN 32, 0, 14, $noreg, implicit-def $sp, implicit $sp 420 ; CHECK: [[X0:%[0-9]+]]:_(s64), [[X1:%[0-9]+]]:_(s64), [[X2:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[INS3]](s192) 421 ; CHECK: [[Y0:%[0-9]+]]:_(s32), [[Y1:%[0-9]+]]:_(s32), [[Y2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[INS6]](s96) 422 ; CHECK: [[Z0:%[0-9]+]]:_(s64), [[Z1:%[0-9]+]]:_(s64), [[Z2:%[0-9]+]]:_(s64), [[Z3:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[INS10]](s256) 423 ; CHECK: $d0 = COPY [[X0]](s64) 424 ; CHECK: $d1 = COPY [[X1]](s64) 425 ; CHECK: $d2 = COPY [[X2]](s64) 426 ; CHECK: $s6 = COPY [[Y0]](s32) 427 ; CHECK: $s7 = COPY [[Y1]](s32) 428 ; CHECK: $s8 = COPY [[Y2]](s32) 429 ; CHECK: [[SP:%[0-9]+]]:_(p0) = COPY $sp 430 ; CHECK: [[Z0_OFFSET:%[0-9]+]]:_(s32) = G_CONSTANT i32 0 431 ; CHECK: [[Z0_ADDR:%[0-9]+]]:_(p0) = G_GEP [[SP]], [[Z0_OFFSET]](s32) 432 ; CHECK: G_STORE [[Z0]](s64), [[Z0_ADDR]](p0){{.*}}store 8 433 ; CHECK: [[SP:%[0-9]+]]:_(p0) = COPY $sp 434 ; CHECK: [[Z1_OFFSET:%[0-9]+]]:_(s32) = G_CONSTANT i32 8 435 ; CHECK: [[Z1_ADDR:%[0-9]+]]:_(p0) = G_GEP [[SP]], [[Z1_OFFSET]](s32) 436 ; CHECK: G_STORE [[Z1]](s64), [[Z1_ADDR]](p0){{.*}}store 8 437 ; CHECK: [[SP:%[0-9]+]]:_(p0) = COPY $sp 438 ; CHECK: [[Z2_OFFSET:%[0-9]+]]:_(s32) = G_CONSTANT i32 16 439 ; CHECK: [[Z2_ADDR:%[0-9]+]]:_(p0) = G_GEP [[SP]], [[Z2_OFFSET]](s32) 440 ; CHECK: G_STORE [[Z2]](s64), [[Z2_ADDR]](p0){{.*}}store 8 441 ; CHECK: [[SP:%[0-9]+]]:_(p0) = COPY $sp 442 ; CHECK: [[Z3_OFFSET:%[0-9]+]]:_(s32) = G_CONSTANT i32 24 443 ; CHECK: [[Z3_ADDR:%[0-9]+]]:_(p0) = G_GEP [[SP]], [[Z3_OFFSET]](s32) 444 ; CHECK: G_STORE [[Z3]](s64), [[Z3_ADDR]](p0){{.*}}store 8 445 ; CHECK: BL @fp_arrays_aapcs_vfp_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $d0, implicit $d1, implicit $d2, implicit $s6, implicit $s7, implicit $s8, implicit-def $s0, implicit-def $s1, implicit-def $s2, implicit-def $s3 446 ; CHECK: [[R0:%[0-9]+]]:_(s32) = COPY $s0 447 ; CHECK: [[R1:%[0-9]+]]:_(s32) = COPY $s1 448 ; CHECK: [[R2:%[0-9]+]]:_(s32) = COPY $s2 449 ; CHECK: [[R3:%[0-9]+]]:_(s32) = COPY $s3 450 ; CHECK: [[R_MERGED:%[0-9]+]]:_(s128) = G_MERGE_VALUES [[R0]](s32), [[R1]](s32), [[R2]](s32), [[R3]](s32) 451 ; CHECK: ADJCALLSTACKUP 32, 0, 14, $noreg, implicit-def $sp, implicit $sp 452 ; CHECK: [[EXT11:%[0-9]+]]:_(s32) = G_EXTRACT [[R_MERGED]](s128), 0 453 ; CHECK: [[EXT12:%[0-9]+]]:_(s32) = G_EXTRACT [[R_MERGED]](s128), 32 454 ; CHECK: [[EXT13:%[0-9]+]]:_(s32) = G_EXTRACT [[R_MERGED]](s128), 64 455 ; CHECK: [[EXT14:%[0-9]+]]:_(s32) = G_EXTRACT [[R_MERGED]](s128), 96 456 ; CHECK: [[IMPDEF4:%[0-9]+]]:_(s128) = G_IMPLICIT_DEF 457 ; CHECK: [[INS11:%[0-9]+]]:_(s128) = G_INSERT [[IMPDEF4]], [[EXT11]](s32), 0 458 ; CHECK: [[INS12:%[0-9]+]]:_(s128) = G_INSERT [[INS11]], [[EXT12]](s32), 32 459 ; CHECK: [[INS13:%[0-9]+]]:_(s128) = G_INSERT [[INS12]], [[EXT13]](s32), 64 460 ; CHECK: [[INS14:%[0-9]+]]:_(s128) = G_INSERT [[INS13]], [[EXT14]](s32), 96 461 ; CHECK: [[R0:%[0-9]+]]:_(s32), [[R1:%[0-9]+]]:_(s32), [[R2:%[0-9]+]]:_(s32), [[R3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[INS14]](s128) 462 ; CHECK: $s0 = COPY [[R0]] 463 ; CHECK: $s1 = COPY [[R1]] 464 ; CHECK: $s2 = COPY [[R2]] 465 ; CHECK: $s3 = COPY [[R3]] 466 ; CHECK: BX_RET 14, $noreg, implicit $s0, implicit $s1, implicit $s2, implicit $s3 467 entry: 468 %r = notail call arm_aapcs_vfpcc [4 x float] @fp_arrays_aapcs_vfp_target([3 x double] %x, [3 x float] %y, [4 x double] %z) 469 ret [4 x float] %r 470 } 471 472 declare arm_aapcscc [2 x i32*] @tough_arrays_target([6 x [4 x i32]] %arr) 473 474 define arm_aapcscc [2 x i32*] @test_tough_arrays([6 x [4 x i32]] %arr) { 475 ; CHECK-LABEL: name: test_tough_arrays 476 ; CHECK: fixedStack: 477 ; The parameters live in separate stack locations, one for each element that 478 ; doesn't fit in the registers. 479 ; CHECK-DAG: id: [[FIRST_STACK_ID:[0-9]+]], type: default, offset: 0, size: 4, 480 ; CHECK-DAG: id: [[LAST_STACK_ID:[-0]+]], type: default, offset: 76, size: 4 481 ; CHECK: liveins: $r0, $r1, $r2, $r3 482 ; CHECK-DAG: [[R0:%[0-9]+]]:_(s32) = COPY $r0 483 ; CHECK-DAG: [[R1:%[0-9]+]]:_(s32) = COPY $r1 484 ; CHECK-DAG: [[R2:%[0-9]+]]:_(s32) = COPY $r2 485 ; CHECK-DAG: [[R3:%[0-9]+]]:_(s32) = COPY $r3 486 ; CHECK: [[FIRST_STACK_ELEMENT_FI:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[FIRST_STACK_ID]] 487 ; CHECK: [[FIRST_STACK_ELEMENT:%[0-9]+]]:_(s32) = G_LOAD [[FIRST_STACK_ELEMENT_FI]]{{.*}}load 4 from %fixed-stack.[[FIRST_STACK_ID]] 488 ; CHECK: [[LAST_STACK_ELEMENT_FI:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[LAST_STACK_ID]] 489 ; CHECK: [[LAST_STACK_ELEMENT:%[0-9]+]]:_(s32) = G_LOAD [[LAST_STACK_ELEMENT_FI]]{{.*}}load 4 from %fixed-stack.[[LAST_STACK_ID]] 490 ; CHECK: [[ARG_ARR:%[0-9]+]]:_(s768) = G_MERGE_VALUES [[R0]](s32), [[R1]](s32), [[R2]](s32), [[R3]](s32), [[FIRST_STACK_ELEMENT]](s32), {{.*}}, [[LAST_STACK_ELEMENT]](s32) 491 ; CHECK: [[INS:%[0-9]+]]:_(s768) = G_INSERT {{.*}}, {{.*}}(s32), 736 492 ; CHECK: ADJCALLSTACKDOWN 80, 0, 14, $noreg, implicit-def $sp, implicit $sp 493 ; CHECK: [[R0:%[0-9]+]]:_(s32), [[R1:%[0-9]+]]:_(s32), [[R2:%[0-9]+]]:_(s32), [[R3:%[0-9]+]]:_(s32), [[FIRST_STACK_ELEMENT:%[0-9]+]]:_(s32), {{.*}}, [[LAST_STACK_ELEMENT:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[INS]](s768) 494 ; CHECK: $r0 = COPY [[R0]] 495 ; CHECK: $r1 = COPY [[R1]] 496 ; CHECK: $r2 = COPY [[R2]] 497 ; CHECK: $r3 = COPY [[R3]] 498 ; CHECK: [[SP:%[0-9]+]]:_(p0) = COPY $sp 499 ; CHECK: [[OFF_FIRST_ELEMENT:%[0-9]+]]:_(s32) = G_CONSTANT i32 0 500 ; CHECK: [[FIRST_STACK_ARG_ADDR:%[0-9]+]]:_(p0) = G_GEP [[SP]], [[OFF_FIRST_ELEMENT]](s32) 501 ; CHECK: G_STORE [[FIRST_STACK_ELEMENT]](s32), [[FIRST_STACK_ARG_ADDR]]{{.*}}store 4 502 ; Match the second-to-last offset, so we can get the correct SP for the last element 503 ; CHECK: G_CONSTANT i32 72 504 ; CHECK: [[SP:%[0-9]+]]:_(p0) = COPY $sp 505 ; CHECK: [[OFF_LAST_ELEMENT:%[0-9]+]]:_(s32) = G_CONSTANT i32 76 506 ; CHECK: [[LAST_STACK_ARG_ADDR:%[0-9]+]]:_(p0) = G_GEP [[SP]], [[OFF_LAST_ELEMENT]](s32) 507 ; CHECK: G_STORE [[LAST_STACK_ELEMENT]](s32), [[LAST_STACK_ARG_ADDR]]{{.*}}store 4 508 ; CHECK: BL @tough_arrays_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit $r2, implicit $r3, implicit-def $r0, implicit-def $r1 509 ; CHECK: [[R0:%[0-9]+]]:_(s32) = COPY $r0 510 ; CHECK: [[R1:%[0-9]+]]:_(s32) = COPY $r1 511 ; CHECK: [[RES_ARR:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[R0]](s32), [[R1]](s32) 512 ; CHECK: ADJCALLSTACKUP 80, 0, 14, $noreg, implicit-def $sp, implicit $sp 513 ; CHECK: [[EXT1:%[0-9]+]]:_(p0) = G_EXTRACT [[RES_ARR]](s64), 0 514 ; CHECK: [[EXT2:%[0-9]+]]:_(p0) = G_EXTRACT [[RES_ARR]](s64), 32 515 ; CHECK: [[IMPDEF:%[0-9]+]]:_(s64) = G_IMPLICIT_DEF 516 ; CHECK: [[INS2:%[0-9]+]]:_(s64) = G_INSERT [[IMPDEF]], [[EXT1]](p0), 0 517 ; CHECK: [[INS3:%[0-9]+]]:_(s64) = G_INSERT [[INS2]], [[EXT2]](p0), 32 518 ; CHECK: [[R0:%[0-9]+]]:_(s32), [[R1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[INS3]](s64) 519 ; CHECK: $r0 = COPY [[R0]] 520 ; CHECK: $r1 = COPY [[R1]] 521 ; CHECK: BX_RET 14, $noreg, implicit $r0, implicit $r1 522 entry: 523 %r = notail call arm_aapcscc [2 x i32*] @tough_arrays_target([6 x [4 x i32]] %arr) 524 ret [2 x i32*] %r 525 } 526 527 declare arm_aapcscc {i32, i32} @structs_target({i32, i32}) 528 529 define arm_aapcscc {i32, i32} @test_structs({i32, i32} %x) { 530 ; CHECK-LABEL: test_structs 531 ; CHECK: liveins: $r0, $r1 532 ; CHECK-DAG: [[X0:%[0-9]+]]:_(s32) = COPY $r0 533 ; CHECK-DAG: [[X1:%[0-9]+]]:_(s32) = COPY $r1 534 ; CHECK: [[X:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[X0]](s32), [[X1]](s32) 535 ; CHECK: [[EXT1:%[0-9]+]]:_(s32) = G_EXTRACT [[X]](s64), 0 536 ; CHECK: [[EXT2:%[0-9]+]]:_(s32) = G_EXTRACT [[X]](s64), 32 537 ; CHECK: [[IMPDEF:%[0-9]+]]:_(s64) = G_IMPLICIT_DEF 538 ; CHECK: [[INS1:%[0-9]+]]:_(s64) = G_INSERT [[IMPDEF]], [[EXT1]](s32), 0 539 ; CHECK: [[INS2:%[0-9]+]]:_(s64) = G_INSERT [[INS1]], [[EXT2]](s32), 32 540 ; CHECK: ADJCALLSTACKDOWN 0, 0, 14, $noreg, implicit-def $sp, implicit $sp 541 ; CHECK: [[X0:%[0-9]+]]:_(s32), [[X1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[INS2]](s64) 542 ; CHECK-DAG: $r0 = COPY [[X0]](s32) 543 ; CHECK-DAG: $r1 = COPY [[X1]](s32) 544 ; CHECK: BL @structs_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit-def $r0, implicit-def $r1 545 ; CHECK: [[R0:%[0-9]+]]:_(s32) = COPY $r0 546 ; CHECK: [[R1:%[0-9]+]]:_(s32) = COPY $r1 547 ; CHECK: [[R:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[R0]](s32), [[R1]](s32) 548 ; CHECK: ADJCALLSTACKUP 0, 0, 14, $noreg, implicit-def $sp, implicit $sp 549 ; CHECK: [[EXT3:%[0-9]+]]:_(s32) = G_EXTRACT [[R]](s64), 0 550 ; CHECK: [[EXT4:%[0-9]+]]:_(s32) = G_EXTRACT [[R]](s64), 32 551 ; CHECK: [[IMPDEF2:%[0-9]+]]:_(s64) = G_IMPLICIT_DEF 552 ; CHECK: [[INS3:%[0-9]+]]:_(s64) = G_INSERT [[IMPDEF2]], [[EXT3]](s32), 0 553 ; CHECK: [[INS4:%[0-9]+]]:_(s64) = G_INSERT [[INS3]], [[EXT4]](s32), 32 554 ; CHECK: [[R0:%[0-9]+]]:_(s32), [[R1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[INS4]](s64) 555 ; CHECK: $r0 = COPY [[R0]](s32) 556 ; CHECK: $r1 = COPY [[R1]](s32) 557 ; CHECK: BX_RET 14, $noreg, implicit $r0, implicit $r1 558 %r = notail call arm_aapcscc {i32, i32} @structs_target({i32, i32} %x) 559 ret {i32, i32} %r 560 } 561