From 13dc2a28ce1eaf6cb73eb1ab6f2b46292db1c585 Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Thu, 7 Mar 2024 11:43:56 +0200 Subject: [PATCH] intel/fs: fix lower_simd_width for MOV_INDIRECT MOV_INDIRECT picks one lane from the src[0] and moves it to all lanes in the destination. Even if we split the instruction, src[0] should remain identical. Noticed this while trying to use this instruction in SIMD32. All current use cases are limited to SIMD8 shaders (or SIMD16 on Xe2). Or maybe in SIMD32 but with a uniform src[0]. That's we think we've never seen the issue so far. Signed-off-by: Lionel Landwerlin Cc: mesa-stable Reviewed-by: Francisco Jerez Part-of: --- src/intel/compiler/brw_fs_lower_simd_width.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/intel/compiler/brw_fs_lower_simd_width.cpp b/src/intel/compiler/brw_fs_lower_simd_width.cpp index 58b18d53b0d..83f77424344 100644 --- a/src/intel/compiler/brw_fs_lower_simd_width.cpp +++ b/src/intel/compiler/brw_fs_lower_simd_width.cpp @@ -483,6 +483,12 @@ brw_fs_get_lowered_simd_width(const fs_visitor *shader, const fs_inst *inst) static inline bool needs_src_copy(const fs_builder &lbld, const fs_inst *inst, unsigned i) { + /* The indirectly indexed register stays the same even if we split the + * instruction. + */ + if (inst->opcode == SHADER_OPCODE_MOV_INDIRECT && i == 0) + return false; + return !(is_periodic(inst->src[i], lbld.dispatch_width()) || (inst->components_read(i) == 1 && lbld.dispatch_width() <= inst->exec_size)) || @@ -513,10 +519,13 @@ emit_unzip(const fs_builder &lbld, fs_inst *inst, unsigned i) lbld.VEC(tmp, comps, num_components); return tmp; - - } else if (is_periodic(inst->src[i], lbld.dispatch_width())) { + } else if (is_periodic(inst->src[i], lbld.dispatch_width()) || + (inst->opcode == SHADER_OPCODE_MOV_INDIRECT && i == 0)) { /* The source is invariant for all dispatch_width-wide groups of the * original region. + * + * The src[0] of MOV_INDIRECT is invariant regardless of the execution + * size. */ return inst->src[i];