diff --git a/src/amd/compiler/README-ISA.md b/src/amd/compiler/README-ISA.md index 296ba7a864a..b49e4d05083 100644 --- a/src/amd/compiler/README-ISA.md +++ b/src/amd/compiler/README-ISA.md @@ -113,6 +113,16 @@ Some instructions have a `_LEGACY` variant which implements "DX9 rules", in whic the zero "wins" in multiplications, ie. `0.0*x` is always `0.0`. The VEGA ISA mentions `V_MAC_LEGACY_F32` but this instruction is not really there on VEGA. +## `m0` with LDS instructions on Vega and newer + +The Vega ISA doc (both the old one and the "7nm" one) claims that LDS instructions +use the `m0` register for address clamping like older GPUs, but this is not the case. + +In reality, only the `_addtid` variants of LDS instructions use `m0` on Vega and +newer GPUs, so the relevant section of the RDNA ISA doc seems to apply. +LLVM also doesn't emit any initialization of `m0` for LDS instructions, and this +was also confirmed by AMD devs. + ## RDNA L0, L1 cache and DLC, GLC bits The old L1 cache was renamed to L0, and a new L1 cache was added to RDNA. The diff --git a/src/amd/compiler/aco_instruction_selection.cpp b/src/amd/compiler/aco_instruction_selection.cpp index 9953130630c..bd81c50083c 100644 --- a/src/amd/compiler/aco_instruction_selection.cpp +++ b/src/amd/compiler/aco_instruction_selection.cpp @@ -3911,7 +3911,10 @@ emit_load(isel_context* ctx, Builder& bld, const LoadEmitInfo& info, Operand load_lds_size_m0(Builder& bld) { - /* TODO: m0 does not need to be initialized on GFX9+ */ + /* m0 does not need to be initialized on GFX9+ */ + if (bld.program->chip_class >= GFX9) + return Operand(s1); + return bld.m0((Temp)bld.copy(bld.def(s1, m0), Operand::c32(0xffffffffu))); } @@ -3977,6 +3980,9 @@ lds_load_callback(Builder& bld, const LoadEmitInfo& info, Temp offset, unsigned instr = bld.ds(op, Definition(val), offset, m, const_offset); instr->ds().sync = info.sync; + if (m.isUndefined()) + instr->operands.pop_back(); + return val; } @@ -4410,6 +4416,9 @@ store_lds(isel_context* ctx, unsigned elem_size_bytes, Temp data, uint32_t wrmas instr = bld.ds(op, address_offset, split_data, m, inline_offset); } instr->ds().sync = memory_sync_info(storage_shared); + + if (m.isUndefined()) + instr->operands.pop_back(); } } @@ -7293,6 +7302,10 @@ visit_shared_atomic(isel_context* ctx, nir_intrinsic_instr* instr) if (return_previous) ds->definitions[0] = Definition(get_ssa_temp(ctx, &instr->dest.ssa)); ds->sync = memory_sync_info(storage_shared, semantic_atomicrmw); + + if (m.isUndefined()) + ds->operands.pop_back(); + ctx->block->instructions.emplace_back(std::move(ds)); }