@@ -7613,54 +7613,54 @@ static SDValue performMulCombine(SDNode *N, SelectionDAG &DAG,
76137613 if (DCI.isBeforeLegalizeOps ())
76147614 return SDValue ();
76157615
7616+ // The below optimizations require a constant RHS.
7617+ if (!isa<ConstantSDNode>(N->getOperand (1 )))
7618+ return SDValue ();
7619+
7620+ ConstantSDNode *C = cast<ConstantSDNode>(N->getOperand (1 ));
7621+ const APInt &ConstValue = C->getAPIntValue ();
7622+
76167623 // Multiplication of a power of two plus/minus one can be done more
76177624 // cheaply as as shift+add/sub. For now, this is true unilaterally. If
76187625 // future CPUs have a cheaper MADD instruction, this may need to be
76197626 // gated on a subtarget feature. For Cyclone, 32-bit MADD is 4 cycles and
76207627 // 64-bit is 5 cycles, so this is always a win.
7621- if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand (1 ))) {
7622- const APInt &Value = C->getAPIntValue ();
7623- EVT VT = N->getValueType (0 );
7624- SDLoc DL (N);
7625- if (Value.isNonNegative ()) {
7626- // (mul x, 2^N + 1) => (add (shl x, N), x)
7627- APInt VM1 = Value - 1 ;
7628- if (VM1.isPowerOf2 ()) {
7629- SDValue ShiftedVal =
7630- DAG.getNode (ISD::SHL, DL, VT, N->getOperand (0 ),
7631- DAG.getConstant (VM1.logBase2 (), DL, MVT::i64 ));
7632- return DAG.getNode (ISD::ADD, DL, VT, ShiftedVal,
7633- N->getOperand (0 ));
7634- }
7635- // (mul x, 2^N - 1) => (sub (shl x, N), x)
7636- APInt VP1 = Value + 1 ;
7637- if (VP1.isPowerOf2 ()) {
7638- SDValue ShiftedVal =
7639- DAG.getNode (ISD::SHL, DL, VT, N->getOperand (0 ),
7640- DAG.getConstant (VP1.logBase2 (), DL, MVT::i64 ));
7641- return DAG.getNode (ISD::SUB, DL, VT, ShiftedVal,
7642- N->getOperand (0 ));
7643- }
7644- } else {
7645- // (mul x, -(2^N - 1)) => (sub x, (shl x, N))
7646- APInt VNP1 = -Value + 1 ;
7647- if (VNP1.isPowerOf2 ()) {
7648- SDValue ShiftedVal =
7649- DAG.getNode (ISD::SHL, DL, VT, N->getOperand (0 ),
7650- DAG.getConstant (VNP1.logBase2 (), DL, MVT::i64 ));
7651- return DAG.getNode (ISD::SUB, DL, VT, N->getOperand (0 ),
7652- ShiftedVal);
7653- }
7654- // (mul x, -(2^N + 1)) => - (add (shl x, N), x)
7655- APInt VNM1 = -Value - 1 ;
7656- if (VNM1.isPowerOf2 ()) {
7657- SDValue ShiftedVal =
7658- DAG.getNode (ISD::SHL, DL, VT, N->getOperand (0 ),
7659- DAG.getConstant (VNM1.logBase2 (), DL, MVT::i64 ));
7660- SDValue Add =
7661- DAG.getNode (ISD::ADD, DL, VT, ShiftedVal, N->getOperand (0 ));
7662- return DAG.getNode (ISD::SUB, DL, VT, DAG.getConstant (0 , DL, VT), Add);
7663- }
7628+ SDLoc DL (N);
7629+ EVT VT = N->getValueType (0 );
7630+ if (ConstValue.isNonNegative ()) {
7631+ // (mul x, 2^N + 1) => (add (shl x, N), x)
7632+ APInt CVMinus1 = ConstValue - 1 ;
7633+ if (CVMinus1.isPowerOf2 ()) {
7634+ SDValue ShiftedVal =
7635+ DAG.getNode (ISD::SHL, DL, VT, N->getOperand (0 ),
7636+ DAG.getConstant (CVMinus1.logBase2 (), DL, MVT::i64 ));
7637+ return DAG.getNode (ISD::ADD, DL, VT, ShiftedVal, N->getOperand (0 ));
7638+ }
7639+ // (mul x, 2^N - 1) => (sub (shl x, N), x)
7640+ APInt CVPlus1 = ConstValue + 1 ;
7641+ if (CVPlus1.isPowerOf2 ()) {
7642+ SDValue ShiftedVal =
7643+ DAG.getNode (ISD::SHL, DL, VT, N->getOperand (0 ),
7644+ DAG.getConstant (CVPlus1.logBase2 (), DL, MVT::i64 ));
7645+ return DAG.getNode (ISD::SUB, DL, VT, ShiftedVal, N->getOperand (0 ));
7646+ }
7647+ } else {
7648+ // (mul x, -(2^N - 1)) => (sub x, (shl x, N))
7649+ APInt CVNegPlus1 = -ConstValue + 1 ;
7650+ if (CVNegPlus1.isPowerOf2 ()) {
7651+ SDValue ShiftedVal =
7652+ DAG.getNode (ISD::SHL, DL, VT, N->getOperand (0 ),
7653+ DAG.getConstant (CVNegPlus1.logBase2 (), DL, MVT::i64 ));
7654+ return DAG.getNode (ISD::SUB, DL, VT, N->getOperand (0 ), ShiftedVal);
7655+ }
7656+ // (mul x, -(2^N + 1)) => - (add (shl x, N), x)
7657+ APInt CVNegMinus1 = -ConstValue - 1 ;
7658+ if (CVNegMinus1.isPowerOf2 ()) {
7659+ SDValue ShiftedVal =
7660+ DAG.getNode (ISD::SHL, DL, VT, N->getOperand (0 ),
7661+ DAG.getConstant (CVNegMinus1.logBase2 (), DL, MVT::i64 ));
7662+ SDValue Add = DAG.getNode (ISD::ADD, DL, VT, ShiftedVal, N->getOperand (0 ));
7663+ return DAG.getNode (ISD::SUB, DL, VT, DAG.getConstant (0 , DL, VT), Add);
76647664 }
76657665 }
76667666 return SDValue ();
0 commit comments