From 90a447677a2abb934b683a012b477e6c52088e35 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 21 May 2024 09:48:04 +0200 Subject: [PATCH] tree-optimization/115149 - VOP live and missing PHIs The following fixes a bug in vop-live get_live_in which was using NULL to indicate the first processed edge but at the same time using it for the case the live-in virtual operand cannot be computed. The following fixes this, avoiding sinking a load to a place where we'd have to insert virtual PHIs to make the virtual operand SSA web OK. PR tree-optimization/115149 * tree-ssa-live.cc (virtual_operand_live::get_live_in): Explicitly track the first processed edge. * gcc.dg/pr115149.c: New testcase. (cherry picked from commit ec9b8bafe20755d13ab9a1b834b5da79ae972c0e) --- gcc/testsuite/gcc.dg/pr115149.c | 16 ++++++++++++++++ gcc/tree-ssa-live.cc | 8 ++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr115149.c diff --git a/gcc/testsuite/gcc.dg/pr115149.c b/gcc/testsuite/gcc.dg/pr115149.c new file mode 100644 index 00000000000..9f6bc97dbe6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr115149.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fno-inline -fno-tree-vrp -fno-ipa-sra -fno-tree-dce -fno-tree-ch" } */ + +int a, c, e, f, g, h[1], i; +static int j(int b) { return 0; } +static void k(int d) {} +int main() +{ + if (h[0]) + while (1) { + k(f && j(i && (h[g] = e))); + while (a) + c ^= 1; + } + return 0; +} diff --git a/gcc/tree-ssa-live.cc b/gcc/tree-ssa-live.cc index d94e94eb3bc..122d8e245dd 100644 --- a/gcc/tree-ssa-live.cc +++ b/gcc/tree-ssa-live.cc @@ -1684,14 +1684,18 @@ virtual_operand_live::get_live_in (basic_block bb) edge_iterator ei; edge e; tree livein = NULL_TREE; + bool first = true; FOR_EACH_EDGE (e, ei, bb->preds) if (e->flags & EDGE_DFS_BACK) /* We can ignore backedges since if there's a def there it would have forced a PHI in the source because it also acts as use downstream. */ continue; - else if (!livein) - livein = get_live_out (e->src); + else if (first) + { + livein = get_live_out (e->src); + first = false; + } else if (get_live_out (e->src) != livein) /* When there's no virtual use downstream this indicates a point where we'd insert a PHI merging the different live virtual