From fa1214d24c8882b4314729e21c5485d889ca0e35 Mon Sep 17 00:00:00 2001 From: Richard-Qin-X Date: Sat, 15 Aug 2026 03:50:01 +0800 Subject: [GlobalISel] Lower atomic subtraction --- backend/lib/CodeGen/GlobalISel/LegalizerHelper.cpp | 38 ++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'backend') diff --git a/backend/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/backend/lib/CodeGen/GlobalISel/LegalizerHelper.cpp index e9c17d0..01e0c1d 100644 --- a/backend/lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ b/backend/lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -3070,6 +3070,44 @@ Expected LegalizerHelper::lower(MachineInstr &Instruction, } return Block->removeInstruction(Instruction); } + case GenericOpcode::G_ATOMICRMW_SUB: { + const Register Result = *Instruction.operandAt(0)->getIf(); + const Register Address = *Instruction.operandAt(1)->getIf(); + const Register Value = *Instruction.operandAt(2)->getIf(); + auto ValueType = MRI.getType(Value); + if (!ValueType) + return std::unexpected(ValueType.error()); + + if (auto Point = MIRBuilder.setInsertPointBefore(Instruction); !Point) + return std::unexpected(Point.error()); + auto Zero = buildConstantRegister(MIRBuilder, *ValueType, 0); + if (!Zero) + return std::unexpected(Zero.error()); + auto Negated = + buildResultInstruction(MIRBuilder, GenericOpcode::G_SUB, *ValueType, {*Zero, Value}); + if (!Negated) + return std::unexpected(Negated.error()); + + auto AtomicAdd = MIRBuilder.buildInstr(opcode(GenericOpcode::G_ATOMICRMW_ADD)); + if (!AtomicAdd) + return std::unexpected(AtomicAdd.error()); + if (auto Added = AtomicAdd->addDef(Result); !Added) + return std::unexpected(Added.error()); + if (auto Added = AtomicAdd->addUse(Address); !Added) + return std::unexpected(Added.error()); + if (auto Added = AtomicAdd->addUse(*Negated); !Added) + return std::unexpected(Added.error()); + if (auto Added = AtomicAdd->addMemOperand(*Instruction.memOperands().front()); !Added) + return std::unexpected(Added.error()); + if (auto Built = AtomicAdd->build(); !Built) + return std::unexpected(Built.error()); + + MachineBasicBlock *Block = Instruction.parent(); + if (Block == nullptr) + return makeUnexpected(ErrorCode::InternalError, + "G_ATOMICRMW_SUB became detached during lowering"); + return Block->removeInstruction(Instruction); + } case GenericOpcode::G_UADDO: { const Register Result = *Instruction.operandAt(0)->getIf(); const Register CarryOut = *Instruction.operandAt(1)->getIf(); -- cgit v1.2.3