re PR tree-optimization/60115 (wrong code at -O3 on x86_64-linux-gnu)
authorRichard Biener <rguenther@suse.de>
Mon, 10 Feb 2014 13:51:23 +0000 (13:51 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 10 Feb 2014 13:51:23 +0000 (13:51 +0000)
2014-02-10  Richard Biener  <rguenther@suse.de>

PR tree-optimization/60115
* tree-eh.c (tree_could_trap_p): Unify TARGET_MEM_REF and
MEM_REF handling.  Properly verify that the accesses are not
out of the objects bound.

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

From-SVN: r207656

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr60115.c [new file with mode: 0644]
gcc/tree-eh.c

index be69545..4abc6eb 100644 (file)
@@ -1,3 +1,10 @@
+2014-02-10  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/60115
+       * tree-eh.c (tree_could_trap_p): Unify TARGET_MEM_REF and
+       MEM_REF handling.  Properly verify that the accesses are not
+       out of the objects bound.
+
 2014-02-10  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
 
        * config/aarch64/aarch64.c (aarch64_override_options): Fix typo from
index ff6ecfa..ebe1e51 100644 (file)
@@ -1,3 +1,8 @@
+2014-02-10  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/60115
+       * gcc.dg/torture/pr60115.c: New testcase.
+
 2014-02-10  Eric Botcazou  <ebotcazou@adacore.com>
 
        * g++.dg/vect/pr33426-ivdep-3.cc: Require vect_int_mult as well.
diff --git a/gcc/testsuite/gcc.dg/torture/pr60115.c b/gcc/testsuite/gcc.dg/torture/pr60115.c
new file mode 100644 (file)
index 0000000..cf7f45d
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do run } */
+
+int a, b[2];
+
+int
+main ()
+{
+lbl:
+  for (; a; a--)
+    if (b[10000])
+      goto lbl;
+
+  return 0;
+}
index 857ee45..06941cd 100644 (file)
@@ -2610,12 +2610,6 @@ tree_could_trap_p (tree expr)
  restart:
   switch (code)
     {
-    case TARGET_MEM_REF:
-      if (TREE_CODE (TMR_BASE (expr)) == ADDR_EXPR
-         && !TMR_INDEX (expr) && !TMR_INDEX2 (expr))
-       return false;
-      return !TREE_THIS_NOTRAP (expr);
-
     case COMPONENT_REF:
     case REALPART_EXPR:
     case IMAGPART_EXPR:
@@ -2642,10 +2636,36 @@ tree_could_trap_p (tree expr)
        return false;
       return !in_array_bounds_p (expr);
 
+    case TARGET_MEM_REF:
     case MEM_REF:
-      if (TREE_CODE (TREE_OPERAND (expr, 0)) == ADDR_EXPR)
+      if (TREE_CODE (TREE_OPERAND (expr, 0)) == ADDR_EXPR
+         && tree_could_trap_p (TREE_OPERAND (TREE_OPERAND (expr, 0), 0)))
+       return true;
+      if (TREE_THIS_NOTRAP (expr))
        return false;
-      /* Fallthru.  */
+      /* We cannot prove that the access is in-bounds when we have
+         variable-index TARGET_MEM_REFs.  */
+      if (code == TARGET_MEM_REF
+         && (TMR_INDEX (expr) || TMR_INDEX2 (expr)))
+       return true;
+      if (TREE_CODE (TREE_OPERAND (expr, 0)) == ADDR_EXPR)
+       {
+         tree base = TREE_OPERAND (TREE_OPERAND (expr, 0), 0);
+         double_int off = mem_ref_offset (expr);
+         if (off.is_negative ())
+           return true;
+         if (TREE_CODE (base) == STRING_CST)
+           return double_int::from_uhwi (TREE_STRING_LENGTH (base)).ule (off);
+         else if (DECL_SIZE_UNIT (base) == NULL_TREE
+                  || TREE_CODE (DECL_SIZE_UNIT (base)) != INTEGER_CST
+                  || tree_to_double_int (DECL_SIZE_UNIT (base)).ule (off))
+           return true;
+         /* Now we are sure the first byte of the access is inside
+            the object.  */
+         return false;
+       }
+      return true;
+
     case INDIRECT_REF:
       return !TREE_THIS_NOTRAP (expr);