@@ -7613,54 +7613,54 @@ static SDValue performMulCombine(SDNode *N, SelectionDAG &DAG,
7613
7613
if (DCI.isBeforeLegalizeOps ())
7614
7614
return SDValue ();
7615
7615
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
+
7616
7623
// Multiplication of a power of two plus/minus one can be done more
7617
7624
// cheaply as as shift+add/sub. For now, this is true unilaterally. If
7618
7625
// future CPUs have a cheaper MADD instruction, this may need to be
7619
7626
// gated on a subtarget feature. For Cyclone, 32-bit MADD is 4 cycles and
7620
7627
// 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);
7664
7664
}
7665
7665
}
7666
7666
return SDValue ();
0 commit comments