diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 53d73ad618bd1..edfddeec4030e 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -359,6 +359,15 @@ static SDValue getCopyFromPartsVector(SelectionDAG &DAG, const SDLoc &DL, *DAG.getContext(), *CallConv, ValueVT, IntermediateVT, NumIntermediates, RegisterVT); } else { + if (!ValueVT.isScalableVector() && PartVT.isVector() && + !PartVT.isScalableVector()) { + if (ValueVT.getSizeInBits() % PartVT.getSizeInBits() == 0) { + MVT NewEltVT = PartVT.getVectorElementType(); + unsigned NewNumElts = + ValueVT.getSizeInBits() / NewEltVT.getSizeInBits(); + ValueVT = MVT::getVectorVT(NewEltVT, NewNumElts); + } + } NumRegs = TLI.getVectorTypeBreakdown(*DAG.getContext(), ValueVT, IntermediateVT, NumIntermediates, RegisterVT); @@ -763,6 +772,16 @@ static void getCopyToPartsVector(SelectionDAG &DAG, const SDLoc &DL, *DAG.getContext(), *CallConv, ValueVT, IntermediateVT, NumIntermediates, RegisterVT); } else { + if (!ValueVT.isScalableVector() && PartVT.isVector() && + !PartVT.isScalableVector()) { + if (ValueVT.getSizeInBits() % PartVT.getSizeInBits() == 0) { + MVT NewEltVT = PartVT.getVectorElementType(); + unsigned NewNumElts = + ValueVT.getSizeInBits() / NewEltVT.getSizeInBits(); + ValueVT = MVT::getVectorVT(NewEltVT, NewNumElts); + Val = DAG.getNode(ISD::BITCAST, DL, ValueVT, Val); + } + } NumRegs = TLI.getVectorTypeBreakdown(*DAG.getContext(), ValueVT, IntermediateVT, NumIntermediates, RegisterVT); diff --git a/llvm/test/CodeGen/AArch64/sve-breakdown-fixed-vectortype.ll b/llvm/test/CodeGen/AArch64/sve-breakdown-fixed-vectortype.ll new file mode 100644 index 0000000000000..aa6983451058a --- /dev/null +++ b/llvm/test/CodeGen/AArch64/sve-breakdown-fixed-vectortype.ll @@ -0,0 +1,19 @@ +; RUN: llc -mtriple=aarch64--linux-gnu < %s | FileCheck %s + +define dso_local void @_Z3fooi(ptr %x, ptr %y) #0 { +; CHECK-LABEL: _Z3fooi: +; CHECK: // %bb.0: +; CHECK-NEXT: //APP +; CHECK-NEXT: //NO_APP +; CHECK-NEXT: stp q1, q2, [x1] +; CHECK-NEXT: ldp q0, q1, [x0] +; CHECK-NEXT: //APP +; CHECK-NEXT: //NO_APP +; CHECK-NEXT: ret +entry: + %0 = call <8 x i32> asm sideeffect "", "={z1}"() + store <8 x i32> %0, ptr %y, align 16 + %13 = load <8 x i32>, ptr %x, align 16 + call void asm sideeffect "", "{z0}"(<8 x i32> %13) + ret void +}