From 0b503d8de96c7006c0fe1c8bfdcd8de02f255992 Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Wed, 30 Dec 2020 10:28:54 +0100 Subject: [PATCH] nir: fix determining if an addition might overflow for phi sources MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit nir_addition_might_overflow() expects the parent instruction to be an alu instr but it might be a phi instr. Fix it by assuming that the addition might overflow. This fixes compiler crashes with Horizon Zero Dawn. No fossils-db changes. Cc: mesa-stable Signed-off-by: Samuel Pitoiset Reviewed-by: Daniel Schürmann Part-of: --- src/compiler/nir/nir_range_analysis.c | 54 ++++++++++++++------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/src/compiler/nir/nir_range_analysis.c b/src/compiler/nir/nir_range_analysis.c index 08bd6acf88b..f2b7211a5f6 100644 --- a/src/compiler/nir/nir_range_analysis.c +++ b/src/compiler/nir/nir_range_analysis.c @@ -1458,36 +1458,38 @@ nir_addition_might_overflow(nir_shader *shader, struct hash_table *range_ht, nir_ssa_scalar ssa, unsigned const_val, const nir_unsigned_upper_bound_config *config) { - nir_op alu_op = nir_ssa_scalar_alu_op(ssa); + if (nir_ssa_scalar_is_alu(ssa)) { + nir_op alu_op = nir_ssa_scalar_alu_op(ssa); - /* iadd(imul(a, #b), #c) */ - if (alu_op == nir_op_imul || alu_op == nir_op_ishl) { - nir_ssa_scalar mul_src0 = nir_ssa_scalar_chase_alu_src(ssa, 0); - nir_ssa_scalar mul_src1 = nir_ssa_scalar_chase_alu_src(ssa, 1); - uint32_t stride = 1; - if (nir_ssa_scalar_is_const(mul_src0)) - stride = nir_ssa_scalar_as_uint(mul_src0); - else if (nir_ssa_scalar_is_const(mul_src1)) - stride = nir_ssa_scalar_as_uint(mul_src1); + /* iadd(imul(a, #b), #c) */ + if (alu_op == nir_op_imul || alu_op == nir_op_ishl) { + nir_ssa_scalar mul_src0 = nir_ssa_scalar_chase_alu_src(ssa, 0); + nir_ssa_scalar mul_src1 = nir_ssa_scalar_chase_alu_src(ssa, 1); + uint32_t stride = 1; + if (nir_ssa_scalar_is_const(mul_src0)) + stride = nir_ssa_scalar_as_uint(mul_src0); + else if (nir_ssa_scalar_is_const(mul_src1)) + stride = nir_ssa_scalar_as_uint(mul_src1); - if (alu_op == nir_op_ishl) - stride = 1u << (stride % 32u); + if (alu_op == nir_op_ishl) + stride = 1u << (stride % 32u); - if (!stride || const_val <= UINT32_MAX - (UINT32_MAX / stride * stride)) - return false; - } + if (!stride || const_val <= UINT32_MAX - (UINT32_MAX / stride * stride)) + return false; + } - /* iadd(iand(a, #b), #c) */ - if (alu_op == nir_op_iand) { - nir_ssa_scalar and_src0 = nir_ssa_scalar_chase_alu_src(ssa, 0); - nir_ssa_scalar and_src1 = nir_ssa_scalar_chase_alu_src(ssa, 1); - uint32_t mask = 0xffffffff; - if (nir_ssa_scalar_is_const(and_src0)) - mask = nir_ssa_scalar_as_uint(and_src0); - else if (nir_ssa_scalar_is_const(and_src1)) - mask = nir_ssa_scalar_as_uint(and_src1); - if (mask == 0 || const_val < (1u << (ffs(mask) - 1))) - return false; + /* iadd(iand(a, #b), #c) */ + if (alu_op == nir_op_iand) { + nir_ssa_scalar and_src0 = nir_ssa_scalar_chase_alu_src(ssa, 0); + nir_ssa_scalar and_src1 = nir_ssa_scalar_chase_alu_src(ssa, 1); + uint32_t mask = 0xffffffff; + if (nir_ssa_scalar_is_const(and_src0)) + mask = nir_ssa_scalar_as_uint(and_src0); + else if (nir_ssa_scalar_is_const(and_src1)) + mask = nir_ssa_scalar_as_uint(and_src1); + if (mask == 0 || const_val < (1u << (ffs(mask) - 1))) + return false; + } } uint32_t ub = nir_unsigned_upper_bound(shader, range_ht, ssa, config);