aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard-Qin-X <richard.qin.001@gmail.com>2026-08-15 03:37:35 +0800
committerRichard-Qin-X <richard.qin.001@gmail.com>2026-08-15 03:37:35 +0800
commitaea4339802650c1765d1cfed1c8cf3b28cb2a09b (patch)
tree2897ce2f5bcb2e20b5550b0fe72a7769fe29061b
parent5e2a50330a643b4580a94b68b1d68107ec4e1e87 (diff)
downloadrcc-project-aea4339802650c1765d1cfed1c8cf3b28cb2a09b.tar.gz
rcc-project-aea4339802650c1765d1cfed1c8cf3b28cb2a09b.tar.xz
[GlobalISel] Lower combined division and remainder
-rw-r--r--backend/include/rcc/CodeGen/GlobalISel/LegalizerHelper.h1
-rw-r--r--backend/lib/CodeGen/GlobalISel/LegalizerHelper.cpp29
2 files changed, 30 insertions, 0 deletions
diff --git a/backend/include/rcc/CodeGen/GlobalISel/LegalizerHelper.h b/backend/include/rcc/CodeGen/GlobalISel/LegalizerHelper.h
index 39304ba..e094356 100644
--- a/backend/include/rcc/CodeGen/GlobalISel/LegalizerHelper.h
+++ b/backend/include/rcc/CodeGen/GlobalISel/LegalizerHelper.h
@@ -35,6 +35,7 @@ public:
[[nodiscard]] Expected<void> lowerAbsDiffToMinMax(MachineInstr &Instruction);
[[nodiscard]] Expected<void> lowerMinMax(MachineInstr &Instruction);
[[nodiscard]] Expected<void> lowerThreewayCompare(MachineInstr &Instruction);
+ [[nodiscard]] Expected<void> lowerDivRem(MachineInstr &Instruction);
[[nodiscard]] Expected<void> lowerRotate(MachineInstr &Instruction);
[[nodiscard]] Expected<void> lowerVAArg(MachineInstr &Instruction);
[[nodiscard]] Expected<void> libcall(MachineInstr &Instruction);
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>();