diff options
author | Bernd Schmidt <bernds@redhat.com> | 2016-12-21 16:45:33 +0000 |
---|---|---|
committer | Bernd Schmidt <bernds@gcc.gnu.org> | 2016-12-21 16:45:33 +0000 |
commit | d697acca12fb5ace0ed1800c39f4fb2d5adb04e8 (patch) | |
tree | 9a979aab8d9f29d5f20951b0c4fd361694945f04 /gcc | |
parent | 4e2044d68d06c85761edf7510e23ea06c9279fdb (diff) | |
download | gcc-d697acca12fb5ace0ed1800c39f4fb2d5adb04e8.zip gcc-d697acca12fb5ace0ed1800c39f4fb2d5adb04e8.tar.gz gcc-d697acca12fb5ace0ed1800c39f4fb2d5adb04e8.tar.bz2 |
re PR target/71321 (x86: worse code for uint8_t % 10 and / 10)
PR target/71321
* config/i386/i386.md (lea<mode>_general_2b, lea<mode>_general_3b): New
patterns.
* config/i386/predicates.md (const123_operand): New.
PR target/71321
* gcc.target/i386/pr71321.c: New test.
From-SVN: r243861
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 47 | ||||
-rw-r--r-- | gcc/config/i386/predicates.md | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr71321.c | 16 |
5 files changed, 83 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8b2af2a..9065731 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2016-12-21 Bernd Schmidt <bschmidt@redhat.com> + + PR target/71321 + * config/i386/i386.md (lea<mode>_general_2b, lea<mode>_general_3b): New + patterns. + * config/i386/predicates.md (const123_operand): New. + 2016-12-21 Jakub Jelinek <jakub@redhat.com> Martin Liska <mliska@suse.cz> diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index a88c0b8..f50dbab 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -6263,6 +6263,27 @@ [(set_attr "type" "lea") (set_attr "mode" "SI")]) +(define_insn_and_split "*lea<mode>_general_2b" + [(set (match_operand:SWI12 0 "register_operand" "=r") + (plus:SWI12 + (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l") + (match_operand 2 "const123_operand" "n")) + (match_operand:SWI12 3 "nonmemory_operand" "ri")))] + "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)" + "#" + "&& reload_completed" + [(set (match_dup 0) + (plus:SI + (ashift:SI (match_dup 1) (match_dup 2)) + (match_dup 3)))] +{ + operands[0] = gen_lowpart (SImode, operands[0]); + operands[1] = gen_lowpart (SImode, operands[1]); + operands[3] = gen_lowpart (SImode, operands[3]); +} + [(set_attr "type" "lea") + (set_attr "mode" "SI")]) + (define_insn_and_split "*lea<mode>_general_3" [(set (match_operand:SWI12 0 "register_operand" "=r") (plus:SWI12 @@ -6289,6 +6310,32 @@ [(set_attr "type" "lea") (set_attr "mode" "SI")]) +(define_insn_and_split "*lea<mode>_general_3b" + [(set (match_operand:SWI12 0 "register_operand" "=r") + (plus:SWI12 + (plus:SWI12 + (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l") + (match_operand 2 "const123_operand" "n")) + (match_operand:SWI12 3 "register_operand" "r")) + (match_operand:SWI12 4 "immediate_operand" "i")))] + "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)" + "#" + "&& reload_completed" + [(set (match_dup 0) + (plus:SI + (plus:SI + (ashift:SI (match_dup 1) (match_dup 2)) + (match_dup 3)) + (match_dup 4)))] +{ + operands[0] = gen_lowpart (SImode, operands[0]); + operands[1] = gen_lowpart (SImode, operands[1]); + operands[3] = gen_lowpart (SImode, operands[3]); + operands[4] = gen_lowpart (SImode, operands[4]); +} + [(set_attr "type" "lea") + (set_attr "mode" "SI")]) + (define_insn_and_split "*lea<mode>_general_4" [(set (match_operand:SWI12 0 "register_operand" "=r") (any_or:SWI12 diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index 4c45df6..eb98598 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -765,6 +765,14 @@ return i == 2 || i == 4 || i == 8; }) +;; Match 1, 2, or 3. Used for lea shift amounts. +(define_predicate "const123_operand" + (match_code "const_int") +{ + HOST_WIDE_INT i = INTVAL (op); + return i == 1 || i == 2 || i == 3; +}) + ;; Match 2, 3, 6, or 7 (define_predicate "const2367_operand" (match_code "const_int") diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f3e48bb..e6ee770 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-12-21 Bernd Schmidt <bschmidt@redhat.com> + + PR target/71321 + * gcc.target/i386/pr71321.c: New test. + 2016-12-21 Jakub Jelinek <jakub@redhat.com> PR fortran/78866 diff --git a/gcc/testsuite/gcc.target/i386/pr71321.c b/gcc/testsuite/gcc.target/i386/pr71321.c new file mode 100644 index 0000000..7b00097 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr71321.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +typedef unsigned char uint8_t; +typedef unsigned int uint32_t; + +unsigned cvt_to_2digit(uint8_t i, uint8_t base) +{ + return ((i / base) | (uint32_t)(i % base)<<8); +} +unsigned cvt_to_2digit_ascii(uint8_t i) +{ + return cvt_to_2digit(i, 10) + 0x0a3030; +} +/* { dg-final { scan-assembler-times "lea.\t\\(%\[0-9a-z\]+,%\[0-9a-z\]+,4" 3 } } */ +/* { dg-final { scan-assembler-times "lea.\t\\(%\[0-9a-z\]+,%\[0-9a-z\]+,8" 1 } } */ |