Mesa (master): ir3: do not fold cmps from different blocks with non-null address

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon May 3 18:03:29 UTC 2021


Module: Mesa
Branch: master
Commit: ea72be8b7c8566c008d81441843ecfb527f39b72
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=ea72be8b7c8566c008d81441843ecfb527f39b72

Author: Danylo Piliaiev <dpiliaiev at igalia.com>
Date:   Tue Apr 20 20:29:21 2021 +0300

ir3: do not fold cmps from different blocks with non-null address

Scheduling don't like address being in the different block from
the instruction.

Fixes a crash in the trace of "War Thunder" (DX11)

Signed-off-by: Danylo Piliaiev <dpiliaiev at igalia.com>
Reviewed-by: Samuel Iglesias Gonsálvez <siglesias at igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10355>

---

 src/freedreno/ir3/ir3_cp.c | 33 ++++++++++++++++++++-------------
 1 file changed, 20 insertions(+), 13 deletions(-)

diff --git a/src/freedreno/ir3/ir3_cp.c b/src/freedreno/ir3/ir3_cp.c
index e5b5e101f9e..887a6f45b81 100644
--- a/src/freedreno/ir3/ir3_cp.c
+++ b/src/freedreno/ir3/ir3_cp.c
@@ -100,6 +100,24 @@ static bool is_eligible_mov(struct ir3_instruction *instr,
 	return false;
 }
 
+/* we can end up with extra cmps.s from frontend, which uses a
+ *
+ *    cmps.s p0.x, cond, 0
+ *
+ * as a way to mov into the predicate register.  But frequently 'cond'
+ * is itself a cmps.s/cmps.f/cmps.u. So detect this special case.
+ */
+static bool is_foldable_double_cmp(struct ir3_instruction *cmp)
+{
+	struct ir3_instruction *cond = ssa(cmp->regs[1]);
+	return (cmp->regs[0]->num == regid(REG_P0, 0)) &&
+				cond &&
+				(cmp->regs[2]->flags & IR3_REG_IMMED) &&
+				(cmp->regs[2]->iim_val == 0) &&
+				(cmp->cat2.condition == IR3_COND_NE) &&
+				(!cond->address || (cmp->block == cond->address->block));
+}
+
 /* propagate register flags from src to dst.. negates need special
  * handling to cancel each other out.
  */
@@ -532,21 +550,10 @@ instr_cp(struct ir3_cp_ctx *ctx, struct ir3_instruction *instr)
 		ir3_instr_set_address(instr, eliminate_output_mov(ctx, instr->address));
 	}
 
-	/* we can end up with extra cmps.s from frontend, which uses a
-	 *
-	 *    cmps.s p0.x, cond, 0
-	 *
-	 * as a way to mov into the predicate register.  But frequently 'cond'
-	 * is itself a cmps.s/cmps.f/cmps.u.  So detect this special case and
-	 * just re-write the instruction writing predicate register to get rid
+	/* Re-write the instruction writing predicate register to get rid
 	 * of the double cmps.
 	 */
-	if ((instr->opc == OPC_CMPS_S) &&
-			(instr->regs[0]->num == regid(REG_P0, 0)) &&
-			ssa(instr->regs[1]) &&
-			(instr->regs[2]->flags & IR3_REG_IMMED) &&
-			(instr->regs[2]->iim_val == 0) &&
-			(instr->cat2.condition == IR3_COND_NE)) {
+	if ((instr->opc == OPC_CMPS_S) && is_foldable_double_cmp(instr)) {
 		struct ir3_instruction *cond = ssa(instr->regs[1]);
 		switch (cond->opc) {
 		case OPC_CMPS_S:



More information about the mesa-commit mailing list