tree-optimization/96522 - transfer of flow-sensitive info in copy_ref_info
authorRichard Biener <rguenther@suse.de>
Thu, 27 Aug 2020 09:48:15 +0000 (11:48 +0200)
committerRichard Biener <rguenther@suse.de>
Thu, 27 Aug 2020 12:25:55 +0000 (14:25 +0200)
This removes the bogus tranfer of flow-sensitive info in copy_ref_info
plus fixes one oversight in FRE when flow-sensitive non-NULLness was added to
points-to info.

2020-08-27  Richard Biener  <rguenther@suse.de>

PR tree-optimization/96522
* tree-ssa-address.c (copy_ref_info): Reset flow-sensitive
info of the copied points-to.  Transfer bigger alignment
via the access type.
* tree-ssa-sccvn.c (eliminate_dom_walker::eliminate_stmt):
Reset all flow-sensitive info.

* gcc.dg/torture/pr96522.c: New testcase.

gcc/testsuite/gcc.dg/torture/pr96522.c [new file with mode: 0644]
gcc/tree-ssa-address.c
gcc/tree-ssa-sccvn.c

diff --git a/gcc/testsuite/gcc.dg/torture/pr96522.c b/gcc/testsuite/gcc.dg/torture/pr96522.c
new file mode 100644 (file)
index 0000000..2f55d1a
--- /dev/null
@@ -0,0 +1,36 @@
+/* { dg-do run } */
+/* { dg-additional-options "-fno-tree-pta" } */
+
+__attribute__((noipa)) void
+bar (void)
+{
+  volatile int v = 1;
+  if (v)
+    __builtin_abort ();
+}
+
+__attribute__((noipa)) void
+baz (void)
+{
+}
+
+__attribute__((noipa)) void
+foo (int n, double *p, double *x)
+{
+  if (n < 10 && p != 0)
+    for (int i = 0; i < 10; i++)
+      if (x[0] < p[i])
+        x[i] = 0;
+  if (p != 0)
+    bar ();
+  else
+    baz ();
+}
+
+int
+main ()
+{
+  double arr[10];
+  foo (1000, 0, arr);
+  return 0;
+}
index ec3741d759824679f40d7ca0be92b39e784d4764..93eae192212668f5d2e641de5c25e19cc9ec877a 100644 (file)
@@ -47,6 +47,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "dumpfile.h"
 #include "tree-affine.h"
 #include "gimplify.h"
+#include "builtins.h"
 
 /* FIXME: We compute address costs using RTL.  */
 #include "tree-ssa-address.h"
@@ -1015,45 +1016,24 @@ copy_ref_info (tree new_ref, tree old_ref)
 
   new_ptr_base = TREE_OPERAND (new_ref, 0);
 
+  tree base = get_base_address (old_ref);
+  if (!base)
+    return;
+
   /* We can transfer points-to information from an old pointer
      or decl base to the new one.  */
   if (new_ptr_base
       && TREE_CODE (new_ptr_base) == SSA_NAME
       && !SSA_NAME_PTR_INFO (new_ptr_base))
     {
-      tree base = get_base_address (old_ref);
-      if (!base)
-       ;
-      else if ((TREE_CODE (base) == MEM_REF
-               || TREE_CODE (base) == TARGET_MEM_REF)
-              && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME
-              && SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0)))
+      if ((TREE_CODE (base) == MEM_REF
+          || TREE_CODE (base) == TARGET_MEM_REF)
+         && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME
+         && SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0)))
        {
-         struct ptr_info_def *new_pi;
-         unsigned int align, misalign;
-
          duplicate_ssa_name_ptr_info
            (new_ptr_base, SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0)));
-         new_pi = SSA_NAME_PTR_INFO (new_ptr_base);
-         /* We have to be careful about transferring alignment information.  */
-         if (get_ptr_info_alignment (new_pi, &align, &misalign)
-             && TREE_CODE (old_ref) == MEM_REF
-             && !(TREE_CODE (new_ref) == TARGET_MEM_REF
-                  && (TMR_INDEX2 (new_ref)
-                      /* TODO: Below conditions can be relaxed if TMR_INDEX
-                         is an indcution variable and its initial value and
-                         step are aligned.  */
-                      || (TMR_INDEX (new_ref) && !TMR_STEP (new_ref))
-                      || (TMR_STEP (new_ref)
-                          && (TREE_INT_CST_LOW (TMR_STEP (new_ref))
-                              < align)))))
-           {
-             poly_uint64 inc = (mem_ref_offset (old_ref)
-                                - mem_ref_offset (new_ref)).force_uhwi ();
-             adjust_ptr_info_misalignment (new_pi, inc);
-           }
-         else
-           mark_ptr_info_alignment_unknown (new_pi);
+         reset_flow_sensitive_info (new_ptr_base);
        }
       else if (VAR_P (base)
               || TREE_CODE (base) == PARM_DECL
@@ -1063,6 +1043,14 @@ copy_ref_info (tree new_ref, tree old_ref)
          pt_solution_set_var (&pi->pt, base);
        }
     }
+
+  /* And alignment info.  Note we cannot transfer misalignment info
+     since that sits on the SSA name but this is flow-sensitive info
+     which we cannot transfer in this generic routine.  */
+  unsigned old_align = get_object_alignment (old_ref);
+  unsigned new_align = get_object_alignment (new_ref);
+  if (new_align < old_align)
+    TREE_TYPE (new_ref) = build_aligned_type (TREE_TYPE (new_ref), old_align);
 }
 
 /* Move constants in target_mem_ref REF to offset.  Returns the new target
index c5f4a1e53a9a7e045e57a8f0911179899ec1e4e8..8fbb1dd46d107fb72f854e83f32e5006830ea91d 100644 (file)
@@ -5860,8 +5860,7 @@ eliminate_dom_walker::eliminate_stmt (basic_block b, gimple_stmt_iterator *gsi)
              duplicate_ssa_name_ptr_info (sprime,
                                           SSA_NAME_PTR_INFO (lhs));
              if (b != sprime_b)
-               mark_ptr_info_alignment_unknown
-                   (SSA_NAME_PTR_INFO (sprime));
+               reset_flow_sensitive_info (sprime);
            }
          else if (INTEGRAL_TYPE_P (TREE_TYPE (lhs))
                   && SSA_NAME_RANGE_INFO (lhs)