aboutsummaryrefslogtreecommitdiff
path: root/backend/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'backend/lib/CodeGen/GlobalISel/LegalizerHelper.cpp')
-rw-r--r--backend/lib/CodeGen/GlobalISel/LegalizerHelper.cpp38
1 files changed, 38 insertions, 0 deletions
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<void> LegalizerHelper::lower(MachineInstr &Instruction,
}
return Block->removeInstruction(Instruction);
}
+ case GenericOpcode::G_ATOMICRMW_SUB: {
+ const Register Result = *Instruction.operandAt(0)->getIf<Register>();
+ const Register Address = *Instruction.operandAt(1)->getIf<Register>();
+ const Register Value = *Instruction.operandAt(2)->getIf<Register>();
+ 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<Register>();
const Register CarryOut = *Instruction.operandAt(1)->getIf<Register>();