summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2020-01-23 12:39:13 +0100
committerJakub Jelinek <jakub@redhat.com>2020-01-23 12:39:13 +0100
commit9592f639ff4655203f1cffb7c6752696e2721fb0 (patch)
tree949dba7cd858fa9cea9afc9746505573a3054489
parent8a990ffafaaa18981c6e91d4ed88f05ed74c5f3f (diff)
downloadgcc-9592f639ff4655203f1cffb7c6752696e2721fb0.tar.gz
i386: Use bzhi for x & ((1 << y) - 1) or x & ((1U << y) - 1) [PR93346]
The bzhi patterns are quite complicated because they need to accurately describe the behavior of the instruction for all input values. The following patterns are simple and make bzhi recognizable even for cases where not all input values are valid, because the user used a shift, in which case the low 8 bit of the last operand need to be in between 0 and precision-1. 2020-01-23 Jakub Jelinek <jakub@redhat.com> PR target/93346 * config/i386/i386.md (*bmi2_bzhi_<mode>3_2, *bmi2_bzhi_<mode>3_3): New define_insn patterns. * gcc.target/i386/pr93346.c: New test.
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/i386/i386.md29
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/i386/pr93346.c76
4 files changed, 116 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d634b378afc..e62d3c02331 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2020-01-23 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/93346
+ * config/i386/i386.md (*bmi2_bzhi_<mode>3_2, *bmi2_bzhi_<mode>3_3):
+ New define_insn patterns.
+
2020-01-23 Richard Sandiford <richard.sandiford@arm.com>
* doc/sourcebuild.texi (check-function-bodies): Add an
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 6c674aaea5b..b5b53bbcfaa 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -14304,6 +14304,35 @@
(set_attr "prefix" "vex")
(set_attr "mode" "<MODE>")])
+(define_insn "*bmi2_bzhi_<mode>3_2"
+ [(set (match_operand:SWI48 0 "register_operand" "=r")
+ (and:SWI48
+ (plus:SWI48
+ (ashift:SWI48 (const_int 1)
+ (match_operand:QI 2 "register_operand" "r"))
+ (const_int -1))
+ (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_BMI2"
+ "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
+ [(set_attr "type" "bitmanip")
+ (set_attr "prefix" "vex")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "*bmi2_bzhi_<mode>3_3"
+ [(set (match_operand:SWI48 0 "register_operand" "=r")
+ (and:SWI48
+ (not:SWI48
+ (ashift:SWI48 (const_int -1)
+ (match_operand:QI 2 "register_operand" "r")))
+ (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_BMI2"
+ "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
+ [(set_attr "type" "bitmanip")
+ (set_attr "prefix" "vex")
+ (set_attr "mode" "<MODE>")])
+
(define_insn "bmi2_pdep_<mode>3"
[(set (match_operand:SWI48 0 "register_operand" "=r")
(unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 22c172f299b..dbcd8dd8390 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2020-01-23 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/93346
+ * gcc.target/i386/pr93346.c: New test.
+
2020-01-23 Martin Sebor <msebor@redhat.com>
PR c/84919
diff --git a/gcc/testsuite/gcc.target/i386/pr93346.c b/gcc/testsuite/gcc.target/i386/pr93346.c
new file mode 100644
index 00000000000..bad5c48f945
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr93346.c
@@ -0,0 +1,76 @@
+/* PR target/93346 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mbmi2" } */
+/* { dg-final { scan-assembler-times "\tbzhi\t" 12 } } */
+
+unsigned int
+f1 (unsigned int x, unsigned int y)
+{
+ return x & ((1 << y) - 1);
+}
+
+unsigned int
+f2 (unsigned int x, unsigned int y)
+{
+ return x & ((1U << y) - 1);
+}
+
+int
+f3 (int x, unsigned int y)
+{
+ return x & ((1 << y) - 1);
+}
+
+unsigned long
+f4 (unsigned long x, unsigned int y)
+{
+ return x & ((1L << y) - 1);
+}
+
+unsigned long
+f5 (unsigned long x, unsigned int y)
+{
+ return x & ((1UL << y) - 1);
+}
+
+long
+f6 (long x, unsigned int y)
+{
+ return x & ((1L << y) - 1);
+}
+
+unsigned int
+f7 (unsigned int x, int y)
+{
+ return x & ((1 << y) - 1);
+}
+
+unsigned int
+f8 (unsigned int x, int y)
+{
+ return x & ((1U << y) - 1);
+}
+
+int
+f9 (int x, int y)
+{
+ return x & ((1 << y) - 1);
+}
+
+unsigned long
+f10 (unsigned long x, int y)
+{
+ return x & ((1L << y) - 1);
+}
+
+unsigned long
+f11 (unsigned long x, int y)
+{
+ return x & ((1UL << y) - 1);
+}
+
+long
+f12 (long x, int y)
+{
+ return x & ((1L << y) - 1);
+}