diff options
Diffstat (limited to 'llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp')
| -rw-r--r-- | llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp | 82 |
1 files changed, 42 insertions, 40 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp index 46b56d332af..9fe0575feca 100644 --- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -654,46 +654,7 @@ LegalizerHelper::LegalizeResult LegalizerHelper::narrowScalar(MachineInstr &MI, // ... // AN = BinOp<Ty/N> BN, CN // A = G_MERGE_VALUES A1, ..., AN - - // FIXME: add support for when SizeOp0 isn't an exact multiple of - // NarrowSize. - if (SizeOp0 % NarrowSize != 0) - return UnableToLegalize; - int NumParts = SizeOp0 / NarrowSize; - - // List the registers where the destination will be scattered. - SmallVector<unsigned, 2> DstRegs; - // List the registers where the first argument will be split. - SmallVector<unsigned, 2> SrcsReg1; - // List the registers where the second argument will be split. - SmallVector<unsigned, 2> SrcsReg2; - // Create all the temporary registers. - for (int i = 0; i < NumParts; ++i) { - unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy); - unsigned SrcReg1 = MRI.createGenericVirtualRegister(NarrowTy); - unsigned SrcReg2 = MRI.createGenericVirtualRegister(NarrowTy); - - DstRegs.push_back(DstReg); - SrcsReg1.push_back(SrcReg1); - SrcsReg2.push_back(SrcReg2); - } - // Explode the big arguments into smaller chunks. - MIRBuilder.buildUnmerge(SrcsReg1, MI.getOperand(1).getReg()); - MIRBuilder.buildUnmerge(SrcsReg2, MI.getOperand(2).getReg()); - - // Do the operation on each small part. - for (int i = 0; i < NumParts; ++i) - MIRBuilder.buildInstr(MI.getOpcode(), {DstRegs[i]}, - {SrcsReg1[i], SrcsReg2[i]}); - - // Gather the destination registers into the final destination. - unsigned DstReg = MI.getOperand(0).getReg(); - if(MRI.getType(DstReg).isVector()) - MIRBuilder.buildBuildVector(DstReg, DstRegs); - else - MIRBuilder.buildMerge(DstReg, DstRegs); - MI.eraseFromParent(); - return Legalized; + return narrowScalarBasic(MI, TypeIdx, NarrowTy); } case TargetOpcode::G_SHL: case TargetOpcode::G_LSHR: @@ -2789,6 +2750,47 @@ LegalizerHelper::narrowScalarInsert(MachineInstr &MI, unsigned TypeIdx, } LegalizerHelper::LegalizeResult +LegalizerHelper::narrowScalarBasic(MachineInstr &MI, unsigned TypeIdx, + LLT NarrowTy) { + unsigned DstReg = MI.getOperand(0).getReg(); + LLT DstTy = MRI.getType(DstReg); + + assert(MI.getNumOperands() == 3 && TypeIdx == 0); + + SmallVector<unsigned, 4> DstRegs, DstLeftoverRegs; + SmallVector<unsigned, 4> Src0Regs, Src0LeftoverRegs; + SmallVector<unsigned, 4> Src1Regs, Src1LeftoverRegs; + LLT LeftoverTy; + if (!extractParts(MI.getOperand(1).getReg(), DstTy, NarrowTy, LeftoverTy, + Src0Regs, Src0LeftoverRegs)) + return UnableToLegalize; + + LLT Unused; + if (!extractParts(MI.getOperand(2).getReg(), DstTy, NarrowTy, Unused, + Src1Regs, Src1LeftoverRegs)) + llvm_unreachable("inconsistent extractParts result"); + + for (unsigned I = 0, E = Src1Regs.size(); I != E; ++I) { + auto Inst = MIRBuilder.buildInstr(MI.getOpcode(), {NarrowTy}, + {Src0Regs[I], Src1Regs[I]}); + DstRegs.push_back(Inst->getOperand(0).getReg()); + } + + for (unsigned I = 0, E = Src1LeftoverRegs.size(); I != E; ++I) { + auto Inst = MIRBuilder.buildInstr( + MI.getOpcode(), + {LeftoverTy}, {Src0LeftoverRegs[I], Src1LeftoverRegs[I]}); + DstLeftoverRegs.push_back(Inst->getOperand(0).getReg()); + } + + insertParts(DstReg, DstTy, NarrowTy, DstRegs, + LeftoverTy, DstLeftoverRegs); + + MI.eraseFromParent(); + return Legalized; +} + +LegalizerHelper::LegalizeResult LegalizerHelper::narrowScalarSelect(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy) { if (TypeIdx != 0) |

