public inbox for gcc-cvs@sourceware.org help / color / mirror / Atom feed
From: Roger Sayle <sayle@gcc.gnu.org> To: gcc-cvs@gcc.gnu.org Subject: [gcc r12-6106] x86: PR target/103773: Fix wrong-code with -Oz from pop to memory. Date: Thu, 23 Dec 2021 12:36:28 +0000 (GMT) [thread overview] Message-ID: <20211223123628.170343858417@sourceware.org> (raw) https://gcc.gnu.org/g:ef26c151c14a87177d46fd3d725e7f82e040e89f commit r12-6106-gef26c151c14a87177d46fd3d725e7f82e040e89f Author: Roger Sayle <roger@nextmovesoftware.com> Date: Thu Dec 23 12:33:07 2021 +0000 x86: PR target/103773: Fix wrong-code with -Oz from pop to memory. This is a fix to PR target/103773 where -Oz shouldn't use push/pop on x86 to shrink writing small integer constants to memory. Instead clang uses "andl $0, mem" for writing zero, and "orl $-1, mem" when writing -1 to memory when using -Oz. This patch implements this via peephole2 where we can confirm that its ok to clobber the flags. 2021-12-23 Roger Sayle <roger@nextmovesoftware.com> Uroš Bizjak <ubizjak@gmail.com> gcc/ChangeLog PR target/103773 * config/i386/i386.md (*mov<mode>_and): New define_insn for writing a zero to memory using AND. (*mov<mode>_or): Extend to allow memory destination and HImode. (*movdi_internal): Remove -Oz push/pop optimization from here. (*movsi_internal): Likewise. (peephole2): Perform -Oz push/pop optimization here, only for register destinations, values other than zero, and in functions that don't used the red zone. (peephole2): With -Oz, convert writes of 0 or -1 to memory into their clobber forms, i.e. *mov<mode>_and and *mov<mode>_or resp. gcc/testsuite/ChangeLog PR target/103773 * gcc.target/i386/pr103773-2.c: New test case. * gcc.target/i386/pr103773.c: New test case. Diff: --- gcc/config/i386/i386.md | 62 +++++++++++++++++++++--------- gcc/testsuite/gcc.target/i386/pr103773-2.c | 19 +++++++++ gcc/testsuite/gcc.target/i386/pr103773.c | 12 ++++++ 3 files changed, 75 insertions(+), 18 deletions(-) diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 58b10643fcb..284b9507466 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -2028,9 +2028,19 @@ (set_attr "mode" "SI") (set_attr "length_immediate" "0")]) +(define_insn "*mov<mode>_and" + [(set (match_operand:SWI248 0 "memory_operand" "=m") + (match_operand:SWI248 1 "const0_operand")) + (clobber (reg:CC FLAGS_REG))] + "reload_completed" + "and{<imodesuffix>}\t{%1, %0|%0, %1}" + [(set_attr "type" "alu1") + (set_attr "mode" "<MODE>") + (set_attr "length_immediate" "1")]) + (define_insn "*mov<mode>_or" - [(set (match_operand:SWI48 0 "register_operand" "=r") - (match_operand:SWI48 1 "constm1_operand")) + [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm") + (match_operand:SWI248 1 "constm1_operand")) (clobber (reg:CC FLAGS_REG))] "reload_completed" "or{<imodesuffix>}\t{%1, %0|%0, %1}" @@ -2218,14 +2228,7 @@ case TYPE_IMOV: gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1])); if (get_attr_mode (insn) == MODE_SI) - { - if (optimize_size > 1 - && TARGET_64BIT - && CONST_INT_P (operands[1]) - && IN_RANGE (INTVAL (operands[1]), -128, 127)) - return "push{q}\t%1\n\tpop{q}\t%0"; - return "mov{l}\t{%k1, %k0|%k0, %k1}"; - } + return "mov{l}\t{%k1, %k0|%k0, %k1}"; else if (which_alternative == 4) return "movabs{q}\t{%1, %0|%0, %1}"; else if (ix86_use_lea_for_mov (insn, operands)) @@ -2443,14 +2446,6 @@ gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1])); if (ix86_use_lea_for_mov (insn, operands)) return "lea{l}\t{%E1, %0|%0, %E1}"; - else if (optimize_size > 1 - && CONST_INT_P (operands[1]) - && IN_RANGE (INTVAL (operands[1]), -128, 127)) - { - if (TARGET_64BIT) - return "push{q}\t%1\n\tpop{q}\t%q0"; - return "push{l}\t%1\n\tpop{l}\t%0"; - } else return "mov{l}\t{%1, %0|%0, %1}"; @@ -2514,6 +2509,37 @@ ] (symbol_ref "true")))]) +;; With -Oz, transform mov $imm,reg to the shorter push $imm; pop reg. +(define_peephole2 + [(set (match_operand:SWI248 0 "general_reg_operand") + (match_operand:SWI248 1 "const_int_operand"))] + "optimize_insn_for_size_p () && optimize_size > 1 + && operands[1] != const0_rtx + && IN_RANGE (INTVAL (operands[1]), -128, 127) + && !ix86_red_zone_used" + [(set (match_dup 2) (match_dup 1)) + (set (match_dup 0) (match_dup 3))] +{ + if (GET_MODE (operands[0]) != word_mode) + operands[0] = gen_rtx_REG (word_mode, REGNO (operands[0])); + + operands[2] = gen_rtx_MEM (word_mode, + gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx)); + operands[3] = gen_rtx_MEM (word_mode, + gen_rtx_POST_INC (Pmode, stack_pointer_rtx)); +}) + +;; With -Oz, transform mov $0,mem to the shorter and $0,mem. +;; Likewise, transform mov $-1,mem to the shorter or $-1,mem. +(define_peephole2 + [(set (match_operand:SWI248 0 "memory_operand") + (match_operand:SWI248 1 "const_int_operand"))] + "(operands[1] == const0_rtx || operands[1] == constm1_rtx) + && optimize_insn_for_size_p () && optimize_size > 1 + && peep2_regno_dead_p (0, FLAGS_REG)" + [(parallel [(set (match_dup 0) (match_dup 1)) + (clobber (reg:CC FLAGS_REG))])]) + (define_insn "*movhi_internal" [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m ,*k,*k ,r ,m ,*k ,?r,?*v,*v,*v,*v,m") diff --git a/gcc/testsuite/gcc.target/i386/pr103773-2.c b/gcc/testsuite/gcc.target/i386/pr103773-2.c new file mode 100644 index 00000000000..9dafebdafbf --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr103773-2.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-Oz" } */ +short s; +int i; +long long l; + +void s0() { s = 0; } +void sm1() { s = -1; } +void i0() { i = 0; } +void im1() { i = -1; } +void l0() { l = 0; } +void lm1() { l = -1; } + +/* { dg-final { scan-assembler-not "\tmov\[wlq\]\t\\\$0," } } */ +/* { dg-final { scan-assembler-not "\tmov\[wlq\]\t\\\$-1," } } */ +/* { dg-final { scan-assembler "\tandw\t\\\$0," } } */ +/* { dg-final { scan-assembler "\torw\t\\\$-1," } } */ +/* { dg-final { scan-assembler "\torl\t\\\$-1," } } */ + diff --git a/gcc/testsuite/gcc.target/i386/pr103773.c b/gcc/testsuite/gcc.target/i386/pr103773.c new file mode 100644 index 00000000000..1e4b8ce903c --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr103773.c @@ -0,0 +1,12 @@ +/* { dg-do run } */ +/* { dg-options "-Oz" } */ + +unsigned long long x; + +int main (void) +{ + __builtin_memset (&x, 0xff, 4); + if (x != 0xffffffff) + __builtin_abort (); + return 0; +}
reply other threads:[~2021-12-23 12:36 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20211223123628.170343858417@sourceware.org \ --to=sayle@gcc.gnu.org \ --cc=gcc-cvs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).