From 05d687723530ed3c5c9f7d0addb3b047138613a3 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Thu, 10 Mar 2022 20:46:23 -0800 Subject: [PATCH] freedreno/ir3: Don't try re-swapping cat3 srcs This can lead us to endless loops of "progress".. Note fixes commit commit really just exposed an existing problem. Fixes: 9c9e8c33498 ("nir: Reorder ffma and fsub combining") Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/6133 Signed-off-by: Rob Clark Part-of: --- src/freedreno/ir3/ir3.h | 1 + src/freedreno/ir3/ir3_cp.c | 22 +++++++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/freedreno/ir3/ir3.h b/src/freedreno/ir3/ir3.h index dcc5ff06995..4461d1daa4e 100644 --- a/src/freedreno/ir3/ir3.h +++ b/src/freedreno/ir3/ir3.h @@ -361,6 +361,7 @@ struct ir3_instruction { IR3_SRC_PACKED_LOW = 0, IR3_SRC_PACKED_HIGH = 1, } packed; + bool swapped; } cat3; struct { unsigned samp, tex; diff --git a/src/freedreno/ir3/ir3_cp.c b/src/freedreno/ir3/ir3_cp.c index c667f0fd03e..66694310a8d 100644 --- a/src/freedreno/ir3/ir3_cp.c +++ b/src/freedreno/ir3/ir3_cp.c @@ -276,10 +276,13 @@ try_swap_mad_two_srcs(struct ir3_instruction *instr, unsigned new_flags) if (!is_mad(instr->opc)) return false; - /* NOTE: pre-swap first two src's before valid_flags(), - * which might try to dereference the n'th src: + /* If we've already tried, nothing more to gain.. we will only + * have previously swapped if the original 2nd src was const or + * immed. So swapping back won't improve anything and could + * result in an infinite "progress" loop. */ - swap(instr->srcs[0], instr->srcs[1]); + if (instr->cat3.swapped) + return false; /* cat3 doesn't encode immediate, but we can lower immediate * to const if that helps: @@ -289,6 +292,19 @@ try_swap_mad_two_srcs(struct ir3_instruction *instr, unsigned new_flags) new_flags |= IR3_REG_CONST; } + /* If the reason we couldn't fold without swapping is something + * other than const source, then swapping won't help: + */ + if (!(new_flags & IR3_REG_CONST)) + return false; + + instr->cat3.swapped = true; + + /* NOTE: pre-swap first two src's before valid_flags(), + * which might try to dereference the n'th src: + */ + swap(instr->srcs[0], instr->srcs[1]); + bool valid_swap = /* can we propagate mov if we move 2nd src to first? */ ir3_valid_flags(instr, 0, new_flags) &&