// 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: {
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
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
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
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
; 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