aboutsummaryrefslogtreecommitdiff
path: root/backend/lib/Target/RISCV
diff options
context:
space:
mode:
authorRichard-Qin-X <richard.qin.001@gmail.com>2026-08-15 20:03:59 +0800
committerRichard-Qin-X <richard.qin.001@gmail.com>2026-08-15 20:03:59 +0800
commit5b6ba4568cf6916a61ecde702f45246db8154b9f (patch)
treee581672bd1f27bf68831ea5222d92a8e8337fcfe /backend/lib/Target/RISCV
parentb5fb607fa3f54e791baf7ab39faf77d925dd53b7 (diff)
downloadrcc-project-5b6ba4568cf6916a61ecde702f45246db8154b9f.tar.gz
rcc-project-5b6ba4568cf6916a61ecde702f45246db8154b9f.tar.xz
[RISCV][GlobalISel] Legalize floating-point remainder
Diffstat (limited to 'backend/lib/Target/RISCV')
-rw-r--r--backend/lib/Target/RISCV/GISel/RISCVCallLowering.cpp56
-rw-r--r--backend/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp3
-rw-r--r--backend/lib/Target/RISCV/RISCVPipeline.cpp4
3 files changed, 46 insertions, 17 deletions
diff --git a/backend/lib/Target/RISCV/GISel/RISCVCallLowering.cpp b/backend/lib/Target/RISCV/GISel/RISCVCallLowering.cpp
index 050de5b..66b4d87 100644
--- a/backend/lib/Target/RISCV/GISel/RISCVCallLowering.cpp
+++ b/backend/lib/Target/RISCV/GISel/RISCVCallLowering.cpp
@@ -839,9 +839,14 @@ createMemoryOperand(MachineFunction &Function, MemoryAccessFlags Accesses, std::
return *Extended;
}
-[[nodiscard]] Expected<void> emitOutgoingRegisterAssignment(MachineIRBuilder &Builder,
- const CCAssignment &Assignment,
- Register Source) {
+struct OutgoingRegisterValue final {
+ PhysicalRegister Location;
+ Register Value;
+};
+
+[[nodiscard]] Expected<OutgoingRegisterValue>
+prepareOutgoingRegisterAssignment(MachineIRBuilder &Builder, const CCAssignment &Assignment,
+ Register Source) {
if (!Assignment.LocationRegister) {
return makeUnexpected(ErrorCode::InternalError,
"RISC-V register assignment has no location register");
@@ -849,9 +854,20 @@ createMemoryOperand(MachineFunction &Function, MemoryAccessFlags Accesses, std::
auto Extended = extendOutgoingRegister(Builder, Source, Assignment);
if (!Extended)
return std::unexpected(Extended.error());
- auto Copy = Builder.buildCopy(Register::fromPhysical(*Assignment.LocationRegister), *Extended);
- if (!Copy)
- return std::unexpected(Copy.error());
+ return OutgoingRegisterValue{
+ .Location = *Assignment.LocationRegister,
+ .Value = *Extended,
+ };
+}
+
+[[nodiscard]] Expected<void>
+emitOutgoingRegisterAssignments(MachineIRBuilder &Builder,
+ std::span<const OutgoingRegisterValue> Assignments) {
+ for (const OutgoingRegisterValue &Assignment : Assignments) {
+ auto Copy = Builder.buildCopy(Register::fromPhysical(Assignment.Location), Assignment.Value);
+ if (!Copy)
+ return std::unexpected(Copy.error());
+ }
return {};
}
@@ -1348,15 +1364,18 @@ emitOutgoingArguments(MachineIRBuilder &Builder, const CallLoweringPlan &Plan,
MachineFunction &Function = Builder.function();
MachineFrameInfo &Frame = Function.frameInfo();
const auto Assignments = Plan.argumentAssignments();
+ std::vector<OutgoingRegisterValue> RegisterAssignments;
+ RegisterAssignments.reserve(Assignments.size());
for (std::size_t Index = 0; Index < Assignments.size(); ++Index) {
const CCAssignment &Assignment = Assignments[Index];
const auto Replacement = Replacements.find(Index);
const Register Source =
Replacement == Replacements.end() ? Assignment.OriginalValue : Replacement->second;
if (Assignment.LocationRegister) {
- auto Copy = emitOutgoingRegisterAssignment(Builder, Assignment, Source);
- if (!Copy)
- return std::unexpected(Copy.error());
+ auto Prepared = prepareOutgoingRegisterAssignment(Builder, Assignment, Source);
+ if (!Prepared)
+ return std::unexpected(Prepared.error());
+ RegisterAssignments.push_back(*Prepared);
continue;
}
@@ -1388,7 +1407,8 @@ emitOutgoingArguments(MachineIRBuilder &Builder, const CallLoweringPlan &Plan,
if (!Store)
return std::unexpected(Store.error());
}
- return {};
+ return emitOutgoingRegisterAssignments(
+ Builder, std::span<const OutgoingRegisterValue>(RegisterAssignments));
}
[[nodiscard]] Expected<void> addCallTarget(MachineInstrBuilder &Instruction,
@@ -1505,11 +1525,19 @@ emitOutgoingArguments(MachineIRBuilder &Builder, const CallLoweringPlan &Plan,
}
[[nodiscard]] Expected<void> emitReturn(MachineIRBuilder &Builder, const CallLoweringPlan &Plan) {
+ std::vector<OutgoingRegisterValue> RegisterAssignments;
+ RegisterAssignments.reserve(Plan.returnAssignments().size());
for (const CCAssignment &Assignment : Plan.returnAssignments()) {
- auto Copy = emitOutgoingRegisterAssignment(Builder, Assignment, Assignment.OriginalValue);
- if (!Copy)
- return std::unexpected(Copy.error());
- }
+ auto Prepared =
+ prepareOutgoingRegisterAssignment(Builder, Assignment, Assignment.OriginalValue);
+ if (!Prepared)
+ return std::unexpected(Prepared.error());
+ RegisterAssignments.push_back(*Prepared);
+ }
+ auto Copies = emitOutgoingRegisterAssignments(
+ Builder, std::span<const OutgoingRegisterValue>(RegisterAssignments));
+ if (!Copies)
+ return std::unexpected(Copies.error());
auto Return = Builder.buildInstr(instructionOpcode(InstructionOpcode::PseudoRET));
if (!Return)
diff --git a/backend/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/backend/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
index 3f8f4cb..243c6de 100644
--- a/backend/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
+++ b/backend/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
@@ -576,7 +576,8 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &Subtarget) : Subtar
.lowerFor({S32, S64, S128});
getActionDefinitionsBuilder(opcode(GenericOpcode::G_FREM))
.libcallFor({S32, S64, S128})
- .minScalar(0, S32);
+ .minScalar(0, S32)
+ .scalarize(0);
getActionDefinitionsBuilder(opcode(GenericOpcode::G_FCOPYSIGN))
.legalFor(HasF, {{S32, S32}})
.legalFor(HasD, {{S64, S64}, {S32, S64}, {S64, S32}})
diff --git a/backend/lib/Target/RISCV/RISCVPipeline.cpp b/backend/lib/Target/RISCV/RISCVPipeline.cpp
index a8d0a20..f1de092 100644
--- a/backend/lib/Target/RISCV/RISCVPipeline.cpp
+++ b/backend/lib/Target/RISCV/RISCVPipeline.cpp
@@ -45,7 +45,7 @@ template <typename PassT, typename... ArgumentT>
if (!Added)
return std::unexpected(Added.error());
Added = addPass<Legalizer>(Pipeline, Subtarget.getLegalizerInfo(), Options.Optimization,
- libcallLoweringInfo(Subtarget));
+ libcallLoweringInfo(Subtarget), Options.GlobalISelAbort);
if (!Added)
return std::unexpected(Added.error());
Added = addPass<RegBankSelect>(Pipeline, Subtarget.getRegBankInfo());
@@ -100,7 +100,7 @@ Expected<void> addCanonicalPipeline(MachineFunctionPassManager &Pipeline,
if (!Added)
return std::unexpected(Added.error());
Added = addPass<Legalizer>(Pipeline, Subtarget.getLegalizerInfo(), Options.Optimization,
- libcallLoweringInfo(Subtarget));
+ libcallLoweringInfo(Subtarget), Options.GlobalISelAbort);
if (!Added)
return std::unexpected(Added.error());
}