Handle a_2= &b properly in range calculations.
authorAndrew MacLeod <amacleod@redhat.com>
Thu, 22 Oct 2020 00:11:16 +0000 (20:11 -0400)
committerAndrew MacLeod <amacleod@redhat.com>
Thu, 22 Oct 2020 00:15:28 +0000 (20:15 -0400)
when processing assignments, we were using the type of b instead of type
of &b when computing a range.  This was usually filtered out by FRE.
turning it off exposed it.

gcc/
PR tree-optimization/97520
* gimple-range.cc (range_of_non_trivial_assignment): Handle x = &a
by returning a non-zero range.
gcc/testsuite/
* gcc.dg/pr97520.c: New.

gcc/gimple-range.cc
gcc/testsuite/gcc.dg/pr97520.c [new file with mode: 0644]

index c5520e0700b3f9cb70aaedb2e52f7e9975528db3..267ebad757fddc7719faa448e80a3fc68d204833 100644 (file)
@@ -446,17 +446,31 @@ gimple_ranger::range_of_non_trivial_assignment (irange &r, gimple *stmt)
     return false;
 
   tree base = gimple_range_base_of_assignment (stmt);
-  if (base && TREE_CODE (base) == MEM_REF
-      && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
+  if (base)
     {
-      int_range_max range1;
-      tree ssa = TREE_OPERAND (base, 0);
-      if (range_of_expr (range1, ssa, stmt))
+      if (TREE_CODE (base) == MEM_REF)
        {
-         tree type = TREE_TYPE (ssa);
-         range_operator *op = range_op_handler (POINTER_PLUS_EXPR, type);
-         int_range<2> offset (TREE_OPERAND (base, 1), TREE_OPERAND (base, 1));
-         op->fold_range (r, type, range1, offset);
+         if (TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
+           {
+             int_range_max range1;
+             tree ssa = TREE_OPERAND (base, 0);
+             if (range_of_expr (range1, ssa, stmt))
+               {
+                 tree type = TREE_TYPE (ssa);
+                 range_operator *op = range_op_handler (POINTER_PLUS_EXPR,
+                                                        type);
+                 int_range<2> offset (TREE_OPERAND (base, 1),
+                                      TREE_OPERAND (base, 1));
+                 op->fold_range (r, type, range1, offset);
+                 return true;
+               }
+           }
+         return false;
+       }
+      if (gimple_assign_rhs_code (stmt) == ADDR_EXPR)
+       {
+         // Handle "= &a"  and return non-zero.
+         r = range_nonzero (TREE_TYPE (gimple_assign_rhs1 (stmt)));
          return true;
        }
     }
diff --git a/gcc/testsuite/gcc.dg/pr97520.c b/gcc/testsuite/gcc.dg/pr97520.c
new file mode 100644 (file)
index 0000000..9f66595
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-tree-fre" } */
+
+char a;
+void b() {
+  char *c[5];
+  char *d = &a;
+  &d;
+  *(c[4] = d);
+}
+int main() { return 0; }