From: Eric Botcazou <ebotcazou@libertysurf.fr>
To: gcc-patches@gcc.gnu.org
Subject: Fix PR rtl-optimization/33822
Date: Wed, 07 Nov 2007 20:49:00 -0000 [thread overview]
Message-ID: <200711072150.47455.ebotcazou@libertysurf.fr> (raw)
[-- 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 );
}
next reply other threads:[~2007-11-07 20:49 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-11-07 20:49 Eric Botcazou [this message]
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
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200711072150.47455.ebotcazou@libertysurf.fr \
--to=ebotcazou@libertysurf.fr \
--cc=gcc-patches@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).