Home | History | Annotate | Download | only in GlobalISel
      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