From fd10764cff590b2743dee8544c78d4229fa6f6d6 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Wed, 8 Jan 2025 17:38:25 -0800 Subject: [PATCH] brw: extend the NOP+WHILE workaround It turns out that we need to add a NOP not only in between two consecutive WHILE instructions, but also after every control flow instruction that immediately precedes a WHILE. v2: Rebase after the renames. Fixes: 5ca883505e29 ("brw: add a NOP in between WHILE instructions on LNL") Reviewed-by: Francisco Jerez Signed-off-by: Paulo Zanoni Part-of: --- src/intel/compiler/brw_generator.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/intel/compiler/brw_generator.cpp b/src/intel/compiler/brw_generator.cpp index 27fcb03a07b..a5552f319d4 100644 --- a/src/intel/compiler/brw_generator.cpp +++ b/src/intel/compiler/brw_generator.cpp @@ -772,7 +772,7 @@ brw_generator::generate_code(const cfg_t *cfg, int dispatch_width, struct disasm_info *disasm_info = disasm_initialize(p->isa, cfg); - enum opcode prev_opcode = BRW_OPCODE_ILLEGAL; + brw_inst *prev_inst = NULL; foreach_block_and_inst (block, brw_inst, inst, cfg) { if (inst->opcode == SHADER_OPCODE_UNDEF) continue; @@ -1095,11 +1095,12 @@ brw_generator::generate_code(const cfg_t *cfg, int dispatch_width, break; case BRW_OPCODE_WHILE: - /* On LNL and newer, if we don't put a NOP in between two consecutive - * WHILE instructions we may end up with misrendering or GPU hangs. - * See HSD 22020521218. + /* Workaround for an issue with branch prediction for WHILE + * instructions that may lead to misrendering or GPU hangs. + * See HSDs 22020521218 and 16026360541. */ - if (devinfo->ver >= 20 && unlikely(prev_opcode == BRW_OPCODE_WHILE)) + if (devinfo->ver >= 20 && prev_inst && + unlikely(prev_inst->is_control_flow())) brw_NOP(p); brw_WHILE(p); @@ -1363,7 +1364,7 @@ brw_generator::generate_code(const cfg_t *cfg, int dispatch_width, case SHADER_OPCODE_LOAD_PAYLOAD: unreachable("Should be lowered by lower_load_payload()"); } - prev_opcode = inst->opcode; + prev_inst = inst; if (multiple_instructions_emitted) continue;