From aea4339802650c1765d1cfed1c8cf3b28cb2a09b Mon Sep 17 00:00:00 2001 From: Richard-Qin-X Date: Sat, 15 Aug 2026 03:37:35 +0800 Subject: [GlobalISel] Lower combined division and remainder --- backend/lib/CodeGen/GlobalISel/LegalizerHelper.cpp | 29 ++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'backend/lib/CodeGen/GlobalISel') diff --git a/backend/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/backend/lib/CodeGen/GlobalISel/LegalizerHelper.cpp index 84513e6..f300680 100644 --- a/backend/lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ b/backend/lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -2966,6 +2966,9 @@ Expected LegalizerHelper::lower(MachineInstr &Instruction, case GenericOpcode::G_SCMP: case GenericOpcode::G_UCMP: return lowerThreewayCompare(Instruction); + case GenericOpcode::G_SDIVREM: + case GenericOpcode::G_UDIVREM: + return lowerDivRem(Instruction); case GenericOpcode::G_ROTL: case GenericOpcode::G_ROTR: return lowerRotate(Instruction); @@ -3424,6 +3427,32 @@ Expected LegalizerHelper::lowerThreewayCompare(MachineInstr &Instruction) return Block->removeInstruction(Instruction); } +Expected LegalizerHelper::lowerDivRem(MachineInstr &Instruction) { + const bool IsSigned = Instruction.opcode() == opcode(GenericOpcode::G_SDIVREM); + const Register Quotient = *Instruction.operandAt(0)->getIf(); + const Register Remainder = *Instruction.operandAt(1)->getIf(); + const Register Dividend = *Instruction.operandAt(2)->getIf(); + const Register Divisor = *Instruction.operandAt(3)->getIf(); + + if (auto Point = MIRBuilder.setInsertPointBefore(Instruction); !Point) + return std::unexpected(Point.error()); + const GenericOpcode DivideOpcode = IsSigned ? GenericOpcode::G_SDIV : GenericOpcode::G_UDIV; + const GenericOpcode RemainderOpcode = IsSigned ? GenericOpcode::G_SREM : GenericOpcode::G_UREM; + if (auto Built = MIRBuilder.buildInstr(opcode(DivideOpcode), {Quotient}, {Dividend, Divisor}); + !Built) { + return std::unexpected(Built.error()); + } + if (auto Built = MIRBuilder.buildInstr(opcode(RemainderOpcode), {Remainder}, {Dividend, Divisor}); + !Built) { + return std::unexpected(Built.error()); + } + + MachineBasicBlock *Block = Instruction.parent(); + if (Block == nullptr) + return makeUnexpected(ErrorCode::InternalError, "DIVREM became detached during lowering"); + return Block->removeInstruction(Instruction); +} + Expected LegalizerHelper::lowerRotate(MachineInstr &Instruction) { const Register Destination = *Instruction.operandAt(0)->getIf(); const Register Source = *Instruction.operandAt(1)->getIf(); -- cgit v1.2.3