[PATCH] D107711: [RISCV] Optimize (add (mul x, c0), c1)

Ben Shi via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sun Aug 8 03:04:54 PDT 2021


benshi001 created this revision.
benshi001 added reviewers: asb, luismarques, craig.topper.
Herald added subscribers: vkmr, frasercrmck, evandro, apazos, sameer.abuasal, s.egerton, Jim, benna, psnobl, jocewei, PkmX, the_o, brucehoult, MartinMosbeck, rogfer01, edward-jones, zzheng, jrtc27, shiva0217, kito-cheng, niosHD, sabuasal, simoncook, johnrusso, rbar, hiraditya.
benshi001 requested review of this revision.
Herald added subscribers: llvm-commits, MaskRay.
Herald added a project: LLVM.

This patch optimizes (add (mul x, c0), c1) to
(mul (add x, c1/c0), c0) if the constants c0 and c1 match
c1/c0 is simm12, while c1 is not, and c1%c0 == 0.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D107711

Files:
  llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
  llvm/test/CodeGen/RISCV/addimm-mulimm.ll


Index: llvm/test/CodeGen/RISCV/addimm-mulimm.ll
===================================================================
--- llvm/test/CodeGen/RISCV/addimm-mulimm.ll
+++ llvm/test/CodeGen/RISCV/addimm-mulimm.ll
@@ -146,20 +146,16 @@
 define i32 @add_mul_trans_accept_a0(i32 %x) {
 ; RV32IM-LABEL: add_mul_trans_accept_a0:
 ; RV32IM:       # %bb.0:
+; RV32IM-NEXT:    addi a0, a0, 1971
 ; RV32IM-NEXT:    addi a1, zero, 19
 ; RV32IM-NEXT:    mul a0, a0, a1
-; RV32IM-NEXT:    lui a1, 9
-; RV32IM-NEXT:    addi a1, a1, 585
-; RV32IM-NEXT:    add a0, a0, a1
 ; RV32IM-NEXT:    ret
 ;
 ; RV64IM-LABEL: add_mul_trans_accept_a0:
 ; RV64IM:       # %bb.0:
+; RV64IM-NEXT:    addi a0, a0, 1971
 ; RV64IM-NEXT:    addi a1, zero, 19
 ; RV64IM-NEXT:    mul a0, a0, a1
-; RV64IM-NEXT:    lui a1, 9
-; RV64IM-NEXT:    addiw a1, a1, 585
-; RV64IM-NEXT:    add a0, a0, a1
 ; RV64IM-NEXT:    ret
   %tmp0 = add i32 %x, 1971
   %tmp1 = mul i32 %tmp0, 19
@@ -169,11 +165,9 @@
 define signext i32 @add_mul_trans_accept_a1(i32 signext %x) {
 ; RV32IM-LABEL: add_mul_trans_accept_a1:
 ; RV32IM:       # %bb.0:
+; RV32IM-NEXT:    addi a0, a0, 1971
 ; RV32IM-NEXT:    addi a1, zero, 19
 ; RV32IM-NEXT:    mul a0, a0, a1
-; RV32IM-NEXT:    lui a1, 9
-; RV32IM-NEXT:    addi a1, a1, 585
-; RV32IM-NEXT:    add a0, a0, a1
 ; RV32IM-NEXT:    ret
 ;
 ; RV64IM-LABEL: add_mul_trans_accept_a1:
@@ -206,11 +200,9 @@
 ;
 ; RV64IM-LABEL: add_mul_trans_accept_a2:
 ; RV64IM:       # %bb.0:
+; RV64IM-NEXT:    addi a0, a0, 1971
 ; RV64IM-NEXT:    addi a1, zero, 19
 ; RV64IM-NEXT:    mul a0, a0, a1
-; RV64IM-NEXT:    lui a1, 9
-; RV64IM-NEXT:    addiw a1, a1, 585
-; RV64IM-NEXT:    add a0, a0, a1
 ; RV64IM-NEXT:    ret
   %tmp0 = add i64 %x, 1971
   %tmp1 = mul i64 %tmp0, 19
Index: llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
===================================================================
--- llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -504,6 +504,41 @@
 
     break;
   }
+  case ISD::ADD: {
+    // Optimize (add (mul x, c0), c1) to (mul (add x, c1/c0), c0),
+    // if c1/c0 is simm12, while c1 is not, and c1%c0==0.
+    MVT VT = Node->getSimpleValueType(0);
+    // The type must be a scalar type.
+    if (VT.isVector())
+      break;
+    // The first operand node must be a MUL and has no other use.
+    SDValue N0 = Node->getOperand(0);
+    if (!N0->hasOneUse() || N0->getOpcode() != ISD::MUL)
+      break;
+    // Check c0 and c1.
+    auto *NC0 = dyn_cast<ConstantSDNode>(N0->getOperand(1));
+    if (!NC0)
+      break;
+    auto *NC1 = dyn_cast<ConstantSDNode>(Node->getOperand(1));
+    if (!NC1)
+      break;
+    int64_t C0 = NC0->getSExtValue();
+    int64_t C1 = NC1->getSExtValue();
+    // Check if c0 and c1 match the conditions mentioned above.
+    if (APInt(64, C1).isSignedIntN(12) || (C1 % C0) != 0 ||
+        !APInt(64, C1 / C0).isSignedIntN(12))
+      break;
+    // Build new nodes (mul (add x, c1/c0), c0).
+    SDLoc DL(Node);
+    SDNode *NA =
+        CurDAG->getMachineNode(RISCV::ADDI, DL, VT, N0->getOperand(0),
+                               CurDAG->getTargetConstant(C1 / C0, DL, VT));
+    SDNode *NM =
+        CurDAG->getMachineNode(RISCV::MUL, DL, VT, SDValue(NA, 0),
+                               N0->getOperand(1));
+    ReplaceNode(Node, NM);
+    return;
+  }
   case ISD::AND: {
     auto *N1C = dyn_cast<ConstantSDNode>(Node->getOperand(1));
     if (!N1C)


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D107711.365011.patch
Type: text/x-patch
Size: 3435 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210808/0648835e/attachment.bin>


More information about the llvm-commits mailing list