aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2014-03-26 07:38:30 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2014-03-26 07:38:30 +0000
commitc7e30a96b100f767d33424bb97a3527fe88f8c14 (patch)
tree545a241db523ea18afe2f6eccda8cad4e7308fc5 /gcc
parentd615d763225f330cf5416c95ad0726db67e227b4 (diff)
downloadgcc-c7e30a96b100f767d33424bb97a3527fe88f8c14.zip
gcc-c7e30a96b100f767d33424bb97a3527fe88f8c14.tar.gz
gcc-c7e30a96b100f767d33424bb97a3527fe88f8c14.tar.bz2
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. <case REG>: Return 1 for invalid offsets from the frame pointer. From-SVN: r208837
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/rtlanal.c42
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20140326-1.c10
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;
+}