Implement BUFFER_ATOMIC_FCMPSWAP

Implement BUFFER_ATOMIC_FCMPSWAP via descriptor aliasing + bitcast
This commit is contained in:
Kravickas 2026-03-31 15:14:01 +02:00 committed by GitHub
parent 969955b8a0
commit ede158f995
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 28 additions and 0 deletions

View File

@ -351,6 +351,15 @@ Id EmitBufferAtomicCmpSwap32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id ad
&Sirit::Module::OpAtomicCompareExchange);
}
Id EmitBufferAtomicFCmpSwap32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value,
Id cmp_value) {
const auto u32_value = ctx.OpBitcast(ctx.U32[1], value);
const auto u32_cmp = ctx.OpBitcast(ctx.U32[1], cmp_value);
const auto result = BufferAtomicU32CmpSwap(ctx, inst, handle, address, u32_value, u32_cmp,
&Sirit::Module::OpAtomicCompareExchange);
return ctx.OpBitcast(ctx.F32[1], result);
}
Id EmitImageAtomicIAdd32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id value) {
return ImageAtomicU32(ctx, inst, handle, coords, value, &Sirit::Module::OpAtomicIAdd);
}

View File

@ -108,6 +108,8 @@ Id EmitBufferAtomicXor32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id addres
Id EmitBufferAtomicSwap32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value);
Id EmitBufferAtomicCmpSwap32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value,
Id cmp_value);
Id EmitBufferAtomicFCmpSwap32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value,
Id cmp_value);
Id EmitGetAttribute(EmitContext& ctx, IR::Attribute attr, u32 comp, u32 index);
Id EmitGetAttributeU32(EmitContext& ctx, IR::Attribute attr, u32 comp);
void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, Id value, u32 comp);

View File

@ -116,6 +116,8 @@ void Translator::EmitVectorMemory(const GcnInst& inst) {
return BUFFER_ATOMIC<IR::F32>(AtomicOp::Fmin, inst);
case Opcode::BUFFER_ATOMIC_FMAX:
return BUFFER_ATOMIC<IR::F32>(AtomicOp::Fmax, inst);
case Opcode::BUFFER_ATOMIC_FCMPSWAP:
return BUFFER_ATOMIC<IR::F32>(AtomicOp::FCmpSwap, inst);
// MIMG
// Image load operations
@ -379,6 +381,10 @@ void Translator::BUFFER_ATOMIC(AtomicOp op, const GcnInst& inst) {
const IR::Value cmp_val = ir.GetVectorReg(vdata + 1);
return ir.BufferAtomicCmpSwap(handle, address, vdata_val, cmp_val, buffer_info);
}
case AtomicOp::FCmpSwap: {
const IR::Value cmp_val = ir.GetVectorReg(vdata + 1);
return ir.BufferAtomicFCmpSwap(handle, address, vdata_val, cmp_val, buffer_info);
}
case AtomicOp::Add:
return ir.BufferAtomicIAdd(handle, address, vdata_val, buffer_info);
case AtomicOp::Smin:

View File

@ -627,6 +627,11 @@ Value IREmitter::BufferAtomicCmpSwap(const Value& handle, const Value& address,
return Inst(Opcode::BufferAtomicCmpSwap32, Flags{info}, handle, address, vdata, cmp_value);
}
Value IREmitter::BufferAtomicFCmpSwap(const Value& handle, const Value& address, const Value& vdata,
const Value& cmp_value, BufferInstInfo info) {
return Inst(Opcode::BufferAtomicFCmpSwap32, Flags{info}, handle, address, vdata, cmp_value);
}
U32 IREmitter::DataAppend(const U32& counter) {
return Inst<U32>(Opcode::DataAppend, counter, Imm32(0));
}

View File

@ -166,6 +166,9 @@ public:
[[nodiscard]] Value BufferAtomicCmpSwap(const Value& handle, const Value& address,
const Value& value, const Value& cmp_value,
BufferInstInfo info);
[[nodiscard]] Value BufferAtomicFCmpSwap(const Value& handle, const Value& address,
const Value& value, const Value& cmp_value,
BufferInstInfo info);
[[nodiscard]] U32 DataAppend(const U32& counter);
[[nodiscard]] U32 DataConsume(const U32& counter);

View File

@ -82,6 +82,7 @@ bool Inst::MayHaveSideEffects() const noexcept {
case Opcode::BufferAtomicXor32:
case Opcode::BufferAtomicSwap32:
case Opcode::BufferAtomicCmpSwap32:
case Opcode::BufferAtomicFCmpSwap32:
case Opcode::DataAppend:
case Opcode::DataConsume:
case Opcode::WriteSharedU16:

View File

@ -150,6 +150,7 @@ OPCODE(BufferAtomicOr32, U32, Opaq
OPCODE(BufferAtomicXor32, U32, Opaque, Opaque, U32, )
OPCODE(BufferAtomicSwap32, U32, Opaque, Opaque, U32, )
OPCODE(BufferAtomicCmpSwap32, U32, Opaque, Opaque, U32, U32, )
OPCODE(BufferAtomicFCmpSwap32, F32, Opaque, Opaque, F32, F32, )
// Vector utility
OPCODE(CompositeConstructU32x2, U32x2, U32, U32, )

View File

@ -39,6 +39,7 @@ bool IsBufferAtomic(const IR::Inst& inst) {
case IR::Opcode::BufferAtomicXor32:
case IR::Opcode::BufferAtomicSwap32:
case IR::Opcode::BufferAtomicCmpSwap32:
case IR::Opcode::BufferAtomicFCmpSwap32:
return true;
default:
return false;