aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernd Schmidt <bernds@redhat.com>2016-12-21 16:45:33 +0000
committerBernd Schmidt <bernds@gcc.gnu.org>2016-12-21 16:45:33 +0000
commitd697acca12fb5ace0ed1800c39f4fb2d5adb04e8 (patch)
tree9a979aab8d9f29d5f20951b0c4fd361694945f04
parent4e2044d68d06c85761edf7510e23ea06c9279fdb (diff)
downloadgcc-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
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/i386/i386.md47
-rw-r--r--gcc/config/i386/predicates.md8
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/i386/pr71321.c16
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 } } */