nir: add nir_alu_instr_is_exact helper

Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@intel.com>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39103>
This commit is contained in:
Georg Lehmann 2025-12-30 20:29:20 +01:00 committed by Marge Bot
parent b70294b91f
commit eb4737a1dd
15 changed files with 29 additions and 20 deletions

View file

@ -16,7 +16,7 @@ static Builder
create_alu_builder(isel_context* ctx, nir_alu_instr* instr)
{
Builder bld(ctx->program, ctx->block);
bld.is_precise = instr->exact;
bld.is_precise = nir_alu_instr_is_exact(instr);
bld.is_sz_preserve = nir_alu_instr_is_signed_zero_preserve(instr);
bld.is_inf_preserve = nir_alu_instr_is_inf_preserve(instr);
bld.is_nan_preserve = nir_alu_instr_is_nan_preserve(instr);

View file

@ -3677,7 +3677,8 @@ libagx_frcp(nir_builder *b, nir_def *x)
static bool
agx_nir_lower_fdiv(nir_builder *b, nir_alu_instr *alu, void *_)
{
if (alu->op != nir_op_frcp || !alu->exact || alu->def.bit_size != 32)
if (alu->op != nir_op_frcp || !nir_alu_instr_is_exact(alu) ||
alu->def.bit_size != 32)
return false;
b->cursor = nir_before_instr(&alu->instr);

View file

@ -1599,6 +1599,12 @@ nir_alu_instr_is_signed_zero_inf_nan_preserve(nir_alu_instr *alu)
return alu->fp_math_ctrl & nir_fp_preserve_sz_inf_nan;
}
static inline bool
nir_alu_instr_is_exact(nir_alu_instr *alu)
{
return alu->exact;
}
void nir_alu_src_copy(nir_alu_src *dest, const nir_alu_src *src);
nir_component_mask_t

View file

@ -390,7 +390,7 @@ convert_flrp_instruction(nir_builder *bld,
* subtract, a multiply, and an FMA)... but in that case the other
* formulation should have been used.
*/
if (alu->exact) {
if (nir_alu_instr_is_exact(alu)) {
if (have_ffma)
replace_with_strict_ffma(bld, dead_flrp, alu);
else

View file

@ -276,7 +276,8 @@ try_opt_exclusive_scan_to_inclusive(nir_builder *b, nir_intrinsic_instr *intrin)
return false;
/* Don't reassociate exact float operations. */
if (nir_alu_type_get_base_type(nir_op_infos[alu->op].output_type) == nir_type_float && alu->exact)
if (nir_alu_type_get_base_type(nir_op_infos[alu->op].output_type) == nir_type_float &&
nir_alu_instr_is_exact(alu))
return false;
/* SPIR-V rules for fmax/fmin scans are *very* stupid.

View file

@ -203,7 +203,7 @@ can_reassociate(nir_alu_instr *alu)
return (props & NIR_OP_IS_2SRC_COMMUTATIVE) &&
((props & NIR_OP_IS_ASSOCIATIVE) ||
(!alu->exact && (props & NIR_OP_IS_INEXACT_ASSOCIATIVE)));
(!nir_alu_instr_is_exact(alu) && (props & NIR_OP_IS_INEXACT_ASSOCIATIVE)));
}
/*

View file

@ -2923,7 +2923,8 @@ find_tes_triangle_interp_3fmul_2fadd(struct linkage_info *linkage, unsigned i)
/* Only maximum of 3 loads expected. Also reject exact ops because we
* are going to do an inexact transformation with it.
*/
if (!fmul || fmul->op != nir_op_fmul || fmul->exact || num_fmuls == 3 ||
if (!fmul || fmul->op != nir_op_fmul || nir_alu_instr_is_exact(fmul) ||
num_fmuls == 3 ||
!gather_fmul_tess_coord(iter->instr, fmul, vertex_index,
&tess_coord_swizzle, &tess_coord_used,
&load_tess_coord))
@ -2934,7 +2935,7 @@ find_tes_triangle_interp_3fmul_2fadd(struct linkage_info *linkage, unsigned i)
/* The multiplication must only be used by fadd. Also reject exact ops.
*/
nir_alu_instr *fadd = get_single_use_as_alu(&fmul->def);
if (!fadd || fadd->op != nir_op_fadd || fadd->exact)
if (!fadd || fadd->op != nir_op_fadd || nir_alu_instr_is_exact(fadd))
return false;
/* The 3 fmuls must only be used by 2 fadds. */
@ -3015,7 +3016,7 @@ find_tes_triangle_interp_1fmul_2ffma(struct linkage_info *linkage, unsigned i)
* with it.
*/
if (!alu || (alu->op != nir_op_fmul && alu->op != nir_op_ffma) ||
alu->exact ||
nir_alu_instr_is_exact(alu) ||
!gather_fmul_tess_coord(iter->instr, alu, vertex_index,
&tess_coord_swizzle, &tess_coord_used,
&load_tess_coord))
@ -3119,7 +3120,7 @@ static bool
can_move_alu_across_interp(struct linkage_info *linkage, nir_alu_instr *alu)
{
/* Exact ALUs can't be moved across interpolation. */
if (alu->exact)
if (nir_alu_instr_is_exact(alu))
return false;
/* Interpolation converts Infs to NaNs. If we turn a result of an ALU

View file

@ -489,7 +489,7 @@ print_alu_instr(nir_alu_instr *instr, print_state *state)
print_def(&instr->def, state);
fprintf(fp, " = %s", nir_op_infos[instr->op].name);
if (instr->exact)
if (nir_alu_instr_is_exact(instr))
fprintf(fp, "!");
if (instr->no_signed_wrap)
fprintf(fp, ".nsw");

View file

@ -392,8 +392,8 @@ match_expression(const nir_algebraic_table *table, const nir_search_expression *
instr->def.bit_size != expr->value.bit_size)
return false;
state->inexact_match = expr->inexact || expr->contract || state->inexact_match;
state->has_exact_alu = (instr->exact && !expr->ignore_exact) || state->has_exact_alu;
state->inexact_match |= expr->inexact || expr->contract;
state->has_exact_alu |= nir_alu_instr_is_exact(instr) && !expr->ignore_exact;
if (state->inexact_match && state->has_exact_alu)
return false;

View file

@ -1449,7 +1449,7 @@ ntt_emit_alu(struct ntt_compile *c, nir_alu_instr *instr)
if (instr->op == nir_op_fsat && nir_legacy_fsat_folds(instr))
return;
c->precise = instr->exact;
c->precise = nir_alu_instr_is_exact(instr);
assert(num_srcs <= ARRAY_SIZE(src));
for (i = 0; i < num_srcs; i++)

View file

@ -3003,7 +3003,7 @@ Converter::visit(nir_alu_instr *insn)
if (!oldPos) {
oldPos = this->bb->getEntry();
oldPos->precise = insn->exact;
oldPos->precise = nir_alu_instr_is_exact(insn);
}
if (unlikely(!oldPos))
@ -3011,7 +3011,7 @@ Converter::visit(nir_alu_instr *insn)
while (oldPos->next) {
oldPos = oldPos->next;
oldPos->precise = insn->exact;
oldPos->precise = nir_alu_instr_is_exact(insn);
}
return true;

View file

@ -818,7 +818,7 @@ ntr_emit_alu(struct ntr_compile *c, nir_alu_instr *instr)
if (instr->op == nir_op_fsat && nir_legacy_fsat_folds(instr))
return;
c->precise = instr->exact;
c->precise = nir_alu_instr_is_exact(instr);
assert(num_srcs <= ARRAY_SIZE(src));
for (i = 0; i < num_srcs; i++)

View file

@ -2234,7 +2234,7 @@ emit_alu(struct ntv_context *ctx, nir_alu_instr *alu)
UNREACHABLE("unsupported opcode");
return;
}
if (alu->exact)
if (nir_alu_instr_is_exact(alu))
spirv_builder_emit_decoration(&ctx->builder, result, SpvDecorationNoContraction);
store_alu_result(ctx, alu, result, atype);

View file

@ -74,7 +74,7 @@ get_mul_for_src(nir_alu_src *src, unsigned num_components,
* value and what they don't care about is the add. Another reason is that
* SPIR-V explicitly requires this behaviour.
*/
if (!alu || alu->exact)
if (!alu || nir_alu_instr_is_exact(alu))
return NULL;
switch (alu->op) {
@ -160,7 +160,7 @@ intel_nir_opt_peephole_ffma_instr(nir_builder *b,
if (add->op != nir_op_fadd)
return false;
if (add->exact)
if (nir_alu_instr_is_exact(add))
return false;

View file

@ -2275,7 +2275,7 @@ emit_binop(struct ntd_context *ctx, nir_alu_instr *alu,
bool is_float_op = nir_alu_type_get_base_type(nir_op_infos[alu->op].output_type) == nir_type_float;
enum dxil_opt_flags flags = 0;
if (is_float_op && !alu->exact)
if (is_float_op && !nir_alu_instr_is_exact(alu))
flags |= DXIL_UNSAFE_ALGEBRA;
const struct dxil_value *v = dxil_emit_binop(&ctx->mod, opcode, op0, op1, flags);