[llvm] 6e0ad5b - [PowerPC] Add an ISEL pattern for Mul with Imm.

via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 9 22:53:35 PST 2020


Author: Esme-Yi
Date: 2020-11-10T06:52:39Z
New Revision: 6e0ad5bc8c34592646a1106e4a0a40f6d7dd5726

URL: https://github.com/llvm/llvm-project/commit/6e0ad5bc8c34592646a1106e4a0a40f6d7dd5726
DIFF: https://github.com/llvm/llvm-project/commit/6e0ad5bc8c34592646a1106e4a0a40f6d7dd5726.diff

LOG: [PowerPC] Add an ISEL pattern for Mul with Imm.

Summary: This patch try to do the following transformation if the multiplier doen't fit int16:
			(mul X, c1 << c2) -> (rldicr (mulli X, c1) c2)

Reviewed By: jsji, steven.zhang

Differential Revision: https://reviews.llvm.org/D87384

Added: 
    

Modified: 
    llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
    llvm/test/CodeGen/PowerPC/mulli.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
index 990b94474be8..c67cf897c397 100644
--- a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
@@ -4963,6 +4963,32 @@ void PPCDAGToDAGISel::Select(SDNode *N) {
     // Other cases are autogenerated.
     break;
   }
+  case ISD::MUL: {
+    SDValue Op1 = N->getOperand(1);
+    if (Op1.getOpcode() != ISD::Constant || Op1.getValueType() != MVT::i64)
+      break;
+
+    // If the multiplier fits int16, we can handle it with mulli.
+    int64_t Imm = cast<ConstantSDNode>(Op1)->getZExtValue();
+    unsigned Shift = countTrailingZeros<uint64_t>(Imm);
+    if (isInt<16>(Imm) || !Shift)
+      break;
+
+    // If the shifted value fits int16, we can do this transformation:
+    // (mul X, c1 << c2) -> (rldicr (mulli X, c1) c2). We do this in ISEL due to
+    // DAGCombiner prefers (shl (mul X, c1), c2) -> (mul X, c1 << c2).
+    uint64_t ImmSh = Imm >> Shift;
+    if (isInt<16>(ImmSh)) {
+      uint64_t SextImm = SignExtend64(ImmSh & 0xFFFF, 16);
+      SDValue SDImm = CurDAG->getTargetConstant(SextImm, dl, MVT::i64);
+      SDNode *MulNode = CurDAG->getMachineNode(PPC::MULLI8, dl, MVT::i64,
+                                               N->getOperand(0), SDImm);
+      CurDAG->SelectNodeTo(N, PPC::RLDICR, MVT::i64, SDValue(MulNode, 0),
+                           getI32Imm(Shift, dl), getI32Imm(63 - Shift, dl));
+      return;
+    }
+    break;
+  }
   // FIXME: Remove this once the ANDI glue bug is fixed:
   case PPCISD::ANDI_rec_1_EQ_BIT:
   case PPCISD::ANDI_rec_1_GT_BIT: {

diff  --git a/llvm/test/CodeGen/PowerPC/mulli.ll b/llvm/test/CodeGen/PowerPC/mulli.ll
index 19c2d9193c38..2c0808628990 100644
--- a/llvm/test/CodeGen/PowerPC/mulli.ll
+++ b/llvm/test/CodeGen/PowerPC/mulli.ll
@@ -4,9 +4,8 @@
 define i64 @test1(i64 %x) {
 ; CHECK-LABEL: test1:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    li 4, 625
-; CHECK-NEXT:    sldi 4, 4, 36
-; CHECK-NEXT:    mulld 3, 3, 4
+; CHECK-NEXT:    mulli 3, 3, 625
+; CHECK-NEXT:    sldi 3, 3, 36
 ; CHECK-NEXT:    blr
   %y = mul i64 %x, 42949672960000
   ret i64 %y
@@ -15,9 +14,8 @@ define i64 @test1(i64 %x) {
 define i64 @test2(i64 %x) {
 ; CHECK-LABEL: test2:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    li 4, -625
-; CHECK-NEXT:    sldi 4, 4, 36
-; CHECK-NEXT:    mulld 3, 3, 4
+; CHECK-NEXT:    mulli 3, 3, -625
+; CHECK-NEXT:    sldi 3, 3, 36
 ; CHECK-NEXT:    blr
   %y = mul i64 %x, -42949672960000
   ret i64 %y
@@ -26,9 +24,8 @@ define i64 @test2(i64 %x) {
 define i64 @test3(i64 %x) {
 ; CHECK-LABEL: test3:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    lis 4, 74
-; CHECK-NEXT:    ori 4, 4, 16384
-; CHECK-NEXT:    mulld 3, 3, 4
+; CHECK-NEXT:    mulli 3, 3, 297
+; CHECK-NEXT:    sldi 3, 3, 14
 ; CHECK-NEXT:    blr
   %y = mul i64 %x, 4866048
   ret i64 %y
@@ -37,9 +34,8 @@ define i64 @test3(i64 %x) {
 define i64 @test4(i64 %x) {
 ; CHECK-LABEL: test4:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    lis 4, -75
-; CHECK-NEXT:    ori 4, 4, 49152
-; CHECK-NEXT:    mulld 3, 3, 4
+; CHECK-NEXT:    mulli 3, 3, -297
+; CHECK-NEXT:    sldi 3, 3, 14
 ; CHECK-NEXT:    blr
   %y = mul i64 %x, -4866048
   ret i64 %y
@@ -96,9 +92,8 @@ define i64 @test9(i64 %x) {
 ; CHECK-NEXT:    sldi 4, 3, 12
 ; CHECK-NEXT:    sldi 5, 3, 32
 ; CHECK-NEXT:    add 4, 5, 4
-; CHECK-NEXT:    li 5, 8193
-; CHECK-NEXT:    sldi 5, 5, 19
-; CHECK-NEXT:    mulld 3, 3, 5
+; CHECK-NEXT:    mulli 3, 3, 8193
+; CHECK-NEXT:    sldi 3, 3, 19
 ; CHECK-NEXT:    sub 3, 4, 3
 ; CHECK-NEXT:    blr
   %y = mul i64 %x, 4294971392


        


More information about the llvm-commits mailing list