The following works around an issue in IPA SRA which does analysis
twice, once on the original function body and once on the cloned one
when replacing refs.  If both end up not agreeing we end up with
stale unreplaced refs - as in this case where earlier analysis had
access to SSA range info which isn't copied in the process of cloning.

Thus the following patch copies over SSA range info which is a good
idea anyways.

Not sure to what extent the IPA SRA issue will prevail with the
new implementation.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2019-06-26  Richard Biener  <rguent...@suse.de>

        PR ipa/90982
        * tree-inline.c (remap_ssa_name): Copy SSA range info.

        * g++.dg/torture/pr90982.C: New testcase.

Index: gcc/tree-inline.c
===================================================================
--- gcc/tree-inline.c   (revision 272636)
+++ gcc/tree-inline.c   (working copy)
@@ -259,6 +259,11 @@ remap_ssa_name (tree name, copy_body_dat
          struct ptr_info_def *new_pi = get_ptr_info (new_tree);
          new_pi->pt = pi->pt;
        }
+      /* So can range-info.  */
+      if (!POINTER_TYPE_P (TREE_TYPE (name))
+         && SSA_NAME_RANGE_INFO (name))
+       duplicate_ssa_name_range_info (new_tree, SSA_NAME_RANGE_TYPE (name),
+                                      SSA_NAME_RANGE_INFO (name));
       return new_tree;
     }
 
@@ -292,6 +297,11 @@ remap_ssa_name (tree name, copy_body_dat
          struct ptr_info_def *new_pi = get_ptr_info (new_tree);
          new_pi->pt = pi->pt;
        }
+      /* So can range-info.  */
+      if (!POINTER_TYPE_P (TREE_TYPE (name))
+         && SSA_NAME_RANGE_INFO (name))
+       duplicate_ssa_name_range_info (new_tree, SSA_NAME_RANGE_TYPE (name),
+                                      SSA_NAME_RANGE_INFO (name));
       if (SSA_NAME_IS_DEFAULT_DEF (name))
        {
          /* By inlining function having uninitialized variable, we might
Index: gcc/testsuite/g++.dg/torture/pr90982.C
===================================================================
--- gcc/testsuite/g++.dg/torture/pr90982.C      (nonexistent)
+++ gcc/testsuite/g++.dg/torture/pr90982.C      (working copy)
@@ -0,0 +1,23 @@
+// { dg-do compile }
+
+template <int n> struct S
+{
+  long c[n];
+  void f (S d)
+    {
+      for (int i = 2;; i++)
+       c[i] &= d.c[i];
+    }
+};
+
+template <int m> struct T:S<m/64>
+{
+  void operator &= (T d)
+    { this -> f (d); }
+};
+
+void g (T<192> &d)
+{
+  T<192> v;
+  d &= v;
+}

Reply via email to