[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