aboutsummaryrefslogtreecommitdiff
path: root/backend/unittests/CodeGen/MachineVerifierTest.cpp
diff options
context:
space:
mode:
authorRichard-Qin-X <richard.qin.001@gmail.com>2026-08-01 13:55:21 +0800
committerRichard-Qin-X <richard.qin.001@gmail.com>2026-08-01 13:55:21 +0800
commitc9634fa9f529afbdf622a9cd96741bd09d14ef86 (patch)
tree59fd91b741fe187ae25854ab0d762864976cf0d8 /backend/unittests/CodeGen/MachineVerifierTest.cpp
parent786ccc115f851962f3a7d234846a50f4af8aad64 (diff)
downloadrcc-project-c9634fa9f529afbdf622a9cd96741bd09d14ef86.tar.gz
rcc-project-c9634fa9f529afbdf622a9cd96741bd09d14ef86.tar.xz
[CodeGen] Add MachineFrameInfo
Model stable frame indices, stack object kinds, tombstones, lifetimes, and frozen layouts. Validate owned frame references in the builder and verifier, and remap complete frame state during MachineFunction cloning.
Diffstat (limited to 'backend/unittests/CodeGen/MachineVerifierTest.cpp')
-rw-r--r--backend/unittests/CodeGen/MachineVerifierTest.cpp53
1 files changed, 50 insertions, 3 deletions
diff --git a/backend/unittests/CodeGen/MachineVerifierTest.cpp b/backend/unittests/CodeGen/MachineVerifierTest.cpp
index b8b985e..82ae68b 100644
--- a/backend/unittests/CodeGen/MachineVerifierTest.cpp
+++ b/backend/unittests/CodeGen/MachineVerifierTest.cpp
@@ -346,12 +346,17 @@ void testPropertyFailures(TestContext &Context) {
auto Frame = createFunction(Context, "frame_index", 9);
rcc::MachineBasicBlock *FrameBlock = Frame ? createBlock(Context, *Frame) : nullptr;
if (Frame && FrameBlock != nullptr) {
+ rcc::StackObjectDesc StackSlot;
+ StackSlot.Size = 8;
+ StackSlot.Align = *rcc::Alignment::create(8);
+ auto FrameIndex = Frame->frameInfo().createObject(StackSlot);
rcc::MachineIRBuilder Builder(*Frame, *InstructionSet);
- Context.expect(Builder.setInsertPoint(*FrameBlock).has_value(),
+ Context.expect(FrameIndex && Builder.setInsertPoint(*FrameBlock).has_value(),
"frame-index negative test setup must succeed");
+ if (!FrameIndex)
+ return;
auto Pending = Builder.buildInstr(rcc::Opcode::fromValue(FrameOpcode));
- Context.expect(Pending && Pending->addFrameIndex(rcc::FrameIndex::fromValue(0)).has_value() &&
- Pending->build(),
+ Context.expect(Pending && Pending->addFrameIndex(*FrameIndex).has_value() && Pending->build(),
"frame-index negative test instruction must build");
Frame->properties().set(rcc::MachineFunctionProperty::NoFrameIndices);
Context.expect(!rcc::MachineVerifier::verify(*Frame, *InstructionSet),
@@ -447,6 +452,47 @@ void testSelectedStateAndPseudoDeadline(TestContext &Context) {
}
}
+void testFrameStateFailures(TestContext &Context) {
+ auto InstructionSet = createInstructionSet();
+ auto Function = createFunction(Context, "frame_references", 14);
+ rcc::MachineBasicBlock *Block = Function ? createBlock(Context, *Function) : nullptr;
+ if (!InstructionSet || !Function || Block == nullptr)
+ return;
+
+ rcc::MachineIRBuilder Builder(*Function, *InstructionSet);
+ Context.expect(Builder.setInsertPoint(*Block).has_value(),
+ "frame reference insertion point must be valid");
+ auto Unknown = Builder.buildInstr(rcc::Opcode::fromValue(FrameOpcode));
+ Context.expect(Unknown && Unknown->addFrameIndex(rcc::FrameIndex::fromValue(99)).has_value() &&
+ !Unknown->build() && Function->allInstructions().empty(),
+ "builder must reject an unknown frame index before instruction allocation");
+
+ rcc::StackObjectDesc StackSlot;
+ StackSlot.Size = 8;
+ StackSlot.Align = *rcc::Alignment::create(8);
+ auto FrameIndex = Function->frameInfo().createObject(StackSlot);
+ if (!FrameIndex)
+ return;
+ auto Live = Builder.buildInstr(rcc::Opcode::fromValue(FrameOpcode));
+ Context.expect(Live && Live->addFrameIndex(*FrameIndex).has_value() && Live->build(),
+ "known live frame index must build");
+ Context.expect(Function->frameInfo().markObjectDead(*FrameIndex).has_value() &&
+ !rcc::MachineVerifier::verify(*Function, *InstructionSet),
+ "verifier must reject an instruction that references a dead stack object");
+
+ auto Lifetime = createFunction(Context, "frame_lifetime", 15);
+ if (!Lifetime)
+ return;
+ rcc::StackObjectDesc LifetimeSlot;
+ LifetimeSlot.Size = 8;
+ LifetimeSlot.Align = *rcc::Alignment::create(8);
+ LifetimeSlot.Lifetime.push_back(
+ {rcc::MachineInstrStableID::fromValue(1), rcc::MachineInstrStableID::fromValue(2)});
+ Context.expect(Lifetime->frameInfo().createObject(LifetimeSlot).has_value() &&
+ !rcc::MachineVerifier::verify(*Lifetime, *InstructionSet),
+ "verifier must reject stack lifetimes that reference unknown instructions");
+}
+
} // namespace
int main() {
@@ -455,5 +501,6 @@ int main() {
testReachableStructuralFailures(Context);
testPropertyFailures(Context);
testSelectedStateAndPseudoDeadline(Context);
+ testFrameStateFailures(Context);
return Context.result();
}