diff options
Diffstat (limited to 'llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp')
| -rw-r--r-- | llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp | 43 |
1 files changed, 31 insertions, 12 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp index b1e851183de0..3b11d0848d30 100644 --- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp @@ -3487,6 +3487,13 @@ bool CombinerHelper::matchUseVectorTruncate(MachineInstr &MI, if (!DstTy.getElementCount().isKnownMultipleOf(UnmergeSrcTy.getNumElements())) return false; + // Check the unmerge source and destination element types match + LLT UnmergeSrcEltTy = UnmergeSrcTy.getElementType(); + Register UnmergeDstReg = UnmergeMI->getOperand(0).getReg(); + LLT UnmergeDstEltTy = MRI.getType(UnmergeDstReg); + if (UnmergeSrcEltTy != UnmergeDstEltTy) + return false; + // Only generate legal instructions post-legalizer if (!IsPreLegalize) { LLT MidTy = DstTy.changeElementType(UnmergeSrcTy.getScalarType()); @@ -5288,12 +5295,13 @@ bool CombinerHelper::matchSubAddSameReg(MachineInstr &MI, return false; } -MachineInstr *CombinerHelper::buildUDivUsingMul(MachineInstr &MI) const { - assert(MI.getOpcode() == TargetOpcode::G_UDIV); - auto &UDiv = cast<GenericMachineInstr>(MI); - Register Dst = UDiv.getReg(0); - Register LHS = UDiv.getReg(1); - Register RHS = UDiv.getReg(2); +MachineInstr *CombinerHelper::buildUDivorURemUsingMul(MachineInstr &MI) const { + unsigned Opcode = MI.getOpcode(); + assert(Opcode == TargetOpcode::G_UDIV || Opcode == TargetOpcode::G_UREM); + auto &UDivorRem = cast<GenericMachineInstr>(MI); + Register Dst = UDivorRem.getReg(0); + Register LHS = UDivorRem.getReg(1); + Register RHS = UDivorRem.getReg(2); LLT Ty = MRI.getType(Dst); LLT ScalarTy = Ty.getScalarType(); const unsigned EltBits = ScalarTy.getScalarSizeInBits(); @@ -5446,11 +5454,18 @@ MachineInstr *CombinerHelper::buildUDivUsingMul(MachineInstr &MI) const { auto IsOne = MIB.buildICmp( CmpInst::Predicate::ICMP_EQ, Ty.isScalar() ? LLT::scalar(1) : Ty.changeElementSize(1), RHS, One); - return MIB.buildSelect(Ty, IsOne, LHS, Q); + auto ret = MIB.buildSelect(Ty, IsOne, LHS, Q); + + if (Opcode == TargetOpcode::G_UREM) { + auto Prod = MIB.buildMul(Ty, ret, RHS); + return MIB.buildSub(Ty, LHS, Prod); + } + return ret; } -bool CombinerHelper::matchUDivByConst(MachineInstr &MI) const { - assert(MI.getOpcode() == TargetOpcode::G_UDIV); +bool CombinerHelper::matchUDivorURemByConst(MachineInstr &MI) const { + unsigned Opcode = MI.getOpcode(); + assert(Opcode == TargetOpcode::G_UDIV || Opcode == TargetOpcode::G_UREM); Register Dst = MI.getOperand(0).getReg(); Register RHS = MI.getOperand(2).getReg(); LLT DstTy = MRI.getType(Dst); @@ -5467,7 +5482,8 @@ bool CombinerHelper::matchUDivByConst(MachineInstr &MI) const { if (MF.getFunction().hasMinSize()) return false; - if (MI.getFlag(MachineInstr::MIFlag::IsExact)) { + if (Opcode == TargetOpcode::G_UDIV && + MI.getFlag(MachineInstr::MIFlag::IsExact)) { return matchUnaryPredicate( MRI, RHS, [](const Constant *C) { return C && !C->isNullValue(); }); } @@ -5487,14 +5503,17 @@ bool CombinerHelper::matchUDivByConst(MachineInstr &MI) const { {DstTy.isVector() ? DstTy.changeElementSize(1) : LLT::scalar(1), DstTy}})) return false; + if (Opcode == TargetOpcode::G_UREM && + !isLegalOrBeforeLegalizer({TargetOpcode::G_SUB, {DstTy, DstTy}})) + return false; } return matchUnaryPredicate( MRI, RHS, [](const Constant *C) { return C && !C->isNullValue(); }); } -void CombinerHelper::applyUDivByConst(MachineInstr &MI) const { - auto *NewMI = buildUDivUsingMul(MI); +void CombinerHelper::applyUDivorURemByConst(MachineInstr &MI) const { + auto *NewMI = buildUDivorURemUsingMul(MI); replaceSingleDefInstWithReg(MI, NewMI->getOperand(0).getReg()); } |
