diff options
author | Richard Biener <rguenther@suse.de> | 2024-05-27 09:40:19 +0200 |
---|---|---|
committer | Richard Biener <rguenther@suse.de> | 2024-05-27 12:45:35 +0200 |
commit | f9fbb47987efc8b5261e4cc36613c928a8693493 (patch) | |
tree | dead92a1281a37db15cfad5fe697772bf9aaf758 | |
parent | f6c5f836df44196a7cd3b206af5bb29df6c7c225 (diff) | |
download | gcc-f9fbb47987efc8b5261e4cc36613c928a8693493.zip gcc-f9fbb47987efc8b5261e4cc36613c928a8693493.tar.gz gcc-f9fbb47987efc8b5261e4cc36613c928a8693493.tar.bz2 |
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.
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr115220.c | 14 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr115226.c | 15 | ||||
-rw-r--r-- | gcc/tree-ssa-sink.cc | 12 |
3 files changed, 38 insertions, 3 deletions
diff --git a/gcc/testsuite/gcc.dg/torture/pr115220.c b/gcc/testsuite/gcc.dg/torture/pr115220.c new file mode 100644 index 0000000..e7b5da6 --- /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 0000000..9a0bc7c --- /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 b0fe871..8c551e4 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; } |