summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorConnor Abbott <cwabbott0@gmail.com>2023-02-16 18:17:35 +0100
committerMarge Bot <emma+marge@anholt.net>2024-04-26 12:55:13 +0000
commit4ee0f6d1fbf62438c69b1fe17ecf029e888414a0 (patch)
tree5ea7aedf1d68b851d868556ae3ba75a51f5b4c92
parentb309418380e6ed25135f31437d30c76a4ddec432 (diff)
ir3: Allow propagation of normal->shared copies
Copies from normal to shared registers are only allowed architecturally if all of the active threads have the same value for the normal register, which means that they can normally be propagated into e.g. ALU instructions or other copies. However, there are a few instruction types where this is not (currently) allowed, namely the scan macro where the source is tied to a shared destination and the collect/split macros where the lowering doesn't currently allow differently-typed sources and destinations (although we may want to allow that in the future), so we need to clean up ir3_valid_flags() to catch that. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22075>
-rw-r--r--src/freedreno/ir3/ir3.c10
-rw-r--r--src/freedreno/ir3/ir3.h10
-rw-r--r--src/freedreno/ir3/ir3_cp.c2
3 files changed, 11 insertions, 11 deletions
diff --git a/src/freedreno/ir3/ir3.c b/src/freedreno/ir3/ir3.c
index 66479bd68a2..381136ddc57 100644
--- a/src/freedreno/ir3/ir3.c
+++ b/src/freedreno/ir3/ir3.c
@@ -1078,7 +1078,10 @@ ir3_valid_flags(struct ir3_instruction *instr, unsigned n, unsigned flags)
if (flags & ~(IR3_REG_IMMED | IR3_REG_CONST | IR3_REG_SHARED))
return false;
- if ((flags & IR3_REG_SHARED) && !(instr->dsts[0]->flags & IR3_REG_SHARED))
+ /* Except for immed/const sources, source and dest shared-ness must match.
+ */
+ if (!(flags & (IR3_REG_IMMED | IR3_REG_CONST)) &&
+ (flags & IR3_REG_SHARED) != (instr->dsts[0]->flags & IR3_REG_SHARED))
return false;
return true;
@@ -1096,7 +1099,10 @@ ir3_valid_flags(struct ir3_instruction *instr, unsigned n, unsigned flags)
valid_flags = IR3_REG_SHARED;
break;
case OPC_SCAN_MACRO:
- return flags == 0;
+ if (n == 0)
+ return flags == 0;
+ else
+ return flags == IR3_REG_SHARED;
break;
case OPC_SCAN_CLUSTERS_MACRO:
if (n == 0)
diff --git a/src/freedreno/ir3/ir3.h b/src/freedreno/ir3/ir3.h
index 89fd12729a4..2caad8ea8e2 100644
--- a/src/freedreno/ir3/ir3.h
+++ b/src/freedreno/ir3/ir3.h
@@ -917,14 +917,8 @@ is_same_type_reg(struct ir3_register *dst, struct ir3_register *src)
unsigned dst_type = (dst->flags & IR3_REG_HALF);
unsigned src_type = (src->flags & IR3_REG_HALF);
- /* Treat shared->normal copies as same-type, because they can generally be
- * folded, but not normal->shared copies.
- */
- if (dst_type != src_type ||
- ((dst->flags & IR3_REG_SHARED) && !(src->flags & IR3_REG_SHARED)))
- return false;
- else
- return true;
+ /* Treat shared->normal copies and normal->shared copies as same-type. */
+ return dst_type == src_type;
}
/* Is it a non-transformative (ie. not type changing) mov? This can
diff --git a/src/freedreno/ir3/ir3_cp.c b/src/freedreno/ir3/ir3_cp.c
index e2c569fbacc..8f3133e18e1 100644
--- a/src/freedreno/ir3/ir3_cp.c
+++ b/src/freedreno/ir3/ir3_cp.c
@@ -116,7 +116,7 @@ combine_flags(unsigned *dstflags, struct ir3_instruction *src)
if (srcflags & IR3_REG_BNOT)
*dstflags ^= IR3_REG_BNOT;
- *dstflags &= ~IR3_REG_SSA;
+ *dstflags &= ~(IR3_REG_SSA | IR3_REG_SHARED);
*dstflags |= srcflags & IR3_REG_SSA;
*dstflags |= srcflags & IR3_REG_CONST;
*dstflags |= srcflags & IR3_REG_IMMED;