From 0e43f63ac7fa5e28497760a0dfec2fe20557bce0 Mon Sep 17 00:00:00 2001 From: Richard-Qin-X Date: Wed, 12 Aug 2026 01:22:08 +0800 Subject: [CodeGen] Track reserved register defs precisely --- backend/unittests/CodeGen/MachineLivenessTest.cpp | 28 ++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) (limited to 'backend/unittests') diff --git a/backend/unittests/CodeGen/MachineLivenessTest.cpp b/backend/unittests/CodeGen/MachineLivenessTest.cpp index 84a247f..cca7629 100644 --- a/backend/unittests/CodeGen/MachineLivenessTest.cpp +++ b/backend/unittests/CodeGen/MachineLivenessTest.cpp @@ -884,16 +884,38 @@ void testRISCVReservedRegisterLiveness(TestContext &Context) { auto Instruction = Immediate ? Pending->build() : rcc::Expected{std::unexpected(Immediate.error())}; - if (!Instruction) { + auto DeadDef = + Instruction ? Builder.buildInstr(rcc::Opcode::fromValue( + static_cast(rcc::riscv::InstructionOpcode::ADDI))) + : rcc::Expected{std::unexpected(Instruction.error())}; + auto DeadDefDestination = DeadDef ? DeadDef->addDef(rcc::Register::fromPhysical(*X0)) + : rcc::Expected{std::unexpected(DeadDef.error())}; + auto DeadDefSource = DeadDefDestination + ? DeadDef->addUse(rcc::Register::fromPhysical(*X0)) + : rcc::Expected{std::unexpected(DeadDefDestination.error())}; + auto DeadDefImmediate = DeadDefSource + ? DeadDef->addImmediate(0) + : rcc::Expected{std::unexpected(DeadDefSource.error())}; + auto DeadDefInstruction = + DeadDefImmediate + ? DeadDef->build() + : rcc::Expected{std::unexpected(DeadDefImmediate.error())}; + if (!Instruction || !DeadDefInstruction) { Context.expect(false, "RV64GC reserved-register liveness instruction must be built"); return; } auto Rebuilt = rcc::rebuildMachineLiveness(*Fixture->Function, *Target); const rcc::MachineOperand *ZeroUse = (*Instruction)->operandAt(1); + const rcc::MachineOperand *ZeroDef = (*DeadDefInstruction)->operandAt(0); + const rcc::MachineOperand *DeadDefZeroUse = (*DeadDefInstruction)->operandAt(1); Context.expect(Rebuilt && Fixture->Blocks[0]->liveIns().empty() && ZeroUse != nullptr && - !ZeroUse->registerFlags().has(rcc::RegisterOperandFlag::Kill), - "reserved registers must remain available without live-ins or kill flags"); + !ZeroUse->registerFlags().has(rcc::RegisterOperandFlag::Kill) && + ZeroDef != nullptr && + ZeroDef->registerFlags().has(rcc::RegisterOperandFlag::Dead) && + DeadDefZeroUse != nullptr && + !DeadDefZeroUse->registerFlags().has(rcc::RegisterOperandFlag::Kill), + "reserved uses must remain available while dead defs retain precise liveness"); } } // namespace -- cgit v1.2.3