From 23bd356b425c885bf48e5349c0b7ee1f74b6ca4b Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Mon, 15 Sep 2025 17:03:02 -0700 Subject: [PATCH] brw/nir: nir_intrinsic_load_reloc_const_intel may not be scalar [v3] If the (NIR) destination is a register (i.e., not an SSA value), the destination of the BRW instruction will not be is_scalar. This occurs in some shaders in Final Fantasy XVI (and finalfantasytype0_1.rdc.2826e29da3722a83.1.foz). If the destination is not is_scalar, revert most of this code to the state previous to f3593df877f. This means - Allocate a SIMD1 register and UNDEF it. - Emit a SIMD1 MOV_RELOC_IMM to that register. - Emit an additional MOV to expand the SIMD1 result. Closes: #12520 Fixes: f3593df877f ("brw/nir: Treat load_reloc_const_intel as convergent") Reviewed-by: Lionel Landwerlin Part-of: --- src/intel/compiler/brw_from_nir.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/intel/compiler/brw_from_nir.cpp b/src/intel/compiler/brw_from_nir.cpp index e0d24021086..cc225f268c6 100644 --- a/src/intel/compiler/brw_from_nir.cpp +++ b/src/intel/compiler/brw_from_nir.cpp @@ -6215,10 +6215,20 @@ brw_from_nir_emit_intrinsic(nir_to_brw_state &ntb, uint32_t id = nir_intrinsic_param_idx(instr); uint32_t base = nir_intrinsic_base(instr); - assert(dest.is_scalar); + /* Emit the reloc in the smallest SIMD size to limit register usage. */ + const brw_builder ubld = dest.is_scalar ? xbld : bld.exec_all().group(1, 0); + brw_reg small_dest = dest.is_scalar ? dest : ubld.vgrf(dest.type); - xbld.emit(SHADER_OPCODE_MOV_RELOC_IMM, retype(dest, BRW_TYPE_D), + if (!dest.is_scalar) + ubld.UNDEF(small_dest); + + ubld.emit(SHADER_OPCODE_MOV_RELOC_IMM, retype(small_dest, BRW_TYPE_D), brw_imm_ud(id), brw_imm_ud(base)); + + /* Copy propagation will get rid of this MOV. */ + if (!dest.is_scalar) + bld.MOV(dest, component(small_dest, 0)); + break; }