aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUros Bizjak <uros@gcc.gnu.org>2012-07-23 18:04:23 +0200
committerUros Bizjak <uros@gcc.gnu.org>2012-07-23 18:04:23 +0200
commit7a49d85edf2622551d712f8d72459b0a50cd9a27 (patch)
treec9149de5c2bddc5d5d95c88d44595c0c603cc26f
parent3c2c4f22022ec41b2a9819244e961e5a267cbd8b (diff)
downloadgcc-7a49d85edf2622551d712f8d72459b0a50cd9a27.zip
gcc-7a49d85edf2622551d712f8d72459b0a50cd9a27.tar.gz
gcc-7a49d85edf2622551d712f8d72459b0a50cd9a27.tar.bz2
re PR target/53961 (internal compiler error: in memory_address_length, at config/i386/i386.c:23341)
PR target/53961 * config/i386/i386.md (*lea): Add asserts to detect invalid addresses. * config/i386/i386.c (ix86_print_operand_address): Ditto. (ix86_decompose_address): Allow (zero_extend:DI (subreg:SI (...))) addresses. Prevent zero extensions of CONST_INT operands. From-SVN: r189787
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/config/i386/i386.c52
-rw-r--r--gcc/config/i386/i386.md13
3 files changed, 56 insertions, 19 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6ab125c..a34897f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2012-07-23 Uros Bizjak <ubizjak@gmail.com>
+
+ PR target/53961
+ * config/i386/i386.md (*lea): Add asserts to detect invalid addresses.
+ * config/i386/i386.c (ix86_print_operand_address): Ditto.
+ (ix86_decompose_address): Allow (zero_extend:DI (subreg:SI (...)))
+ addresses. Prevent zero extensions of CONST_INT operands.
+
2012-07-22 Steven Bosscher <steven@gcc.gnu.org>
* sbitmap.h (struct int_list): Remove.
@@ -50,7 +58,7 @@
2012-07-22 Steven Bosscher <steven@gcc.gnu.org>
- * opts.c (common_handle_option): Do not set
+ * opts.c (common_handle_option): Do not set
flag_value_profile_transformations for -fprofile-generate.
* profile.c (instrument_values): Use COUNTER_FOR_HIST_TYPE.
(BB_TO_GCOV_INDEX): Remove.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 06ef5db..13e0fdc 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -11576,22 +11576,17 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
int retval = 1;
enum ix86_address_seg seg = SEG_DEFAULT;
- /* Allow SImode subregs of DImode addresses,
- they will be emitted with addr32 prefix. */
- if (TARGET_64BIT && GET_MODE (addr) == SImode)
- {
- if (GET_CODE (addr) == SUBREG
- && GET_MODE (XEXP (addr, 0)) == DImode)
- addr = SUBREG_REG (addr);
- }
-
/* Allow zero-extended SImode addresses,
they will be emitted with addr32 prefix. */
- else if (TARGET_64BIT && GET_MODE (addr) == DImode)
+ if (TARGET_64BIT && GET_MODE (addr) == DImode)
{
if (GET_CODE (addr) == ZERO_EXTEND
&& GET_MODE (XEXP (addr, 0)) == SImode)
- addr = XEXP (addr, 0);
+ {
+ addr = XEXP (addr, 0);
+ if (CONST_INT_P (addr))
+ return 0;
+ }
else if (GET_CODE (addr) == AND
&& const_32bit_mask (XEXP (addr, 1), DImode))
{
@@ -11600,7 +11595,11 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
/* Adjust SUBREGs. */
if (GET_CODE (addr) == SUBREG
&& GET_MODE (SUBREG_REG (addr)) == SImode)
- addr = SUBREG_REG (addr);
+ {
+ addr = SUBREG_REG (addr);
+ if (CONST_INT_P (addr))
+ return 0;
+ }
else if (GET_MODE (addr) == DImode)
addr = gen_rtx_SUBREG (SImode, addr, 0);
else if (GET_MODE (addr) != VOIDmode)
@@ -11608,6 +11607,19 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
}
}
+ /* Allow SImode subregs of DImode addresses,
+ they will be emitted with addr32 prefix. */
+ if (TARGET_64BIT && GET_MODE (addr) == SImode)
+ {
+ if (GET_CODE (addr) == SUBREG
+ && GET_MODE (SUBREG_REG (addr)) == DImode)
+ {
+ addr = SUBREG_REG (addr);
+ if (CONST_INT_P (addr))
+ return 0;
+ }
+ }
+
if (REG_P (addr))
base = addr;
else if (GET_CODE (addr) == SUBREG)
@@ -14765,11 +14777,19 @@ ix86_print_operand_address (FILE *file, rtx addr)
else
{
/* Print SImode register names to force addr32 prefix. */
- if (TARGET_64BIT
- && (GET_CODE (addr) == SUBREG
- || GET_CODE (addr) == ZERO_EXTEND
- || GET_CODE (addr) == AND))
+ if (GET_CODE (addr) == SUBREG)
+ {
+ gcc_assert (TARGET_64BIT);
+ gcc_assert (GET_MODE (addr) == SImode);
+ gcc_assert (GET_MODE (SUBREG_REG (addr)) == DImode);
+ gcc_assert (!code);
+ code = 'l';
+ }
+ else if (GET_CODE (addr) == ZERO_EXTEND
+ || GET_CODE (addr) == AND)
{
+ gcc_assert (TARGET_64BIT);
+ gcc_assert (GET_MODE (addr) == DImode);
gcc_assert (!code);
code = 'l';
}
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index f559ff2..114ad13 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -5458,10 +5458,19 @@
rtx addr = operands[1];
if (GET_CODE (addr) == SUBREG)
- return "lea{l}\t{%E1, %0|%0, %E1}";
+ {
+ gcc_assert (TARGET_64BIT);
+ gcc_assert (<MODE>mode == SImode);
+ gcc_assert (GET_MODE (SUBREG_REG (addr)) == DImode);
+ return "lea{l}\t{%E1, %0|%0, %E1}";
+ }
else if (GET_CODE (addr) == ZERO_EXTEND
|| GET_CODE (addr) == AND)
- return "lea{l}\t{%E1, %k0|%k0, %E1}";
+ {
+ gcc_assert (TARGET_64BIT);
+ gcc_assert (<MODE>mode == DImode);
+ return "lea{l}\t{%E1, %k0|%k0, %E1}";
+ }
else
return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
}