From f9fbb47987efc8b5261e4cc36613c928a8693493 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 27 May 2024 09:40:19 +0200 Subject: [PATCH] tree-optimization/115220 - fix store sinking virtual operand constraints The following makes sure the virtual operand updating when sinking stores works for the case we ignore paths to kills. The final sink location might not post-dominate the original stmt location which would require inserting of a virtual PHI which we do not support. PR tree-optimization/115220 PR tree-optimization/115226 * tree-ssa-sink.cc (statement_sink_location): When ignoring paths to kills when sinking stores make sure the final sink location is still post-dominated by the original one. Otherwise we'd need to insert a PHI node to merge virtual operands. * gcc.dg/torture/pr115220.c: New testcase. * gcc.dg/torture/pr115226.c: New testcase. --- gcc/testsuite/gcc.dg/torture/pr115220.c | 14 ++++++++++++++ gcc/testsuite/gcc.dg/torture/pr115226.c | 15 +++++++++++++++ gcc/tree-ssa-sink.cc | 12 +++++++++--- 3 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr115220.c create mode 100644 gcc/testsuite/gcc.dg/torture/pr115226.c diff --git a/gcc/testsuite/gcc.dg/torture/pr115220.c b/gcc/testsuite/gcc.dg/torture/pr115220.c new file mode 100644 index 000000000000..e7b5da6ba426 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr115220.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-additional-options "--param logical-op-non-short-circuit=0" } */ + +extern char **environ; +static char ***p_environ = &environ; +int +_setenv_r (const char *name, const char *value) +{ + register char *C; + int offset; + for (C = (*p_environ)[offset]; (*C = *name++) && *C != '='; ++C); + for (*C++ = '='; (*C++ = *value++) != 0;); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr115226.c b/gcc/testsuite/gcc.dg/torture/pr115226.c new file mode 100644 index 000000000000..9a0bc7c9b6a3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr115226.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +extern void c(); +int a, b; +int main() { + while (b) { + int d, e = 0, *f = &a; + *f = 1; + e = 1 >> d ? : 1 << d; + if (e) + a = 0; + c(); + } + return 0; +} diff --git a/gcc/tree-ssa-sink.cc b/gcc/tree-ssa-sink.cc index b0fe871cf1ea..8c551e42a4d2 100644 --- a/gcc/tree-ssa-sink.cc +++ b/gcc/tree-ssa-sink.cc @@ -467,11 +467,17 @@ statement_sink_location (gimple *stmt, basic_block frombb, if (!sinkbb) return false; - sinkbb = select_best_block (frombb, sinkbb, stmt); - if (sinkbb == frombb) + basic_block bestbb = select_best_block (frombb, sinkbb, stmt); + if (bestbb == frombb + /* When we sink a store make sure there's not a path to any of + the possibly skipped killing defs as that wrecks the virtual + operand update, requiring inserting of a PHI node. */ + || (gimple_vdef (stmt) + && bestbb != sinkbb + && !dominated_by_p (CDI_POST_DOMINATORS, bestbb, sinkbb))) return false; - *togsi = gsi_after_labels (sinkbb); + *togsi = gsi_after_labels (bestbb); return true; } -- 2.47.2