diff options
| -rw-r--r-- | backend/lib/Target/RISCV/RISCVCallLowering.cpp | 16 | ||||
| -rw-r--r-- | backend/unittests/Target/RISCVCallLoweringTest.cpp | 27 |
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); |
