From 23dad063b9172982467b69650ae334bbec63e759 Mon Sep 17 00:00:00 2001 From: Richard-Qin-X Date: Wed, 12 Aug 2026 02:44:40 +0800 Subject: [CodeGen] Allow narrow atomic RMW memory types --- backend/lib/CodeGen/GenericOpcodes.cpp | 2 +- backend/unittests/CodeGen/GenericOpcodesTest.cpp | 25 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) (limited to 'backend') diff --git a/backend/lib/CodeGen/GenericOpcodes.cpp b/backend/lib/CodeGen/GenericOpcodes.cpp index 3c2cee1..73c56f6 100644 --- a/backend/lib/CodeGen/GenericOpcodes.cpp +++ b/backend/lib/CodeGen/GenericOpcodes.cpp @@ -927,7 +927,7 @@ private: if (MemoryOperands.size() != 1 || MemoryOperands.front()->description().AtomicKind != AtomicOperation::ReadModifyWrite) return semanticError("generic atomic RMW requires one read-modify-write MMO"); - return VerifySingleAccess(1, 0, true, true, SizeRelation::Equal); + return VerifySingleAccess(1, 0, true, true, SizeRelation::NoLarger); case GO::G_PREFETCH: { if (MemoryOperands.size() != 1) return semanticError("G_PREFETCH requires exactly one MMO"); diff --git a/backend/unittests/CodeGen/GenericOpcodesTest.cpp b/backend/unittests/CodeGen/GenericOpcodesTest.cpp index 4527004..26f7442 100644 --- a/backend/unittests/CodeGen/GenericOpcodesTest.cpp +++ b/backend/unittests/CodeGen/GenericOpcodesTest.cpp @@ -527,6 +527,7 @@ void testInstructionMemorySemantics(TestContext &Context) { const rcc::LLT P1 = *rcc::LLT::makePointer(1, 64); const rcc::Register Dst32 = createVirtualRegister(**Function, I32); const rcc::Register Dst64 = createVirtualRegister(**Function, I64); + const rcc::Register Src32 = createVirtualRegister(**Function, I32); const rcc::Register Src64 = createVirtualRegister(**Function, I64); const rcc::Register Float64 = createVirtualRegister(**Function, F64); const rcc::Register Status = createVirtualRegister(**Function, I1); @@ -606,6 +607,30 @@ void testInstructionMemorySemantics(TestContext &Context) { Context.expect(!Set->validateInstruction(WrongAtomic, (*Function)->registerInfo()), "generic atomic RMW must reject a compare-exchange MMO"); + std::vector NarrowAtomicOperands; + NarrowAtomicOperands.push_back(registerOperand(Dst64, true)); + NarrowAtomicOperands.push_back(registerOperand(Address0, false)); + NarrowAtomicOperands.push_back(registerOperand(Src64, false)); + rcc::MachineInstr &NarrowAtomic = createInstruction( + **Function, rcc::GenericOpcode::G_ATOMICRMW_ADD, std::move(NarrowAtomicOperands)); + addMemOperand(**Function, NarrowAtomic, + memoryDescription({rcc::MemoryAccessFlag::Load, rcc::MemoryAccessFlag::Store}, 1, 0, + rcc::AtomicOperation::ReadModifyWrite)); + Context.expect(Set->validateInstruction(NarrowAtomic, (*Function)->registerInfo()).has_value(), + "generic atomic RMW must accept an MMO narrower than its register container"); + + std::vector OversizedAtomicOperands; + OversizedAtomicOperands.push_back(registerOperand(Dst32, true)); + OversizedAtomicOperands.push_back(registerOperand(Address0, false)); + OversizedAtomicOperands.push_back(registerOperand(Src32, false)); + rcc::MachineInstr &OversizedAtomic = createInstruction( + **Function, rcc::GenericOpcode::G_ATOMICRMW_ADD, std::move(OversizedAtomicOperands)); + addMemOperand(**Function, OversizedAtomic, + memoryDescription({rcc::MemoryAccessFlag::Load, rcc::MemoryAccessFlag::Store}, 8, 0, + rcc::AtomicOperation::ReadModifyWrite)); + Context.expect(!Set->validateInstruction(OversizedAtomic, (*Function)->registerInfo()), + "generic atomic RMW must reject an MMO wider than its register container"); + std::vector FloatingAtomicOperands; FloatingAtomicOperands.push_back(registerOperand(Float64, true)); FloatingAtomicOperands.push_back(registerOperand(Address0, false)); -- cgit v1.2.3