475 lines · plain
1; RUN: llc -O0 -mtriple arm-unknown -mattr=+vfp2,+v4t -global-isel -stop-after=irtranslator -verify-machineinstrs %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=ARM -check-prefix=LITTLE2; RUN: llc -O0 -mtriple armeb-unknown -mattr=+vfp2,+v4t -global-isel -global-isel-abort=0 -enable-arm-gisel-bigendian -stop-after=irtranslator -verify-machineinstrs %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=ARM -check-prefix=BIG3; RUN: llc -O0 -mtriple thumb-unknown -mattr=+vfp2,+v6t2 -global-isel -stop-after=irtranslator -verify-machineinstrs %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=LITTLE -check-prefix=THUMB4 5declare arm_aapcscc ptr @simple_reg_params_target(i32, ptr)6 7define arm_aapcscc ptr @test_call_simple_reg_params(ptr %a, i32 %b) {8; CHECK-LABEL: name: test_call_simple_reg_params9; CHECK-DAG: [[AVREG:%[0-9]+]]:_(p0) = COPY $r010; CHECK-DAG: [[BVREG:%[0-9]+]]:_(s32) = COPY $r111; CHECK: ADJCALLSTACKDOWN 0, 0, 14 /* CC::al */, $noreg, implicit-def $sp, implicit $sp12; CHECK-DAG: $r0 = COPY [[BVREG]]13; CHECK-DAG: $r1 = COPY [[AVREG]]14; ARM: BL @simple_reg_params_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit-def $r015; THUMB: tBL 14 /* CC::al */, $noreg, @simple_reg_params_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit-def $r016; CHECK: [[RVREG:%[0-9]+]]:_(p0) = COPY $r017; CHECK: ADJCALLSTACKUP 0, -1, 14 /* CC::al */, $noreg, implicit-def $sp, implicit $sp18; CHECK: $r0 = COPY [[RVREG]]19; ARM: BX_RET 14 /* CC::al */, $noreg, implicit $r020; THUMB: tBX_RET 14 /* CC::al */, $noreg, implicit $r021entry:22 %r = notail call arm_aapcscc ptr @simple_reg_params_target(i32 %b, ptr %a)23 ret ptr %r24}25 26declare arm_aapcscc ptr @simple_stack_params_target(i32, ptr, i32, ptr, i32, ptr)27 28define arm_aapcscc ptr @test_call_simple_stack_params(ptr %a, i32 %b) {29; CHECK-LABEL: name: test_call_simple_stack_params30; CHECK-DAG: [[AVREG:%[0-9]+]]:_(p0) = COPY $r031; CHECK-DAG: [[BVREG:%[0-9]+]]:_(s32) = COPY $r132; CHECK: ADJCALLSTACKDOWN 8, 0, 14 /* CC::al */, $noreg, implicit-def $sp, implicit $sp33; CHECK: [[SP1:%[0-9]+]]:_(p0) = COPY $sp34; CHECK: [[OFF1:%[0-9]+]]:_(s32) = G_CONSTANT i32 035; CHECK: [[FI1:%[0-9]+]]:_(p0) = G_PTR_ADD [[SP1]], [[OFF1]](s32)36; CHECK: G_STORE [[BVREG]](s32), [[FI1]](p0){{.*}}store (s32)37; CHECK: [[SP2:%[0-9]+]]:_(p0) = COPY $sp38; CHECK: [[OFF2:%[0-9]+]]:_(s32) = G_CONSTANT i32 439; CHECK: [[FI2:%[0-9]+]]:_(p0) = G_PTR_ADD [[SP2]], [[OFF2]](s32)40; CHECK: G_STORE [[AVREG]](p0), [[FI2]](p0){{.*}}store (p0)41; CHECK-DAG: $r0 = COPY [[BVREG]]42; CHECK-DAG: $r1 = COPY [[AVREG]]43; CHECK-DAG: $r2 = COPY [[BVREG]]44; CHECK-DAG: $r3 = COPY [[AVREG]]45; ARM: BL @simple_stack_params_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit $r2, implicit $r3, implicit-def $r046; THUMB: tBL 14 /* CC::al */, $noreg, @simple_stack_params_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit $r2, implicit $r3, implicit-def $r047; CHECK: [[RVREG:%[0-9]+]]:_(p0) = COPY $r048; CHECK: ADJCALLSTACKUP 8, -1, 14 /* CC::al */, $noreg, implicit-def $sp, implicit $sp49; CHECK: $r0 = COPY [[RVREG]]50; ARM: BX_RET 14 /* CC::al */, $noreg, implicit $r051; THUMB: tBX_RET 14 /* CC::al */, $noreg, implicit $r052entry:53 %r = notail call arm_aapcscc ptr @simple_stack_params_target(i32 %b, ptr %a, i32 %b, ptr %a, i32 %b, ptr %a)54 ret ptr %r55}56 57declare arm_aapcscc signext i16 @ext_target(i8 signext, i8 zeroext, i16 signext, i16 zeroext, i8 signext, i8 zeroext, i16 signext, i16 zeroext, i1 zeroext)58 59define arm_aapcscc signext i16 @test_call_ext_params(i8 %a, i16 %b, i1 %c) {60; CHECK-LABEL: name: test_call_ext_params61; CHECK-DAG: [[R0VREG:%[0-9]+]]:_(s32) = COPY $r062; CHECK-DAG: [[AVREG:%[0-9]+]]:_(s8) = G_TRUNC [[R0VREG]]63; CHECK-DAG: [[R1VREG:%[0-9]+]]:_(s32) = COPY $r164; CHECK-DAG: [[BVREG:%[0-9]+]]:_(s16) = G_TRUNC [[R1VREG]]65; CHECK-DAG: [[R2VREG:%[0-9]+]]:_(s32) = COPY $r266; CHECK-DAG: [[CVREG:%[0-9]+]]:_(s1) = G_TRUNC [[R2VREG]]67; CHECK: ADJCALLSTACKDOWN 20, 0, 14 /* CC::al */, $noreg, implicit-def $sp, implicit $sp68; CHECK: [[SEXTA:%[0-9]+]]:_(s32) = G_SEXT [[AVREG]](s8)69; CHECK: [[ZEXTA:%[0-9]+]]:_(s32) = G_ZEXT [[AVREG]](s8)70; CHECK: [[SEXTB:%[0-9]+]]:_(s32) = G_SEXT [[BVREG]](s16)71; CHECK: [[ZEXTB:%[0-9]+]]:_(s32) = G_ZEXT [[BVREG]](s16)72; CHECK: [[SEXTA2:%[0-9]+]]:_(s32) = G_SEXT [[AVREG]]73; CHECK: [[SP1:%[0-9]+]]:_(p0) = COPY $sp74; CHECK: [[OFF1:%[0-9]+]]:_(s32) = G_CONSTANT i32 075; CHECK: [[FI1:%[0-9]+]]:_(p0) = G_PTR_ADD [[SP1]], [[OFF1]](s32)76; CHECK: G_STORE [[SEXTA2]](s32), [[FI1]](p0){{.*}}store (s32)77; CHECK: [[ZEXTA2:%[0-9]+]]:_(s32) = G_ZEXT [[AVREG]]78; CHECK: [[SP2:%[0-9]+]]:_(p0) = COPY $sp79; CHECK: [[OFF2:%[0-9]+]]:_(s32) = G_CONSTANT i32 480; CHECK: [[FI2:%[0-9]+]]:_(p0) = G_PTR_ADD [[SP2]], [[OFF2]](s32)81; CHECK: G_STORE [[ZEXTA2]](s32), [[FI2]](p0){{.*}}store (s32)82; CHECK: [[SEXTB2:%[0-9]+]]:_(s32) = G_SEXT [[BVREG]]83; CHECK: [[SP3:%[0-9]+]]:_(p0) = COPY $sp84; CHECK: [[OFF3:%[0-9]+]]:_(s32) = G_CONSTANT i32 885; CHECK: [[FI3:%[0-9]+]]:_(p0) = G_PTR_ADD [[SP3]], [[OFF3]](s32)86; CHECK: G_STORE [[SEXTB2]](s32), [[FI3]](p0){{.*}}store (s32)87; CHECK: [[ZEXTB2:%[0-9]+]]:_(s32) = G_ZEXT [[BVREG]]88; CHECK: [[SP4:%[0-9]+]]:_(p0) = COPY $sp89; CHECK: [[OFF4:%[0-9]+]]:_(s32) = G_CONSTANT i32 1290; CHECK: [[FI4:%[0-9]+]]:_(p0) = G_PTR_ADD [[SP4]], [[OFF4]](s32)91; CHECK: G_STORE [[ZEXTB2]](s32), [[FI4]](p0){{.*}}store (s32)92; CHECK: [[ZEXTC:%[0-9]+]]:_(s32) = G_ZEXT [[CVREG]]93; CHECK: [[SP5:%[0-9]+]]:_(p0) = COPY $sp94; CHECK: [[OFF5:%[0-9]+]]:_(s32) = G_CONSTANT i32 1695; CHECK: [[FI5:%[0-9]+]]:_(p0) = G_PTR_ADD [[SP5]], [[OFF5]](s32)96; CHECK: G_STORE [[ZEXTC]](s32), [[FI5]](p0){{.*}}store (s32)97; CHECK: $r0 = COPY [[SEXTA]]98; CHECK: $r1 = COPY [[ZEXTA]]99; CHECK: $r2 = COPY [[SEXTB]]100; CHECK: $r3 = COPY [[ZEXTB]]101; ARM: BL @ext_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit $r2, implicit $r3, implicit-def $r0102; THUMB: tBL 14 /* CC::al */, $noreg, @ext_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit $r2, implicit $r3, implicit-def $r0103; CHECK: [[R0VREG:%[0-9]+]]:_(s32) = COPY $r0104; CHECK: [[R0VREG_ASSERT:%[0-9]+]]:_(s32) = G_ASSERT_SEXT [[R0VREG]], 16105; CHECK: [[RVREG:%[0-9]+]]:_(s16) = G_TRUNC [[R0VREG_ASSERT]]106; CHECK: ADJCALLSTACKUP 20, -1, 14 /* CC::al */, $noreg, implicit-def $sp, implicit $sp107; CHECK: [[RExtVREG:%[0-9]+]]:_(s32) = G_SEXT [[RVREG]]108; CHECK: $r0 = COPY [[RExtVREG]]109; ARM: BX_RET 14 /* CC::al */, $noreg, implicit $r0110; THUMB: tBX_RET 14 /* CC::al */, $noreg, implicit $r0111entry:112 %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)113 ret i16 %r114}115 116declare arm_aapcs_vfpcc double @vfpcc_fp_target(float, double)117 118define arm_aapcs_vfpcc double @test_call_vfpcc_fp_params(double %a, float %b) {119; CHECK-LABEL: name: test_call_vfpcc_fp_params120; CHECK-DAG: [[AVREG:%[0-9]+]]:_(s64) = COPY $d0121; CHECK-DAG: [[BVREG:%[0-9]+]]:_(s32) = COPY $s2122; CHECK: ADJCALLSTACKDOWN 0, 0, 14 /* CC::al */, $noreg, implicit-def $sp, implicit $sp123; CHECK-DAG: $s0 = COPY [[BVREG]]124; CHECK-DAG: $d1 = COPY [[AVREG]]125; ARM: BL @vfpcc_fp_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $s0, implicit $d1, implicit-def $d0126; THUMB: tBL 14 /* CC::al */, $noreg, @vfpcc_fp_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $s0, implicit $d1, implicit-def $d0127; CHECK: [[RVREG:%[0-9]+]]:_(s64) = COPY $d0128; CHECK: ADJCALLSTACKUP 0, -1, 14 /* CC::al */, $noreg, implicit-def $sp, implicit $sp129; CHECK: $d0 = COPY [[RVREG]]130; ARM: BX_RET 14 /* CC::al */, $noreg, implicit $d0131; THUMB: tBX_RET 14 /* CC::al */, $noreg, implicit $d0132entry:133 %r = notail call arm_aapcs_vfpcc double @vfpcc_fp_target(float %b, double %a)134 ret double %r135}136 137declare arm_aapcscc double @aapcscc_fp_target(float, double, float, double)138 139define arm_aapcscc double @test_call_aapcs_fp_params(double %a, float %b) {140; CHECK-LABEL: name: test_call_aapcs_fp_params141; CHECK-DAG: [[A1:%[0-9]+]]:_(s32) = COPY $r0142; CHECK-DAG: [[A2:%[0-9]+]]:_(s32) = COPY $r1143; LITTLE-DAG: [[AVREG:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[A1]](s32), [[A2]](s32)144; BIG-DAG: [[AVREG:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[A2]](s32), [[A1]](s32)145; CHECK-DAG: [[BVREG:%[0-9]+]]:_(s32) = COPY $r2146; CHECK: ADJCALLSTACKDOWN 16, 0, 14 /* CC::al */, $noreg, implicit-def $sp, implicit $sp147; CHECK-DAG: [[A1:%[0-9]+]]:_(s32), [[A2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[AVREG]](s64)148; CHECK: [[SP1:%[0-9]+]]:_(p0) = COPY $sp149; CHECK: [[OFF1:%[0-9]+]]:_(s32) = G_CONSTANT i32 0150; CHECK: [[FI1:%[0-9]+]]:_(p0) = G_PTR_ADD [[SP1]], [[OFF1]](s32)151; CHECK: G_STORE [[BVREG]](s32), [[FI1]](p0){{.*}}store (s32)152; CHECK: [[SP2:%[0-9]+]]:_(p0) = COPY $sp153; CHECK: [[OFF2:%[0-9]+]]:_(s32) = G_CONSTANT i32 8154; CHECK: [[FI2:%[0-9]+]]:_(p0) = G_PTR_ADD [[SP2]], [[OFF2]](s32)155; CHECK: G_STORE [[AVREG]](s64), [[FI2]](p0){{.*}}store (s64)156; CHECK-DAG: $r0 = COPY [[BVREG]]157; LITTLE-DAG: $r2 = COPY [[A1]]158; LITTLE-DAG: $r3 = COPY [[A2]]159; BIG-DAG: $r2 = COPY [[A2]]160; BIG-DAG: $r3 = COPY [[A1]]161; ARM: BL @aapcscc_fp_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r2, implicit $r3, implicit-def $r0, implicit-def $r1162; THUMB: tBL 14 /* CC::al */, $noreg, @aapcscc_fp_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r2, implicit $r3, implicit-def $r0, implicit-def $r1163; CHECK-DAG: [[R1:%[0-9]+]]:_(s32) = COPY $r0164; CHECK-DAG: [[R2:%[0-9]+]]:_(s32) = COPY $r1165; LITTLE: [[RVREG:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[R1]](s32), [[R2]](s32)166; BIG: [[RVREG:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[R2]](s32), [[R1]](s32)167; CHECK: ADJCALLSTACKUP 16, -1, 14 /* CC::al */, $noreg, implicit-def $sp, implicit $sp168; CHECK: [[R1:%[0-9]+]]:_(s32), [[R2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[RVREG]](s64)169; LITTLE-DAG: $r0 = COPY [[R1]]170; LITTLE-DAG: $r1 = COPY [[R2]]171; BIG-DAG: $r0 = COPY [[R2]]172; BIG-DAG: $r1 = COPY [[R1]]173; ARM: BX_RET 14 /* CC::al */, $noreg, implicit $r0, implicit $r1174; THUMB: tBX_RET 14 /* CC::al */, $noreg, implicit $r0, implicit $r1175entry:176 %r = notail call arm_aapcscc double @aapcscc_fp_target(float %b, double %a, float %b, double %a)177 ret double %r178}179 180declare arm_aapcscc float @different_call_conv_target(float)181 182define arm_aapcs_vfpcc float @test_call_different_call_conv(float %x) {183; CHECK-LABEL: name: test_call_different_call_conv184; CHECK: [[X:%[0-9]+]]:_(s32) = COPY $s0185; CHECK: ADJCALLSTACKDOWN 0, 0, 14 /* CC::al */, $noreg, implicit-def $sp, implicit $sp186; CHECK: $r0 = COPY [[X]]187; ARM: BL @different_call_conv_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit-def $r0188; THUMB: tBL 14 /* CC::al */, $noreg, @different_call_conv_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit-def $r0189; CHECK: [[R:%[0-9]+]]:_(s32) = COPY $r0190; CHECK: ADJCALLSTACKUP 0, -1, 14 /* CC::al */, $noreg, implicit-def $sp, implicit $sp191; CHECK: $s0 = COPY [[R]]192; ARM: BX_RET 14 /* CC::al */, $noreg, implicit $s0193; THUMB: tBX_RET 14 /* CC::al */, $noreg, implicit $s0194entry:195 %r = notail call arm_aapcscc float @different_call_conv_target(float %x)196 ret float %r197}198 199declare arm_aapcscc [3 x i32] @tiny_int_arrays_target([2 x i32])200 201define arm_aapcscc [3 x i32] @test_tiny_int_arrays([2 x i32] %arr) {202; CHECK-LABEL: name: test_tiny_int_arrays203; CHECK: liveins: $r0, $r1204; CHECK: [[R0:%[0-9]+]]:_(s32) = COPY $r0205; CHECK: [[R1:%[0-9]+]]:_(s32) = COPY $r1206; CHECK: ADJCALLSTACKDOWN 0, 0, 14 /* CC::al */, $noreg, implicit-def $sp, implicit $sp207; CHECK: $r0 = COPY [[R0]]208; CHECK: $r1 = COPY [[R1]]209; ARM: BL @tiny_int_arrays_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit-def $r0, implicit-def $r1210; THUMB: tBL 14 /* CC::al */, $noreg, @tiny_int_arrays_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit-def $r0, implicit-def $r1211; CHECK: [[R0:%[0-9]+]]:_(s32) = COPY $r0212; CHECK: [[R1:%[0-9]+]]:_(s32) = COPY $r1213; CHECK: [[R2:%[0-9]+]]:_(s32) = COPY $r2214; CHECK: ADJCALLSTACKUP 0, -1, 14 /* CC::al */, $noreg, implicit-def $sp, implicit $sp215; FIXME: This doesn't seem correct with regard to the AAPCS docs (which say216; that composite types larger than 4 bytes should be passed through memory),217; but it's what DAGISel does. We should fix it in the common code for both.218; CHECK: $r0 = COPY [[R0]]219; CHECK: $r1 = COPY [[R1]]220; CHECK: $r2 = COPY [[R2]]221; ARM: BX_RET 14 /* CC::al */, $noreg, implicit $r0, implicit $r1, implicit $r2222; THUMB: tBX_RET 14 /* CC::al */, $noreg, implicit $r0, implicit $r1, implicit $r2223entry:224 %r = notail call arm_aapcscc [3 x i32] @tiny_int_arrays_target([2 x i32] %arr)225 ret [3 x i32] %r226}227 228declare arm_aapcscc void @multiple_int_arrays_target([2 x i32], [2 x i32])229 230define arm_aapcscc void @test_multiple_int_arrays([2 x i32] %arr0, [2 x i32] %arr1) {231; CHECK-LABEL: name: test_multiple_int_arrays232; CHECK: liveins: $r0, $r1233; CHECK: [[R0:%[0-9]+]]:_(s32) = COPY $r0234; CHECK: [[R1:%[0-9]+]]:_(s32) = COPY $r1235; CHECK: [[R2:%[0-9]+]]:_(s32) = COPY $r2236; CHECK: [[R3:%[0-9]+]]:_(s32) = COPY $r3237; CHECK: ADJCALLSTACKDOWN 0, 0, 14 /* CC::al */, $noreg, implicit-def $sp, implicit $sp238; CHECK: $r0 = COPY [[R0]]239; CHECK: $r1 = COPY [[R1]]240; CHECK: $r2 = COPY [[R2]]241; CHECK: $r3 = COPY [[R3]]242; ARM: BL @multiple_int_arrays_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit $r2, implicit $r3243; THUMB: tBL 14 /* CC::al */, $noreg, @multiple_int_arrays_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit $r2, implicit $r3244; CHECK: ADJCALLSTACKUP 0, -1, 14 /* CC::al */, $noreg, implicit-def $sp, implicit $sp245; ARM: BX_RET 14 /* CC::al */, $noreg246; THUMB: tBX_RET 14 /* CC::al */, $noreg247entry:248 notail call arm_aapcscc void @multiple_int_arrays_target([2 x i32] %arr0, [2 x i32] %arr1)249 ret void250}251 252declare arm_aapcscc void @large_int_arrays_target([20 x i32])253 254define arm_aapcscc void @test_large_int_arrays([20 x i32] %arr) {255; CHECK-LABEL: name: test_large_int_arrays256; CHECK: fixedStack:257; The parameters live in separate stack locations, one for each element that258; doesn't fit in the registers.259; CHECK-DAG: id: [[FIRST_STACK_ID:[0-9]+]], type: default, offset: 0, size: 4,260; CHECK-DAG: id: [[LAST_STACK_ID:[-0]+]], type: default, offset: 60, size: 4261; CHECK: liveins: $r0, $r1, $r2, $r3262; CHECK-DAG: [[R0:%[0-9]+]]:_(s32) = COPY $r0263; CHECK-DAG: [[R1:%[0-9]+]]:_(s32) = COPY $r1264; CHECK-DAG: [[R2:%[0-9]+]]:_(s32) = COPY $r2265; CHECK-DAG: [[R3:%[0-9]+]]:_(s32) = COPY $r3266; CHECK: [[FIRST_STACK_ELEMENT_FI:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[FIRST_STACK_ID]]267; CHECK: [[FIRST_STACK_ELEMENT:%[0-9]+]]:_(s32) = G_LOAD [[FIRST_STACK_ELEMENT_FI]]{{.*}}load (s32) from %fixed-stack.[[FIRST_STACK_ID]]268; CHECK: [[LAST_STACK_ELEMENT_FI:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[LAST_STACK_ID]]269; CHECK: [[LAST_STACK_ELEMENT:%[0-9]+]]:_(s32) = G_LOAD [[LAST_STACK_ELEMENT_FI]]{{.*}}load (s32) from %fixed-stack.[[LAST_STACK_ID]]270; CHECK: ADJCALLSTACKDOWN 64, 0, 14 /* CC::al */, $noreg, implicit-def $sp, implicit $sp271; CHECK: [[SP:%[0-9]+]]:_(p0) = COPY $sp272; CHECK: [[OFF_FIRST_ELEMENT:%[0-9]+]]:_(s32) = G_CONSTANT i32 0273; CHECK: [[FIRST_STACK_ARG_ADDR:%[0-9]+]]:_(p0) = G_PTR_ADD [[SP]], [[OFF_FIRST_ELEMENT]](s32)274; CHECK: G_STORE [[FIRST_STACK_ELEMENT]](s32), [[FIRST_STACK_ARG_ADDR]]{{.*}}store (s32)275; Match the second-to-last offset, so we can get the correct SP for the last element276; CHECK: G_CONSTANT i32 56277; CHECK: [[SP:%[0-9]+]]:_(p0) = COPY $sp278; CHECK: [[OFF_LAST_ELEMENT:%[0-9]+]]:_(s32) = G_CONSTANT i32 60279; CHECK: [[LAST_STACK_ARG_ADDR:%[0-9]+]]:_(p0) = G_PTR_ADD [[SP]], [[OFF_LAST_ELEMENT]](s32)280; CHECK: G_STORE [[LAST_STACK_ELEMENT]](s32), [[LAST_STACK_ARG_ADDR]]{{.*}}store (s32)281; CHECK: $r0 = COPY [[R0]]282; CHECK: $r1 = COPY [[R1]]283; CHECK: $r2 = COPY [[R2]]284; CHECK: $r3 = COPY [[R3]]285; ARM: BL @large_int_arrays_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit $r2, implicit $r3286; THUMB: tBL 14 /* CC::al */, $noreg, @large_int_arrays_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit $r2, implicit $r3287; CHECK: ADJCALLSTACKUP 64, -1, 14 /* CC::al */, $noreg, implicit-def $sp, implicit $sp288; ARM: BX_RET 14 /* CC::al */, $noreg289; THUMB: tBX_RET 14 /* CC::al */, $noreg290entry:291 notail call arm_aapcscc void @large_int_arrays_target([20 x i32] %arr)292 ret void293}294 295declare arm_aapcscc [2 x float] @fp_arrays_aapcs_target([3 x double])296 297define arm_aapcscc [2 x float] @test_fp_arrays_aapcs([3 x double] %arr) {298; CHECK-LABEL: name: test_fp_arrays_aapcs299; CHECK: fixedStack:300; CHECK: id: [[ARR2_ID:[0-9]+]], type: default, offset: 0, size: 8,301; CHECK: liveins: $r0, $r1, $r2, $r3302; CHECK: [[ARR0_0:%[0-9]+]]:_(s32) = COPY $r0303; CHECK: [[ARR0_1:%[0-9]+]]:_(s32) = COPY $r1304; LITTLE: [[ARR0:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[ARR0_0]](s32), [[ARR0_1]](s32)305; BIG: [[ARR0:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[ARR0_1]](s32), [[ARR0_0]](s32)306; CHECK: [[ARR1_0:%[0-9]+]]:_(s32) = COPY $r2307; CHECK: [[ARR1_1:%[0-9]+]]:_(s32) = COPY $r3308; LITTLE: [[ARR1:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[ARR1_0]](s32), [[ARR1_1]](s32)309; BIG: [[ARR1:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[ARR1_1]](s32), [[ARR1_0]](s32)310; CHECK: [[ARR2_FI:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[ARR2_ID]]311; CHECK: [[ARR2:%[0-9]+]]:_(s64) = G_LOAD [[ARR2_FI]]{{.*}}load (s64) from %fixed-stack.[[ARR2_ID]]312; CHECK: ADJCALLSTACKDOWN 8, 0, 14 /* CC::al */, $noreg, implicit-def $sp, implicit $sp313; CHECK: [[ARR0_0:%[0-9]+]]:_(s32), [[ARR0_1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[ARR0]](s64)314; CHECK: [[ARR1_0:%[0-9]+]]:_(s32), [[ARR1_1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[ARR1]](s64)315; CHECK: [[SP:%[0-9]+]]:_(p0) = COPY $sp316; CHECK: [[ARR2_OFFSET:%[0-9]+]]:_(s32) = G_CONSTANT i32 0317; CHECK: [[ARR2_ADDR:%[0-9]+]]:_(p0) = G_PTR_ADD [[SP]], [[ARR2_OFFSET]](s32)318; CHECK: G_STORE [[ARR2]](s64), [[ARR2_ADDR]](p0){{.*}}store (s64)319; LITTLE: $r0 = COPY [[ARR0_0]](s32)320; LITTLE: $r1 = COPY [[ARR0_1]](s32)321; BIG: $r0 = COPY [[ARR0_1]](s32)322; BIG: $r1 = COPY [[ARR0_0]](s32)323; LITTLE: $r2 = COPY [[ARR1_0]](s32)324; LITTLE: $r3 = COPY [[ARR1_1]](s32)325; BIG: $r2 = COPY [[ARR1_1]](s32)326; BIG: $r3 = COPY [[ARR1_0]](s32)327; ARM: 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 $r1328; THUMB: tBL 14 /* CC::al */, $noreg, @fp_arrays_aapcs_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit $r2, implicit $r3, implicit-def $r0, implicit-def $r1329; CHECK: [[R0:%[0-9]+]]:_(s32) = COPY $r0330; CHECK: [[R1:%[0-9]+]]:_(s32) = COPY $r1331; CHECK: ADJCALLSTACKUP 8, -1, 14 /* CC::al */, $noreg, implicit-def $sp, implicit $sp332; CHECK: $r0 = COPY [[R0]]333; CHECK: $r1 = COPY [[R1]]334; ARM: BX_RET 14 /* CC::al */, $noreg, implicit $r0, implicit $r1335; THUMB: tBX_RET 14 /* CC::al */, $noreg, implicit $r0, implicit $r1336entry:337 %r = notail call arm_aapcscc [2 x float] @fp_arrays_aapcs_target([3 x double] %arr)338 ret [2 x float] %r339}340 341declare arm_aapcs_vfpcc [4 x float] @fp_arrays_aapcs_vfp_target([3 x double], [3 x float], [4 x double])342 343define arm_aapcs_vfpcc [4 x float] @test_fp_arrays_aapcs_vfp([3 x double] %x, [3 x float] %y, [4 x double] %z) {344; CHECK-LABEL: name: test_fp_arrays_aapcs_vfp345; CHECK: fixedStack:346; CHECK-DAG: id: [[Z0_ID:[0-9]+]], type: default, offset: 0, size: 8,347; CHECK-DAG: id: [[Z1_ID:[0-9]+]], type: default, offset: 8, size: 8,348; CHECK-DAG: id: [[Z2_ID:[0-9]+]], type: default, offset: 16, size: 8,349; CHECK-DAG: id: [[Z3_ID:[0-9]+]], type: default, offset: 24, size: 8,350; CHECK: liveins: $d0, $d1, $d2, $s6, $s7, $s8351; CHECK: [[X0:%[0-9]+]]:_(s64) = COPY $d0352; CHECK: [[X1:%[0-9]+]]:_(s64) = COPY $d1353; CHECK: [[X2:%[0-9]+]]:_(s64) = COPY $d2354; CHECK: [[Y0:%[0-9]+]]:_(s32) = COPY $s6355; CHECK: [[Y1:%[0-9]+]]:_(s32) = COPY $s7356; CHECK: [[Y2:%[0-9]+]]:_(s32) = COPY $s8357; CHECK: [[Z0_FI:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[Z0_ID]]358; CHECK: [[Z0:%[0-9]+]]:_(s64) = G_LOAD [[Z0_FI]]{{.*}}load (s64)359; CHECK: [[Z1_FI:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[Z1_ID]]360; CHECK: [[Z1:%[0-9]+]]:_(s64) = G_LOAD [[Z1_FI]]{{.*}}load (s64)361; CHECK: [[Z2_FI:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[Z2_ID]]362; CHECK: [[Z2:%[0-9]+]]:_(s64) = G_LOAD [[Z2_FI]]{{.*}}load (s64)363; CHECK: [[Z3_FI:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[Z3_ID]]364; CHECK: [[Z3:%[0-9]+]]:_(s64) = G_LOAD [[Z3_FI]]{{.*}}load (s64)365; CHECK: ADJCALLSTACKDOWN 32, 0, 14 /* CC::al */, $noreg, implicit-def $sp, implicit $sp366; CHECK: [[SP:%[0-9]+]]:_(p0) = COPY $sp367; CHECK: [[Z0_OFFSET:%[0-9]+]]:_(s32) = G_CONSTANT i32 0368; CHECK: [[Z0_ADDR:%[0-9]+]]:_(p0) = G_PTR_ADD [[SP]], [[Z0_OFFSET]](s32)369; CHECK: G_STORE [[Z0]](s64), [[Z0_ADDR]](p0){{.*}}store (s64)370; CHECK: [[SP:%[0-9]+]]:_(p0) = COPY $sp371; CHECK: [[Z1_OFFSET:%[0-9]+]]:_(s32) = G_CONSTANT i32 8372; CHECK: [[Z1_ADDR:%[0-9]+]]:_(p0) = G_PTR_ADD [[SP]], [[Z1_OFFSET]](s32)373; CHECK: G_STORE [[Z1]](s64), [[Z1_ADDR]](p0){{.*}}store (s64)374; CHECK: [[SP:%[0-9]+]]:_(p0) = COPY $sp375; CHECK: [[Z2_OFFSET:%[0-9]+]]:_(s32) = G_CONSTANT i32 16376; CHECK: [[Z2_ADDR:%[0-9]+]]:_(p0) = G_PTR_ADD [[SP]], [[Z2_OFFSET]](s32)377; CHECK: G_STORE [[Z2]](s64), [[Z2_ADDR]](p0){{.*}}store (s64)378; CHECK: [[SP:%[0-9]+]]:_(p0) = COPY $sp379; CHECK: [[Z3_OFFSET:%[0-9]+]]:_(s32) = G_CONSTANT i32 24380; CHECK: [[Z3_ADDR:%[0-9]+]]:_(p0) = G_PTR_ADD [[SP]], [[Z3_OFFSET]](s32)381; CHECK: G_STORE [[Z3]](s64), [[Z3_ADDR]](p0){{.*}}store (s64)382; CHECK: $d0 = COPY [[X0]](s64)383; CHECK: $d1 = COPY [[X1]](s64)384; CHECK: $d2 = COPY [[X2]](s64)385; CHECK: $s6 = COPY [[Y0]](s32)386; CHECK: $s7 = COPY [[Y1]](s32)387; CHECK: $s8 = COPY [[Y2]](s32)388; ARM: 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 $s3389; THUMB: tBL 14 /* CC::al */, $noreg, @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 $s3390; CHECK: [[R0:%[0-9]+]]:_(s32) = COPY $s0391; CHECK: [[R1:%[0-9]+]]:_(s32) = COPY $s1392; CHECK: [[R2:%[0-9]+]]:_(s32) = COPY $s2393; CHECK: [[R3:%[0-9]+]]:_(s32) = COPY $s3394; CHECK: ADJCALLSTACKUP 32, -1, 14 /* CC::al */, $noreg, implicit-def $sp, implicit $sp395; CHECK: $s0 = COPY [[R0]]396; CHECK: $s1 = COPY [[R1]]397; CHECK: $s2 = COPY [[R2]]398; CHECK: $s3 = COPY [[R3]]399; ARM: BX_RET 14 /* CC::al */, $noreg, implicit $s0, implicit $s1, implicit $s2, implicit $s3400; THUMB: tBX_RET 14 /* CC::al */, $noreg, implicit $s0, implicit $s1, implicit $s2, implicit $s3401entry:402 %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)403 ret [4 x float] %r404}405 406declare arm_aapcscc [2 x ptr] @tough_arrays_target([6 x [4 x i32]] %arr)407 408define arm_aapcscc [2 x ptr] @test_tough_arrays([6 x [4 x i32]] %arr) {409; CHECK-LABEL: name: test_tough_arrays410; CHECK: fixedStack:411; The parameters live in separate stack locations, one for each element that412; doesn't fit in the registers.413; CHECK-DAG: id: [[FIRST_STACK_ID:[0-9]+]], type: default, offset: 0, size: 4,414; CHECK-DAG: id: [[LAST_STACK_ID:[-0]+]], type: default, offset: 76, size: 4415; CHECK: liveins: $r0, $r1, $r2, $r3416; CHECK-DAG: [[R0:%[0-9]+]]:_(s32) = COPY $r0417; CHECK-DAG: [[R1:%[0-9]+]]:_(s32) = COPY $r1418; CHECK-DAG: [[R2:%[0-9]+]]:_(s32) = COPY $r2419; CHECK-DAG: [[R3:%[0-9]+]]:_(s32) = COPY $r3420; CHECK: [[FIRST_STACK_ELEMENT_FI:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[FIRST_STACK_ID]]421; CHECK: [[FIRST_STACK_ELEMENT:%[0-9]+]]:_(s32) = G_LOAD [[FIRST_STACK_ELEMENT_FI]]{{.*}}load (s32) from %fixed-stack.[[FIRST_STACK_ID]]422; CHECK: [[LAST_STACK_ELEMENT_FI:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.[[LAST_STACK_ID]]423; CHECK: [[LAST_STACK_ELEMENT:%[0-9]+]]:_(s32) = G_LOAD [[LAST_STACK_ELEMENT_FI]]{{.*}}load (s32) from %fixed-stack.[[LAST_STACK_ID]]424; CHECK: ADJCALLSTACKDOWN 80, 0, 14 /* CC::al */, $noreg, implicit-def $sp, implicit $sp425; CHECK: [[SP:%[0-9]+]]:_(p0) = COPY $sp426; CHECK: [[OFF_FIRST_ELEMENT:%[0-9]+]]:_(s32) = G_CONSTANT i32 0427; CHECK: [[FIRST_STACK_ARG_ADDR:%[0-9]+]]:_(p0) = G_PTR_ADD [[SP]], [[OFF_FIRST_ELEMENT]](s32)428; CHECK: G_STORE [[FIRST_STACK_ELEMENT]](s32), [[FIRST_STACK_ARG_ADDR]]{{.*}}store (s32)429; Match the second-to-last offset, so we can get the correct SP for the last element430; CHECK: G_CONSTANT i32 72431; CHECK: [[SP:%[0-9]+]]:_(p0) = COPY $sp432; CHECK: [[OFF_LAST_ELEMENT:%[0-9]+]]:_(s32) = G_CONSTANT i32 76433; CHECK: [[LAST_STACK_ARG_ADDR:%[0-9]+]]:_(p0) = G_PTR_ADD [[SP]], [[OFF_LAST_ELEMENT]](s32)434; CHECK: G_STORE [[LAST_STACK_ELEMENT]](s32), [[LAST_STACK_ARG_ADDR]]{{.*}}store (s32)435; CHECK: $r0 = COPY [[R0]]436; CHECK: $r1 = COPY [[R1]]437; CHECK: $r2 = COPY [[R2]]438; CHECK: $r3 = COPY [[R3]]439; ARM: BL @tough_arrays_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit $r2, implicit $r3, implicit-def $r0, implicit-def $r1440; THUMB: tBL 14 /* CC::al */, $noreg, @tough_arrays_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit $r2, implicit $r3, implicit-def $r0, implicit-def $r1441; CHECK: [[R0:%[0-9]+]]:_(p0) = COPY $r0442; CHECK: [[R1:%[0-9]+]]:_(p0) = COPY $r1443; CHECK: ADJCALLSTACKUP 80, -1, 14 /* CC::al */, $noreg, implicit-def $sp, implicit $sp444; CHECK: $r0 = COPY [[R0]]445; CHECK: $r1 = COPY [[R1]]446; ARM: BX_RET 14 /* CC::al */, $noreg, implicit $r0, implicit $r1447; THUMB: tBX_RET 14 /* CC::al */, $noreg, implicit $r0, implicit $r1448entry:449 %r = notail call arm_aapcscc [2 x ptr] @tough_arrays_target([6 x [4 x i32]] %arr)450 ret [2 x ptr] %r451}452 453declare arm_aapcscc {i32, i32} @structs_target({i32, i32})454 455define arm_aapcscc {i32, i32} @test_structs({i32, i32} %x) {456; CHECK-LABEL: test_structs457; CHECK: liveins: $r0, $r1458; CHECK-DAG: [[X0:%[0-9]+]]:_(s32) = COPY $r0459; CHECK-DAG: [[X1:%[0-9]+]]:_(s32) = COPY $r1460; CHECK: ADJCALLSTACKDOWN 0, 0, 14 /* CC::al */, $noreg, implicit-def $sp, implicit $sp461; CHECK-DAG: $r0 = COPY [[X0]](s32)462; CHECK-DAG: $r1 = COPY [[X1]](s32)463; ARM: BL @structs_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit-def $r0, implicit-def $r1464; THUMB: tBL 14 /* CC::al */, $noreg, @structs_target, csr_aapcs, implicit-def $lr, implicit $sp, implicit $r0, implicit $r1, implicit-def $r0, implicit-def $r1465; CHECK: [[R0:%[0-9]+]]:_(s32) = COPY $r0466; CHECK: [[R1:%[0-9]+]]:_(s32) = COPY $r1467; CHECK: ADJCALLSTACKUP 0, -1, 14 /* CC::al */, $noreg, implicit-def $sp, implicit $sp468; CHECK: $r0 = COPY [[R0]](s32)469; CHECK: $r1 = COPY [[R1]](s32)470; ARM: BX_RET 14 /* CC::al */, $noreg, implicit $r0, implicit $r1471; THUMB: tBX_RET 14 /* CC::al */, $noreg, implicit $r0, implicit $r1472 %r = notail call arm_aapcscc {i32, i32} @structs_target({i32, i32} %x)473 ret {i32, i32} %r474}475