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>
This commit is contained in:
Connor Abbott 2023-02-16 18:17:35 +01:00 committed by Marge Bot
parent b309418380
commit 4ee0f6d1fb
3 changed files with 11 additions and 11 deletions

View file

@ -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)

View file

@ -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

View file

@ -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;