diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h --- a/llvm/include/llvm/CodeGen/TargetLowering.h +++ b/llvm/include/llvm/CodeGen/TargetLowering.h @@ -1686,10 +1686,6 @@ virtual bool isJumpTableRelative() const; - /// Return true if a mulh[s|u] node for a specific type is cheaper than - /// a multiply followed by a shift. This is false by default. - virtual bool isMulhCheaperThanMulShift(EVT Type) const { return false; } - /// If a physical register, this specifies the register that /// llvm.savestack/llvm.restorestack should save and restore. unsigned getStackPointerRegisterToSaveRestore() const { diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -4290,7 +4290,8 @@ // If the type twice as wide is legal, transform the mulhs to a wider multiply // plus a shift. - if (!TLI.isMulhCheaperThanMulShift(VT) && VT.isSimple() && !VT.isVector()) { + if (!TLI.isOperationLegalOrCustom(ISD::MULHS, VT) && VT.isSimple() && + !VT.isVector()) { MVT Simple = VT.getSimpleVT(); unsigned SimpleSize = Simple.getSizeInBits(); EVT NewVT = EVT::getIntegerVT(*DAG.getContext(), SimpleSize*2); @@ -4346,7 +4347,8 @@ // If the type twice as wide is legal, transform the mulhu to a wider multiply // plus a shift. - if (!TLI.isMulhCheaperThanMulShift(VT) && VT.isSimple() && !VT.isVector()) { + if (!TLI.isOperationLegalOrCustom(ISD::MULHU, VT) && VT.isSimple() && + !VT.isVector()) { MVT Simple = VT.getSimpleVT(); unsigned SimpleSize = Simple.getSizeInBits(); EVT NewVT = EVT::getIntegerVT(*DAG.getContext(), SimpleSize*2); @@ -8188,12 +8190,6 @@ if (NarrowVT != RightOp.getOperand(0).getValueType()) return SDValue(); - // Only transform into mulh if mulh for the narrow type is cheaper than - // a multiply followed by a shift. This should also check if mulh is - // legal for NarrowVT on the target. - if (!TLI.isMulhCheaperThanMulShift(NarrowVT)) - return SDValue(); - // Proceed with the transformation if the wide type is twice as large // as the narrow type. unsigned NarrowVTSize = NarrowVT.getScalarSizeInBits(); @@ -8211,6 +8207,10 @@ // we use mulhs. Othewise, zero extends (zext) use mulhu. unsigned MulhOpcode = IsSignExt ? ISD::MULHS : ISD::MULHU; + // Combine to mulh if mulh is legal/custom for the narrow type on the target. + if (!TLI.isOperationLegalOrCustom(MulhOpcode, NarrowVT)) + return SDValue(); + SDValue Result = DAG.getNode(MulhOpcode, DL, NarrowVT, LeftOp.getOperand(0), RightOp.getOperand(0)); return (N->getOpcode() == ISD::SRA ? DAG.getSExtOrTrunc(Result, DL, WideVT1) diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.h b/llvm/lib/Target/PowerPC/PPCISelLowering.h --- a/llvm/lib/Target/PowerPC/PPCISelLowering.h +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.h @@ -1019,11 +1019,6 @@ Register getExceptionSelectorRegister(const Constant *PersonalityFn) const override; - /// isMulhCheaperThanMulShift - Return true if a mulh[s|u] node for a - /// specific type is cheaper than a multiply followed by a shift. - /// This is true for words and doublewords on 64-bit PowerPC. - bool isMulhCheaperThanMulShift(EVT Type) const override; - /// Override to support customized stack guard loading. bool useLoadStackGuardNode() const override; void insertSSPDeclarations(Module &M) const override; diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -1400,16 +1400,6 @@ return VT.isScalarInteger(); } -/// isMulhCheaperThanMulShift - Return true if a mulh[s|u] node for a specific -/// type is cheaper than a multiply followed by a shift. -/// This is true for words and doublewords on 64-bit PowerPC. -bool PPCTargetLowering::isMulhCheaperThanMulShift(EVT Type) const { - if (Subtarget.isPPC64() && (isOperationLegal(ISD::MULHS, Type) || - isOperationLegal(ISD::MULHU, Type))) - return true; - return TargetLowering::isMulhCheaperThanMulShift(Type); -} - const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const { switch ((PPCISD::NodeType)Opcode) { case PPCISD::FIRST_NUMBER: break; diff --git a/llvm/test/CodeGen/X86/pmulh.ll b/llvm/test/CodeGen/X86/pmulh.ll --- a/llvm/test/CodeGen/X86/pmulh.ll +++ b/llvm/test/CodeGen/X86/pmulh.ll @@ -489,10 +489,11 @@ ; SSE2-LABEL: mulhsw_v8i16_ashr: ; SSE2: # %bb.0: ; SSE2-NEXT: pmulhw %xmm1, %xmm0 +; SSE2-NEXT: punpcklwd {{.*#+}} xmm2 = xmm2[0],xmm0[0],xmm2[1],xmm0[1],xmm2[2],xmm0[2],xmm2[3],xmm0[3] +; SSE2-NEXT: psrad $16, %xmm2 ; SSE2-NEXT: punpckhwd {{.*#+}} xmm1 = xmm1[4],xmm0[4],xmm1[5],xmm0[5],xmm1[6],xmm0[6],xmm1[7],xmm0[7] -; SSE2-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0,0,1,1,2,2,3,3] -; SSE2-NEXT: psrad $16, %xmm0 ; SSE2-NEXT: psrad $16, %xmm1 +; SSE2-NEXT: movdqa %xmm2, %xmm0 ; SSE2-NEXT: retq ; ; SSE41-LABEL: mulhsw_v8i16_ashr: