From: Eric Botcazou Date: Wed, 26 Mar 2014 07:38:30 +0000 (+0000) Subject: re PR rtl-optimization/60452 (wrong code at -O1 with large offsets in the frame) X-Git-Tag: releases/gcc-4.9.0~298 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c7e30a96b100f767d33424bb97a3527fe88f8c14;p=thirdparty%2Fgcc.git re PR rtl-optimization/60452 (wrong code at -O1 with large offsets in the frame) PR rtl-optimization/60452 * rtlanal.c (rtx_addr_can_trap_p_1): Fix head comment. : Return 1 for invalid offsets from the frame pointer. From-SVN: r208837 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8680951ae1af..7fea9dedf08d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2014-03-26 Eric Botcazou + + PR rtl-optimization/60452 + * rtlanal.c (rtx_addr_can_trap_p_1): Fix head comment. + : Return 1 for invalid offsets from the frame pointer. + 2014-03-26 Marek Polacek PR c/37428 diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index 7a9efecdddac..98fbacce4a2d 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -224,10 +224,10 @@ rtx_varies_p (const_rtx x, bool for_alias) return 0; } -/* Return nonzero if the use of X as an address in a MEM can cause a trap. - MODE is the mode of the MEM (not that of X) and UNALIGNED_MEMS controls - whether nonzero is returned for unaligned memory accesses on strict - alignment machines. */ +/* Return nonzero if the use of X+OFFSET as an address in a MEM with SIZE + bytes can cause a trap. MODE is the mode of the MEM (not that of X) and + UNALIGNED_MEMS controls whether nonzero is returned for unaligned memory + references on strict alignment machines. */ static int rtx_addr_can_trap_p_1 (const_rtx x, HOST_WIDE_INT offset, HOST_WIDE_INT size, @@ -235,11 +235,12 @@ rtx_addr_can_trap_p_1 (const_rtx x, HOST_WIDE_INT offset, HOST_WIDE_INT size, { enum rtx_code code = GET_CODE (x); - if (STRICT_ALIGNMENT - && unaligned_mems - && GET_MODE_SIZE (mode) != 0) + /* The offset must be a multiple of the mode size if we are considering + unaligned memory references on strict alignment machines. */ + if (STRICT_ALIGNMENT && unaligned_mems && GET_MODE_SIZE (mode) != 0) { HOST_WIDE_INT actual_offset = offset; + #ifdef SPARC_STACK_BOUNDARY_HACK /* ??? The SPARC port may claim a STACK_BOUNDARY higher than the real alignment of %sp. However, when it does this, the @@ -298,8 +299,27 @@ rtx_addr_can_trap_p_1 (const_rtx x, HOST_WIDE_INT offset, HOST_WIDE_INT size, return 0; case REG: - /* As in rtx_varies_p, we have to use the actual rtx, not reg number. */ - if (x == frame_pointer_rtx || x == hard_frame_pointer_rtx + /* Stack references are assumed not to trap, but we need to deal with + nonsensical offsets. */ + if (x == frame_pointer_rtx) + { + HOST_WIDE_INT adj_offset = offset - STARTING_FRAME_OFFSET; + if (size == 0) + size = GET_MODE_SIZE (mode); + if (FRAME_GROWS_DOWNWARD) + { + if (adj_offset < frame_offset || adj_offset + size - 1 >= 0) + return 1; + } + else + { + if (adj_offset < 0 || adj_offset + size - 1 >= frame_offset) + return 1; + } + return 0; + } + /* ??? Need to add a similar guard for nonsensical offsets. */ + if (x == hard_frame_pointer_rtx || x == stack_pointer_rtx /* The arg pointer varies if it is not a fixed register. */ || (x == arg_pointer_rtx && fixed_regs[ARG_POINTER_REGNUM])) @@ -320,9 +340,7 @@ rtx_addr_can_trap_p_1 (const_rtx x, HOST_WIDE_INT offset, HOST_WIDE_INT size, if (XEXP (x, 0) == pic_offset_table_rtx && CONSTANT_P (XEXP (x, 1))) return 0; - /* - or it is an address that can't trap plus a constant integer, - with the proper remainder modulo the mode size if we are - considering unaligned memory references. */ + /* - or it is an address that can't trap plus a constant integer. */ if (CONST_INT_P (XEXP (x, 1)) && !rtx_addr_can_trap_p_1 (XEXP (x, 0), offset + INTVAL (XEXP (x, 1)), size, mode, unaligned_mems)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9c745e10834c..5b245870efe8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2014-03-26 Eric Botcazou + + * gcc.c-torture/execute/20140326-1.c: New test. + 2014-03-25 Jan Hubicka PR ipa/60315 diff --git a/gcc/testsuite/gcc.c-torture/execute/20140326-1.c b/gcc/testsuite/gcc.c-torture/execute/20140326-1.c new file mode 100644 index 000000000000..552e21891cb0 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/20140326-1.c @@ -0,0 +1,10 @@ +int a; + +int +main (void) +{ + char e[2] = { 0, 0 }, f = 0; + if (a == 131072) + f = e[a]; + return f; +}