agx: fix SSA repair with phis with constants

For large constants inlined into phis, this would overread the remap[] array,
which could crash. No CTS tests affected though.

Christoph found the bug and fixed it for Bifrost over in
https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39305. I just did a
quick CTS run of the obvious AGX backport over this morning's breakfast.

Cc: mesa-stable
Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Reported-by: Christoph Pillmayer <christoph.pillmayer@arm.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39313>
This commit is contained in:
Alyssa Rosenzweig 2026-01-14 09:37:23 -05:00 committed by Marge Bot
parent d69daf28d0
commit e4520b1dda

View file

@ -176,8 +176,24 @@ agx_opt_trivial_phi(agx_context *ctx)
bool all_same = true;
agx_foreach_src(phi, s) {
/* TODO: Handle cycles faster */
if (!agx_is_null(remap[phi->src[s].value])) {
/* Only optimize trivial phis with normal sources. It is possible
* to optimize something like `phi #0, #0` but...
*
* 1. It would inadvently propagate constants which may be
* invalid. Copyprop knows the rules for this, but we don't here.
*
* 2. These trivial phis should be optimized at the NIR level.
* This pass is just to clean up spilling.
*
* So skip them for correctness in case NIR misses something
* (which can happen depending on pass order).
*
* ---
*
* TODO: Handle cycles faster.
*/
if (phi->src[s].type != AGX_INDEX_NORMAL ||
agx_is_null(remap[phi->src[s].value])) {
all_same = false;
break;
}
@ -195,19 +211,7 @@ agx_opt_trivial_phi(agx_context *ctx)
same = phi->src[s];
}
/* Only optimize trivial phis with normal sources. It is possible
* to optimize something like `phi #0, #0` but...
*
* 1. It would inadvently propagate constants which may be invalid.
* Copyprop knows the rules for this, but we don't here.
*
* 2. These trivial phis should be optimized at the NIR level. This
* pass is just to clean up spilling.
*
* So skip them for correctness in case NIR misses something (which
* can happen depending on pass order).
*/
if (all_same && same.type == AGX_INDEX_NORMAL) {
if (all_same) {
remap[phi->dest[0].value] = same;
agx_remove_instruction(phi);
progress = true;