]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR rtl-optimization/33822
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 7 Nov 2007 20:48:08 +0000 (20:48 +0000)
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 7 Nov 2007 20:48:08 +0000 (20:48 +0000)
* rtl.h (REG_OFFSET): Fix comment.
* var-tracking.c (INT_MEM_OFFSET): New macro.
(var_mem_set): Use it.
(var_mem_delete_and_set): Likewise.
(var_mem_delete): Likewise.
(same_variable_part_p): Likewise.
(vt_get_decl_and_offset): Likewise.
(offset_valid_for_tracked_p): New predicate.
(count_uses): Do not track locations with invalid offsets.
(add_uses): Likewise.
(add_stores): Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@129970 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/rtl.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/out-of-bounds-1.c [new file with mode: 0644]
gcc/var-tracking.c

index c8ae925a99983f6d76661ea91bc0a049b88eb36e..d005a094b3e2740a47760b0d113d96b7c3dca232 100644 (file)
@@ -1,3 +1,18 @@
+2007-11-07  Eric Botcazou  <ebotcazou@libertysurf.fr>
+
+       PR rtl-optimization/33822
+       * rtl.h (REG_OFFSET): Fix comment.
+       * var-tracking.c (INT_MEM_OFFSET): New macro.
+       (var_mem_set): Use it.
+       (var_mem_delete_and_set): Likewise.
+       (var_mem_delete): Likewise.
+       (same_variable_part_p): Likewise.
+       (vt_get_decl_and_offset): Likewise.
+       (offset_valid_for_tracked_p): New predicate.
+       (count_uses): Do not track locations with invalid offsets.
+       (add_uses): Likewise.
+       (add_stores): Likewise.
+
 2007-11-07  Tom Tromey  <tromey@redhat.com>
 
        * Makefile.in (tree-ssa-structalias.o): Depend on $(FUNCTION_H)
index 28ab8f60e71f6b8fe1089bb9ed79033607c890db..ef3a97e7ef6308e6978d879bd2f663eba9976646 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1210,8 +1210,8 @@ do {                                              \
    refer to part of a DECL.  */
 #define REG_EXPR(RTX) (REG_ATTRS (RTX) == 0 ? 0 : REG_ATTRS (RTX)->decl)
 
-/* For a MEM rtx, the offset from the start of MEM_DECL, if known, as a
-   RTX that is always a CONST_INT.  */
+/* For a REG rtx, the offset from the start of REG_EXPR, if known, as an
+   HOST_WIDE_INT.  */
 #define REG_OFFSET(RTX) (REG_ATTRS (RTX) == 0 ? 0 : REG_ATTRS (RTX)->offset)
 
 /* Copy the attributes that apply to memory locations from RHS to LHS.  */
index 74a7e3baa7b3cb58befbaeaf6d0329cca41ba2e0..60e2429a50e31fedd1faac0bd29b021751665863 100644 (file)
@@ -1,3 +1,7 @@
+2007-11-07  Eric Botcazou  <ebotcazou@libertysurf.fr>
+
+       * gcc.dg/out-of-bounds-1.c: New test.
+
 2007-11-07  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/33501
diff --git a/gcc/testsuite/gcc.dg/out-of-bounds-1.c b/gcc/testsuite/gcc.dg/out-of-bounds-1.c
new file mode 100644 (file)
index 0000000..14c4591
--- /dev/null
@@ -0,0 +1,13 @@
+/* PR rtl-optimization/33822 */
+/* Origin: Andrew Pinski <pinskia@gcc.gnu.org> */
+
+/* { dg-do compile } */
+/* { dg-options "-O -g" } */
+/* { dg-options "-O -g -mstrict-align" { target powerpc*-*-* } } */
+
+void ProjectOverlay(const float localTextureAxis[2], char *lump)
+{
+   const void *d = &localTextureAxis;
+   int size = sizeof(float)*8 ;
+   __builtin_memcpy( &lump[ 0 ], d, size );  
+}
index 9599b5aac7b768f4296a09caba6873926c14d629..46752fa1ef0b1990ca9e64f53452e60fae187ba3 100644 (file)
@@ -267,6 +267,9 @@ typedef const struct variable_def *const_variable;
 /* Pointer to the BB's information specific to variable tracking pass.  */
 #define VTI(BB) ((variable_tracking_info) (BB)->aux)
 
+/* Macro to access MEM_OFFSET as an HOST_WIDE_INT.  Evaluates MEM twice.  */
+#define INT_MEM_OFFSET(mem) (MEM_OFFSET (mem) ? INTVAL (MEM_OFFSET (mem)) : 0)
+
 /* Alloc pool for struct attrs_def.  */
 static alloc_pool attrs_pool;
 
@@ -986,7 +989,7 @@ var_mem_set (dataflow_set *set, rtx loc, enum var_init_status initialized,
             rtx set_src)
 {
   tree decl = MEM_EXPR (loc);
-  HOST_WIDE_INT offset = MEM_OFFSET (loc) ? INTVAL (MEM_OFFSET (loc)) : 0;
+  HOST_WIDE_INT offset = INT_MEM_OFFSET (loc);
 
   decl = var_debug_decl (decl);
 
@@ -1005,7 +1008,7 @@ var_mem_delete_and_set (dataflow_set *set, rtx loc, bool modify,
                        enum var_init_status initialized, rtx set_src)
 {
   tree decl = MEM_EXPR (loc);
-  HOST_WIDE_INT offset = MEM_OFFSET (loc) ? INTVAL (MEM_OFFSET (loc)) : 0;
+  HOST_WIDE_INT offset = INT_MEM_OFFSET (loc);
 
   decl = var_debug_decl (decl);
 
@@ -1025,7 +1028,7 @@ static void
 var_mem_delete (dataflow_set *set, rtx loc, bool clobber)
 {
   tree decl = MEM_EXPR (loc);
-  HOST_WIDE_INT offset = MEM_OFFSET (loc) ? INTVAL (MEM_OFFSET (loc)) : 0;
+  HOST_WIDE_INT offset = INT_MEM_OFFSET (loc);
 
   decl = var_debug_decl (decl);
   if (clobber)
@@ -1642,6 +1645,18 @@ track_expr_p (tree expr)
   return 1;
 }
 
+/* Return true if OFFSET is a valid offset for a register or memory
+   access we want to track.  This is used to reject out-of-bounds
+   accesses that can cause assertions to fail later.  Note that we
+   don't reject negative offsets because they can be generated for
+   paradoxical subregs on big-endian architectures.  */
+
+static inline bool
+offset_valid_for_tracked_p (HOST_WIDE_INT offset)
+{
+  return (-MAX_VAR_PARTS < offset) && (offset < MAX_VAR_PARTS);
+}
+
 /* Determine whether a given LOC refers to the same variable part as
    EXPR+OFFSET.  */
 
@@ -1662,7 +1677,7 @@ same_variable_part_p (rtx loc, tree expr, HOST_WIDE_INT offset)
   else if (MEM_P (loc))
     {
       expr2 = MEM_EXPR (loc);
-      offset2 = MEM_OFFSET (loc) ? INTVAL (MEM_OFFSET (loc)) : 0;
+      offset2 = INT_MEM_OFFSET (loc);
     }
   else
     return false;
@@ -1740,7 +1755,8 @@ count_uses (rtx *loc, void *insn)
     }
   else if (MEM_P (*loc)
           && MEM_EXPR (*loc)
-          && track_expr_p (MEM_EXPR (*loc)))
+          && track_expr_p (MEM_EXPR (*loc))
+          && offset_valid_for_tracked_p (INT_MEM_OFFSET (*loc)))
     {
       VTI (bb)->n_mos++;
     }
@@ -1776,7 +1792,9 @@ add_uses (rtx *loc, void *insn)
       basic_block bb = BLOCK_FOR_INSN ((rtx) insn);
       micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
 
-      if (REG_EXPR (*loc) && track_expr_p (REG_EXPR (*loc)))
+      if (REG_EXPR (*loc)
+         && track_expr_p (REG_EXPR (*loc))
+         && offset_valid_for_tracked_p (REG_OFFSET (*loc)))
        {
          mo->type = MO_USE;
          mo->u.loc = var_lowpart (mode_for_reg_attrs (*loc), *loc);
@@ -1790,7 +1808,8 @@ add_uses (rtx *loc, void *insn)
     }
   else if (MEM_P (*loc)
           && MEM_EXPR (*loc)
-          && track_expr_p (MEM_EXPR (*loc)))
+          && track_expr_p (MEM_EXPR (*loc))
+          && offset_valid_for_tracked_p (INT_MEM_OFFSET (*loc)))
     {
       basic_block bb = BLOCK_FOR_INSN ((rtx) insn);
       micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
@@ -1824,8 +1843,9 @@ add_stores (rtx loc, const_rtx expr, void *insn)
       micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
 
       if (GET_CODE (expr) == CLOBBER
-         || ! REG_EXPR (loc)
-         || ! track_expr_p (REG_EXPR (loc)))
+         || !(REG_EXPR (loc)
+              && track_expr_p (REG_EXPR (loc))
+              && offset_valid_for_tracked_p (REG_OFFSET (loc))))
        {
          mo->type = MO_CLOBBER;
          mo->u.loc = loc;
@@ -1859,7 +1879,8 @@ add_stores (rtx loc, const_rtx expr, void *insn)
     }
   else if (MEM_P (loc)
           && MEM_EXPR (loc)
-          && track_expr_p (MEM_EXPR (loc)))
+          && track_expr_p (MEM_EXPR (loc))
+          && offset_valid_for_tracked_p (INT_MEM_OFFSET (loc)))
     {
       basic_block bb = BLOCK_FOR_INSN ((rtx) insn);
       micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
@@ -1885,8 +1906,7 @@ add_stores (rtx loc, const_rtx expr, void *insn)
            {
              if (same_variable_part_p (SET_SRC (expr),
                                        MEM_EXPR (loc),
-                                       MEM_OFFSET (loc)
-                                       ? INTVAL (MEM_OFFSET (loc)) : 0))
+                                       INT_MEM_OFFSET (loc)))
                mo->type = MO_COPY;
              else
                mo->type = MO_SET;
@@ -3075,7 +3095,7 @@ vt_get_decl_and_offset (rtx rtl, tree *declp, HOST_WIDE_INT *offsetp)
       if (MEM_ATTRS (rtl))
        {
          *declp = MEM_EXPR (rtl);
-         *offsetp = MEM_OFFSET (rtl) ? INTVAL (MEM_OFFSET (rtl)) : 0;
+         *offsetp = INT_MEM_OFFSET (rtl);
          return true;
        }
     }