@@ -5473,7 +5473,8 @@ void PPCDAGToDAGISel::Select(SDNode *N) {
5473
5473
}
5474
5474
case ISD::MUL: {
5475
5475
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))
5477
5478
break ;
5478
5479
5479
5480
// If the multiplier fits int16, we can handle it with mulli.
@@ -5486,13 +5487,27 @@ void PPCDAGToDAGISel::Select(SDNode *N) {
5486
5487
// (mul X, c1 << c2) -> (rldicr (mulli X, c1) c2). We do this in ISEL due to
5487
5488
// DAGCombiner prefers (shl (mul X, c1), c2) -> (mul X, c1 << c2).
5488
5489
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) {
5491
5495
SDValue SDImm = CurDAG->getTargetConstant (SextImm, dl, MVT::i64);
5492
5496
SDNode *MulNode = CurDAG->getMachineNode (PPC::MULLI8, dl, MVT::i64,
5493
5497
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);
5496
5511
return ;
5497
5512
}
5498
5513
break ;
0 commit comments