diff --git a/src/freedreno/ir3/ir3.c b/src/freedreno/ir3/ir3.c index fd0f18c3703..a6a5defa10e 100644 --- a/src/freedreno/ir3/ir3.c +++ b/src/freedreno/ir3/ir3.c @@ -1297,3 +1297,18 @@ ir3_valid_immediate(struct ir3_instruction *instr, int32_t immed) /* Other than cat1 (mov) we can only encode up to 10 bits, sign-extended: */ return !(immed & ~0x1ff) || !(-immed & ~0x1ff); } + +struct ir3_instruction * +ir3_get_cond_for_nonzero_compare(struct ir3_instruction *instr) +{ + /* If instr is a negation (likely as a result of an nir_b2n), we can ignore + * that and use its source, since the nonzero-ness stays the same. + */ + if (instr->opc == OPC_ABSNEG_S && instr->flags == 0 && + (instr->srcs[0]->flags & (IR3_REG_SNEG | IR3_REG_SABS)) == + IR3_REG_SNEG) { + return instr->srcs[0]->def->instr; + } + + return instr; +} diff --git a/src/freedreno/ir3/ir3.h b/src/freedreno/ir3/ir3.h index 3120dde2fd3..9458b1e196e 100644 --- a/src/freedreno/ir3/ir3.h +++ b/src/freedreno/ir3/ir3.h @@ -844,6 +844,14 @@ bool ir3_valid_flags(struct ir3_instruction *instr, unsigned n, unsigned flags); bool ir3_valid_immediate(struct ir3_instruction *instr, int32_t immed); +/** + * Given an instruction whose result we want to test for nonzero, return a + * potentially different instruction for which the result would be the same. + * This might be one of its sources if instr doesn't change the nonzero-ness. + */ +struct ir3_instruction * +ir3_get_cond_for_nonzero_compare(struct ir3_instruction *instr); + #include "util/set.h" #define foreach_ssa_use(__use, __instr) \ for (struct ir3_instruction *__use = (void *)~0; __use && (__instr)->uses; \ diff --git a/src/freedreno/ir3/ir3_compiler_nir.c b/src/freedreno/ir3/ir3_compiler_nir.c index c510e0eed99..b1ed40355a7 100644 --- a/src/freedreno/ir3/ir3_compiler_nir.c +++ b/src/freedreno/ir3/ir3_compiler_nir.c @@ -712,17 +712,7 @@ emit_alu(struct ir3_context *ctx, nir_alu_instr *alu) break; case nir_op_bcsel: { - struct ir3_instruction *cond = src[0]; - - /* If src[0] is a negation (likely as a result of an ir3_b2n(cond)), - * we can ignore that and use original cond, since the nonzero-ness of - * cond stays the same. - */ - if (cond->opc == OPC_ABSNEG_S && cond->flags == 0 && - (cond->srcs[0]->flags & (IR3_REG_SNEG | IR3_REG_SABS)) == - IR3_REG_SNEG) { - cond = cond->srcs[0]->def->instr; - } + struct ir3_instruction *cond = ir3_get_cond_for_nonzero_compare(src[0]); compile_assert(ctx, bs[1] == bs[2]); diff --git a/src/freedreno/ir3/ir3_context.c b/src/freedreno/ir3/ir3_context.c index ecde7e6f033..fb9bd1d03d5 100644 --- a/src/freedreno/ir3/ir3_context.c +++ b/src/freedreno/ir3/ir3_context.c @@ -461,6 +461,8 @@ ir3_get_addr1(struct ir3_context *ctx, unsigned const_val) struct ir3_instruction * ir3_get_predicate(struct ir3_context *ctx, struct ir3_instruction *src) { + src = ir3_get_cond_for_nonzero_compare(src); + struct hash_entry *src_entry = _mesa_hash_table_search(ctx->predicate_conversions, src); if (src_entry)