@@ -6817,11 +6817,18 @@ SDValue TargetLowering::BuildUDIV(SDNode *N, SelectionDAG &DAG,
68176817 }
68186818 const unsigned SVTBits = SVT.getSizeInBits();
68196819
6820+ // Allow i32 to be widened to i64 for uncooperative divisors if i64 MULHU or
6821+ // UMUL_LOHI is supported.
6822+ const EVT WideSVT = MVT::i64;
6823+ const bool HasWideMULHU =
6824+ VT == MVT::i32 &&
6825+ isOperationLegalOrCustom(ISD::MULHU, WideSVT, IsAfterLegalization);
6826+ const bool HasWideUMUL_LOHI =
6827+ VT == MVT::i32 &&
6828+ isOperationLegalOrCustom(ISD::UMUL_LOHI, WideSVT, IsAfterLegalization);
6829+ const bool AllowWiden = (HasWideMULHU || HasWideUMUL_LOHI);
6830+
68206831 bool UseNPQ = false, UsePreShift = false, UsePostShift = false;
6821- const bool HasWideVT64MULHU =
6822- isOperationLegalOrCustom(ISD::MULHU, MVT::i64, IsAfterLegalization);
6823- const bool HasWideVT64UMUL_LOHI =
6824- isOperationLegalOrCustom(ISD::UMUL_LOHI, MVT::i64, IsAfterLegalization);
68256832 bool UseWiden = false;
68266833 SmallVector<SDValue, 16> PreShifts, PostShifts, MagicFactors, NPQFactors;
68276834
@@ -6840,8 +6847,6 @@ SDValue TargetLowering::BuildUDIV(SDNode *N, SelectionDAG &DAG,
68406847 PreShift = PostShift = DAG.getUNDEF(ShSVT);
68416848 MagicFactor = NPQFactor = DAG.getUNDEF(SVT);
68426849 } else {
6843- const bool AllowWiden = (EltBits == 32 && !VT.isVector() &&
6844- (HasWideVT64MULHU || HasWideVT64UMUL_LOHI));
68456850 UnsignedDivisionByConstantInfo magics =
68466851 UnsignedDivisionByConstantInfo::get(
68476852 Divisor, std::min(KnownLeadingZeros, Divisor.countl_zero()),
@@ -6850,7 +6855,7 @@ SDValue TargetLowering::BuildUDIV(SDNode *N, SelectionDAG &DAG,
68506855
68516856 if (magics.Widen) {
68526857 UseWiden = true;
6853- MagicFactor = DAG.getConstant(magics.Magic, dl, MVT::i64 );
6858+ MagicFactor = DAG.getConstant(magics.Magic, dl, WideSVT );
68546859 } else {
68556860 MagicFactor = DAG.getConstant(magics.Magic.zext(SVTBits), dl, SVT);
68566861 }
@@ -6906,18 +6911,20 @@ SDValue TargetLowering::BuildUDIV(SDNode *N, SelectionDAG &DAG,
69066911 }
69076912
69086913 if (UseWiden) {
6909- // Compute: (i64 (x) * MagicFactor) >> 64
6910- SDValue X64 = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i64 , N0);
6914+ // Compute: (WideSVT (x) * MagicFactor) >> WideSVTBits.
6915+ SDValue WideN0 = DAG.getNode(ISD::ZERO_EXTEND, dl, WideSVT , N0);
69116916
6912- // Perform 64x64 -> 128 multiplication and extract high 64 bits
6917+ // Perform WideSVTxWideSVT -> 2*WideSVT multiplication and extract high
6918+ // WideSVT bits
69136919 SDValue High;
6914- if (HasWideVT64MULHU ) {
6915- High = DAG.getNode(ISD::MULHU, dl, MVT::i64, X64 , MagicFactor);
6920+ if (HasWideMULHU ) {
6921+ High = DAG.getNode(ISD::MULHU, dl, WideSVT, WideN0 , MagicFactor);
69166922 } else {
6923+ assert(HasWideUMUL_LOHI);
69176924 SDValue LoHi =
6918- DAG.getNode(ISD::UMUL_LOHI, dl, DAG.getVTList(MVT::i64, MVT::i64 ),
6919- X64 , MagicFactor);
6920- High = SDValue( LoHi.getNode(), 1);
6925+ DAG.getNode(ISD::UMUL_LOHI, dl, DAG.getVTList(WideSVT, WideSVT ),
6926+ WideN0 , MagicFactor);
6927+ High = LoHi.getValue( 1);
69216928 }
69226929
69236930 Created.push_back(High.getNode());
0 commit comments