Index: lib/CodeGen/GlobalISel/LegalizerHelper.cpp =================================================================== --- lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -536,6 +536,7 @@ } case TargetOpcode::G_MUL: case TargetOpcode::G_UMULH: + case TargetOpcode::G_SMULH: return narrowScalarMul(MI, NarrowTy); case TargetOpcode::G_EXTRACT: return narrowScalarExtract(MI, TypeIdx, NarrowTy); @@ -2637,10 +2638,18 @@ unsigned NumDstParts = DstSize / NarrowSize; unsigned NumSrcParts = SrcSize / NarrowSize; - bool IsMulHigh = MI.getOpcode() == TargetOpcode::G_UMULH; + bool IsMulHigh = MI.getOpcode() == TargetOpcode::G_UMULH || + MI.getOpcode() == TargetOpcode::G_SMULH; unsigned DstTmpParts = NumDstParts * (IsMulHigh ? 2 : 1); SmallVector Src1Parts, Src2Parts, DstTmpRegs; + if (MI.getOpcode() == TargetOpcode::G_SMULH) { + LLT SextTy = LLT::scalar(SrcSize * 2); + Src1 = MRI.createGenericVirtualRegister(SextTy); + Src2 = MRI.createGenericVirtualRegister(SextTy); + MIRBuilder.buildSExt(Src1, MI.getOperand(1).getReg()); + MIRBuilder.buildSExt(Src2, MI.getOperand(2).getReg()); + } extractParts(Src1, NarrowTy, NumSrcParts, Src1Parts); extractParts(Src2, NarrowTy, NumSrcParts, Src2Parts); DstTmpRegs.resize(DstTmpParts); @@ -2650,7 +2659,6 @@ ArrayRef DstRegs( IsMulHigh ? &DstTmpRegs[DstTmpParts / 2] : &DstTmpRegs[0], NumDstParts); MIRBuilder.buildMerge(DstReg, DstRegs); - MI.eraseFromParent(); return Legalized; } Index: lib/Target/Mips/MipsInstructionSelector.cpp =================================================================== --- lib/Target/Mips/MipsInstructionSelector.cpp +++ lib/Target/Mips/MipsInstructionSelector.cpp @@ -143,20 +143,24 @@ using namespace TargetOpcode; switch (I.getOpcode()) { - case G_UMULH: { - unsigned PseudoMULTuReg = MRI.createVirtualRegister(&Mips::ACC64RegClass); - MachineInstr *PseudoMULTu, *PseudoMove; - - PseudoMULTu = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::PseudoMULTu)) - .addDef(PseudoMULTuReg) - .add(I.getOperand(1)) - .add(I.getOperand(2)); - if (!constrainSelectedInstRegOperands(*PseudoMULTu, TII, TRI, RBI)) + case G_UMULH: + case G_SMULH: { + unsigned PseudoMULReg = MRI.createVirtualRegister(&Mips::ACC64RegClass); + bool IsSigned = I.getOpcode() == TargetOpcode::G_SMULH; + MachineInstr *PseudoMUL, *PseudoMove; + + PseudoMUL = + BuildMI(MBB, I, I.getDebugLoc(), + TII.get(IsSigned ? Mips::PseudoMULT : Mips::PseudoMULTu)) + .addDef(PseudoMULReg) + .add(I.getOperand(1)) + .add(I.getOperand(2)); + if (!constrainSelectedInstRegOperands(*PseudoMUL, TII, TRI, RBI)) return false; PseudoMove = BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::PseudoMFHI)) .addDef(I.getOperand(0).getReg()) - .addUse(PseudoMULTuReg); + .addUse(PseudoMULReg); if (!constrainSelectedInstRegOperands(*PseudoMove, TII, TRI, RBI)) return false; Index: lib/Target/Mips/MipsLegalizerInfo.cpp =================================================================== --- lib/Target/Mips/MipsLegalizerInfo.cpp +++ lib/Target/Mips/MipsLegalizerInfo.cpp @@ -31,7 +31,7 @@ getActionDefinitionsBuilder({G_UADDO, G_UADDE, G_USUBO, G_USUBE, G_UMULO}) .lowerFor({{s32, s1}}); - getActionDefinitionsBuilder(G_UMULH) + getActionDefinitionsBuilder({G_UMULH, G_SMULH}) .legalFor({s32}) .maxScalar(0, s32); Index: lib/Target/Mips/MipsRegisterBankInfo.cpp =================================================================== --- lib/Target/Mips/MipsRegisterBankInfo.cpp +++ lib/Target/Mips/MipsRegisterBankInfo.cpp @@ -87,6 +87,7 @@ case G_SUB: case G_MUL: case G_UMULH: + case G_SMULH: case G_LOAD: case G_STORE: case G_ZEXTLOAD: