tree-optimization/98499 - fix modref analysis on RVO statements
authorSergei Trofimovich <siarheit@google.com>
Mon, 11 Jan 2021 18:05:57 +0000 (18:05 +0000)
committerSergei Trofimovich <siarheit@google.com>
Mon, 1 Feb 2021 18:13:42 +0000 (18:13 +0000)
Before the change RVO gimple statements were treated as local
stores by modres analysis. But in practice RVO escapes target.

2021-02-01  Sergei Trofimovich  <siarheit@google.com>

gcc/ChangeLog:

PR tree-optimization/98499
* ipa-modref.c (analyze_ssa_name_flags): treat RVO
conservatively and assume all possible side-effects.

gcc/testsuite/ChangeLog:

PR tree-optimization/98499
* g++.dg/pr98499.C: new test.

gcc/ipa-modref.c
gcc/testsuite/g++.dg/pr98499.C [new file with mode: 0644]

index 8a5669c7f9bf8e948306a2c34724c9032ba877db..7aaf53be8f4613ea4e1fb1058c37e4c34d3e0f17 100644 (file)
@@ -36,7 +36,7 @@ along with GCC; see the file COPYING3.  If not see
 
    The following information is computed
      1) load/store access tree described in ipa-modref-tree.h
-       This is used by tree-ssa-alias to disambiguate load/dtores
+       This is used by tree-ssa-alias to disambiguate load/stores
      2) EAF flags used by points-to analysis (in tree-ssa-structlias).
        and defined in tree-core.h.
    and stored to optimization_summaries.
@@ -1604,7 +1604,7 @@ analyze_ssa_name_flags (tree name, vec<modref_lattice> &lattice, int depth,
        continue;
       if (dump_file)
        {
-         fprintf (dump_file, "%*s  Analyzing stmt:", depth * 4, "");
+         fprintf (dump_file, "%*s  Analyzing stmt: ", depth * 4, "");
          print_gimple_stmt (dump_file, use_stmt, 0);
        }
 
@@ -1621,9 +1621,19 @@ analyze_ssa_name_flags (tree name, vec<modref_lattice> &lattice, int depth,
       else if (gcall *call = dyn_cast <gcall *> (use_stmt))
        {
          tree callee = gimple_call_fndecl (call);
-
+         /* Return slot optiomization would require bit of propagation;
+            give up for now.  */
+         if (gimple_call_return_slot_opt_p (call)
+             && gimple_call_lhs (call) != NULL_TREE
+             && TREE_ADDRESSABLE (TREE_TYPE (gimple_call_lhs (call))))
+           {
+             if (dump_file)
+               fprintf (dump_file, "%*s  Unhandled return slot opt\n",
+                        depth * 4, "");
+             lattice[index].merge (0);
+           }
          /* Recursion would require bit of propagation; give up for now.  */
-         if (callee && !ipa && recursive_call_p (current_function_decl,
+         else if (callee && !ipa && recursive_call_p (current_function_decl,
                                                  callee))
            lattice[index].merge (0);
          else
diff --git a/gcc/testsuite/g++.dg/pr98499.C b/gcc/testsuite/g++.dg/pr98499.C
new file mode 100644 (file)
index 0000000..ace088a
--- /dev/null
@@ -0,0 +1,31 @@
+/* PR tree-optimization/98499.  */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+struct string {
+  // pointer to local store
+  char * _M_buf;
+  // local store
+  char _M_local_buf[16];
+
+  __attribute__((noinline)) string() : _M_buf(_M_local_buf) {}
+
+  ~string() {
+    if (_M_buf != _M_local_buf)
+      __builtin_trap();
+  }
+
+  string(const string &__str); // no copies
+};
+
+__attribute__((noinline)) static string dir_name() { return string(); }
+class Importer {
+  string base_path;
+
+public:
+  __attribute__((noinline)) Importer() : base_path (dir_name()) {}
+};
+
+int main() {
+  Importer imp;
+}