https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114161

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
     Ever confirmed|0                           |1
                 CC|                            |hubicka at gcc dot gnu.org
   Last reconfirmed|                            |2024-02-29

--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> ---
Yeah, we don't have any sort of IPA pass that would optimistically treat 'a' as
constant [zero] and figure the stores from non-constant would not be executed.

I bet it breaks down with clang if you had two of those functions in the TU.

In other context we spoke about that knowing a variable is only ever set in a
single function would help and might get this optimized during value-numbering.
But I think no such feature ever materialized?  There is the partly
matching used_by_single_function flag in the cgraph which would be good
enough here but if there's another function reading from a it would break down.

For example the following fixes the testcase, but this really isn't enough
because if a store to 'a' prevails this is an invalid transform so we'd have to
make sure to iterate and somehow invalidate the global.

I bet that clang has some very simple IPA hack that makes this work since
IIRC it comes up in SPEC libquantum which has a global 'debug' initialized
to zero in main() but read in many places, guarding printf calls.  So you'd
need the written-in-single-function and there
written-with-same-as-static-init-value.  IIRC there's a similar case in some
SPEC 2000 benchmark.

diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc
index 2ee02e45d56..8f094c05bae 100644
--- a/gcc/tree-ssa-sccvn.cc
+++ b/gcc/tree-ssa-sccvn.cc
@@ -2401,6 +2401,11 @@ vn_reference_lookup_2 (ao_ref *op, tree vuse, void
*data_)
                                          SSA_NAME_VAR (TREE_OPERAND (base,
0)),
                                          true, op_offset, op_size);
        }
+      if (base
+         && VAR_P (base))
+       if (auto n = varpool_node::get (base))
+         if (n->used_by_single_function)
+           v = DECL_INITIAL (base);
       if (v)
        return data->finish (vr->set, vr->base_set, v);
     }

Reply via email to