[gcc/devel/c++-modules] i386: Use bzhi for x & ((1 << y) - 1) or x & ((1U << y) - 1) [PR93346]

Nathan Sidwell nathan@gcc.gnu.org
Fri Jan 24 14:40:00 GMT 2020


https://gcc.gnu.org/g:9592f639ff4655203f1cffb7c6752696e2721fb0

commit 9592f639ff4655203f1cffb7c6752696e2721fb0
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Thu Jan 23 12:39:13 2020 +0100

    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.

Diff:
---
 gcc/ChangeLog                           |  6 +++
 gcc/config/i386/i386.md                 | 29 +++++++++++++
 gcc/testsuite/ChangeLog                 |  5 +++
 gcc/testsuite/gcc.target/i386/pr93346.c | 76 +++++++++++++++++++++++++++++++++
 4 files changed, 116 insertions(+)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d634b37..e62d3c0 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 6c674aa..b5b53bb 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 22c172f..dbcd8dd 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 0000000..bad5c48
--- /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);
+}



More information about the Gcc-cvs mailing list