diff options
| author | Matt Arsenault <Matthew.Arsenault@amd.com> | 2018-09-10 11:49:23 +0000 |
|---|---|---|
| committer | Matt Arsenault <Matthew.Arsenault@amd.com> | 2018-09-10 11:49:23 +0000 |
| commit | 57b5966dad858f30fd3bbdf42ba560ef9382f0c2 (patch) | |
| tree | 6f5385281a1576628bdfbf20d7f08daf9e40157d /llvm/lib/CodeGen | |
| parent | 38a889c1853c1831a1b3eef07122415645582fac (diff) | |
| download | bcm5719-llvm-57b5966dad858f30fd3bbdf42ba560ef9382f0c2.tar.gz bcm5719-llvm-57b5966dad858f30fd3bbdf42ba560ef9382f0c2.zip | |
DAG: Handle odd vector sizes in calling conv splitting
This already worked if only one register piece was used,
but didn't if a type was split into multiple, unequal
sized pieces.
Fixes not splitting 3i16/v3f16 into two registers for
AMDGPU.
This will also allow fixing the ABI for 16-bit vectors
in a future commit so that it's the same for all subtargets.
llvm-svn: 341801
Diffstat (limited to 'llvm/lib/CodeGen')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 29 |
1 files changed, 17 insertions, 12 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index e0a3d54cf2f..418551438c1 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -701,33 +701,38 @@ static void getCopyToPartsVector(SelectionDAG &DAG, const SDLoc &DL, TLI.getVectorTypeBreakdown(*DAG.getContext(), ValueVT, IntermediateVT, NumIntermediates, RegisterVT); } - unsigned NumElements = ValueVT.getVectorNumElements(); assert(NumRegs == NumParts && "Part count doesn't match vector breakdown!"); NumParts = NumRegs; // Silence a compiler warning. assert(RegisterVT == PartVT && "Part type doesn't match vector breakdown!"); + unsigned IntermediateNumElts = IntermediateVT.isVector() ? + IntermediateVT.getVectorNumElements() : 1; + // Convert the vector to the appropiate type if necessary. - unsigned DestVectorNoElts = - NumIntermediates * - (IntermediateVT.isVector() ? IntermediateVT.getVectorNumElements() : 1); + unsigned DestVectorNoElts = NumIntermediates * IntermediateNumElts; + EVT BuiltVectorTy = EVT::getVectorVT( *DAG.getContext(), IntermediateVT.getScalarType(), DestVectorNoElts); - if (Val.getValueType() != BuiltVectorTy) + MVT IdxVT = TLI.getVectorIdxTy(DAG.getDataLayout()); + if (ValueVT != BuiltVectorTy) { + if (SDValue Widened = widenVectorToPartType(DAG, Val, DL, BuiltVectorTy)) + Val = Widened; + Val = DAG.getNode(ISD::BITCAST, DL, BuiltVectorTy, Val); + } // Split the vector into intermediate operands. SmallVector<SDValue, 8> Ops(NumIntermediates); for (unsigned i = 0; i != NumIntermediates; ++i) { - if (IntermediateVT.isVector()) - Ops[i] = - DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, IntermediateVT, Val, - DAG.getConstant(i * (NumElements / NumIntermediates), DL, - TLI.getVectorIdxTy(DAG.getDataLayout()))); - else + if (IntermediateVT.isVector()) { + Ops[i] = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, IntermediateVT, Val, + DAG.getConstant(i * IntermediateNumElts, DL, IdxVT)); + } else { Ops[i] = DAG.getNode( ISD::EXTRACT_VECTOR_ELT, DL, IntermediateVT, Val, - DAG.getConstant(i, DL, TLI.getVectorIdxTy(DAG.getDataLayout()))); + DAG.getConstant(i, DL, IdxVT)); + } } // Split the intermediate operands into legal parts. |

