ir3: fold negations into cmps.ne zero

It was already implemented for sel so pull that functionality into a
helper function which can be used from ir3_get_predicate.

Signed-off-by: Job Noorman <jnoorman@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27411>
This commit is contained in:
Job Noorman 2024-02-01 14:51:24 +01:00 committed by Marge Bot
parent c43d0e4e4f
commit ddd5f6abae
4 changed files with 26 additions and 11 deletions

View file

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

View file

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

View file

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

View file

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