nir/instr_set: Consider normalization when calculating hash
Some checks are pending
macOS-CI / macOS-CI (dri) (push) Waiting to run
macOS-CI / macOS-CI (xlib) (push) Waiting to run

The nir_instrs_equal normalizes the some indices but hash_intrinsic
wasn't normalizing them.  Reorganize the code so both do it using the
same helper.

Fixes: b2bc57551a ("nir/instr_set: allow cse with fp_math_ctrl mismatches for intrinsics")
Assisted-by: Pi coding agent (GPT-5.5)
Reviewed-by: Georg Lehmann <dadschoorse@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41606>
This commit is contained in:
Caio Oliveira 2026-05-14 23:58:56 -07:00 committed by Marge Bot
parent 82ba7c4c44
commit 992b35704e

View file

@ -231,6 +231,38 @@ hash_phi(uint32_t hash, const nir_phi_instr *instr)
return hash;
}
/* Returns either the original indices or the provided buffer, if some
* change was necessary.
*/
static const int *
normalized_intrinsic_const_indices(const nir_intrinsic_instr *instr,
int const_index[NIR_INTRINSIC_MAX_CONST_INDEX])
{
const nir_intrinsic_info *info = &nir_intrinsic_infos[instr->intrinsic];
if (!nir_intrinsic_has_fp_math_ctrl(instr) &&
!nir_intrinsic_has_io_semantics(instr))
return instr->const_index;
memcpy(const_index, instr->const_index,
info->num_index_slots * sizeof(instr->const_index[0]));
/* Keep this in sync with nir_instr_set_add_or_rewrite(): these bits are
* merged into the rewritten instruction instead of preventing equality.
*/
if (nir_intrinsic_has_fp_math_ctrl(instr)) {
unsigned offset = info->index_map[NIR_INTRINSIC_FP_MATH_CTRL] - 1;
const_index[offset] = 0;
} else if (nir_intrinsic_has_io_semantics(instr)) {
unsigned offset = info->index_map[NIR_INTRINSIC_IO_SEMANTICS] - 1;
nir_io_semantics sem = nir_intrinsic_io_semantics(instr);
sem.no_signed_zero = false;
memcpy(&const_index[offset], &sem, sizeof(sem));
}
return const_index;
}
static uint32_t
hash_intrinsic(uint32_t hash, const nir_intrinsic_instr *instr)
{
@ -242,7 +274,10 @@ hash_intrinsic(uint32_t hash, const nir_intrinsic_instr *instr)
hash = XXH32(v, sizeof(v), hash);
}
hash = XXH32(instr->const_index, info->num_index_slots * sizeof(instr->const_index[0]), hash);
int const_index[NIR_INTRINSIC_MAX_CONST_INDEX];
const int *normalized =
normalized_intrinsic_const_indices(instr, const_index);
hash = XXH32(normalized, info->num_index_slots * sizeof(normalized[0]), hash);
for (unsigned i = 0; i < nir_intrinsic_infos[instr->intrinsic].num_srcs; i++)
hash = hash_src(hash, &instr->src[i]);
@ -748,30 +783,16 @@ nir_instrs_equal(const nir_instr *instr1, const nir_instr *instr2)
return false;
}
/* Compare indices, but allow fp_math_ctrl mismatches. */
for (unsigned i = 0; i < info->num_indices; i++) {
nir_intrinsic_index_flag index = info->indices[i];
int const_index1[NIR_INTRINSIC_MAX_CONST_INDEX];
int const_index2[NIR_INTRINSIC_MAX_CONST_INDEX];
const int *normalized1 =
normalized_intrinsic_const_indices(intrinsic1, const_index1);
const int *normalized2 =
normalized_intrinsic_const_indices(intrinsic2, const_index2);
if (index == NIR_INTRINSIC_FP_MATH_CTRL) {
continue;
} else if (index == NIR_INTRINSIC_IO_SEMANTICS) {
nir_io_semantics sem1 = nir_intrinsic_io_semantics(intrinsic1);
nir_io_semantics sem2 = nir_intrinsic_io_semantics(intrinsic2);
sem1.no_signed_zero = false;
sem2.no_signed_zero = false;
if (memcmp(&sem1, &sem2, sizeof(sem1)))
return false;
} else {
unsigned size = nir_intrinsic_index_size(index);
unsigned offset = info->index_map[index] - 1;
if (memcmp(&intrinsic1->const_index[offset],
&intrinsic2->const_index[offset],
sizeof(intrinsic1->const_index[0]) * size))
return false;
}
}
if (memcmp(normalized1, normalized2,
info->num_index_slots * sizeof(intrinsic1->const_index[0])))
return false;
return true;
}