315 lines · plain
1; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve -stop-after=finalize-isel < %s | FileCheck %s --check-prefixes=CHECK,LINUX2; RUN: llc -mtriple=aarch64-apple-darwin -mattr=+sve -stop-after=finalize-isel < %s | FileCheck %s --check-prefixes=CHECK,DARWIN3 4; Test that z8 and z9, passed in by reference, are correctly loaded from x0 and x1.5; i.e. z0 = %z06; :7; z7 = %z78; x0 = &%z89; x1 = &%z910define aarch64_sve_vector_pcs <vscale x 4 x i32> @callee_with_many_sve_arg(<vscale x 4 x i32> %z0, <vscale x 4 x i32> %z1, <vscale x 4 x i32> %z2, <vscale x 4 x i32> %z3, <vscale x 4 x i32> %z4, <vscale x 4 x i32> %z5, <vscale x 4 x i32> %z6, <vscale x 4 x i32> %z7, <vscale x 4 x i32> %z8, <vscale x 4 x i32> %z9) {11; CHECK: name: callee_with_many_sve_arg12; CHECK-DAG: [[BASE:%[0-9]+]]:gpr64common = COPY $x113; CHECK-DAG: [[RES:%[0-9]+]]:zpr = LDR_ZXI [[BASE]], 014; CHECK-DAG: $z0 = COPY [[RES]]15; CHECK: RET_ReallyLR implicit $z016 ret <vscale x 4 x i32> %z917}18 19; Test that z8 and z9 are passed by reference.20define aarch64_sve_vector_pcs <vscale x 4 x i32> @caller_with_many_sve_arg(<vscale x 4 x i32> %z) {21; CHECK: name: caller_with_many_sve_arg22; CHECK: stack:23; CHECK: - { id: 0, name: '', type: default, offset: 0, size: 16, alignment: 16,24; CHECK-NEXT: stack-id: scalable-vector25; CHECK: - { id: 1, name: '', type: default, offset: 0, size: 16, alignment: 16,26; CHECK-NEXT: stack-id: scalable-vector27; CHECK-DAG: STR_ZXI %{{[0-9]+}}, %stack.1, 028; CHECK-DAG: STR_ZXI %{{[0-9]+}}, %stack.0, 029; CHECK-DAG: [[BASE2:%[0-9]+]]:gpr64sp = ADDXri %stack.1, 030; CHECK-DAG: [[BASE1:%[0-9]+]]:gpr64sp = ADDXri %stack.0, 031; CHECK-DAG: $x0 = COPY [[BASE1]]32; CHECK-DAG: $x1 = COPY [[BASE2]]33; CHECK-NEXT: BL @callee_with_many_sve_arg34; CHECK: RET_ReallyLR implicit $z035 %ret = call aarch64_sve_vector_pcs <vscale x 4 x i32> @callee_with_many_sve_arg(<vscale x 4 x i32> %z, <vscale x 4 x i32> %z, <vscale x 4 x i32> %z, <vscale x 4 x i32> %z, <vscale x 4 x i32> %z, <vscale x 4 x i32> %z, <vscale x 4 x i32> %z, <vscale x 4 x i32> %z, <vscale x 4 x i32> %z, <vscale x 4 x i32> %z)36 ret <vscale x 4 x i32> %ret37}38 39; Test that p4 and p5, passed in by reference, are correctly loaded from register x0 and x1.40; i.e. p0 = %p041; :42; p3 = %p343; x0 = &%p444; x1 = &%p545define aarch64_sve_vector_pcs <vscale x 16 x i1> @callee_with_many_svepred_arg(<vscale x 16 x i1> %p0, <vscale x 16 x i1> %p1, <vscale x 16 x i1> %p2, <vscale x 16 x i1> %p3, <vscale x 16 x i1> %p4, <vscale x 16 x i1> %p5) {46; CHECK: name: callee_with_many_svepred_arg47; CHECK-DAG: [[BASE:%[0-9]+]]:gpr64common = COPY $x148; CHECK-DAG: [[RES:%[0-9]+]]:ppr = LDR_PXI [[BASE]], 049; CHECK-DAG: $p0 = COPY [[RES]]50; CHECK: RET_ReallyLR implicit $p051 ret <vscale x 16 x i1> %p552}53 54; Test that p4 and p5 are passed by reference.55define aarch64_sve_vector_pcs <vscale x 16 x i1> @caller_with_many_svepred_arg(<vscale x 16 x i1> %p) {56; CHECK: name: caller_with_many_svepred_arg57; CHECK: stack:58; CHECK: - { id: 0, name: '', type: default, offset: 0, size: 2, alignment: 2,59; CHECK-NEXT: stack-id: scalable-predicate-vector60; CHECK: - { id: 1, name: '', type: default, offset: 0, size: 2, alignment: 2,61; CHECK-NEXT: stack-id: scalable-predicate-vector62; CHECK-DAG: STR_PXI %{{[0-9]+}}, %stack.0, 063; CHECK-DAG: STR_PXI %{{[0-9]+}}, %stack.1, 064; CHECK-DAG: [[BASE1:%[0-9]+]]:gpr64sp = ADDXri %stack.0, 065; CHECK-DAG: [[BASE2:%[0-9]+]]:gpr64sp = ADDXri %stack.1, 066; CHECK-DAG: $x0 = COPY [[BASE1]]67; CHECK-DAG: $x1 = COPY [[BASE2]]68; CHECK-NEXT: BL @callee_with_many_svepred_arg69; CHECK: RET_ReallyLR implicit $p070 %ret = call aarch64_sve_vector_pcs <vscale x 16 x i1> @callee_with_many_svepred_arg(<vscale x 16 x i1> %p, <vscale x 16 x i1> %p, <vscale x 16 x i1> %p, <vscale x 16 x i1> %p, <vscale x 16 x i1> %p, <vscale x 16 x i1> %p)71 ret <vscale x 16 x i1> %ret72}73 74; Test that arg2 is passed through x0, i.e., x0 = &%arg2; and return values are loaded from x0:75; P0 = ldr [x0]76define aarch64_sve_vector_pcs <vscale x 16 x i1> @callee_with_svepred_arg_4xv16i1_1xv16i1([4 x <vscale x 16 x i1>] %arg1, [1 x <vscale x 16 x i1>] %arg2) {77; CHECK: name: callee_with_svepred_arg_4xv16i1_1xv16i178; CHECK: [[BASE:%[0-9]+]]:gpr64common = COPY $x079; CHECK: [[PRED0:%[0-9]+]]:ppr = LDR_PXI [[BASE]], 0 :: (load (<vscale x 1 x s16>))80; CHECK: $p0 = COPY [[PRED0]]81; CHECK: RET_ReallyLR implicit $p082 %res = extractvalue [1 x <vscale x 16 x i1>] %arg2, 083 ret <vscale x 16 x i1> %res84}85 86; Test that arg1 is stored to the stack from p0; and the stack location is passed throuch x0 to setup the call:87; str P0, [stack_loc_for_args]88; x0 = stack_loc_for_args89define aarch64_sve_vector_pcs <vscale x 16 x i1> @caller_with_svepred_arg_1xv16i1_4xv16i1([1 x <vscale x 16 x i1>] %arg1, [4 x <vscale x 16 x i1>] %arg2) {90; CHECK: name: caller_with_svepred_arg_1xv16i1_4xv16i191; CHECK: stack:92; CHECK: - { id: 0, name: '', type: default, offset: 0, size: 2, alignment: 2,93; CHECK-NEXT: stack-id: scalable-predicate-vector,94; CHECK: [[PRED0:%[0-9]+]]:ppr = COPY $p095; CHECK: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp96; CHECK: STR_PXI [[PRED0]], %stack.0, 0 :: (store (<vscale x 1 x s16>) into %stack.0)97; CHECK: [[STACK:%[0-9]+]]:gpr64sp = ADDXri %stack.0, 0, 098; CHECK: $x0 = COPY [[STACK]]99; LINUX: BL @callee_with_svepred_arg_4xv16i1_1xv16i1, csr_aarch64_sve_aapcs, implicit-def dead $lr, implicit $sp, implicit $p0, implicit $p1, implicit $p2, implicit $p3, implicit $x0, implicit-def $sp, implicit-def $p0100; DARWIN: BL @callee_with_svepred_arg_4xv16i1_1xv16i1, csr_darwin_aarch64_sve_aapcs, implicit-def dead $lr, implicit $sp, implicit $p0, implicit $p1, implicit $p2, implicit $p3, implicit $x0, implicit-def $sp, implicit-def $p0101; CHECK: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp102 %res = call <vscale x 16 x i1> @callee_with_svepred_arg_4xv16i1_1xv16i1([4 x <vscale x 16 x i1>] %arg2, [1 x <vscale x 16 x i1>] %arg1)103 ret <vscale x 16 x i1> %res104}105 106; Test that arg2 is passed through x0, i.e., x0 = &%arg2; and return values are loaded from x0:107; P0 = ldr [x0]108; P1 = ldr [x0 + sizeof(Px)]109; P2 = ldr [x0 + 2*sizeof(Px)]110; P3 = ldr [x0 + 3*sizeof(Px)]111define aarch64_sve_vector_pcs [4 x <vscale x 16 x i1>] @callee_with_svepred_arg_4xv16i1_4xv16i1([4 x <vscale x 16 x i1>] %arg1, [4 x <vscale x 16 x i1>] %arg2) {112; CHECK: name: callee_with_svepred_arg_4xv16i1_4xv16i1113; CHECK: [[BASE:%[0-9]+]]:gpr64common = COPY $x0114; CHECK: [[OFFSET1:%[0-9]+]]:gpr64 = CNTD_XPiI 31, 1, implicit $vg115; CHECK: [[ADDR1:%[0-9]+]]:gpr64common = nuw ADDXrr [[BASE]], killed [[OFFSET1]]116; CHECK: [[PRED1:%[0-9]+]]:ppr = LDR_PXI killed [[ADDR1]], 0 :: (load (<vscale x 1 x s16>))117; CHECK: [[OFFSET2:%[0-9]+]]:gpr64 = CNTW_XPiI 31, 1, implicit $vg118; CHECK: [[ADDR2:%[0-9]+]]:gpr64common = ADDXrr [[BASE]], killed [[OFFSET2]]119; CHECK: [[PRED2:%[0-9]+]]:ppr = LDR_PXI killed [[ADDR2]], 0 :: (load (<vscale x 1 x s16>))120; CHECK: [[OFFSET3:%[0-9]+]]:gpr64 = CNTD_XPiI 31, 3, implicit $vg121; CHECK: [[ADDR3:%[0-9]+]]:gpr64common = ADDXrr [[BASE]], killed [[OFFSET3]]122; CHECK: [[PRED3:%[0-9]+]]:ppr = LDR_PXI killed [[ADDR3]], 0 :: (load (<vscale x 1 x s16>))123; CHECK: [[PRED0:%[0-9]+]]:ppr = LDR_PXI [[BASE]], 0 :: (load (<vscale x 1 x s16>))124; CHECK: $p0 = COPY [[PRED0]]125; CHECK: $p1 = COPY [[PRED1]]126; CHECK: $p2 = COPY [[PRED2]]127; CHECK: $p3 = COPY [[PRED3]]128; CHECK: RET_ReallyLR implicit $p0, implicit $p1, implicit $p2, implicit $p3129 ret [4 x <vscale x 16 x i1>] %arg2130}131 132; Test that arg1 is stored to the stack from p0~p3; and the stack location is passed throuch x0 to setup the call:133; str P0, [stack_loc_for_args]134; str P1, [stack_loc_for_args + sizeof(Px)]135; str P2, [stack_loc_for_args + 2*sizeof(Px)]136; str P3, [stack_loc_for_args + 3*sizeof(Px)]137; x0 = stack_loc_for_args138define [4 x <vscale x 16 x i1>] @caller_with_svepred_arg_4xv16i1_4xv16i1([4 x <vscale x 16 x i1>] %arg1, [4 x <vscale x 16 x i1>] %arg2) {139; CHECK: name: caller_with_svepred_arg_4xv16i1_4xv16i1140; CHECK: stack:141; CHECK: - { id: 0, name: '', type: default, offset: 0, size: 8, alignment: 2,142; CHECK-NEXT: stack-id: scalable-predicate-vector,143; CHECK: [[PRED3:%[0-9]+]]:ppr = COPY $p3144; CHECK: [[PRED2:%[0-9]+]]:ppr = COPY $p2145; CHECK: [[PRED1:%[0-9]+]]:ppr = COPY $p1146; CHECK: [[PRED0:%[0-9]+]]:ppr = COPY $p0147; CHECK: [[OFFSET1:%[0-9]+]]:gpr64 = CNTD_XPiI 31, 1, implicit $vg148; CHECK: [[OFFSET2:%[0-9]+]]:gpr64 = CNTW_XPiI 31, 1, implicit $vg149; CHECK: [[OFFSET3:%[0-9]+]]:gpr64 = CNTD_XPiI 31, 3, implicit $vg150; CHECK: [[STACK:%[0-9]+]]:gpr64common = ADDXri %stack.0, 0, 0151; CHECK: [[ADDR3:%[0-9]+]]:gpr64common = ADDXrr [[STACK]], [[OFFSET3]]152; CHECK: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp153; CHECK: STR_PXI [[PRED3]], killed [[ADDR3]], 0 :: (store (<vscale x 1 x s16>))154; CHECK: [[ADDR2:%[0-9]+]]:gpr64common = ADDXrr [[STACK]], [[OFFSET2]]155; CHECK: STR_PXI [[PRED2]], killed [[ADDR2]], 0 :: (store (<vscale x 1 x s16>))156; CHECK: [[ADDR1:%[0-9]+]]:gpr64common = nuw ADDXrr [[STACK]], [[OFFSET1]]157; CHECK: STR_PXI [[PRED1]], killed [[ADDR1]], 0 :: (store (<vscale x 1 x s16>))158; CHECK: STR_PXI [[PRED0]], %stack.0, 0 :: (store (<vscale x 1 x s16>) into %stack.0)159; CHECK: $x0 = COPY [[STACK]]160; LINUX: BL @callee_with_svepred_arg_4xv16i1_4xv16i1, csr_aarch64_sve_aapcs, implicit-def dead $lr, implicit $sp, implicit $p0, implicit $p1, implicit $p2, implicit $p3, implicit $x0, implicit-def $sp, implicit-def $p0, implicit-def $p1, implicit-def $p2, implicit-def $p3161; DARWIN: BL @callee_with_svepred_arg_4xv16i1_4xv16i1, csr_darwin_aarch64_sve_aapcs, implicit-def dead $lr, implicit $sp, implicit $p0, implicit $p1, implicit $p2, implicit $p3, implicit $x0, implicit-def $sp, implicit-def $p0, implicit-def $p1, implicit-def $p2, implicit-def $p3162; CHECK: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp163 %res = call [4 x <vscale x 16 x i1>] @callee_with_svepred_arg_4xv16i1_4xv16i1([4 x <vscale x 16 x i1>] %arg2, [4 x <vscale x 16 x i1>] %arg1)164 ret [4 x <vscale x 16 x i1>] %res165}166 167; Test that arg2 is passed through x0, i.e., x0 = &%arg2; and return values are loaded from x0:168; P0 = ldr [x0]169; P1 = ldr [x0 + sizeof(Px)]170; P2 = ldr [x0 + 2*sizeof(Px)]171; P3 = ldr [x0 + 3*sizeof(Px)]172define aarch64_sve_vector_pcs [2 x <vscale x 32 x i1>] @callee_with_svepred_arg_1xv16i1_2xv32i1([1 x <vscale x 16 x i1>] %arg1, [2 x <vscale x 32 x i1>] %arg2) {173; CHECK: name: callee_with_svepred_arg_1xv16i1_2xv32i1174; CHECK: [[BASE:%[0-9]+]]:gpr64common = COPY $x0175; CHECK: [[OFFSET1:%[0-9]+]]:gpr64 = CNTD_XPiI 31, 1, implicit $vg176; CHECK: [[ADDR1:%[0-9]+]]:gpr64common = nuw ADDXrr [[BASE]], killed [[OFFSET1]]177; CHECK: [[PRED1:%[0-9]+]]:ppr = LDR_PXI killed [[ADDR1]], 0 :: (load (<vscale x 1 x s16>))178; CHECK: [[OFFSET2:%[0-9]+]]:gpr64 = CNTW_XPiI 31, 1, implicit $vg179; CHECK: [[ADDR2:%[0-9]+]]:gpr64common = ADDXrr [[BASE]], killed [[OFFSET2]]180; CHECK: [[PRED2:%[0-9]+]]:ppr = LDR_PXI killed [[ADDR2]], 0 :: (load (<vscale x 1 x s16>))181; CHECK: [[OFFSET3:%[0-9]+]]:gpr64 = CNTD_XPiI 31, 3, implicit $vg182; CHECK: [[ADDR3:%[0-9]+]]:gpr64common = ADDXrr [[BASE]], killed [[OFFSET3]]183; CHECK: [[PRED3:%[0-9]+]]:ppr = LDR_PXI killed [[ADDR3]], 0 :: (load (<vscale x 1 x s16>))184; CHECK: [[PRED0:%[0-9]+]]:ppr = LDR_PXI [[BASE]], 0 :: (load (<vscale x 1 x s16>))185; CHECK: $p0 = COPY [[PRED0]]186; CHECK: $p1 = COPY [[PRED1]]187; CHECK: $p2 = COPY [[PRED2]]188; CHECK: $p3 = COPY [[PRED3]]189; CHECK: RET_ReallyLR implicit $p0, implicit $p1, implicit $p2, implicit $p3190 ret [2 x <vscale x 32 x i1>] %arg2191}192 193; Test that arg1 is stored to the stack from p0~p3; and the stack location is passed throuch x0 to setup the call:194; str P0, [stack_loc_for_args]195; str P1, [stack_loc_for_args + sizeof(Px)]196; str P2, [stack_loc_for_args + 2*sizeof(Px)]197; str P3, [stack_loc_for_args + 3*sizeof(Px)]198; x0 = stack_loc_for_args199define [2 x <vscale x 32 x i1>] @caller_with_svepred_arg_2xv32i1_1xv16i1([2 x <vscale x 32 x i1>] %arg1, [1 x <vscale x 16 x i1>] %arg2) {200; CHECK: name: caller_with_svepred_arg_2xv32i1_1xv16i1201; CHECK: stack:202; CHECK: - { id: 0, name: '', type: default, offset: 0, size: 8, alignment: 2,203; CHECK-NEXT: stack-id: scalable-predicate-vector,204; CHECK: [[PRED3:%[0-9]+]]:ppr = COPY $p3205; CHECK: [[PRED2:%[0-9]+]]:ppr = COPY $p2206; CHECK: [[PRED1:%[0-9]+]]:ppr = COPY $p1207; CHECK: [[PRED0:%[0-9]+]]:ppr = COPY $p0208; CHECK: [[OFFSET3:%[0-9]+]]:gpr64 = CNTD_XPiI 31, 3, implicit $vg209; CHECK: [[STACK:%[0-9]+]]:gpr64common = ADDXri %stack.0, 0, 0210; CHECK: [[ADDR3:%[0-9]+]]:gpr64common = ADDXrr [[STACK]], killed [[OFFSET3]]211; CHECK: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp212; CHECK: STR_PXI [[PRED3]], killed [[ADDR3]], 0 :: (store (<vscale x 1 x s16>))213; CHECK: [[OFFSET2:%[0-9]+]]:gpr64 = CNTW_XPiI 31, 1, implicit $vg214; CHECK: [[ADDR2:%[0-9]+]]:gpr64common = ADDXrr [[STACK]], killed [[OFFSET2]]215; CHECK: STR_PXI [[PRED2]], killed [[ADDR2]], 0 :: (store (<vscale x 1 x s16>))216; CHECK: [[OFFSET1:%[0-9]+]]:gpr64 = CNTD_XPiI 31, 1, implicit $vg217; CHECK: [[ADDR1:%[0-9]+]]:gpr64common = nuw ADDXrr [[STACK]], killed [[OFFSET1]]218; CHECK: STR_PXI [[PRED1]], killed [[ADDR1]], 0 :: (store (<vscale x 1 x s16>))219; CHECK: STR_PXI [[PRED0]], %stack.0, 0 :: (store (<vscale x 1 x s16>) into %stack.0)220; CHECK: $x0 = COPY [[STACK]]221; LINUX: BL @callee_with_svepred_arg_1xv16i1_2xv32i1, csr_aarch64_sve_aapcs, implicit-def dead $lr, implicit $sp, implicit $p0, implicit $x0, implicit-def $sp, implicit-def $p0, implicit-def $p1, implicit-def $p2, implicit-def $p3222; DARWIN: BL @callee_with_svepred_arg_1xv16i1_2xv32i1, csr_darwin_aarch64_sve_aapcs, implicit-def dead $lr, implicit $sp, implicit $p0, implicit $x0, implicit-def $sp, implicit-def $p0, implicit-def $p1, implicit-def $p2, implicit-def $p3223; CHECK: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp224 %res = call [2 x <vscale x 32 x i1>] @callee_with_svepred_arg_1xv16i1_2xv32i1([1 x <vscale x 16 x i1>] %arg2, [2 x <vscale x 32 x i1>] %arg1)225 ret [2 x <vscale x 32 x i1>] %res226}227 228; Test that arg1 and arg3 are passed via P0~P3, arg1 is passed indirectly through address on stack in x0229define aarch64_sve_vector_pcs [4 x <vscale x 16 x i1>] @callee_with_svepred_arg_2xv16i1_4xv16i1_2xv16i1([2 x <vscale x 16 x i1>] %arg1, [4 x <vscale x 16 x i1>] %arg2, [2 x <vscale x 16 x i1>] %arg3) nounwind {230; CHECK: name: callee_with_svepred_arg_2xv16i1_4xv16i1_2xv16i1231; CHECK: [[P3:%[0-9]+]]:ppr = COPY $p3232; CHECK: [[P2:%[0-9]+]]:ppr = COPY $p2233; CHECK: [[X0:%[0-9]+]]:gpr64common = COPY $x0234; CHECK: [[P1:%[0-9]+]]:ppr = COPY $p1235; CHECK: [[P0:%[0-9]+]]:ppr = COPY $p0236; CHECK: [[OFFSET3:%[0-9]+]]:gpr64 = CNTD_XPiI 31, 3, implicit $vg237; CHECK: [[ADDR3:%[0-9]+]]:gpr64common = ADDXrr [[X0]], killed [[OFFSET3]]238; CHECK: [[P7:%[0-9]+]]:ppr = LDR_PXI killed [[ADDR3]], 0 :: (load (<vscale x 1 x s16>))239; CHECK: [[OFFSET2:%[0-9]+]]:gpr64 = CNTW_XPiI 31, 1, implicit $vg240; CHECK: [[ADDR2:%[0-9]+]]:gpr64common = ADDXrr [[X0]], killed [[OFFSET2]]241; CHECK: [[P6:%[0-9]+]]:ppr = LDR_PXI killed [[ADDR2]], 0 :: (load (<vscale x 1 x s16>))242; CHECK: [[OFFSET1:%[0-9]+]]:gpr64 = CNTD_XPiI 31, 1, implicit $vg243; CHECK: [[ADDR1:%[0-9]+]]:gpr64common = nuw ADDXrr [[X0]], killed [[OFFSET1]]244; CHECK: [[P5:%[0-9]+]]:ppr = LDR_PXI killed [[ADDR1]], 0 :: (load (<vscale x 1 x s16>))245; CHECK: [[P4:%[0-9]+]]:ppr = LDR_PXI [[X0]], 0 :: (load (<vscale x 1 x s16>))246; CHECK: [[RES0:%[0-9]+]]:ppr = AND_PPzPP [[P0]], [[P0]], killed [[P4]]247; CHECK: [[RES1:%[0-9]+]]:ppr = AND_PPzPP [[P1]], [[P1]], killed [[P5]]248; CHECK: [[RES2:%[0-9]+]]:ppr = AND_PPzPP [[P2]], [[P2]], killed [[P6]]249; CHECK: [[RES3:%[0-9]+]]:ppr = AND_PPzPP [[P3]], [[P3]], killed [[P7]]250; CHECK: $p0 = COPY [[RES0]]251; CHECK: $p1 = COPY [[RES1]]252; CHECK: $p2 = COPY [[RES2]]253; CHECK: $p3 = COPY [[RES3]]254; CHECK: RET_ReallyLR implicit $p0, implicit $p1, implicit $p2, implicit $p3255 %p0 = extractvalue [2 x <vscale x 16 x i1>] %arg1, 0256 %p1 = extractvalue [2 x <vscale x 16 x i1>] %arg1, 1257 %p2 = extractvalue [2 x <vscale x 16 x i1>] %arg3, 0258 %p3 = extractvalue [2 x <vscale x 16 x i1>] %arg3, 1259 %p4 = extractvalue [4 x <vscale x 16 x i1>] %arg2, 0260 %p5 = extractvalue [4 x <vscale x 16 x i1>] %arg2, 1261 %p6 = extractvalue [4 x <vscale x 16 x i1>] %arg2, 2262 %p7 = extractvalue [4 x <vscale x 16 x i1>] %arg2, 3263 %r0 = and <vscale x 16 x i1> %p0, %p4264 %r1 = and <vscale x 16 x i1> %p1, %p5265 %r2 = and <vscale x 16 x i1> %p2, %p6266 %r3 = and <vscale x 16 x i1> %p3, %p7267 %1 = insertvalue [4 x <vscale x 16 x i1>] poison, <vscale x 16 x i1> %r0, 0268 %2 = insertvalue [4 x <vscale x 16 x i1>] %1, <vscale x 16 x i1> %r1, 1269 %3 = insertvalue [4 x <vscale x 16 x i1>] %2, <vscale x 16 x i1> %r2, 2270 %4 = insertvalue [4 x <vscale x 16 x i1>] %3, <vscale x 16 x i1> %r3, 3271 ret [4 x <vscale x 16 x i1>] %4272}273 274; Test that z8 and z9, passed by reference, are loaded from a location that is passed on the stack.275; i.e. x0 = %x0276; :277; x7 = %x7278; z0 = %z0279; :280; z7 = %z7281; [sp] = &%z8282; [sp+8] = &%z9283;284define aarch64_sve_vector_pcs <vscale x 4 x i32> @callee_with_many_gpr_sve_arg(i64 %x0, i64 %x1, i64 %x2, i64 %x3, i64 %x4, i64 %x5, i64 %x6, i64 %x7, <vscale x 4 x i32> %z0, <vscale x 4 x i32> %z1, <vscale x 4 x i32> %z2, <vscale x 4 x i32> %z3, <vscale x 4 x i32> %z4, <vscale x 4 x i32> %z5, <vscale x 4 x i32> %z6, <vscale x 4 x i32> %z7, <vscale x 2 x i64> %z8, <vscale x 4 x i32> %z9) {285; CHECK: name: callee_with_many_gpr_sve_arg286; CHECK: fixedStack:287; CHECK: - { id: 0, type: default, offset: 8, size: 8, alignment: 8, stack-id: default,288; CHECK-DAG: [[BASE:%[0-9]+]]:gpr64common = LDRXui %fixed-stack.0, 0289; CHECK-DAG: [[RES:%[0-9]+]]:zpr = LDR_ZXI killed [[BASE]]290; CHECK-DAG: $z0 = COPY [[RES]]291; CHECK: RET_ReallyLR implicit $z0292 ret <vscale x 4 x i32> %z9293}294 295; Test that z8 and z9 are passed by reference, where reference is passed on the stack.296define aarch64_sve_vector_pcs <vscale x 4 x i32> @caller_with_many_gpr_sve_arg(i64 %x, <vscale x 4 x i32> %z, <vscale x 2 x i64> %z2) {297; CHECK: name: caller_with_many_gpr_sve_arg298; CHECK: stack:299; CHECK: - { id: 0, name: '', type: default, offset: 0, size: 16, alignment: 16,300; CHECK-NEXT: stack-id: scalable-vector301; CHECK: - { id: 1, name: '', type: default, offset: 0, size: 16, alignment: 16,302; CHECK-NEXT: stack-id: scalable-vector303; CHECK-DAG: STR_ZXI %{{[0-9]+}}, %stack.0, 0304; CHECK-DAG: STR_ZXI %{{[0-9]+}}, %stack.1, 0305; CHECK-DAG: [[BASE1:%[0-9]+]]:gpr64common = ADDXri %stack.0, 0306; CHECK-DAG: [[BASE2:%[0-9]+]]:gpr64common = ADDXri %stack.1, 0307; CHECK-DAG: [[SP:%[0-9]+]]:gpr64sp = COPY $sp308; CHECK-DAG: STRXui killed [[BASE1]], [[SP]], 0309; CHECK-DAG: STRXui killed [[BASE2]], [[SP]], 1310; CHECK: BL @callee_with_many_gpr_sve_arg311; CHECK: RET_ReallyLR implicit $z0312 %ret = call aarch64_sve_vector_pcs <vscale x 4 x i32> @callee_with_many_gpr_sve_arg(i64 %x, i64 %x, i64 %x, i64 %x, i64 %x, i64 %x, i64 %x, i64 %x, <vscale x 4 x i32> %z, <vscale x 4 x i32> %z, <vscale x 4 x i32> %z, <vscale x 4 x i32> %z, <vscale x 4 x i32> %z, <vscale x 4 x i32> %z, <vscale x 4 x i32> %z, <vscale x 4 x i32> %z, <vscale x 2 x i64> %z2, <vscale x 4 x i32> %z)313 ret <vscale x 4 x i32> %ret314}315