diff mbox series

Handle a_2= &b properly in range calculations.

Message ID f6c023ca-18af-576c-f25d-82ed078a266a@redhat.com
State New
Headers show
Series Handle a_2= &b properly in range calculations. | expand

Commit Message

Andrew MacLeod Oct. 22, 2020, 12:19 a.m. UTC
Pick up the correct type for the RHS of  a_2 = &b.

bootstrapped on  x86_64-pc-linux-gnu, no regressions, pushed.

Andrew
diff mbox series

Patch

commit 966fdb2e12c0347aa3f9efaf5f4e1cd8237fa024
Author: Andrew MacLeod <amacleod@redhat.com>
Date:   Wed Oct 21 20:11:16 2020 -0400

    Handle a_2= &b properly in range calculations.
    
    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.

diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc
index c5520e0700b..267ebad757f 100644
--- a/gcc/gimple-range.cc
+++ b/gcc/gimple-range.cc
@@ -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
index 00000000000..9f665959138
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97520.c
@@ -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; }