aboutsummaryrefslogtreecommitdiff
path: root/backend
diff options
context:
space:
mode:
Diffstat (limited to 'backend')
-rw-r--r--backend/lib/Target/RISCV/RISCVCallLowering.cpp16
-rw-r--r--backend/unittests/Target/RISCVCallLoweringTest.cpp27
2 files changed, 28 insertions, 15 deletions
diff --git a/backend/lib/Target/RISCV/RISCVCallLowering.cpp b/backend/lib/Target/RISCV/RISCVCallLowering.cpp
index 4780edb..60bf6f2 100644
--- a/backend/lib/Target/RISCV/RISCVCallLowering.cpp
+++ b/backend/lib/Target/RISCV/RISCVCallLowering.cpp
@@ -1352,6 +1352,14 @@ emitOutgoingArguments(MachineIRBuilder &Builder, const CallLoweringPlan &Plan,
if (!Mask)
return std::unexpected(Mask.error());
+ std::unordered_set<PhysicalRegister> DynamicUses;
+ for (const CCAssignment &Assignment : Plan.argumentAssignments()) {
+ if (Assignment.LocationRegister && DynamicUses.insert(*Assignment.LocationRegister).second) {
+ auto Use = Instruction->addImplicitUse(Register::fromPhysical(*Assignment.LocationRegister));
+ if (!Use)
+ return std::unexpected(Use.error());
+ }
+ }
std::unordered_set<PhysicalRegister> DynamicDefs;
if (!IsTail) {
for (const CCAssignment &Assignment : Plan.returnAssignments()) {
@@ -1363,14 +1371,6 @@ emitOutgoingArguments(MachineIRBuilder &Builder, const CallLoweringPlan &Plan,
}
}
}
- std::unordered_set<PhysicalRegister> DynamicUses;
- for (const CCAssignment &Assignment : Plan.argumentAssignments()) {
- if (Assignment.LocationRegister && DynamicUses.insert(*Assignment.LocationRegister).second) {
- auto Use = Instruction->addImplicitUse(Register::fromPhysical(*Assignment.LocationRegister));
- if (!Use)
- return std::unexpected(Use.error());
- }
- }
auto Built = Instruction->build();
if (!Built)
return std::unexpected(Built.error());
diff --git a/backend/unittests/Target/RISCVCallLoweringTest.cpp b/backend/unittests/Target/RISCVCallLoweringTest.cpp
index 08049f6..c18898f 100644
--- a/backend/unittests/Target/RISCVCallLoweringTest.cpp
+++ b/backend/unittests/Target/RISCVCallLoweringTest.cpp
@@ -551,19 +551,32 @@ void testOrdinaryAndIndirectEmission(TestContext &Context) {
"call-frame pseudos must use LLVM amount/prepared-byte operands and implicit SP effects");
bool HasArgumentUse = false;
bool HasResultDef = false;
+ std::optional<std::size_t> ArgumentUseIndex;
+ std::optional<std::size_t> ResultDefIndex;
+ std::size_t OperandIndex = 0;
for (const rcc::MachineOperand &Operand : Call->operands()) {
- if (!Operand.isRegister() || !Operand.isImplicit())
+ if (!Operand.isRegister() || !Operand.isImplicit()) {
+ ++OperandIndex;
continue;
- HasArgumentUse |=
- Operand.isUse() && Operand.registerValue() == rcc::Register::fromPhysical(argumentGPR(0));
- HasResultDef |=
- Operand.isDef() && Operand.registerValue() == rcc::Register::fromPhysical(returnFPR(0));
+ }
+ if (Operand.isUse() && Operand.registerValue() == rcc::Register::fromPhysical(argumentGPR(0))) {
+ HasArgumentUse = true;
+ ArgumentUseIndex = OperandIndex;
+ }
+ if (Operand.isDef() && Operand.registerValue() == rcc::Register::fromPhysical(returnFPR(0))) {
+ HasResultDef = true;
+ ResultDefIndex = OperandIndex;
+ }
+ ++OperandIndex;
}
- Context.expect(HasArgumentUse && HasResultDef && Function->frameInfo().state().HasCalls &&
+ Context.expect(HasArgumentUse && HasResultDef && ArgumentUseIndex && ResultDefIndex &&
+ *ArgumentUseIndex < *ResultDefIndex &&
+ Function->frameInfo().state().HasCalls &&
Function->frameInfo().maxCallFrameSize() == 0 &&
Function->frameInfo().stackAlignment().bytes() == 16 &&
verifyFunction(*Function, *Target),
- "ordinary call emission must record implicit ABI registers and valid frame state");
+ "ordinary call emission must order implicit uses before defs and record frame "
+ "state");
rcc::MachineBasicBlock *IndirectBlock = nullptr;
auto IndirectFunction = createFunction(Context, "indirect_call", 2, IndirectBlock);