diff --git a/src/compiler/nir/nir_lower_bit_size.c b/src/compiler/nir/nir_lower_bit_size.c index 6e7b26bff45..81bc4489d97 100644 --- a/src/compiler/nir/nir_lower_bit_size.c +++ b/src/compiler/nir/nir_lower_bit_size.c @@ -184,6 +184,31 @@ lower_intrinsic_instr(nir_builder *b, nir_intrinsic_instr *intrin, } } +static void +lower_phi_instr(nir_builder *b, nir_phi_instr *phi, unsigned bit_size, + nir_phi_instr *last_phi) +{ + assert(phi->dest.is_ssa); + unsigned old_bit_size = phi->dest.ssa.bit_size; + assert(old_bit_size < bit_size); + + nir_foreach_phi_src(src, phi) { + b->cursor = nir_after_block_before_jump(src->pred); + assert(src->src.is_ssa); + nir_ssa_def *new_src = nir_u2u(b, src->src.ssa, bit_size); + + nir_instr_rewrite_src(&phi->instr, &src->src, nir_src_for_ssa(new_src)); + } + + phi->dest.ssa.bit_size = bit_size; + + b->cursor = nir_after_instr(&last_phi->instr); + + nir_ssa_def *new_dest = nir_u2u(b, &phi->dest.ssa, old_bit_size); + nir_ssa_def_rewrite_uses_after(&phi->dest.ssa, nir_src_for_ssa(new_dest), + new_dest->parent_instr); +} + static bool lower_impl(nir_function_impl *impl, nir_lower_bit_size_callback callback, @@ -194,6 +219,9 @@ lower_impl(nir_function_impl *impl, bool progress = false; nir_foreach_block(block, impl) { + /* Stash this so we can rewrite phi destinations quickly. */ + nir_phi_instr *last_phi = nir_block_last_phi_instr(block); + nir_foreach_instr_safe(instr, block) { unsigned lower_bit_size = callback(instr, callback_data); if (lower_bit_size == 0) @@ -209,6 +237,11 @@ lower_impl(nir_function_impl *impl, lower_bit_size); break; + case nir_instr_type_phi: + lower_phi_instr(&b, nir_instr_as_phi(instr), + lower_bit_size, last_phi); + break; + default: unreachable("Unsupported instruction type"); }