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:
parent
220b59797b
commit
bbf46384ae
|
@ -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
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue