@@ -16498,43 +16498,60 @@ static SDValue expandMul(SDNode *N, SelectionDAG &DAG,
1649816498 SDValue X = N->getOperand(0);
1649916499
1650016500 if (Subtarget.hasShlAdd(3)) {
16501-  for (uint64_t Divisor : {3, 5, 9}) {
16502-  if (MulAmt % Divisor != 0)
16503-  continue;
16504-  uint64_t MulAmt2 = MulAmt / Divisor;
16505-  // 3/5/9 * 2^N -> shl (shXadd X, X), N
16506-  if (isPowerOf2_64(MulAmt2)) {
16507-  SDLoc DL(N);
16508-  SDValue X = N->getOperand(0);
16509-  // Put the shift first if we can fold a zext into the
16510-  // shift forming a slli.uw.
16511-  if (X.getOpcode() == ISD::AND && isa<ConstantSDNode>(X.getOperand(1)) &&
16512-  X.getConstantOperandVal(1) == UINT64_C(0xffffffff)) {
16513-  SDValue Shl = DAG.getNode(ISD::SHL, DL, VT, X,
16514-  DAG.getConstant(Log2_64(MulAmt2), DL, VT));
16515-  return DAG.getNode(RISCVISD::SHL_ADD, DL, VT, Shl,
16516-  DAG.getConstant(Log2_64(Divisor - 1), DL, VT),
16517-  Shl);
16518-  }
16519-  // Otherwise, put rhe shl second so that it can fold with following
16520-  // instructions (e.g. sext or add).
16521-  SDValue Mul359 =
16522-  DAG.getNode(RISCVISD::SHL_ADD, DL, VT, X,
16523-  DAG.getConstant(Log2_64(Divisor - 1), DL, VT), X);
16524-  return DAG.getNode(ISD::SHL, DL, VT, Mul359,
16525-  DAG.getConstant(Log2_64(MulAmt2), DL, VT));
16526-  }
16527- 
16528-  // 3/5/9 * 3/5/9 -> shXadd (shYadd X, X), (shYadd X, X)
16529-  if (MulAmt2 == 3 || MulAmt2 == 5 || MulAmt2 == 9) {
16530-  SDLoc DL(N);
16531-  SDValue Mul359 =
16532-  DAG.getNode(RISCVISD::SHL_ADD, DL, VT, X,
16533-  DAG.getConstant(Log2_64(Divisor - 1), DL, VT), X);
16534-  return DAG.getNode(RISCVISD::SHL_ADD, DL, VT, Mul359,
16535-  DAG.getConstant(Log2_64(MulAmt2 - 1), DL, VT),
16536-  Mul359);
16501+  int Shift;
16502+  if (int ShXAmount = isShifted359(MulAmt, Shift)) {
16503+  // 3/5/9 * 2^N -> shl (shXadd X, X), N
16504+  SDLoc DL(N);
16505+  SDValue X = N->getOperand(0);
16506+  // Put the shift first if we can fold a zext into the shift forming
16507+  // a slli.uw.
16508+  if (X.getOpcode() == ISD::AND && isa<ConstantSDNode>(X.getOperand(1)) &&
16509+  X.getConstantOperandVal(1) == UINT64_C(0xffffffff)) {
16510+  SDValue Shl =
16511+  DAG.getNode(ISD::SHL, DL, VT, X, DAG.getConstant(Shift, DL, VT));
16512+  return DAG.getNode(RISCVISD::SHL_ADD, DL, VT, Shl,
16513+  DAG.getConstant(ShXAmount, DL, VT), Shl);
1653716514 }
16515+  // Otherwise, put the shl second so that it can fold with following
16516+  // instructions (e.g. sext or add).
16517+  SDValue Mul359 = DAG.getNode(RISCVISD::SHL_ADD, DL, VT, X,
16518+  DAG.getConstant(ShXAmount, DL, VT), X);
16519+  return DAG.getNode(ISD::SHL, DL, VT, Mul359,
16520+  DAG.getConstant(Shift, DL, VT));
16521+  }
16522+ 
16523+  // 3/5/9 * 3/5/9 -> shXadd (shYadd X, X), (shYadd X, X)
16524+  int ShX;
16525+  int ShY;
16526+  switch (MulAmt) {
16527+  case 3 * 5:
16528+  ShY = 1;
16529+  ShX = 2;
16530+  break;
16531+  case 3 * 9:
16532+  ShY = 1;
16533+  ShX = 3;
16534+  break;
16535+  case 5 * 5:
16536+  ShX = ShY = 2;
16537+  break;
16538+  case 5 * 9:
16539+  ShY = 2;
16540+  ShX = 3;
16541+  break;
16542+  case 9 * 9:
16543+  ShX = ShY = 3;
16544+  break;
16545+  default:
16546+  ShX = ShY = 0;
16547+  break;
16548+  }
16549+  if (ShX) {
16550+  SDLoc DL(N);
16551+  SDValue Mul359 = DAG.getNode(RISCVISD::SHL_ADD, DL, VT, X,
16552+  DAG.getConstant(ShY, DL, VT), X);
16553+  return DAG.getNode(RISCVISD::SHL_ADD, DL, VT, Mul359,
16554+  DAG.getConstant(ShX, DL, VT), Mul359);
1653816555 }
1653916556
1654016557 // If this is a power 2 + 2/4/8, we can use a shift followed by a single
@@ -16557,26 +16574,22 @@ static SDValue expandMul(SDNode *N, SelectionDAG &DAG,
1655716574 // variants we could implement. e.g.
1655816575 // (2^(1,2,3) * 3,5,9 + 1) << C2
1655916576 // 2^(C1>3) * 3,5,9 +/- 1
16560-  for (uint64_t Divisor : {3, 5, 9}) {
16561-  uint64_t C = MulAmt - 1;
16562-  if (C <= Divisor)
16563-  continue;
16564-  unsigned TZ = llvm::countr_zero(C);
16565-  if ((C >> TZ) == Divisor && (TZ == 1 || TZ == 2 || TZ == 3)) {
16577+  if (int ShXAmount = isShifted359(MulAmt - 1, Shift)) {
16578+  assert(Shift != 0 && "MulAmt=4,6,10 handled before");
16579+  if (Shift <= 3) {
1656616580 SDLoc DL(N);
16567-  SDValue Mul359 =
16568-  DAG.getNode(RISCVISD::SHL_ADD, DL, VT, X,
16569-  DAG.getConstant(Log2_64(Divisor - 1), DL, VT), X);
16581+  SDValue Mul359 = DAG.getNode(RISCVISD::SHL_ADD, DL, VT, X,
16582+  DAG.getConstant(ShXAmount, DL, VT), X);
1657016583 return DAG.getNode(RISCVISD::SHL_ADD, DL, VT, Mul359,
16571-  DAG.getConstant(TZ , DL, VT), X);
16584+  DAG.getConstant(Shift , DL, VT), X);
1657216585 }
1657316586 }
1657416587
1657516588 // 2^n + 2/4/8 + 1 -> (add (shl X, C1), (shXadd X, X))
1657616589 if (MulAmt > 2 && isPowerOf2_64((MulAmt - 1) & (MulAmt - 2))) {
1657716590 unsigned ScaleShift = llvm::countr_zero(MulAmt - 1);
1657816591 if (ScaleShift >= 1 && ScaleShift < 4) {
16579-  unsigned ShiftAmt = Log2_64((( MulAmt - 1) & (MulAmt - 2) ));
16592+  unsigned ShiftAmt = llvm::countr_zero(( MulAmt - 1) & (MulAmt - 2));
1658016593 SDLoc DL(N);
1658116594 SDValue Shift1 =
1658216595 DAG.getNode(ISD::SHL, DL, VT, X, DAG.getConstant(ShiftAmt, DL, VT));
@@ -16589,7 +16602,7 @@ static SDValue expandMul(SDNode *N, SelectionDAG &DAG,
1658916602 // 2^N - 3/5/9 --> (sub (shl X, C1), (shXadd X, x))
1659016603 for (uint64_t Offset : {3, 5, 9}) {
1659116604 if (isPowerOf2_64(MulAmt + Offset)) {
16592-  unsigned ShAmt = Log2_64 (MulAmt + Offset);
16605+  unsigned ShAmt = llvm::countr_zero (MulAmt + Offset);
1659316606 if (ShAmt >= VT.getSizeInBits())
1659416607 continue;
1659516608 SDLoc DL(N);
@@ -16608,21 +16621,16 @@ static SDValue expandMul(SDNode *N, SelectionDAG &DAG,
1660816621 uint64_t MulAmt2 = MulAmt / Divisor;
1660916622 // 3/5/9 * 3/5/9 * 2^N - In particular, this covers multiples
1661016623 // of 25 which happen to be quite common.
16611-  for (uint64_t Divisor2 : {3, 5, 9}) {
16612-  if (MulAmt2 % Divisor2 != 0)
16613-  continue;
16614-  uint64_t MulAmt3 = MulAmt2 / Divisor2;
16615-  if (isPowerOf2_64(MulAmt3)) {
16616-  SDLoc DL(N);
16617-  SDValue Mul359A =
16618-  DAG.getNode(RISCVISD::SHL_ADD, DL, VT, X,
16619-  DAG.getConstant(Log2_64(Divisor - 1), DL, VT), X);
16620-  SDValue Mul359B = DAG.getNode(
16621-  RISCVISD::SHL_ADD, DL, VT, Mul359A,
16622-  DAG.getConstant(Log2_64(Divisor2 - 1), DL, VT), Mul359A);
16623-  return DAG.getNode(ISD::SHL, DL, VT, Mul359B,
16624-  DAG.getConstant(Log2_64(MulAmt3), DL, VT));
16625-  }
16624+  if (int ShBAmount = isShifted359(MulAmt2, Shift)) {
16625+  SDLoc DL(N);
16626+  SDValue Mul359A =
16627+  DAG.getNode(RISCVISD::SHL_ADD, DL, VT, X,
16628+  DAG.getConstant(Log2_64(Divisor - 1), DL, VT), X);
16629+  SDValue Mul359B =
16630+  DAG.getNode(RISCVISD::SHL_ADD, DL, VT, Mul359A,
16631+  DAG.getConstant(ShBAmount, DL, VT), Mul359A);
16632+  return DAG.getNode(ISD::SHL, DL, VT, Mul359B,
16633+  DAG.getConstant(Shift, DL, VT));
1662616634 }
1662716635 }
1662816636 }
0 commit comments