diff --git a/src/freedreno/ir3/ir3.h b/src/freedreno/ir3/ir3.h index 63b6bc39751..775d3e38b21 100644 --- a/src/freedreno/ir3/ir3.h +++ b/src/freedreno/ir3/ir3.h @@ -3311,6 +3311,13 @@ regmask_get(regmask_t *regmask, struct ir3_register *reg) } return false; } + +static inline bool +regmask_get_any_gpr(regmask_t *regmask) +{ + return BITSET_TEST_RANGE(regmask->full, 0, GPR_REG_SIZE * 2) || + BITSET_TEST_RANGE(regmask->half, 0, GPR_REG_SIZE); +} /* ************************************************************************* */ struct ir3_nop_state { diff --git a/src/freedreno/ir3/ir3_legalize.c b/src/freedreno/ir3/ir3_legalize.c index 4d452e24e70..5a12b6d1721 100644 --- a/src/freedreno/ir3/ir3_legalize.c +++ b/src/freedreno/ir3/ir3_legalize.c @@ -754,6 +754,11 @@ legalize_block(struct ir3_legalize_ctx *ctx, struct ir3_block *block) if (writes_addr1(n) && block->in_early_preamble) n->srcs[0]->flags |= IR3_REG_R; + if ((n->opc == OPC_SHPE) && (ctx->compiler->gen >= 8) && + regmask_get_any_gpr(&state->needs_sy)) { + last_n = insert_nop_flags(ctx, state, last_n, &build, IR3_INSTR_SY); + } + /* cat5+ does not have an (ss) bit, if needed we need to * insert a nop to carry the sync flag. Would be kinda * clever if we were aware of this during scheduling, but