diff options
author | Kai Nacke <kai@redstar.de> | 2022-08-01 23:35:55 -0400 |
---|---|---|
committer | Kai Nacke <kai@redstar.de> | 2022-11-13 11:07:39 -0500 |
commit | af16dd4a0b0e2b10fa7149e81ec0d5839d2d103e (patch) | |
tree | 6dc2e21016b56880f0c12ec88330ff4ff8bd4f39 /llvm | |
parent | b076c1b283b8d1ba262247dda505ebbce83f0fa3 (diff) | |
download | llvm-af16dd4a0b0e2b10fa7149e81ec0d5839d2d103e.zip llvm-af16dd4a0b0e2b10fa7149e81ec0d5839d2d103e.tar.gz llvm-af16dd4a0b0e2b10fa7149e81ec0d5839d2d103e.tar.bz2 |
[m88k] Legalize & select G_MUL
With special check to generate mulu.d instruction from 88110.
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/lib/Target/M88k/GISel/M88kInstructionSelector.cpp | 40 | ||||
-rw-r--r-- | llvm/lib/Target/M88k/GISel/M88kLegalizerInfo.cpp | 46 | ||||
-rw-r--r-- | llvm/lib/Target/M88k/GISel/M88kRegisterBankInfo.cpp | 11 |
3 files changed, 92 insertions, 5 deletions
diff --git a/llvm/lib/Target/M88k/GISel/M88kInstructionSelector.cpp b/llvm/lib/Target/M88k/GISel/M88kInstructionSelector.cpp index 2bc663f..1172343 100644 --- a/llvm/lib/Target/M88k/GISel/M88kInstructionSelector.cpp +++ b/llvm/lib/Target/M88k/GISel/M88kInstructionSelector.cpp @@ -82,6 +82,8 @@ private: MachineRegisterInfo &MRI) const; bool selectPtrAdd(MachineInstr &I, MachineBasicBlock &MBB, MachineRegisterInfo &MRI) const; + bool selectMul(MachineInstr &I, MachineBasicBlock &MBB, + MachineRegisterInfo &MRI) const; bool selectExt(MachineInstr &I, MachineBasicBlock &MBB, MachineRegisterInfo &MRI) const; bool selectLoadStore(MachineInstr &I, MachineBasicBlock &MBB, @@ -594,6 +596,38 @@ bool M88kInstructionSelector::selectPtrAdd(MachineInstr &I, return constrainSelectedInstRegOperands(*MI, TII, TRI, RBI); } +bool M88kInstructionSelector::selectMul(MachineInstr &I, MachineBasicBlock &MBB, + MachineRegisterInfo &MRI) const { + assert(I.getOpcode() == TargetOpcode::G_MUL && "Unexpected G code"); + + // Only selects special mulu.d instruction, the other mul instructions are + // matched by the patterns from the target description. + if (!isMC88110()) + return false; + + MachineInstr *MI = nullptr; + Register DstReg = I.getOperand(0).getReg(); + Register Src1Reg = I.getOperand(1).getReg(); + Register Src2Reg = I.getOperand(2).getReg(); + + MachineInstr *Merge1MI = + getOpcodeDef(TargetOpcode::G_MERGE_VALUES, Src1Reg, MRI); + MachineInstr *Merge2MI = + getOpcodeDef(TargetOpcode::G_MERGE_VALUES, Src2Reg, MRI); + if (Merge1MI && + mi_match(Merge1MI->getOperand(1).getReg(), MRI, m_ZeroInt()) && + Merge2MI && + mi_match(Merge2MI->getOperand(1).getReg(), MRI, m_ZeroInt())) { + MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(M88k::MULUrrd), DstReg) + .addReg(Merge1MI->getOperand(2).getReg()) + .addReg(Merge2MI->getOperand(2).getReg()); + } else + return false; + + I.eraseFromParent(); + return constrainSelectedInstRegOperands(*MI, TII, TRI, RBI); +} + bool M88kInstructionSelector::selectExt(MachineInstr &I, MachineBasicBlock &MBB, MachineRegisterInfo &MRI) const { assert(I.getOpcode() == TargetOpcode::G_ZEXT || @@ -832,14 +866,14 @@ bool M88kInstructionSelector::selectMergeUnmerge( // Copy to dst. MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(TargetOpcode::COPY), I.getOperand(0).getReg()) - .addReg(SrcReg, 0, M88k::sub_hi); + .addReg(SrcReg, 0, M88k::sub_lo); RBI.constrainGenericRegister(I.getOperand(0).getReg(), M88k::GPRRCRegClass, MRI); constrainSelectedInstRegOperands(*MI, TII, TRI, RBI); MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(TargetOpcode::COPY), I.getOperand(1).getReg()) - .addReg(SrcReg, 0, M88k::sub_lo); + .addReg(SrcReg, 0, M88k::sub_hi); RBI.constrainGenericRegister(I.getOperand(1).getReg(), M88k::GPRRCRegClass, MRI); } @@ -1064,6 +1098,8 @@ bool M88kInstructionSelector::select(MachineInstr &I) { return selectBrJT(I, MBB, MRI); case TargetOpcode::G_BRINDIRECT: return selectBrIndirect(I, MBB, MRI); + case TargetOpcode::G_MUL: + return selectMul(I, MBB, MRI); case TargetOpcode::G_ZEXT: case TargetOpcode::G_SEXT: case TargetOpcode::G_ANYEXT: // TODO Can G_ANYEXT end up here? diff --git a/llvm/lib/Target/M88k/GISel/M88kLegalizerInfo.cpp b/llvm/lib/Target/M88k/GISel/M88kLegalizerInfo.cpp index 4f439a2..1d55cac 100644 --- a/llvm/lib/Target/M88k/GISel/M88kLegalizerInfo.cpp +++ b/llvm/lib/Target/M88k/GISel/M88kLegalizerInfo.cpp @@ -35,6 +35,11 @@ M88kLegalizerInfo::M88kLegalizerInfo(const M88kSubtarget &ST) { const LLT S64 = LLT::scalar(64); const LLT S80 = LLT::scalar(80); const LLT P0 = LLT::pointer(0, 32); + + auto IsMC88110 = [=, &ST](const LegalityQuery &Query) { + return ST.isMC88110(); + }; + getActionDefinitionsBuilder(G_PHI).legalFor({S32, P0}); getActionDefinitionsBuilder(G_SELECT) .customForCartesianProduct({S32, S64, P0}, {S1}); @@ -72,7 +77,11 @@ M88kLegalizerInfo::M88kLegalizerInfo(const M88kSubtarget &ST) { .clampScalar(1, S32, S32); getActionDefinitionsBuilder(G_ADD).legalFor({S32}); getActionDefinitionsBuilder(G_SUB).legalFor({S32}); - getActionDefinitionsBuilder(G_MUL).legalFor({S32}); + getActionDefinitionsBuilder(G_MUL) + .legalFor({S32}) + .customIf(all(typeInSet(0, {S64}), LegalityPredicate(IsMC88110))) + .libcallFor({S64}) + .clampScalar(0, S32, S64); getActionDefinitionsBuilder(G_UDIV).legalFor({S32}).libcallFor({S64}); getActionDefinitionsBuilder(G_SDIV) #if 0 @@ -171,6 +180,41 @@ bool M88kLegalizerInfo::legalizeCustom(LegalizerHelper &Helper, MI.eraseFromParent(); break; } + case G_MUL: { + // MC88110 only: 32bit multiplication with 64bit result. + Register DstReg = MI.getOperand(0).getReg(); + if (MRI.getType(DstReg) != S64) + return false; + MachineInstr *Src1I = getDefIgnoringCopies(MI.getOperand(1).getReg(), MRI); + MachineInstr *Src2I = getDefIgnoringCopies(MI.getOperand(2).getReg(), MRI); + unsigned Opc1 = Src1I->getOpcode(); + unsigned Opc2 = Src2I->getOpcode(); + // Check if the multiplicants are blown-up 32 bit values. If yes then the + // multiplication is legal. + if (Opc1 == G_MERGE_VALUES && Opc2 == G_MERGE_VALUES) { + auto C1 = getIConstantVRegValWithLookThrough( + Src1I->getOperand(1).getReg(), MRI); + auto C2 = getIConstantVRegValWithLookThrough( + Src1I->getOperand(1).getReg(), MRI); + return C1 && C1->Value.isZero() && C2 && C2->Value.isZero(); + } + + // Try to legalize the instruction. + if (!((Opc1 == G_ZEXT || Opc1 == G_SEXT) && + (Opc2 == G_ZEXT || Opc2 == G_SEXT))) + return false; + if (MRI.getType(Src1I->getOperand(1).getReg()) != S32 || + MRI.getType(Src2I->getOperand(1).getReg()) != S32) + return false; + auto Zero = MIRBuilder.buildConstant(S32, 0); + auto Mult1 = MIRBuilder.buildMerge( + S64, {Zero.getReg(0), Src1I->getOperand(1).getReg()}); + auto Mult2 = MIRBuilder.buildMerge( + S64, {Zero.getReg(0), Src2I->getOperand(1).getReg()}); + MIRBuilder.buildMul(DstReg, Mult1, Mult2, MI.getFlags()); + MI.eraseFromParent(); + break; + } case G_SELECT: { using namespace MIPatternMatch; // The instruction diff --git a/llvm/lib/Target/M88k/GISel/M88kRegisterBankInfo.cpp b/llvm/lib/Target/M88k/GISel/M88kRegisterBankInfo.cpp index 7529d89..cfa198c 100644 --- a/llvm/lib/Target/M88k/GISel/M88kRegisterBankInfo.cpp +++ b/llvm/lib/Target/M88k/GISel/M88kRegisterBankInfo.cpp @@ -147,9 +147,7 @@ M88kRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { case TargetOpcode::G_ADD: case TargetOpcode::G_SUB: case TargetOpcode::G_PTR_ADD: - case TargetOpcode::G_MUL: case TargetOpcode::G_SDIV: - case TargetOpcode::G_UDIV: // Bitwise ops. case TargetOpcode::G_AND: case TargetOpcode::G_OR: @@ -162,6 +160,15 @@ M88kRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { case TargetOpcode::G_LSHR: OperandsMapping = getValueMapping(PMI_GR32); break; + case TargetOpcode::G_MUL: + case TargetOpcode::G_UDIV: { + LLT Ty = MRI.getType(MI.getOperand(0).getReg()); + if (Ty.getSizeInBits() != 64 && Ty.getSizeInBits() != 32) + return getInvalidInstructionMapping(); + PartialMappingIdx RBIdx = (Ty.getSizeInBits() == 64) ? PMI_GR64 : PMI_GR32; + OperandsMapping = getValueMapping(RBIdx); + break; + } // Floating point ops. case TargetOpcode::G_FADD: case TargetOpcode::G_FSUB: |