diff options
author | Eric Botcazou <ebotcazou@libertysurf.fr> | 2007-11-07 21:48:08 +0100 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2007-11-07 20:48:08 +0000 |
commit | 8c6c36a3c9583d2e804edd181c75e076a4f38b3e (patch) | |
tree | e242c9c5a82d38692b13f502a139a829581391e2 | |
parent | 83eb8eb789ffa18d8fe0aad243adaa753f532385 (diff) | |
download | gcc-8c6c36a3c9583d2e804edd181c75e076a4f38b3e.zip gcc-8c6c36a3c9583d2e804edd181c75e076a4f38b3e.tar.gz gcc-8c6c36a3c9583d2e804edd181c75e076a4f38b3e.tar.bz2 |
re PR rtl-optimization/33822 (-g -O -mstrict-align causes an ICE in set_variable_part,)
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.
From-SVN: r129970
-rw-r--r-- | gcc/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/rtl.h | 4 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/out-of-bounds-1.c | 13 | ||||
-rw-r--r-- | gcc/var-tracking.c | 46 |
5 files changed, 67 insertions, 15 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c8ae925..d005a09 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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) @@ -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. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 74a7e3b..60e2429 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 index 0000000..14c4591 --- /dev/null +++ b/gcc/testsuite/gcc.dg/out-of-bounds-1.c @@ -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 ); +} diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c index 9599b5a..46752fa 100644 --- a/gcc/var-tracking.c +++ b/gcc/var-tracking.c @@ -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; } } |