@@ -10857,6 +10857,64 @@ SDValue TargetLowering::expandShlSat(SDNode *Node, SelectionDAG &DAG) const {
1085710857 return DAG.getSelect (dl, VT, Cond, SatVal, Result);
1085810858}
1085910859
10860+ void TargetLowering::forceExpandMUL (SelectionDAG &DAG, const SDLoc &dl,
10861+ bool Signed, SDValue &Lo, SDValue &Hi,
10862+ SDValue LHS, SDValue RHS, SDValue HiLHS,
10863+ SDValue HiRHS) const {
10864+ EVT VT = LHS.getValueType ();
10865+ assert (RHS.getValueType () == VT && " Mismatching operand types" );
10866+
10867+ assert ((HiLHS && HiRHS) || (!HiLHS && !HiRHS));
10868+ assert ((!Signed || !HiLHS) &&
10869+ " Signed flag should only be set when HiLHS and RiRHS are null" );
10870+
10871+ // We'll expand the multiplication by brute force because we have no other
10872+ // options. This is a trivially-generalized version of the code from
10873+ // Hacker's Delight (itself derived from Knuth's Algorithm M from section
10874+ // 4.3.1). If Signed is set, we can use arithmetic right shifts to propagate
10875+ // sign bits while calculating the Hi half.
10876+ unsigned Bits = VT.getSizeInBits ();
10877+ unsigned HalfBits = Bits / 2 ;
10878+ SDValue Mask = DAG.getConstant (APInt::getLowBitsSet (Bits, HalfBits), dl, VT);
10879+ SDValue LL = DAG.getNode (ISD::AND, dl, VT, LHS, Mask);
10880+ SDValue RL = DAG.getNode (ISD::AND, dl, VT, RHS, Mask);
10881+
10882+ SDValue T = DAG.getNode (ISD::MUL, dl, VT, LL, RL);
10883+ SDValue TL = DAG.getNode (ISD::AND, dl, VT, T, Mask);
10884+
10885+ SDValue Shift = DAG.getShiftAmountConstant (HalfBits, VT, dl);
10886+ // This is always an unsigned shift.
10887+ SDValue TH = DAG.getNode (ISD::SRL, dl, VT, T, Shift);
10888+
10889+ unsigned ShiftOpc = Signed ? ISD::SRA : ISD::SRL;
10890+ SDValue LH = DAG.getNode (ShiftOpc, dl, VT, LHS, Shift);
10891+ SDValue RH = DAG.getNode (ShiftOpc, dl, VT, RHS, Shift);
10892+
10893+ SDValue U =
10894+ DAG.getNode (ISD::ADD, dl, VT, DAG.getNode (ISD::MUL, dl, VT, LH, RL), TH);
10895+ SDValue UL = DAG.getNode (ISD::AND, dl, VT, U, Mask);
10896+ SDValue UH = DAG.getNode (ShiftOpc, dl, VT, U, Shift);
10897+
10898+ SDValue V =
10899+ DAG.getNode (ISD::ADD, dl, VT, DAG.getNode (ISD::MUL, dl, VT, LL, RH), UL);
10900+ SDValue VH = DAG.getNode (ShiftOpc, dl, VT, V, Shift);
10901+
10902+ Lo = DAG.getNode (ISD::ADD, dl, VT, TL,
10903+ DAG.getNode (ISD::SHL, dl, VT, V, Shift));
10904+
10905+ Hi = DAG.getNode (ISD::ADD, dl, VT, DAG.getNode (ISD::MUL, dl, VT, LH, RH),
10906+ DAG.getNode (ISD::ADD, dl, VT, UH, VH));
10907+
10908+ // If HiLHS and HiRHS are set, multiply them by the opposite low part and add
10909+ // them to products to Hi.
10910+ if (HiLHS) {
10911+ Hi = DAG.getNode (ISD::ADD, dl, VT, Hi,
10912+ DAG.getNode (ISD::ADD, dl, VT,
10913+ DAG.getNode (ISD::MUL, dl, VT, HiRHS, LHS),
10914+ DAG.getNode (ISD::MUL, dl, VT, RHS, HiLHS)));
10915+ }
10916+ }
10917+
1086010918void TargetLowering::forceExpandWideMUL (SelectionDAG &DAG, const SDLoc &dl,
1086110919 bool Signed, const SDValue LHS,
1086210920 const SDValue RHS, SDValue &Lo,
@@ -10876,7 +10934,11 @@ void TargetLowering::forceExpandWideMUL(SelectionDAG &DAG, const SDLoc &dl,
1087610934 else if (WideVT == MVT::i128 )
1087710935 LC = RTLIB::MUL_I128;
1087810936
10879- if (LC != RTLIB::UNKNOWN_LIBCALL && getLibcallName (LC)) {
10937+ if (LC == RTLIB::UNKNOWN_LIBCALL || !getLibcallName (LC)) {
10938+ forceExpandMUL (DAG, dl, Signed, Lo, Hi, LHS, RHS);
10939+ return ;
10940+ }
10941+
1088010942 SDValue HiLHS, HiRHS;
1088110943 if (Signed) {
1088210944 // The high part is obtained by SRA'ing all but one of the bits of low
@@ -10916,44 +10978,6 @@ void TargetLowering::forceExpandWideMUL(SelectionDAG &DAG, const SDLoc &dl,
1091610978 Lo = Ret.getOperand (1 );
1091710979 Hi = Ret.getOperand (0 );
1091810980 }
10919- return ;
10920- }
10921-
10922- // Expand the multiplication by brute force. This is a generalized-version of
10923- // the code from Hacker's Delight (itself derived from Knuth's Algorithm M
10924- // from section 4.3.1) combined with the Hacker's delight code
10925- // for calculating mulhs.
10926- unsigned Bits = VT.getSizeInBits ();
10927- unsigned HalfBits = Bits / 2 ;
10928- SDValue Mask = DAG.getConstant (APInt::getLowBitsSet (Bits, HalfBits), dl, VT);
10929- SDValue LL = DAG.getNode (ISD::AND, dl, VT, LHS, Mask);
10930- SDValue RL = DAG.getNode (ISD::AND, dl, VT, RHS, Mask);
10931-
10932- SDValue T = DAG.getNode (ISD::MUL, dl, VT, LL, RL);
10933- SDValue TL = DAG.getNode (ISD::AND, dl, VT, T, Mask);
10934-
10935- SDValue Shift = DAG.getShiftAmountConstant (HalfBits, VT, dl);
10936- // This is always an unsigned shift.
10937- SDValue TH = DAG.getNode (ISD::SRL, dl, VT, T, Shift);
10938-
10939- unsigned ShiftOpc = Signed ? ISD::SRA : ISD::SRL;
10940- SDValue LH = DAG.getNode (ShiftOpc, dl, VT, LHS, Shift);
10941- SDValue RH = DAG.getNode (ShiftOpc, dl, VT, RHS, Shift);
10942-
10943- SDValue U =
10944- DAG.getNode (ISD::ADD, dl, VT, DAG.getNode (ISD::MUL, dl, VT, LH, RL), TH);
10945- SDValue UL = DAG.getNode (ISD::AND, dl, VT, U, Mask);
10946- SDValue UH = DAG.getNode (ShiftOpc, dl, VT, U, Shift);
10947-
10948- SDValue V =
10949- DAG.getNode (ISD::ADD, dl, VT, DAG.getNode (ISD::MUL, dl, VT, LL, RH), UL);
10950- SDValue VH = DAG.getNode (ShiftOpc, dl, VT, V, Shift);
10951-
10952- Lo = DAG.getNode (ISD::ADD, dl, VT, TL,
10953- DAG.getNode (ISD::SHL, dl, VT, V, Shift));
10954-
10955- Hi = DAG.getNode (ISD::ADD, dl, VT, DAG.getNode (ISD::MUL, dl, VT, LH, RH),
10956- DAG.getNode (ISD::ADD, dl, VT, UH, VH));
1095710981}
1095810982
1095910983SDValue
0 commit comments