diff options
| author | Jessica Paquette <jpaquette@apple.com> | 2019-03-29 21:39:36 +0000 |
|---|---|---|
| committer | Jessica Paquette <jpaquette@apple.com> | 2019-03-29 21:39:36 +0000 |
| commit | d3ffd47df94b362ebf52c0681bc2cdcfef00b98f (patch) | |
| tree | 2535ba8bfb7d4cbfd8e266661cf9d6887015c426 /llvm/lib/Target | |
| parent | d413f41de6baf500e5d20c638375447e18777db2 (diff) | |
| download | bcm5719-llvm-d3ffd47df94b362ebf52c0681bc2cdcfef00b98f.tar.gz bcm5719-llvm-d3ffd47df94b362ebf52c0681bc2cdcfef00b98f.zip | |
[GlobalISel][AArch64] Add isel support for G_INSERT_VECTOR_ELT on v2s32s
This adds support for v2s32 vector inserts, and updates the selection +
regbankselect tests for G_INSERT_VECTOR_ELT.
Differential Revision: https://reviews.llvm.org/D59910
llvm-svn: 357318
Diffstat (limited to 'llvm/lib/Target')
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp | 51 | ||||
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64LegalizerInfo.cpp | 3 |
2 files changed, 46 insertions, 8 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp index cd80518f900..f1274d7fa22 100644 --- a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp @@ -2561,11 +2561,7 @@ bool AArch64InstructionSelector::selectInsertElt( // Get information on the destination. unsigned DstReg = I.getOperand(0).getReg(); const LLT DstTy = MRI.getType(DstReg); - if (DstTy.getSizeInBits() < 128) { - // TODO: Handle unpacked vectors. - LLVM_DEBUG(dbgs() << "Unpacked vectors not supported yet!"); - return false; - } + unsigned VecSize = DstTy.getSizeInBits(); // Get information on the element we want to insert into the destination. unsigned EltReg = I.getOperand(2).getReg(); @@ -2585,7 +2581,50 @@ bool AArch64InstructionSelector::selectInsertElt( unsigned SrcReg = I.getOperand(1).getReg(); const RegisterBank &EltRB = *RBI.getRegBank(EltReg, MRI, TRI); MachineIRBuilder MIRBuilder(I); - emitLaneInsert(DstReg, SrcReg, EltReg, LaneIdx, EltRB, MIRBuilder); + + if (VecSize < 128) { + // If the vector we're inserting into is smaller than 128 bits, widen it + // to 128 to do the insert. + MachineInstr *ScalarToVec = emitScalarToVector( + VecSize, &AArch64::FPR128RegClass, SrcReg, MIRBuilder); + if (!ScalarToVec) + return false; + SrcReg = ScalarToVec->getOperand(0).getReg(); + } + + // Create an insert into a new FPR128 register. + // Note that if our vector is already 128 bits, we end up emitting an extra + // register. + MachineInstr *InsMI = + emitLaneInsert(None, SrcReg, EltReg, LaneIdx, EltRB, MIRBuilder); + + if (VecSize < 128) { + // If we had to widen to perform the insert, then we have to demote back to + // the original size to get the result we want. + unsigned DemoteVec = InsMI->getOperand(0).getReg(); + const TargetRegisterClass *RC = + getMinClassForRegBank(*RBI.getRegBank(DemoteVec, MRI, TRI), VecSize); + if (RC != &AArch64::FPR32RegClass && RC != &AArch64::FPR64RegClass) { + LLVM_DEBUG(dbgs() << "Unsupported register class!\n"); + return false; + } + unsigned SubReg = 0; + if (!getSubRegForClass(RC, TRI, SubReg)) + return false; + if (SubReg != AArch64::ssub && SubReg != AArch64::dsub) { + LLVM_DEBUG(dbgs() << "Unsupported destination size! (" << VecSize + << "\n"); + return false; + } + MIRBuilder.buildInstr(TargetOpcode::COPY, {DstReg}, {}) + .addReg(DemoteVec, 0, SubReg); + RBI.constrainGenericRegister(DstReg, *RC, MRI); + } else { + // No widening needed. + InsMI->getOperand(0).setReg(DstReg); + constrainSelectedInstRegOperands(*InsMI, TII, TRI, RBI); + } + I.eraseFromParent(); return true; } diff --git a/llvm/lib/Target/AArch64/AArch64LegalizerInfo.cpp b/llvm/lib/Target/AArch64/AArch64LegalizerInfo.cpp index b05e2afb8aa..854355c619c 100644 --- a/llvm/lib/Target/AArch64/AArch64LegalizerInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64LegalizerInfo.cpp @@ -448,9 +448,8 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST) { getActionDefinitionsBuilder(G_INSERT_VECTOR_ELT) .legalIf([=](const LegalityQuery &Query) { const LLT &VecTy = Query.Types[0]; - // TODO: Support destination sizes of < 128 bits. // TODO: Support s8 and s16 - return VecTy == v4s32 || VecTy == v2s64; + return VecTy == v2s32 || VecTy == v4s32 || VecTy == v2s64; }); getActionDefinitionsBuilder(G_BUILD_VECTOR) |

