diff --git a/src/freedreno/ir3/ir3.h b/src/freedreno/ir3/ir3.h index 25a5f36731f..20b2298b7b1 100644 --- a/src/freedreno/ir3/ir3.h +++ b/src/freedreno/ir3/ir3.h @@ -861,6 +861,23 @@ is_const_mov(struct ir3_instruction *instr) (type_sint(src_type) && type_sint(dst_type)); } +static inline bool +is_subgroup_cond_mov_macro(struct ir3_instruction *instr) +{ + switch (instr->opc) { + case OPC_BALLOT_MACRO: + case OPC_ANY_MACRO: + case OPC_ALL_MACRO: + case OPC_ELECT_MACRO: + case OPC_READ_COND_MACRO: + case OPC_READ_FIRST_MACRO: + case OPC_SWZ_SHARED_MACRO: + return true; + default: + return false; + } +} + static inline bool is_alu(struct ir3_instruction *instr) { diff --git a/src/freedreno/ir3/ir3_cp.c b/src/freedreno/ir3/ir3_cp.c index 551e50d44e0..55fe8d6589d 100644 --- a/src/freedreno/ir3/ir3_cp.c +++ b/src/freedreno/ir3/ir3_cp.c @@ -397,6 +397,11 @@ reg_cp(struct ir3_cp_ctx *ctx, struct ir3_instruction *instr, conflicts(instr->address, reg->def->instr->address)) return false; + /* These macros expand to a mov in an if statement */ + if ((src_reg->flags & IR3_REG_RELATIV) && + is_subgroup_cond_mov_macro(instr)) + return false; + /* This seems to be a hw bug, or something where the timings * just somehow don't work out. This restriction may only * apply if the first src is also CONST. diff --git a/src/freedreno/ir3/ir3_cp_postsched.c b/src/freedreno/ir3/ir3_cp_postsched.c index 967b50f9ce3..ff9c72465ec 100644 --- a/src/freedreno/ir3/ir3_cp_postsched.c +++ b/src/freedreno/ir3/ir3_cp_postsched.c @@ -149,6 +149,9 @@ instr_cp_postsched(struct ir3_instruction *mov) if (is_meta(use)) continue; + if (is_subgroup_cond_mov_macro(use)) + continue; + struct ir3_register *def = src->def; if (has_conflicting_write(mov, use, &def, src->array.id, offset)) continue;