public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Fix PR rtl-optimization/33822
@ 2007-11-07 20:49 Eric Botcazou
  2007-11-09 22:14 ` Richard Sandiford
  0 siblings, 1 reply; 10+ messages in thread
From: Eric Botcazou @ 2007-11-07 20:49 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1725 bytes --]

This is a regression introduced by the var-tracking pass in the 4.x series.
The pass puts a limit (16) on the number of "location parts" it can track for 
each variable.  This limit is tested only in track_expr_p, implicitly for 
variables in registers (16 is the size of TImode) and explicitly for 
variables in memory:

/* Maximum number of location parts.  */
#define MAX_VAR_PARTS 16

  /* If RTX is a memory it should not be very large (because it would be
     an array or struct).  */
  if (MEM_P (decl_rtl))
    {
      /* Do not track structures and arrays.  */
      if (GET_MODE (decl_rtl) == BLKmode
	  || AGGREGATE_TYPE_P (TREE_TYPE (realdecl)))
	return 0;
      if (MEM_SIZE (decl_rtl)
	  && INTVAL (MEM_SIZE (decl_rtl)) > MAX_VAR_PARTS)
	return 0;
    }

But it is asserted in several places later.

This works fine for valid programs, but the assertions can trigger for invalid 
programs with out-of-bounds accesses (testcase from Andrew attached).  The 
patch makes it so that out-of-bounds accesses are not tracked.

Bootstrapped/regtested on x86_64-suse-linux, applied on all active branches.


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  Eric Botcazou  <ebotcazou@libertysurf.fr>

        * gcc.dg/out-of-bounds-1.c: New test.


-- 
Eric Botcazou

[-- Attachment #2: pr33822.diff --]
[-- Type: text/x-diff, Size: 5460 bytes --]

Index: rtl.h
===================================================================
--- rtl.h	(revision 129844)
+++ rtl.h	(working copy)
@@ -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: var-tracking.c
===================================================================
--- var-tracking.c	(revision 129844)
+++ var-tracking.c	(working copy)
@@ -267,6 +267,9 @@ typedef const struct variable_def *const
 /* 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,
 	     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 *se
 			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
   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, voi
       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, voi
     }
   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, voi
 	    {
 	      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 *d
       if (MEM_ATTRS (rtl))
 	{
 	  *declp = MEM_EXPR (rtl);
-	  *offsetp = MEM_OFFSET (rtl) ? INTVAL (MEM_OFFSET (rtl)) : 0;
+	  *offsetp = INT_MEM_OFFSET (rtl);
 	  return true;
 	}
     }

[-- Attachment #3: out-of-bounds-1.c --]
[-- Type: text/x-csrc, Size: 390 bytes --]

/* 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 );  
}

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2007-12-19 10:00 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-11-07 20:49 Fix PR rtl-optimization/33822 Eric Botcazou
2007-11-09 22:14 ` Richard Sandiford
2007-11-12 15:39   ` Eric Botcazou
2007-11-15 12:31     ` Richard Sandiford
2007-11-15 12:44       ` RFA: Fix tracking of pass-by-reference parameters Richard Sandiford
2007-12-14 15:38         ` Eric Botcazou
2007-12-16 12:44       ` Fix PR rtl-optimization/33822 Eric Botcazou
2007-12-18 10:47         ` Richard Sandiford
2007-12-18 18:57           ` Eric Botcazou
2007-12-19 10:44             ` Richard Sandiford

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).