@@ -5300,7 +5300,7 @@ bool CombinerHelper::matchSubAddSameReg(MachineInstr &MI,
53005300 return false ;
53015301}
53025302
5303- MachineInstr *CombinerHelper::buildUDivorURemUsingMul (MachineInstr &MI) const {
5303+ MachineInstr *CombinerHelper::buildUDivOrURemUsingMul (MachineInstr &MI) const {
53045304 unsigned Opcode = MI.getOpcode ();
53055305 assert (Opcode == TargetOpcode::G_UDIV || Opcode == TargetOpcode::G_UREM);
53065306 auto &UDivorRem = cast<GenericMachineInstr>(MI);
@@ -5468,7 +5468,7 @@ MachineInstr *CombinerHelper::buildUDivorURemUsingMul(MachineInstr &MI) const {
54685468 return ret;
54695469}
54705470
5471- bool CombinerHelper::matchUDivorURemByConst (MachineInstr &MI) const {
5471+ bool CombinerHelper::matchUDivOrURemByConst (MachineInstr &MI) const {
54725472 unsigned Opcode = MI.getOpcode ();
54735473 assert (Opcode == TargetOpcode::G_UDIV || Opcode == TargetOpcode::G_UREM);
54745474 Register Dst = MI.getOperand (0 ).getReg ();
@@ -5517,13 +5517,14 @@ bool CombinerHelper::matchUDivorURemByConst(MachineInstr &MI) const {
55175517 MRI, RHS, [](const Constant *C) { return C && !C->isNullValue (); });
55185518}
55195519
5520- void CombinerHelper::applyUDivorURemByConst (MachineInstr &MI) const {
5521- auto *NewMI = buildUDivorURemUsingMul (MI);
5520+ void CombinerHelper::applyUDivOrURemByConst (MachineInstr &MI) const {
5521+ auto *NewMI = buildUDivOrURemUsingMul (MI);
55225522 replaceSingleDefInstWithReg (MI, NewMI->getOperand (0 ).getReg ());
55235523}
55245524
5525- bool CombinerHelper::matchSDivByConst (MachineInstr &MI) const {
5526- assert (MI.getOpcode () == TargetOpcode::G_SDIV && " Expected SDIV" );
5525+ bool CombinerHelper::matchSDivOrSRemByConst (MachineInstr &MI) const {
5526+ unsigned Opcode = MI.getOpcode ();
5527+ assert (Opcode == TargetOpcode::G_SDIV || Opcode == TargetOpcode::G_SREM);
55275528 Register Dst = MI.getOperand (0 ).getReg ();
55285529 Register RHS = MI.getOperand (2 ).getReg ();
55295530 LLT DstTy = MRI.getType (Dst);
@@ -5543,7 +5544,8 @@ bool CombinerHelper::matchSDivByConst(MachineInstr &MI) const {
55435544 return false ;
55445545
55455546 // If the sdiv has an 'exact' flag we can use a simpler lowering.
5546- if (MI.getFlag (MachineInstr::MIFlag::IsExact)) {
5547+ if (Opcode == TargetOpcode::G_SDIV &&
5548+ MI.getFlag (MachineInstr::MIFlag::IsExact)) {
55475549 return matchUnaryPredicate (
55485550 MRI, RHS, [](const Constant *C) { return C && !C->isNullValue (); });
55495551 }
@@ -5559,23 +5561,28 @@ bool CombinerHelper::matchSDivByConst(MachineInstr &MI) const {
55595561 if (!isLegal ({TargetOpcode::G_SMULH, {DstTy}}) &&
55605562 !isLegalOrHasWidenScalar ({TargetOpcode::G_MUL, {WideTy, WideTy}}))
55615563 return false ;
5564+ if (Opcode == TargetOpcode::G_SREM &&
5565+ !isLegalOrBeforeLegalizer ({TargetOpcode::G_SUB, {DstTy, DstTy}}))
5566+ return false ;
55625567 }
55635568
55645569 return matchUnaryPredicate (
55655570 MRI, RHS, [](const Constant *C) { return C && !C->isNullValue (); });
55665571}
55675572
5568- void CombinerHelper::applySDivByConst (MachineInstr &MI) const {
5569- auto *NewMI = buildSDivUsingMul (MI);
5573+ void CombinerHelper::applySDivOrSRemByConst (MachineInstr &MI) const {
5574+ auto *NewMI = buildSDivOrSRemUsingMul (MI);
55705575 replaceSingleDefInstWithReg (MI, NewMI->getOperand (0 ).getReg ());
55715576}
55725577
5573- MachineInstr *CombinerHelper::buildSDivUsingMul (MachineInstr &MI) const {
5574- assert (MI.getOpcode () == TargetOpcode::G_SDIV && " Expected SDIV" );
5575- auto &SDiv = cast<GenericMachineInstr>(MI);
5576- Register Dst = SDiv.getReg (0 );
5577- Register LHS = SDiv.getReg (1 );
5578- Register RHS = SDiv.getReg (2 );
5578+ MachineInstr *CombinerHelper::buildSDivOrSRemUsingMul (MachineInstr &MI) const {
5579+ unsigned Opcode = MI.getOpcode ();
5580+ assert (MI.getOpcode () == TargetOpcode::G_SDIV ||
5581+ Opcode == TargetOpcode::G_SREM);
5582+ auto &SDivorRem = cast<GenericMachineInstr>(MI);
5583+ Register Dst = SDivorRem.getReg (0 );
5584+ Register LHS = SDivorRem.getReg (1 );
5585+ Register RHS = SDivorRem.getReg (2 );
55795586 LLT Ty = MRI.getType (Dst);
55805587 LLT ScalarTy = Ty.getScalarType ();
55815588 const unsigned EltBits = ScalarTy.getScalarSizeInBits ();
@@ -5705,7 +5712,13 @@ MachineInstr *CombinerHelper::buildSDivUsingMul(MachineInstr &MI) const {
57055712 auto SignShift = MIB.buildConstant (ShiftAmtTy, EltBits - 1 );
57065713 auto T = MIB.buildLShr (Ty, Q, SignShift);
57075714 T = MIB.buildAnd (Ty, T, ShiftMask);
5708- return MIB.buildAdd (Ty, Q, T);
5715+ auto ret = MIB.buildAdd (Ty, Q, T);
5716+
5717+ if (Opcode == TargetOpcode::G_SREM) {
5718+ auto Prod = MIB.buildMul (Ty, ret, RHS);
5719+ return MIB.buildSub (Ty, LHS, Prod);
5720+ }
5721+ return ret;
57095722}
57105723
57115724bool CombinerHelper::matchDivByPow2 (MachineInstr &MI, bool IsSigned) const {
0 commit comments