From 907cc49c3201170de01167a728bac0366066a6f2 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Wed, 29 Apr 2026 17:22:22 -0700 Subject: [PATCH] brw: Calcuate divergence before brw_from_nir We were previously assuming that potentially stale divergence data was valid. On some paths the register pressure estimator would recalculate this, but, as is obvious from the results, not always. v2: Add an assertion in brw_from_nir_emit_impl to ensure we don't end up in this situation again. v3: Call nir_divergence_analysis from brw_nir_lower_deferred_urb_writes. This fixes assertion failures (the assertion added in v2) in basically every graphics shader. The altnerative was to call it from brw_compile_vs, brw_compile_gs, and brw_compile_tes. shader-db: All Intel platformms had similar results. (Lunar Lake shown) total instructions in shared programs: 17050403 -> 17054033 (0.02%) instructions in affected programs: 296344 -> 299974 (1.22%) helped: 0 / HURT: 376 total cycles in shared programs: 876063126 -> 875817316 (-0.03%) cycles in affected programs: 78627328 -> 78381518 (-0.31%) helped: 91 / HURT: 276 LOST: 1 GAINED: 10 fossil-db: All Intel platformms had similar results. (Lunar Lake shown) Totals: Instrs: 913770429 -> 916075391 (+0.25%); split: -0.00%, +0.26% CodeSize: 14647414640 -> 14726176320 (+0.54%); split: -0.02%, +0.56% Cycle count: 102308091527 -> 102290664775 (-0.02%); split: -0.26%, +0.24% Spill count: 3469632 -> 3469124 (-0.01%); split: -0.08%, +0.07% Fill count: 5007038 -> 4998674 (-0.17%); split: -0.51%, +0.34% Max live registers: 192568853 -> 192595355 (+0.01%); split: -0.00%, +0.02% Max dispatch width: 48713168 -> 48712880 (-0.00%); split: +0.00%, -0.00% Non SSA regs after NIR: 140252767 -> 140253718 (+0.00%) Totals from 223099 (11.11% of 2007586) affected shaders: Instrs: 314077245 -> 316382207 (+0.73%); split: -0.01%, +0.75% CodeSize: 5335583824 -> 5414345504 (+1.48%); split: -0.06%, +1.54% Cycle count: 45868025821 -> 45850599069 (-0.04%); split: -0.58%, +0.54% Spill count: 2062649 -> 2062141 (-0.02%); split: -0.14%, +0.11% Fill count: 3343019 -> 3334655 (-0.25%); split: -0.76%, +0.51% Max live registers: 36762498 -> 36789000 (+0.07%); split: -0.02%, +0.09% Max dispatch width: 5542224 -> 5541936 (-0.01%); split: +0.03%, -0.03% Non SSA regs after NIR: 43727142 -> 43728093 (+0.00%) Reviewed-by: Lionel Landwerlin [v1] Fixes: 1bff4f93ca9 ("brw: Basic infrastructure to store convergent values as scalars") Part-of: --- src/intel/compiler/brw/brw_from_nir.cpp | 2 ++ src/intel/compiler/brw/brw_nir.c | 18 +++++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/intel/compiler/brw/brw_from_nir.cpp b/src/intel/compiler/brw/brw_from_nir.cpp index 11aa0df5624..7a2cd2b4c57 100644 --- a/src/intel/compiler/brw/brw_from_nir.cpp +++ b/src/intel/compiler/brw/brw_from_nir.cpp @@ -250,6 +250,8 @@ brw_from_nir_emit_impl(nir_to_brw_state &ntb, nir_function_impl *impl) ntb.ssa_values = rzalloc_array(ntb.mem_ctx, brw_reg, impl->ssa_alloc); ntb.ssa_bind_infos = rzalloc_array(ntb.mem_ctx, struct brw_bind_info, impl->ssa_alloc); + assert(impl->valid_metadata & nir_metadata_divergence); + brw_from_nir_emit_cf_list(ntb, &impl->body); } diff --git a/src/intel/compiler/brw/brw_nir.c b/src/intel/compiler/brw/brw_nir.c index e2e7cab6811..0ee43cab65e 100644 --- a/src/intel/compiler/brw/brw_nir.c +++ b/src/intel/compiler/brw/brw_nir.c @@ -689,7 +689,17 @@ brw_nir_lower_deferred_urb_writes(nir_shader *nir, free(outputs); - return nir_progress(true, impl, nir_metadata_control_flow); + bool progress = nir_progress(true, impl, nir_metadata_control_flow); + + if (progress) { + /* This is important! brw_from_nir really, really needs divergence + * information. Call this explicitly here becuase this function just + * dirtied divergence metadata. + */ + nir_divergence_analysis(nir); + } + + return progress; } @@ -3262,6 +3272,12 @@ brw_postprocess_nir_out_of_ssa(brw_pass_tracker *pt, nir_sweep(nir); + /* This is important! brw_from_nir really, really needs divergence + * information. Calculate it here so that it will be logged with + * INTEL_DEBUG=shaders or INTEL_DEBUG=mda. + */ + nir_divergence_analysis(nir); + if (unlikely(debug_enabled)) { fprintf(stderr, "NIR (final form) for %s shader:\n", _mesa_shader_stage_to_string(nir->info.stage));