nir: add fp class analysis for some intrinsics

I also tried ddx/ddy, but that was not worth it.

Foz-DB Navi48:
Totals from 1019 (1.23% of 82636) affected shaders:
Instrs: 516459 -> 515700 (-0.15%); split: -0.17%, +0.02%
CodeSize: 2712428 -> 2707008 (-0.20%); split: -0.21%, +0.01%
VGPRs: 70152 -> 70140 (-0.02%)
Latency: 1799198 -> 1795926 (-0.18%); split: -0.19%, +0.00%
InvThroughput: 233497 -> 232628 (-0.37%); split: -0.37%, +0.00%
VClause: 15315 -> 15346 (+0.20%); split: -0.11%, +0.31%
Copies: 30009 -> 30035 (+0.09%); split: -0.06%, +0.14%
VALU: 305519 -> 304727 (-0.26%); split: -0.27%, +0.01%
SALU: 45855 -> 45854 (-0.00%)

Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39987>
This commit is contained in:
Georg Lehmann 2026-02-12 10:17:46 +01:00 committed by Marge Bot
parent 73bce23f65
commit 6d3a279a3b

View file

@ -704,6 +704,45 @@ handle_sz(const nir_alu_instr *alu, fp_class_mask src)
return src | FP_CLASS_ANY_ZERO;
}
static fp_class_mask
intrinsic_fp_class(const nir_intrinsic_instr *intrin)
{
switch (intrin->intrinsic) {
case nir_intrinsic_load_typed_buffer_amd: {
const enum pipe_format format = nir_intrinsic_format(intrin);
if (format == PIPE_FORMAT_NONE)
return FP_CLASS_UNKNOWN;
const struct util_format_description *desc = util_format_description(format);
int i = util_format_get_first_non_void_channel(format);
if (i == -1)
return FP_CLASS_UNKNOWN;
bool is_signed = desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED;
bool is_unsigned = desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED;
bool normalized = desc->channel[i].normalized;
if ((!is_signed && !is_unsigned) || desc->channel[i].pure_integer)
return FP_CLASS_UNKNOWN;
fp_class_mask result = FP_CLASS_POS_ZERO | FP_CLASS_POS_ONE;
result |= is_signed ? FP_CLASS_NEG_ONE : 0;
if (normalized) {
result |= FP_CLASS_GT_ZERO_LT_POS_ONE | FP_CLASS_NON_INTEGRAL;
result |= is_signed ? FP_CLASS_LT_ZERO_GT_NEG_ONE : 0;
} else {
result |= FP_CLASS_GT_POS_ONE;
result |= is_signed ? FP_CLASS_LT_NEG_ONE : 0;
}
return result;
}
case nir_intrinsic_load_front_face_fsign:
return FP_CLASS_POS_ONE | FP_CLASS_NEG_ONE;
default:
return FP_CLASS_UNKNOWN;
}
}
/**
* Analyze an expression to determine the possible fp classes of its result
*/
@ -717,9 +756,10 @@ process_fp_query(struct analysis_state *state, struct analysis_query *aq, uint32
if (nir_def_is_const(def)) {
*result = analyze_fp_constant(nir_def_as_load_const(def));
return;
}
if (!nir_def_is_alu(def)) {
} else if (nir_def_is_intrinsic(def)) {
*result = intrinsic_fp_class(nir_def_as_intrinsic(def));
return;
} else if (!nir_def_is_alu(def)) {
*result = FP_CLASS_UNKNOWN;
return;
}