From 01d452de585560868359729ca459437298789485 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Fri, 30 Aug 2019 13:55:02 -0500 Subject: [PATCH] nir: Don't infinitely recurse in lower_ssa_defs_to_regs_block Cc: mesa-stable@lists.freedesktop.org Reviewed-by: Caio Marcelo de Oliveira Filho (cherry picked from commit 517142252f0c63189293c7176efbf490b7ae95ea) [Juan A. Suarez: resolve trivial conflicts] Signed-off-by: Juan A. Suarez Romero Conflicts: src/compiler/nir/nir_from_ssa.c --- src/compiler/nir/nir_from_ssa.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/compiler/nir/nir_from_ssa.c b/src/compiler/nir/nir_from_ssa.c index 99cfe757477..f0d868c38d4 100644 --- a/src/compiler/nir/nir_from_ssa.c +++ b/src/compiler/nir/nir_from_ssa.c @@ -827,7 +827,7 @@ nir_convert_from_ssa(nir_shader *shader, bool phi_webs_only) static void place_phi_read(nir_shader *shader, nir_register *reg, - nir_ssa_def *def, nir_block *block) + nir_ssa_def *def, nir_block *block, unsigned depth) { if (block != def->parent_instr->block) { /* Try to go up the single-successor tree */ @@ -840,14 +840,24 @@ place_phi_read(nir_shader *shader, nir_register *reg, } } - if (all_single_successors) { + if (all_single_successors && depth < 32) { /* All predecessors of this block have exactly one successor and it * is this block so they must eventually lead here without * intersecting each other. Place the reads in the predecessors * instead of this block. + * + * We only let this function recurse 32 times because it can recurse + * indefinitely in the presence of infinite loops. Because we're + * crawling a single-successor chain, it doesn't matter where we + * place it so it's ok to stop at an arbitrary distance. + * + * TODO: One day, we could detect back edges and avoid the recursion + * that way. */ - set_foreach(block->predecessors, entry) - place_phi_read(shader, reg, def, (nir_block *)entry->key); + set_foreach(block->predecessors, entry) { + place_phi_read(shader, reg, def, (nir_block *)entry->key, + depth + 1); + } return; } } @@ -904,7 +914,7 @@ nir_lower_phis_to_regs_block(nir_block *block) assert(src->src.is_ssa); /* We don't want derefs ending up in phi sources */ assert(!nir_src_as_deref(src->src)); - place_phi_read(shader, reg, src->src.ssa, src->pred); + place_phi_read(shader, reg, src->src.ssa, src->pred, 0); } nir_instr_remove(&phi->instr);