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
This commit is contained in:
Uros Bizjak 2012-07-23 18:04:23 +02:00
parent 3c2c4f2202
commit 7a49d85edf
3 changed files with 56 additions and 19 deletions

View File

@ -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.

View File

@ -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';
}

View File

@ -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}";
}