diff options
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/rtlanal.c | 42 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/20140326-1.c | 10 |
4 files changed, 50 insertions, 12 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8680951..7fea9de 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2014-03-26 Eric Botcazou <ebotcazou@adacore.com> + + PR rtl-optimization/60452 + * rtlanal.c (rtx_addr_can_trap_p_1): Fix head comment. + <case REG>: Return 1 for invalid offsets from the frame pointer. + 2014-03-26 Marek Polacek <polacek@redhat.com> PR c/37428 diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index 7a9efecd..98fbacc 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 9c745e1..5b24587 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2014-03-26 Eric Botcazou <ebotcazou@adacore.com> + + * gcc.c-torture/execute/20140326-1.c: New test. + 2014-03-25 Jan Hubicka <hubicka@ucw.cz> 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 0000000..552e218 --- /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; +} |