diff options
| author | Richard-Qin-X <richard.qin.001@gmail.com> | 2026-08-15 03:37:35 +0800 |
|---|---|---|
| committer | Richard-Qin-X <richard.qin.001@gmail.com> | 2026-08-15 03:37:35 +0800 |
| commit | aea4339802650c1765d1cfed1c8cf3b28cb2a09b (patch) | |
| tree | 2897ce2f5bcb2e20b5550b0fe72a7769fe29061b /backend/lib/CodeGen/GlobalISel/LegalizerHelper.cpp | |
| parent | 5e2a50330a643b4580a94b68b1d68107ec4e1e87 (diff) | |
| download | rcc-project-aea4339802650c1765d1cfed1c8cf3b28cb2a09b.tar.gz rcc-project-aea4339802650c1765d1cfed1c8cf3b28cb2a09b.tar.xz | |
[GlobalISel] Lower combined division and remainder
Diffstat (limited to 'backend/lib/CodeGen/GlobalISel/LegalizerHelper.cpp')
| -rw-r--r-- | backend/lib/CodeGen/GlobalISel/LegalizerHelper.cpp | 29 |
1 files changed, 29 insertions, 0 deletions
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<void> 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<void> LegalizerHelper::lowerThreewayCompare(MachineInstr &Instruction) return Block->removeInstruction(Instruction); } +Expected<void> LegalizerHelper::lowerDivRem(MachineInstr &Instruction) { + const bool IsSigned = Instruction.opcode() == opcode(GenericOpcode::G_SDIVREM); + const Register Quotient = *Instruction.operandAt(0)->getIf<Register>(); + const Register Remainder = *Instruction.operandAt(1)->getIf<Register>(); + const Register Dividend = *Instruction.operandAt(2)->getIf<Register>(); + const Register Divisor = *Instruction.operandAt(3)->getIf<Register>(); + + 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<void> LegalizerHelper::lowerRotate(MachineInstr &Instruction) { const Register Destination = *Instruction.operandAt(0)->getIf<Register>(); const Register Source = *Instruction.operandAt(1)->getIf<Register>(); |
