r17-1273-g391ee229b737eb added support for the case where the middle bb was
non-empty but
with a trailing store. This meant if there was a load in the middle bb, it
might cause
nontrapping to have the lhs in it. So we now need to check for a load in the
middle-bb
to reject this case.
Bootstrapped and tested on x86_64-linux-gnu.
PR tree-optimization/125612
gcc/ChangeLog:
* tree-ssa-phiopt.cc (cond_store_replacement): For the case where
lhs is "known" to be nontrapping make sure there are no loads in
the middle bb.
gcc/testsuite/ChangeLog:
* gcc.dg/tree-ssa/pr125612-1.c: New test.
Signed-off-by: Andrew Pinski <[email protected]>
---
gcc/testsuite/gcc.dg/tree-ssa/pr125612-1.c | 26 ++++++++++++++++++++++
gcc/tree-ssa-phiopt.cc | 19 +++++++++++++++-
2 files changed, 44 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr125612-1.c
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr125612-1.c
b/gcc/testsuite/gcc.dg/tree-ssa/pr125612-1.c
new file mode 100644
index 00000000000..201f2f4fb3f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr125612-1.c
@@ -0,0 +1,26 @@
+/* { dg-do run } */
+/* { dg-options "-O3 -fno-tree-dse -fno-tree-dce -fdump-tree-cselim-details" }
*/
+/* PR tree-optimization/125612 */
+
+/* The conditional store of `h[2000]` should not become unconditional since
+ it traps. */
+
+int a, b, c = 2, d, e[4], f, i;
+void g() {
+ int h[5];
+ e[0] = 2;
+ while (1) {
+ if (e[b]) {
+ if (!c)
+ h[2000] &= 1;
+ return;
+ }
+ }
+}
+int main() {
+ for (; i < 4; i++)
+ g();
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-not "Conditional store replacement happened"
"cselim"} } */
diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc
index 3e7dd3b0ee3..0c5c4982d3f 100644
--- a/gcc/tree-ssa-phiopt.cc
+++ b/gcc/tree-ssa-phiopt.cc
@@ -3089,7 +3089,24 @@ cond_store_replacement (basic_block middle_bb,
basic_block join_bb, edge e0,
/* Prove that we can move the store down. We could also check
TREE_THIS_NOTRAP here, but in that case we also could move stores,
whose value is not available readily, which we want to avoid. */
- if (!nontrap->contains (lhs))
+ if (nontrap->contains (lhs))
+ {
+ /* Make sure there is no load in the middle bb,
+ this invalidates nontrap.
+ FIXME: this is over conserative, this check could be made to
+ allow loads unrelated to lhs. */
+ tree vuse = gimple_vuse (assign);
+ imm_use_iterator iter;
+ gimple *use_stmt;
+ FOR_EACH_IMM_USE_STMT (use_stmt, iter, vuse)
+ {
+ if (use_stmt == assign)
+ continue;
+ if (gimple_bb (use_stmt) == middle_bb)
+ return false;
+ }
+ }
+ else
{
/* If LHS is an access to a local variable without address-taken
(or when we allow data races) and known not to trap, we could
--
2.43.0