backport: re PR target/53961 (internal compiler error: in memory_address_length, at config/i386/i386.c:23341)

Backport from mainline
	2012-07-24  Uros Bizjak  <ubizjak@gmail.com>

	PR target/53961
	* config/i386/i386.c (ix86_legitimate_address_p): Move check for
	negative constant address for TARGET_X32 ...
	(ix86_decompose_address): ... here.  Reject constant addresses
	that don't satisfy x86_64_immediate_operand predicate.

	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  Uros Bizjak  <ubizjak@gmail.com>

	PR target/53961
	* config/i386/i386.md (*lea): New insn pattern.
	(*lea_1): Remove.
	(*lea<mode>_2): Ditto.
	(*lea_{3,4,5,6}_zext): Ditto.
	* config/i386/predicates.md (lea_address_operand): Do not reject
	zero-extended address operands.
	* config/i386/constraints.md (j): Remove address constraint.
	* config/i386/i386.c (ix86_decompose_address): Allow SImode subreg
	of an address.
	(ix86_print_operand_address): Handle SImode subreg of an address.
	(ix86_avoid_lea_for_addr): Reject zero-extended addresses for now.

From-SVN: r190089
This commit is contained in:
Uros Bizjak 2012-08-02 18:24:25 +02:00 committed by Uros Bizjak
parent 220b59797b
commit bbf46384ae
5 changed files with 129 additions and 92 deletions

View File

@ -1,3 +1,37 @@
2012-08-02 Uros Bizjak <ubizjak@gmail.com>
Backport from mainline
2012-07-24 Uros Bizjak <ubizjak@gmail.com>
PR target/53961
* config/i386/i386.c (ix86_legitimate_address_p): Move check for
negative constant address for TARGET_X32 ...
(ix86_decompose_address): ... here. Reject constant addresses
that don't satisfy x86_64_immediate_operand predicate.
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 Uros Bizjak <ubizjak@gmail.com>
PR target/53961
* config/i386/i386.md (*lea): New insn pattern.
(*lea_1): Remove.
(*lea<mode>_2): Ditto.
(*lea_{3,4,5,6}_zext): Ditto.
* config/i386/predicates.md (lea_address_operand): Do not reject
zero-extended address operands.
* config/i386/constraints.md (j): Remove address constraint.
* config/i386/i386.c (ix86_decompose_address): Allow SImode subreg
of an address.
(ix86_print_operand_address): Handle SImode subreg of an address.
(ix86_avoid_lea_for_addr): Reject zero-extended addresses for now.
2012-08-01 Uros Bizjak <ubizjak@gmail.com>
Backport from mainline

View File

@ -19,7 +19,7 @@
;;; Unused letters:
;;; B H T W
;;; h k v
;;; h jk v
;; Integer register constraints.
;; It is not necessary to define 'r' here.
@ -127,11 +127,6 @@
(and (not (match_test "TARGET_X32"))
(match_operand 0 "memory_operand")))
(define_address_constraint "j"
"@internal Address operand that can be zero extended in LEA instruction."
(and (not (match_code "const_int"))
(match_operand 0 "address_operand")))
;; Integer constant constraints.
(define_constraint "I"
"Integer constant in the range 0 @dots{} 31, for 32-bit shifts."

View File

@ -11425,16 +11425,41 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
{
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))
{
addr = XEXP (addr, 0);
/* Strip subreg. */
/* 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)
return 0;
}
}
/* 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;
}
}
@ -11545,6 +11570,19 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
scale = 1 << scale;
retval = -1;
}
else if (CONST_INT_P (addr))
{
if (!x86_64_immediate_operand (addr, VOIDmode))
return 0;
/* Constant addresses are sign extended to 64bit, we have to
prevent addresses from 0x80000000 to 0xffffffff in x32 mode. */
if (TARGET_X32
&& val_signbit_known_set_p (SImode, INTVAL (addr)))
return 0;
disp = addr;
}
else
disp = addr; /* displacement */
@ -12048,13 +12086,6 @@ ix86_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
rtx base, index, disp;
HOST_WIDE_INT scale;
/* Since constant address in x32 is signed extended to 64bit,
we have to prevent addresses from 0x80000000 to 0xffffffff. */
if (TARGET_X32
&& CONST_INT_P (addr)
&& INTVAL (addr) < 0)
return false;
if (ix86_decompose_address (addr, &parts) <= 0)
/* Decomposition failed. */
return false;
@ -14589,12 +14620,20 @@ ix86_print_operand_address (FILE *file, rtx addr)
}
else
{
/* Print SImode register names for zero-extended
addresses to force addr32 prefix. */
if (TARGET_64BIT
&& (GET_CODE (addr) == ZERO_EXTEND
|| GET_CODE (addr) == AND))
/* Print SImode register names to force addr32 prefix. */
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';
}
@ -16802,6 +16841,11 @@ ix86_avoid_lea_for_addr (rtx insn, rtx operands[])
struct ix86_address parts;
int ok;
/* FIXME: Handle zero-extended addresses. */
if (GET_CODE (operands[1]) == ZERO_EXTEND
|| GET_CODE (operands[1]) == AND)
return false;
/* Check we need to optimize. */
if (!TARGET_OPT_AGU || optimize_function_for_size_p (cfun))
return false;

View File

@ -5375,6 +5375,41 @@
DONE;
})
;; Load effective address instructions
(define_insn_and_split "*lea<mode>"
[(set (match_operand:SWI48 0 "register_operand" "=r")
(match_operand:SWI48 1 "lea_address_operand" "p"))]
""
{
rtx addr = operands[1];
if (GET_CODE (addr) == SUBREG)
{
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)
{
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}";
}
"reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
[(const_int 0)]
{
ix86_split_lea_for_addr (operands, <MODE>mode);
DONE;
}
[(set_attr "type" "lea")
(set_attr "mode" "<MODE>")])
;; Add instructions
(define_expand "add<mode>3"
@ -5433,72 +5468,6 @@
[(set_attr "type" "alu")
(set_attr "mode" "QI")])
(define_insn_and_split "*lea_1"
[(set (match_operand:SI 0 "register_operand" "=r")
(subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
"TARGET_64BIT"
"lea{l}\t{%E1, %0|%0, %E1}"
"&& reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
[(const_int 0)]
{
ix86_split_lea_for_addr (operands, SImode);
DONE;
}
[(set_attr "type" "lea")
(set_attr "mode" "SI")])
(define_insn_and_split "*lea<mode>_2"
[(set (match_operand:SWI48 0 "register_operand" "=r")
(match_operand:SWI48 1 "lea_address_operand" "p"))]
""
"lea{<imodesuffix>}\t{%E1, %0|%0, %E1}"
"reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
[(const_int 0)]
{
ix86_split_lea_for_addr (operands, <MODE>mode);
DONE;
}
[(set_attr "type" "lea")
(set_attr "mode" "<MODE>")])
(define_insn "*lea_3_zext"
[(set (match_operand:DI 0 "register_operand" "=r")
(zero_extend:DI
(subreg:SI (match_operand:DI 1 "lea_address_operand" "j") 0)))]
"TARGET_64BIT"
"lea{l}\t{%E1, %k0|%k0, %E1}"
[(set_attr "type" "lea")
(set_attr "mode" "SI")])
(define_insn "*lea_4_zext"
[(set (match_operand:DI 0 "register_operand" "=r")
(zero_extend:DI
(match_operand:SI 1 "lea_address_operand" "j")))]
"TARGET_64BIT"
"lea{l}\t{%E1, %k0|%k0, %E1}"
[(set_attr "type" "lea")
(set_attr "mode" "SI")])
(define_insn "*lea_5_zext"
[(set (match_operand:DI 0 "register_operand" "=r")
(and:DI
(subreg:DI (match_operand:SI 1 "lea_address_operand" "p") 0)
(match_operand:DI 2 "const_32bit_mask" "n")))]
"TARGET_64BIT"
"lea{l}\t{%E1, %k0|%k0, %E1}"
[(set_attr "type" "lea")
(set_attr "mode" "SI")])
(define_insn "*lea_6_zext"
[(set (match_operand:DI 0 "register_operand" "=r")
(and:DI
(match_operand:DI 1 "lea_address_operand" "p")
(match_operand:DI 2 "const_32bit_mask" "n")))]
"TARGET_64BIT"
"lea{l}\t{%E1, %k0|%k0, %E1}"
[(set_attr "type" "lea")
(set_attr "mode" "SI")])
(define_insn "*add<mode>_1"
[(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
(plus:SWI48

View File

@ -817,11 +817,6 @@
struct ix86_address parts;
int ok;
/* LEA handles zero-extend by itself. */
if (GET_CODE (op) == ZERO_EXTEND
|| GET_CODE (op) == AND)
return false;
ok = ix86_decompose_address (op, &parts);
gcc_assert (ok);
return parts.seg == SEG_DEFAULT;