From: Uros Bizjak Date: Thu, 11 Aug 2011 20:03:29 +0000 (+0200) Subject: re PR target/49781 ([x32] Unnecessary lea in x32 mode) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=88b590c5128b80298568fe15f341cdcf94d9acb7;p=gcc.git re PR target/49781 ([x32] Unnecessary lea in x32 mode) PR target/49781 * config/i386/i386.md (*lea_5_zext): New. (*lea_6_zext): Ditto. * config/i386/predicates.md (const_32bit_mask): New predicate. (lea_address_operand): Reject AND. * config/i386/i386.c (ix86_decompose_address): Allow Dimode AND with const_32bit_mask immediate. (ix86_print_operand_address): Handle AND. (memory_address_length): Ditto. From-SVN: r177683 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 803e9c7481d..5d6e2d0fc26 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,17 @@ +2011-08-11 Uros Bizjak + + PR target/49781 + * config/i386/i386.md (*lea_5_zext): New. + (*lea_6_zext): Ditto. + * config/i386/predicates.md (const_32bit_mask): New predicate. + (lea_address_operand): Reject AND. + * config/i386/i386.c (ix86_decompose_address): Allow Dimode AND with + const_32bit_mask immediate. + (ix86_print_operand_address): Handle AND. + (memory_address_length): Ditto. + 2011-08-11 Romain Geissler - Brian Hackett + Brian Hackett * plugin.def: Add event for finish_decl. * plugin.c (register_callback, invoke_plugin_callbacks): Same. @@ -40,8 +52,7 @@ 2011-08-11 Kazuhiro Inaoka - * config/rx/rx.md (movsicc): Allow register to register - transfers. + * config/rx/rx.md (movsicc): Allow register to register transfers. (*movsicc): Likewise. (*stcc): Restrict this pattern to EQ and NE compares. (*stcc_reg): New pattern. Works for any comparison but only for @@ -71,8 +82,7 @@ (lto_materialize_tree): ... here. Handle CALL_EXPR codes. Remove call to lto_streamer_cache_append. - * tree-streamer-out.c (lto_output_tree_header): Handle - CALL_EXPR nodes. + * tree-streamer-out.c (lto_output_tree_header): Handle CALL_EXPR nodes. * tree-streamer.h (tree_read_bitfields): Declare. * Makefile.in (TREE_STREAMER_H): Add STREAMER_HOOKS_H. @@ -96,8 +106,7 @@ Remove assertions and adjustments for nodes main_identifier_node, ptrdiff_type_node and fileptr_type_node. (lto_streamer_hooks_init): Set streamer_hooks.write_tree to - lto_output_tree and streamer_hooks.read_tree to - lto_input_tree. + lto_output_tree and streamer_hooks.read_tree to lto_input_tree. * lto-streamer.h (lto_input_tree): Declare. (lto_output_tree_ref): Remove. * streamer-hooks.h (struct streamer_hooks): Remove fields @@ -121,8 +130,7 @@ (lto_output_integer_cst): Likewise. (lto_write_tree): Move to lto-streamer-out.c. (lto_output_tree): Likewise. - * tree-streamer.c (lto_record_common_node): Move from - lto-streamer.c + * tree-streamer.c (lto_record_common_node): Move from lto-streamer.c (preload_common_nodes): Likewise. (lto_streamer_cache_create): Call it. * tree-streamer.h: Include streamer-hooks.h. @@ -281,7 +289,7 @@ * doc/tm.texi: Regenerate. 2011-08-10 Georg-Johann Lay - + PR target/29560 * config/avr/avr.md (*ashlhiqi3): New insn-and-split. (*ashlqihiqi3): New insn-and-splits. @@ -337,12 +345,12 @@ 2011-08-09 Kirill Yukhin - * config/i386/i386.c: Remove traling spaces. - * config/i386/sse.md: Likewise. - (*fma_fmadd_): Fix insn alternative 1 mnemonic. - (*fma_fmsub_): Likewise. - (*fma_fnmadd_): Likewise. - (*fma_fnmsub_): Likewise. + * config/i386/i386.c: Remove traling spaces. + * config/i386/sse.md: Likewise. + (*fma_fmadd_): Fix insn alternative 1 mnemonic. + (*fma_fmsub_): Likewise. + (*fma_fnmadd_): Likewise. + (*fma_fnmsub_): Likewise. 2011-08-09 Nick Clifton diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 05dd57c7ece..fedb2cacc71 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -11146,11 +11146,22 @@ ix86_decompose_address (rtx addr, struct ix86_address *out) /* Allow zero-extended SImode addresses, they will be emitted with addr32 prefix. */ - if (TARGET_64BIT - && GET_CODE (addr) == ZERO_EXTEND - && GET_MODE (addr) == DImode - && GET_MODE (XEXP (addr, 0)) == SImode) - addr = XEXP (addr, 0); + if (TARGET_64BIT && GET_MODE (addr) == DImode) + { + if (GET_CODE (addr) == ZERO_EXTEND + && GET_MODE (XEXP (addr, 0)) == SImode) + addr = XEXP (addr, 0); + else if (GET_CODE (addr) == AND + && const_32bit_mask (XEXP (addr, 1), DImode)) + { + addr = XEXP (addr, 0); + + /* Strip subreg. */ + if (GET_CODE (addr) == SUBREG + && GET_MODE (SUBREG_REG (addr)) == SImode) + addr = SUBREG_REG (addr); + } + } if (REG_P (addr)) base = addr; @@ -14174,7 +14185,10 @@ ix86_print_operand_address (FILE *file, rtx addr) /* Print SImode registers for zero-extended addresses to force addr32 prefix. Otherwise print DImode registers to avoid it. */ if (TARGET_64BIT) - code = (GET_CODE (addr) == ZERO_EXTEND) ? 'l' : 'q'; + code = ((GET_CODE (addr) == ZERO_EXTEND + || GET_CODE (addr) == AND) + ? 'l' + : 'q'); if (ASSEMBLER_DIALECT == ASM_ATT) { @@ -21785,9 +21799,9 @@ assign_386_stack_local (enum machine_mode mode, enum ix86_stack_slot n) return s->rtl; } -/* Calculate the length of the memory address in the instruction - encoding. Includes addr32 prefix, does not include the one-byte modrm, - opcode, or other prefixes. */ +/* Calculate the length of the memory address in the instruction encoding. + Includes addr32 prefix, does not include the one-byte modrm, opcode, + or other prefixes. */ int memory_address_length (rtx addr) @@ -21816,7 +21830,8 @@ memory_address_length (rtx addr) disp = parts.disp; /* Add length of addr32 prefix. */ - len = (GET_CODE (addr) == ZERO_EXTEND); + len = (GET_CODE (addr) == ZERO_EXTEND + || GET_CODE (addr) == AND); /* Rule of thumb: - esp as the base always wants an index, diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 1b37118cfb8..e61b0f4a03e 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -5477,6 +5477,14 @@ (set_attr "mode" "QI")]) (define_insn "*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{%a1, %0|%0, %a1}" + [(set_attr "type" "lea") + (set_attr "mode" "SI")]) + +(define_insn "*lea_2" [(set (match_operand:SWI48 0 "register_operand" "=r") (match_operand:SWI48 1 "lea_address_operand" "p"))] "" @@ -5484,7 +5492,16 @@ [(set_attr "type" "lea") (set_attr "mode" "")]) -(define_insn "*lea_1_zext" +(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" "p") 0)))] + "TARGET_64BIT" + "lea{l}\t{%a1, %k0|%k0, %a1}" + [(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" "p")))] @@ -5493,18 +5510,21 @@ [(set_attr "type" "lea") (set_attr "mode" "SI")]) -(define_insn "*lea_2" - [(set (match_operand:SI 0 "register_operand" "=r") - (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))] +(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{%a1, %0|%0, %a1}" + "lea{l}\t{%a1, %k0|%k0, %a1}" [(set_attr "type" "lea") (set_attr "mode" "SI")]) -(define_insn "*lea_2_zext" +(define_insn "*lea_6_zext" [(set (match_operand:DI 0 "register_operand" "=r") - (zero_extend:DI - (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0)))] + (and:DI + (match_operand:DI 1 "lea_address_operand" "p") + (match_operand:DI 2 "const_32bit_mask" "n")))] "TARGET_64BIT" "lea{l}\t{%a1, %k0|%k0, %a1}" [(set_attr "type" "lea") diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index cfcd061e1f6..bc0a357b744 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -597,6 +597,12 @@ (and (match_code "const_int") (match_test "INTVAL (op) == 128"))) +;; Match exactly 0x0FFFFFFFF in anddi as a zero-extension operation +(define_predicate "const_32bit_mask" + (and (match_code "const_int") + (match_test "trunc_int_for_mode (INTVAL (op), DImode) + == (HOST_WIDE_INT) 0xffffffff"))) + ;; Match 2, 4, or 8. Used for leal multiplicands. (define_predicate "const248_operand" (match_code "const_int") @@ -802,7 +808,8 @@ int ok; /* LEA handles zero-extend by itself. */ - if (GET_CODE (op) == ZERO_EXTEND) + if (GET_CODE (op) == ZERO_EXTEND + || GET_CODE (op) == AND) return false; ok = ix86_decompose_address (op, &parts);