nir: Use alu source components count in nir_alu_srcs_negative_equal

When we use source from ALU instruction directly, the default swizzle array
should be populated with the same amount of components as the src has.

Otherwise, if we use nir_ssa_alu_instr_src_components, it can return
the destination components count that is lower than component index
actually used in that source. This can lead to false equality
between 0 (uninitialized) and 0 (.x) in swizzle comparison below.

Fixes: c6ee46a7 ("nir: Add nir_alu_srcs_negative_equal")
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/8704
Signed-off-by: Sviatoslav Peleshko <sviatoslav.peleshko@globallogic.com>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22655>
This commit is contained in:
Sviatoslav Peleshko
2023-04-24 07:57:24 +03:00
committed by Marge Bot
parent e19ecf49ea
commit 6b0bfdfa9e
2 changed files with 94 additions and 2 deletions
+2 -2
View File
@@ -441,7 +441,7 @@ nir_alu_srcs_negative_equal(const nir_alu_instr *alu1,
} else {
alu1_actual_src = alu1->src[src1].src;
for (unsigned i = 0; i < nir_ssa_alu_instr_src_components(alu1, src1); i++)
for (unsigned i = 0; i < nir_src_num_components(alu1_actual_src); i++)
alu1_swizzle[i] = i;
}
@@ -458,7 +458,7 @@ nir_alu_srcs_negative_equal(const nir_alu_instr *alu1,
} else {
alu2_actual_src = alu2->src[src2].src;
for (unsigned i = 0; i < nir_ssa_alu_instr_src_components(alu2, src2); i++)
for (unsigned i = 0; i < nir_src_num_components(alu2_actual_src); i++)
alu2_swizzle[i] = i;
}
@@ -579,3 +579,95 @@ TEST_F(comparison_pre_test, non_scalar_add_result)
EXPECT_FALSE(nir_opt_comparison_pre_impl(bld.impl));
}
TEST_F(comparison_pre_test, multi_comps_load)
{
/* Before:
*
* vec1 32 ssa_0 = load_ubo (...)
* vec4 32 ssa_1 = load_ubo (...)
* vec1 1 ssa_2 = flt ssa_0, ssa_1.w
*
* if ssa_2 {
* vec1 32 ssa_3 = fneg ssa_1.x
* vec1 32 ssa_4 = fadd ssa_0, ssa_3
* } else {
* }
*/
nir_def *ssa_0 = nir_load_ubo(&bld, 1, 32,
nir_imm_int(&bld, 0),
nir_imm_int(&bld, 0));
nir_def *ssa_1 = nir_load_ubo(&bld, 4, 32,
nir_imm_int(&bld, 1),
nir_imm_int(&bld, 0));
nir_alu_instr *flt = nir_alu_instr_create(bld.shader, nir_op_flt);
flt->src[0].src = nir_src_for_ssa(ssa_0);
flt->src[1].src = nir_src_for_ssa(ssa_1);
memcpy(&flt->src[0].swizzle, xxxx, sizeof(xxxx));
memcpy(&flt->src[1].swizzle, wwww, sizeof(wwww));
nir_builder_alu_instr_finish_and_insert(&bld, flt);
flt->def.num_components = 1;
nir_def *ssa_2 = &flt->def;
nir_if *nif = nir_push_if(&bld, ssa_2);
{
nir_alu_instr *fneg = nir_alu_instr_create(bld.shader, nir_op_fneg);
fneg->src[0].src = nir_src_for_ssa(ssa_1);
memcpy(&fneg->src[0].swizzle, xxxx, sizeof(xxxx));
nir_builder_alu_instr_finish_and_insert(&bld, fneg);
fneg->def.num_components = 1;
nir_def *ssa_3 = &fneg->def;
nir_fadd(&bld, ssa_0, ssa_3);
}
nir_pop_if(&bld, nif);
EXPECT_FALSE(nir_opt_comparison_pre_impl(bld.impl));
}
TEST_F(comparison_pre_test, multi_comps_load2)
{
/* Before:
*
* vec1 32 ssa_0 = load_ubo (...)
* vec4 32 ssa_1 = load_ubo (...)
* vec1 1 ssa_2 = flt ssa_0, ssa_1.x
*
* if ssa_2 {
* vec1 32 ssa_3 = fneg ssa_1.w
* vec1 32 ssa_4 = fadd ssa_0, ssa_3
* } else {
* }
*/
nir_def *ssa_0 = nir_load_ubo(&bld, 1, 32,
nir_imm_int(&bld, 0),
nir_imm_int(&bld, 0));
nir_def *ssa_1 = nir_load_ubo(&bld, 4, 32,
nir_imm_int(&bld, 1),
nir_imm_int(&bld, 0));
nir_alu_instr *flt = nir_alu_instr_create(bld.shader, nir_op_flt);
flt->src[0].src = nir_src_for_ssa(ssa_0);
flt->src[1].src = nir_src_for_ssa(ssa_1);
memcpy(&flt->src[0].swizzle, xxxx, sizeof(xxxx));
memcpy(&flt->src[1].swizzle, xxxx, sizeof(xxxx));
nir_builder_alu_instr_finish_and_insert(&bld, flt);
flt->def.num_components = 1;
nir_def *ssa_2 = &flt->def;
nir_if *nif = nir_push_if(&bld, ssa_2);
{
nir_alu_instr *fneg = nir_alu_instr_create(bld.shader, nir_op_fneg);
fneg->src[0].src = nir_src_for_ssa(ssa_1);
memcpy(&fneg->src[0].swizzle, wwww, sizeof(wwww));
nir_builder_alu_instr_finish_and_insert(&bld, fneg);
fneg->def.num_components = 1;
nir_def *ssa_3 = &fneg->def;
nir_fadd(&bld, ssa_0, ssa_3);
}
nir_pop_if(&bld, nif);
EXPECT_FALSE(nir_opt_comparison_pre_impl(bld.impl));
}