@@ -15503,8 +15503,11 @@ static SDValue performXORCombine(SDNode *N, SelectionDAG &DAG,
15503
15503
return combineSelectAndUseCommutative(N, DAG, /*AllOnes*/ false, Subtarget);
15504
15504
}
15505
15505
15506
+ // Try to expand a multiply to a sequence of shifts and add/subs,
15507
+ // for a machine without native mul instruction.
15506
15508
static SDValue expandMulToNAFSequence(SDNode *N, SelectionDAG &DAG,
15507
- const SDLoc &DL, uint64_t MulAmt) {
15509
+ uint64_t MulAmt) {
15510
+ SDLoc DL(N);
15508
15511
EVT VT = N->getValueType(0);
15509
15512
const uint64_t BitWidth = VT.getFixedSizeInBits();
15510
15513
@@ -15522,85 +15525,13 @@ static SDValue expandMulToNAFSequence(SDNode *N, SelectionDAG &DAG,
15522
15525
SDValue N0 = N->getOperand(0);
15523
15526
15524
15527
for (const auto &Op : Sequence) {
15525
- SDValue ShiftVal;
15526
- if (Op.second > 0)
15527
- ShiftVal =
15528
- DAG.getNode(ISD::SHL, DL, VT, N0, DAG.getConstant(Op.second, DL, VT));
15529
- else
15530
- ShiftVal = N0;
15531
-
15528
+ SDValue ShiftVal = DAG.getNode(
15529
+ ISD::SHL, DL, VT, N0, DAG.getShiftAmountConstant(Op.second, VT, DL));
15532
15530
ISD::NodeType AddSubOp = Op.first ? ISD::ADD : ISD::SUB;
15533
15531
Result = DAG.getNode(AddSubOp, DL, VT, Result, ShiftVal);
15534
15532
}
15535
15533
return Result;
15536
15534
}
15537
- // Try to expand a multiply to a sequence of shifts and add/subs,
15538
- // for a machine without native mul instruction.
15539
- static SDValue expandMulToBasicOps(SDNode *N, SelectionDAG &DAG,
15540
- uint64_t MulAmt) {
15541
- EVT VT = N->getValueType(0);
15542
- const uint64_t BitWidth = VT.getFixedSizeInBits();
15543
- SDLoc DL(N);
15544
-
15545
- if (MulAmt == 0)
15546
- return DAG.getConstant(0, DL, N->getValueType(0));
15547
-
15548
- // Try to factorize into (2^N) * (2^M_1 +/- 1) * (2^M_2 +/- 1) * ...
15549
- uint64_t TrailingZeros = llvm::countr_zero(MulAmt);
15550
- uint64_t E = MulAmt >> TrailingZeros;
15551
-
15552
- llvm::SmallVector<std::pair<bool, uint64_t>> Factors; // {is_2^M+1, M}
15553
-
15554
- while (E > 1) {
15555
- bool Found = false;
15556
- for (int64_t I = BitWidth - 1; I >= 2; --I) {
15557
- uint64_t Factor = 1ULL << I;
15558
-
15559
- if (E % (Factor + 1) == 0) {
15560
- Factors.push_back({true, I});
15561
- E /= Factor + 1;
15562
- Found = true;
15563
- break;
15564
- }
15565
- if (E % (Factor - 1) == 0) {
15566
- Factors.push_back({false, I});
15567
- E /= Factor - 1;
15568
- Found = true;
15569
- break;
15570
- }
15571
- }
15572
- if (!Found)
15573
- break;
15574
- }
15575
-
15576
- SDValue Result;
15577
- SDValue N0 = N->getOperand(0);
15578
-
15579
- bool UseFactorization = !Factors.empty() && (Factors.size() < 5);
15580
-
15581
- if (UseFactorization) {
15582
- if (E == 1)
15583
- Result = N0;
15584
- else
15585
- Result = expandMulToNAFSequence(N, DAG, DL, E);
15586
-
15587
- for (const auto &F : Factors) {
15588
- SDValue ShiftVal = DAG.getNode(ISD::SHL, DL, VT, Result,
15589
- DAG.getConstant(F.second, DL, VT));
15590
-
15591
- ISD::NodeType AddSubOp = F.first ? ISD::ADD : ISD::SUB;
15592
- Result = DAG.getNode(AddSubOp, DL, N->getValueType(0), ShiftVal, Result);
15593
- }
15594
-
15595
- if (TrailingZeros > 0)
15596
- Result = DAG.getNode(ISD::SHL, DL, VT, Result,
15597
- DAG.getConstant(TrailingZeros, DL, VT));
15598
-
15599
- return Result;
15600
- }
15601
-
15602
- return expandMulToNAFSequence(N, DAG, DL, MulAmt);
15603
- }
15604
15535
15605
15536
// X * (2^N +/- 2^M) -> (add/sub (shl X, C1), (shl X, C2))
15606
15537
static SDValue expandMulToAddOrSubOfShl(SDNode *N, SelectionDAG &DAG,
@@ -15640,17 +15571,17 @@ static SDValue expandMul(SDNode *N, SelectionDAG &DAG,
15640
15571
if (VT != Subtarget.getXLenVT())
15641
15572
return SDValue();
15642
15573
15574
+ bool ShouldExpandMul =
15575
+ (!DCI.isBeforeLegalize() && !DCI.isCalledByLegalizer()) ||
15576
+ !Subtarget.hasStdExtZmmul();
15577
+ if (!ShouldExpandMul)
15578
+ return SDValue();
15579
+
15643
15580
ConstantSDNode *CNode = dyn_cast<ConstantSDNode>(N->getOperand(1));
15644
15581
if (!CNode)
15645
15582
return SDValue();
15646
15583
uint64_t MulAmt = CNode->getZExtValue();
15647
15584
15648
- if (!Subtarget.hasStdExtM() && !Subtarget.hasStdExtZmmul())
15649
- return expandMulToBasicOps(N, DAG, MulAmt);
15650
-
15651
- if (DCI.isBeforeLegalize() || DCI.isCalledByLegalizer())
15652
- return SDValue();
15653
-
15654
15585
const bool HasShlAdd = Subtarget.hasStdExtZba() ||
15655
15586
Subtarget.hasVendorXTHeadBa() ||
15656
15587
Subtarget.hasVendorXAndesPerf();
@@ -15792,6 +15723,9 @@ static SDValue expandMul(SDNode *N, SelectionDAG &DAG,
15792
15723
if (SDValue V = expandMulToAddOrSubOfShl(N, DAG, MulAmt))
15793
15724
return V;
15794
15725
15726
+ if (!Subtarget.hasStdExtZmmul())
15727
+ return expandMulToNAFSequence(N, DAG, MulAmt);
15728
+
15795
15729
return SDValue();
15796
15730
}
15797
15731
0 commit comments