From: Bernd Schmidt Date: Wed, 21 Dec 2016 16:45:33 +0000 (+0000) Subject: re PR target/71321 (x86: worse code for uint8_t % 10 and / 10) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d697acca12fb5ace0ed1800c39f4fb2d5adb04e8;p=gcc.git re PR target/71321 (x86: worse code for uint8_t % 10 and / 10) PR target/71321 * config/i386/i386.md (lea_general_2b, lea_general_3b): New patterns. * config/i386/predicates.md (const123_operand): New. PR target/71321 * gcc.target/i386/pr71321.c: New test. From-SVN: r243861 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8b2af2a1440..9065731661d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2016-12-21 Bernd Schmidt + + PR target/71321 + * config/i386/i386.md (lea_general_2b, lea_general_3b): New + patterns. + * config/i386/predicates.md (const123_operand): New. + 2016-12-21 Jakub Jelinek Martin Liska diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index a88c0b8c81a..f50dbab42e9 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_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_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_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_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 4c45df68a48..eb985983ff6 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 f3e48bb3bb6..e6ee77023aa 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-12-21 Bernd Schmidt + + PR target/71321 + * gcc.target/i386/pr71321.c: New test. + 2016-12-21 Jakub Jelinek 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 00000000000..7b0009740ea --- /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 } } */