@@ -15453,8 +15453,11 @@ static SDValue performXORCombine(SDNode *N, SelectionDAG &DAG,
15453
15453
return combineSelectAndUseCommutative(N, DAG, /*AllOnes*/ false, Subtarget);
15454
15454
}
15455
15455
15456
+ // Try to expand a multiply to a sequence of shifts and add/subs,
15457
+ // for a machine without native mul instruction.
15456
15458
static SDValue expandMulToNAFSequence(SDNode *N, SelectionDAG &DAG,
15457
- const SDLoc &DL, uint64_t MulAmt) {
15459
+ uint64_t MulAmt) {
15460
+ SDLoc DL(N);
15458
15461
EVT VT = N->getValueType(0);
15459
15462
const uint64_t BitWidth = VT.getFixedSizeInBits();
15460
15463
@@ -15472,85 +15475,13 @@ static SDValue expandMulToNAFSequence(SDNode *N, SelectionDAG &DAG,
15472
15475
SDValue N0 = N->getOperand(0);
15473
15476
15474
15477
for (const auto &Op : Sequence) {
15475
- SDValue ShiftVal;
15476
- if (Op.second > 0)
15477
- ShiftVal =
15478
- DAG.getNode(ISD::SHL, DL, VT, N0, DAG.getConstant(Op.second, DL, VT));
15479
- else
15480
- ShiftVal = N0;
15481
-
15478
+ SDValue ShiftVal = DAG.getNode(
15479
+ ISD::SHL, DL, VT, N0, DAG.getShiftAmountConstant(Op.second, VT, DL));
15482
15480
ISD::NodeType AddSubOp = Op.first ? ISD::ADD : ISD::SUB;
15483
15481
Result = DAG.getNode(AddSubOp, DL, VT, Result, ShiftVal);
15484
15482
}
15485
15483
return Result;
15486
15484
}
15487
- // Try to expand a multiply to a sequence of shifts and add/subs,
15488
- // for a machine without native mul instruction.
15489
- static SDValue expandMulToBasicOps(SDNode *N, SelectionDAG &DAG,
15490
- uint64_t MulAmt) {
15491
- EVT VT = N->getValueType(0);
15492
- const uint64_t BitWidth = VT.getFixedSizeInBits();
15493
- SDLoc DL(N);
15494
-
15495
- if (MulAmt == 0)
15496
- return DAG.getConstant(0, DL, N->getValueType(0));
15497
-
15498
- // Try to factorize into (2^N) * (2^M_1 +/- 1) * (2^M_2 +/- 1) * ...
15499
- uint64_t TrailingZeros = llvm::countr_zero(MulAmt);
15500
- uint64_t E = MulAmt >> TrailingZeros;
15501
-
15502
- llvm::SmallVector<std::pair<bool, uint64_t>> Factors; // {is_2^M+1, M}
15503
-
15504
- while (E > 1) {
15505
- bool Found = false;
15506
- for (int64_t I = BitWidth - 1; I >= 2; --I) {
15507
- uint64_t Factor = 1ULL << I;
15508
-
15509
- if (E % (Factor + 1) == 0) {
15510
- Factors.push_back({true, I});
15511
- E /= Factor + 1;
15512
- Found = true;
15513
- break;
15514
- }
15515
- if (E % (Factor - 1) == 0) {
15516
- Factors.push_back({false, I});
15517
- E /= Factor - 1;
15518
- Found = true;
15519
- break;
15520
- }
15521
- }
15522
- if (!Found)
15523
- break;
15524
- }
15525
-
15526
- SDValue Result;
15527
- SDValue N0 = N->getOperand(0);
15528
-
15529
- bool UseFactorization = !Factors.empty() && (Factors.size() < 5);
15530
-
15531
- if (UseFactorization) {
15532
- if (E == 1)
15533
- Result = N0;
15534
- else
15535
- Result = expandMulToNAFSequence(N, DAG, DL, E);
15536
-
15537
- for (const auto &F : Factors) {
15538
- SDValue ShiftVal = DAG.getNode(ISD::SHL, DL, VT, Result,
15539
- DAG.getConstant(F.second, DL, VT));
15540
-
15541
- ISD::NodeType AddSubOp = F.first ? ISD::ADD : ISD::SUB;
15542
- Result = DAG.getNode(AddSubOp, DL, N->getValueType(0), ShiftVal, Result);
15543
- }
15544
-
15545
- if (TrailingZeros > 0)
15546
- Result = DAG.getNode(ISD::SHL, DL, VT, Result,
15547
- DAG.getConstant(TrailingZeros, DL, VT));
15548
-
15549
- return Result;
15550
- }
15551
-
15552
- return expandMulToNAFSequence(N, DAG, DL, MulAmt);
15553
- }
15554
15485
15555
15486
// X * (2^N +/- 2^M) -> (add/sub (shl X, C1), (shl X, C2))
15556
15487
static SDValue expandMulToAddOrSubOfShl(SDNode *N, SelectionDAG &DAG,
@@ -15590,17 +15521,17 @@ static SDValue expandMul(SDNode *N, SelectionDAG &DAG,
15590
15521
if (VT != Subtarget.getXLenVT())
15591
15522
return SDValue();
15592
15523
15524
+ bool ShouldExpandMul =
15525
+ (!DCI.isBeforeLegalize() && !DCI.isCalledByLegalizer()) ||
15526
+ !Subtarget.hasStdExtZmmul();
15527
+ if (!ShouldExpandMul)
15528
+ return SDValue();
15529
+
15593
15530
ConstantSDNode *CNode = dyn_cast<ConstantSDNode>(N->getOperand(1));
15594
15531
if (!CNode)
15595
15532
return SDValue();
15596
15533
uint64_t MulAmt = CNode->getZExtValue();
15597
15534
15598
- if (!Subtarget.hasStdExtM() && !Subtarget.hasStdExtZmmul())
15599
- return expandMulToBasicOps(N, DAG, MulAmt);
15600
-
15601
- if (DCI.isBeforeLegalize() || DCI.isCalledByLegalizer())
15602
- return SDValue();
15603
-
15604
15535
const bool HasShlAdd = Subtarget.hasStdExtZba() ||
15605
15536
Subtarget.hasVendorXTHeadBa() ||
15606
15537
Subtarget.hasVendorXAndesPerf();
@@ -15742,6 +15673,9 @@ static SDValue expandMul(SDNode *N, SelectionDAG &DAG,
15742
15673
if (SDValue V = expandMulToAddOrSubOfShl(N, DAG, MulAmt))
15743
15674
return V;
15744
15675
15676
+ if (!Subtarget.hasStdExtZmmul())
15677
+ return expandMulToNAFSequence(N, DAG, MulAmt);
15678
+
15745
15679
return SDValue();
15746
15680
}
15747
15681
0 commit comments