From f5ebe810b5197dbb268db890c5bfec016f447101 Mon Sep 17 00:00:00 2001 From: Richard-Qin-X Date: Tue, 11 Aug 2026 17:47:01 +0800 Subject: [MIR] Parse one-ordering compare-exchange MMOs --- backend/unittests/MIR/MIParserTest.cpp | 56 ++++++++++++++++++++++++++++------ 1 file changed, 47 insertions(+), 9 deletions(-) (limited to 'backend/unittests/MIR/MIParserTest.cpp') diff --git a/backend/unittests/MIR/MIParserTest.cpp b/backend/unittests/MIR/MIParserTest.cpp index 918de62..ab6b69d 100644 --- a/backend/unittests/MIR/MIParserTest.cpp +++ b/backend/unittests/MIR/MIParserTest.cpp @@ -3,6 +3,7 @@ #include "rcc/MIR/MIParser.h" #include "Target/TestTarget.h" +#include "rcc/CodeGen/GenericOpcodes.h" #include "rcc/CodeGen/InstructionDescriptor.h" #include "rcc/CodeGen/MachineBasicBlock.h" #include "rcc/CodeGen/MachineFunction.h" @@ -161,6 +162,13 @@ registerOperand(rcc::RegisterOperandRole Role, Descriptors.push_back(std::move(Metadata)); Descriptors.push_back(std::move(Load)); Descriptors.push_back(std::move(InlineAsm)); + for (const rcc::InstructionDescriptor &Generic : rcc::genericInstructionDescriptors()) { + if (Generic.InstructionOpcode == rcc::opcode(rcc::GenericOpcode::G_ATOMIC_CMPXCHG) || + Generic.InstructionOpcode == + rcc::opcode(rcc::GenericOpcode::G_ATOMIC_CMPXCHG_WITH_SUCCESS)) { + Descriptors.push_back(Generic); + } + } auto Instructions = rcc::InstructionSet::create(std::move(Descriptors)); if (!Instructions) return std::unexpected(Instructions.error()); @@ -464,17 +472,14 @@ void testTypedIntegerTruncation(TestContext &Context) { ? Instructions[0]->operandAt(1)->getIf() : nullptr; const auto *NarrowNegative = - Instructions.size() > 1 - ? Instructions[1]->operandAt(1)->getIf() - : nullptr; + Instructions.size() > 1 ? Instructions[1]->operandAt(1)->getIf() + : nullptr; const auto *NarrowMinimum = - Instructions.size() > 2 - ? Instructions[2]->operandAt(1)->getIf() - : nullptr; + Instructions.size() > 2 ? Instructions[2]->operandAt(1)->getIf() + : nullptr; const auto *WidePositive = - Instructions.size() > 3 - ? Instructions[3]->operandAt(1)->getIf() - : nullptr; + Instructions.size() > 3 ? Instructions[3]->operandAt(1)->getIf() + : nullptr; Context.expect(Parsed.has_value() && MinusOne != nullptr && MinusOne->Value.words()[0] == std::numeric_limits::max() && NarrowNegative != nullptr && NarrowNegative->Value.bitWidth() == 16 && @@ -532,6 +537,38 @@ void testLLVMInlineAsmAndConstantMemorySyntax(TestContext &Context) { "canonical MIR must print symbolic inline-asm flags and LLVM constant bases"); } +void testLLVMCompareExchangeMemorySyntax(TestContext &Context) { + auto Target = createTarget(); + auto Function = createFunction(Context, 12); + Context.expect(Target.has_value(), "compare-exchange target description must be valid"); + if (!Target || !Function) + return; + + const std::string Body = R"(bb.0: + %0:gpr64(p0) = TEST_COPY $g0 + %1:_(s8) = TEST_CONSTANT i8 0 + %2:_(s8) = TEST_CONSTANT i8 1 + %3:_(s8) = G_ATOMIC_CMPXCHG %0, %1, %2 :: (load store monotonic (s8)) +)"; + rcc::mir::MIParserContext ParserContext; + ParserContext.DefaultPointerSizeInBits = 64; + rcc::mir::MIParser Parser(*Function, *Target, "llvm-cmpxchg.mir", Body, ParserContext); + const auto Parsed = Parser.parse(); + Context.expect(Parsed.has_value(), "LLVM one-ordering compare-exchange MMO syntax must parse"); + if (!Parsed) { + for (const auto &Diagnostic : Parser.diagnostics()) + std::cerr << Diagnostic.Category << ": " << Diagnostic.Message << '\n'; + return; + } + + const rcc::MachineInstr *CompareExchange = Function->allInstructions().back(); + const rcc::MachineMemOperandDesc &Memory = CompareExchange->memOperands().front()->description(); + Context.expect(Memory.AtomicKind == rcc::AtomicOperation::CompareExchange && + Memory.SuccessOrdering == rcc::AtomicOrdering::Monotonic && + Memory.FailureOrdering == rcc::AtomicOrdering::NotAtomic, + "compare-exchange opcode must disambiguate a one-ordering LLVM MMO"); +} + void expectParseError(TestContext &Context, const rcc::TargetDescription &Target, std::string Body, std::string_view Message) { auto Function = createFunction(Context, 10); @@ -583,6 +620,7 @@ int main() { testCompatibleRegisterClassAndBankAnnotations(Context); testTypedIntegerTruncation(Context); testLLVMInlineAsmAndConstantMemorySyntax(Context); + testLLVMCompareExchangeMemorySyntax(Context); testDiagnostics(Context); return Context.result(); } -- cgit v1.2.3