Skip to content

Commit

Permalink
[PowerPC] Add an ISEL pattern for i32 MULLI.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
EsmeYi committed Jul 18, 2022
1 parent 118d8fe commit 28b1ba1
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 5 deletions.
25 changes: 20 additions & 5 deletions llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
Expand Up @@ -5473,7 +5473,8 @@ void PPCDAGToDAGISel::Select(SDNode *N) {
}
case ISD::MUL: {
SDValue Op1 = N->getOperand(1);
if (Op1.getOpcode() != ISD::Constant || Op1.getValueType() != MVT::i64)
if (Op1.getOpcode() != ISD::Constant ||
(Op1.getValueType() != MVT::i64 && Op1.getValueType() != MVT::i32))
break;

// If the multiplier fits int16, we can handle it with mulli.
Expand All @@ -5486,13 +5487,27 @@ void PPCDAGToDAGISel::Select(SDNode *N) {
// (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);
if (!isInt<16>(ImmSh))
break;

uint64_t SextImm = SignExtend64(ImmSh & 0xFFFF, 16);
if (Op1.getValueType() == MVT::i64) {
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));

SDValue Ops[] = {SDValue(MulNode, 0), getI32Imm(Shift, dl),
getI32Imm(63 - Shift, dl)};
CurDAG->SelectNodeTo(N, PPC::RLDICR, MVT::i64, Ops);
return;
} else {
SDValue SDImm = CurDAG->getTargetConstant(SextImm, dl, MVT::i32);
SDNode *MulNode = CurDAG->getMachineNode(PPC::MULLI, dl, MVT::i32,
N->getOperand(0), SDImm);

SDValue Ops[] = {SDValue(MulNode, 0), getI32Imm(Shift, dl),
getI32Imm(0, dl), getI32Imm(31 - Shift, dl)};
CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Ops);
return;
}
break;
Expand Down
9 changes: 9 additions & 0 deletions llvm/test/CodeGen/PowerPC/mulli.ll
Expand Up @@ -116,3 +116,12 @@ define i64 @test10(i64 %x) {
ret i64 %res
}

define i32 @test11(i32 %x) {
; CHECK-LABEL: test11:
; CHECK: # %bb.0:
; CHECK-NEXT: mulli 3, 3, 21845
; CHECK-NEXT: slwi 3, 3, 5
; CHECK-NEXT: blr
%y = mul nsw i32 %x, 699040
ret i32 %y
}

0 comments on commit 28b1ba1

Please sign in to comment.