Skip to content

Commit 28b1ba1

Browse files
committed
[PowerPC] Add an ISEL pattern for i32 MULLI.
We add the following ISEL pattern for i64 imm in D87384, this patch is for i32. `mul with (2^N * int16_imm) -> MULLI + RLWINM` Reviewed By: shchenz Differential Revision: https://reviews.llvm.org/D129708
1 parent 118d8fe commit 28b1ba1

File tree

2 files changed

+29
-5
lines changed

2 files changed

+29
-5
lines changed

llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5473,7 +5473,8 @@ void PPCDAGToDAGISel::Select(SDNode *N) {
54735473
}
54745474
case ISD::MUL: {
54755475
SDValue Op1 = N->getOperand(1);
5476-
if (Op1.getOpcode() != ISD::Constant || Op1.getValueType() != MVT::i64)
5476+
if (Op1.getOpcode() != ISD::Constant ||
5477+
(Op1.getValueType() != MVT::i64 && Op1.getValueType() != MVT::i32))
54775478
break;
54785479

54795480
// If the multiplier fits int16, we can handle it with mulli.
@@ -5486,13 +5487,27 @@ void PPCDAGToDAGISel::Select(SDNode *N) {
54865487
// (mul X, c1 << c2) -> (rldicr (mulli X, c1) c2). We do this in ISEL due to
54875488
// DAGCombiner prefers (shl (mul X, c1), c2) -> (mul X, c1 << c2).
54885489
uint64_t ImmSh = Imm >> Shift;
5489-
if (isInt<16>(ImmSh)) {
5490-
uint64_t SextImm = SignExtend64(ImmSh & 0xFFFF, 16);
5490+
if (!isInt<16>(ImmSh))
5491+
break;
5492+
5493+
uint64_t SextImm = SignExtend64(ImmSh & 0xFFFF, 16);
5494+
if (Op1.getValueType() == MVT::i64) {
54915495
SDValue SDImm = CurDAG->getTargetConstant(SextImm, dl, MVT::i64);
54925496
SDNode *MulNode = CurDAG->getMachineNode(PPC::MULLI8, dl, MVT::i64,
54935497
N->getOperand(0), SDImm);
5494-
CurDAG->SelectNodeTo(N, PPC::RLDICR, MVT::i64, SDValue(MulNode, 0),
5495-
getI32Imm(Shift, dl), getI32Imm(63 - Shift, dl));
5498+
5499+
SDValue Ops[] = {SDValue(MulNode, 0), getI32Imm(Shift, dl),
5500+
getI32Imm(63 - Shift, dl)};
5501+
CurDAG->SelectNodeTo(N, PPC::RLDICR, MVT::i64, Ops);
5502+
return;
5503+
} else {
5504+
SDValue SDImm = CurDAG->getTargetConstant(SextImm, dl, MVT::i32);
5505+
SDNode *MulNode = CurDAG->getMachineNode(PPC::MULLI, dl, MVT::i32,
5506+
N->getOperand(0), SDImm);
5507+
5508+
SDValue Ops[] = {SDValue(MulNode, 0), getI32Imm(Shift, dl),
5509+
getI32Imm(0, dl), getI32Imm(31 - Shift, dl)};
5510+
CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Ops);
54965511
return;
54975512
}
54985513
break;

llvm/test/CodeGen/PowerPC/mulli.ll

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,3 +116,12 @@ define i64 @test10(i64 %x) {
116116
ret i64 %res
117117
}
118118

119+
define i32 @test11(i32 %x) {
120+
; CHECK-LABEL: test11:
121+
; CHECK: # %bb.0:
122+
; CHECK-NEXT: mulli 3, 3, 21845
123+
; CHECK-NEXT: slwi 3, 3, 5
124+
; CHECK-NEXT: blr
125+
%y = mul nsw i32 %x, 699040
126+
ret i32 %y
127+
}

0 commit comments

Comments
 (0)