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.
--- /dev/null
+/* { 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;
+}
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