From: Eric Botcazou Date: Wed, 7 Nov 2007 20:48:38 +0000 (+0100) Subject: re PR rtl-optimization/33822 (-g -O -mstrict-align causes an ICE in set_variable_part,) X-Git-Tag: prereleases/gcc-4.2.3-rc1~137 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9306914fc4af87a822a0a325bc1cb6dff2111f5d;p=thirdparty%2Fgcc.git 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: r129971 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 46c275e11604..f98829a6c702 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2007-11-07 Eric Botcazou + + 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-02 Bob Wilson * config/xtensa/xtensa.c (xtensa_expand_prologue): Put a diff --git a/gcc/rtl.h b/gcc/rtl.h index 79e8a1ca5b92..39f34c41ed14 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -1183,8 +1183,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 6036762071f1..38b8cdcf8d5b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2007-11-07 Eric Botcazou + + * gcc.dg/out-of-bounds-1.c: New test. + 2007-11-02 Eric Botcazou PR rtl-optimization/28062 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 000000000000..14c4591a40a1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/out-of-bounds-1.c @@ -0,0 +1,13 @@ +/* PR rtl-optimization/33822 */ +/* Origin: Andrew Pinski */ + +/* { 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 eb6ab11f2e50..722c34ce58e9 100644 --- a/gcc/var-tracking.c +++ b/gcc/var-tracking.c @@ -258,6 +258,9 @@ typedef struct variable_def /* 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; @@ -926,7 +929,7 @@ static void var_mem_set (dataflow_set *set, rtx loc) { 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); @@ -944,7 +947,7 @@ static void var_mem_delete_and_set (dataflow_set *set, rtx loc, bool modify) { 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); @@ -961,7 +964,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) @@ -1539,6 +1542,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. */ @@ -1559,7 +1574,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; @@ -1589,7 +1604,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++; } @@ -1625,14 +1641,19 @@ add_uses (rtx *loc, void *insn) basic_block bb = BLOCK_FOR_INSN ((rtx) insn); micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++; - mo->type = ((REG_EXPR (*loc) && track_expr_p (REG_EXPR (*loc))) - ? MO_USE : MO_USE_NO_VAR); + if (REG_EXPR (*loc) + && track_expr_p (REG_EXPR (*loc)) + && offset_valid_for_tracked_p (REG_OFFSET (*loc))) + mo->type = MO_USE; + else + mo->type = MO_USE_NO_VAR; mo->u.loc = *loc; mo->insn = (rtx) 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++; @@ -1666,8 +1687,9 @@ add_stores (rtx loc, 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; else if (GET_CODE (expr) == SET && SET_DEST (expr) == loc @@ -1682,7 +1704,8 @@ add_stores (rtx loc, 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++; @@ -1693,8 +1716,7 @@ add_stores (rtx loc, rtx expr, void *insn) && SET_DEST (expr) == loc && 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; @@ -2725,7 +2747,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; } }