public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* PR target/107671: Make more use of btl/btq on x86_64.
@ 2023-08-07  7:37 Roger Sayle
  2023-08-07  9:45 ` Uros Bizjak
  0 siblings, 1 reply; 2+ messages in thread
From: Roger Sayle @ 2023-08-07  7:37 UTC (permalink / raw)
  To: gcc-patches; +Cc: 'Uros Bizjak'

[-- Attachment #1: Type: text/plain, Size: 1732 bytes --]


This patch is a partial solution to PR target/107671, updating Uros'
patch from comment #4, to catch both bit set (setc) and bit not set
(setnc) cases from the code in comment #2, when compiled on x86_64.
Unfortunately, this is a partial solution, as the pointer variants
in comment #1, aren't yet all optimized, and my attempts to check
whether the 32-bit versions are optimized with -m32 revealed they
also need further improvement.  (Some of) These remaining issues
might best be fixed in the middle-end, in either match.pd or the
RTL optimizers, so I thought it reasonable to submit this independent
backend piece, and gain/bank the improvements on x86_64.

This patch has been tested on x86_64-pc-linux-gnu with make bootstrap
and make -k check, both with and without --target_board=unix{-m32}
with no new failures.  Ok for mainline?


2023-08-07  Roger Sayle  <roger@nextmovesoftware.com>
            Uros Bizjak  <ubizjak@gmail.com>

gcc/ChangeLog
        PR target/107671
        * config/i386/i386.md (*bt<mode>_setc<mode>_mask): Allow the
        shift count to have a different mode (using SWI248) from either
        the bit-test or the result.
        (*bt<mode>_setnc<mode>_mask): New define_insn_and_split for the
        setnc (bit not set) case of the above pattern.
        (*btdi_setncsi_mask): New define_insn_and_split to handle the
        SImode result from a DImode bit-test variant of the above patterns.
        (*bt<mode>_setncqi_mask_2): New define_insn_and_split for the
        setnc (bit not set) version of *bt<mode>_setcqi_mask_2.

gcc/testsuite/ChangeLog
        PR target/107671
        * gcc.target/i386/pr107671-1.c: New test case.
        * gcc.target/i386/pr107671-2.c: Likewise.


Roger
--


[-- Attachment #2: patchbt2.txt --]
[-- Type: text/plain, Size: 5866 bytes --]

diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index ba376f8..aa8946a 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -16405,19 +16405,19 @@
         (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))])
 
 ;; Help combine recognize bt followed by setc
-(define_insn_and_split "*bt<mode>_setc<mode>_mask"
+(define_insn_and_split "*bt<SWI48:mode>_setc<SWI48:mode>_mask"
   [(set (match_operand:SWI48 0 "register_operand")
 	(zero_extract:SWI48
  	  (match_operand:SWI48 1 "register_operand")
 	  (const_int 1)
 	  (subreg:QI
-	    (and:SWI48
-	      (match_operand:SWI48 2 "register_operand")
+	    (and:SWI248
+	      (match_operand:SWI248 2 "register_operand")
 	      (match_operand 3 "const_int_operand")) 0)))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_USE_BT
-   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
-      == GET_MODE_BITSIZE (<MODE>mode)-1
+   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<SWI48:MODE>mode)-1))
+      == GET_MODE_BITSIZE (<SWI48:MODE>mode)-1
    && ix86_pre_reload_split ()"
   "#"
   "&& 1"
@@ -16432,6 +16432,90 @@
   operands[2] = gen_lowpart (QImode, operands[2]);
   operands[3] = gen_reg_rtx (QImode);
 })
+
+;; Help combine recognize bt followed by setnc
+(define_insn_and_split "*bt<SWI48:mode>_setnc<SWI48:mode>_mask"
+  [(set (match_operand:SWI48 0 "register_operand")
+	(and:SWI48
+	  (not:SWI48
+	    (lshiftrt:SWI48
+	      (match_operand:SWI48 1 "register_operand")
+	      (subreg:QI
+		(and:SWI248 (match_operand:SWI248 2 "register_operand")
+			    (match_operand 3 "const_int_operand")) 0)))
+	  (const_int 1)))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_USE_BT
+   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<SWI48:MODE>mode)-1))
+      == GET_MODE_BITSIZE (<SWI48:MODE>mode)-1
+   && ix86_pre_reload_split ()"
+  "#"
+  "&& 1"
+  [(set (reg:CCC FLAGS_REG)
+        (compare:CCC
+         (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
+         (const_int 0)))
+   (set (match_dup 3)
+        (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))
+   (set (match_dup 0) (zero_extend:SWI48 (match_dup 3)))]
+{
+  operands[2] = gen_lowpart (QImode, operands[2]);
+  operands[3] = gen_reg_rtx (QImode);
+})
+
+;; Help combine recognize bt followed by setnc
+(define_insn_and_split "*btdi_setncsi_mask"
+  [(set (match_operand:SI 0 "register_operand")
+	(and:SI
+	  (not:SI
+	    (subreg:SI
+	      (lshiftrt:DI (match_operand:DI 1 "register_operand")
+			   (subreg:QI
+			     (and:SWI248
+				(match_operand:SWI248 2 "register_operand")
+				(const_int 63)) 0)) 0))
+	  (const_int 1)))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_64BIT && TARGET_USE_BT && ix86_pre_reload_split ()"
+  "#"
+  "&& 1"
+  [(set (reg:CCC FLAGS_REG)
+        (compare:CCC
+         (zero_extract:DI (match_dup 1) (const_int 1) (match_dup 2))
+         (const_int 0)))
+   (set (match_dup 3)
+        (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))
+   (set (match_dup 0) (zero_extend:SI (match_dup 3)))]
+{
+  operands[2] = gen_lowpart (QImode, operands[2]);
+  operands[3] = gen_reg_rtx (QImode);
+})
+
+;; Help combine recognize bt followed by setnc
+(define_insn_and_split "*bt<SWI48:mode>_setncqi_mask_2"
+  [(set (match_operand:QI 0 "register_operand")
+	(eq:QI
+	  (zero_extract:SWI48
+ 	    (match_operand:SWI48 1 "register_operand")
+	    (const_int 1)
+	    (subreg:QI
+	      (and:SWI248 (match_operand:SWI248 2 "register_operand")
+			  (match_operand 3 "const_int_operand")) 0))
+	  (const_int 0)))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_USE_BT
+   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<SWI48:MODE>mode)-1))
+      == GET_MODE_BITSIZE (<SWI48:MODE>mode)-1
+   && ix86_pre_reload_split ()"
+  "#"
+  "&& 1"
+  [(set (reg:CCC FLAGS_REG)
+        (compare:CCC
+         (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
+         (const_int 0)))
+   (set (match_dup 0)
+        (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))]
+  "operands[2] = gen_lowpart (QImode, operands[2]);")
 \f
 ;; Store-flag instructions.
 
diff --git a/gcc/testsuite/gcc.target/i386/pr107671-1.c b/gcc/testsuite/gcc.target/i386/pr107671-1.c
new file mode 100644
index 0000000..d05b178
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr107671-1.c
@@ -0,0 +1,24 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2" } */
+
+int bt32v_setb(const __UINT32_TYPE__ v, __UINT32_TYPE__ bitnum)
+{
+    return ((v & (1  << (bitnum & 31)))) != 0;
+}
+
+int bt32v_setb2(const __UINT32_TYPE__ v, __UINT32_TYPE__ bitnum)
+{
+    return (v >> (bitnum & 31)) & 1;
+}
+
+int bt32v_setae(const __UINT32_TYPE__ v, __UINT32_TYPE__ bitnum)
+{
+    return ((v & (1  << (bitnum & 31)))) == 0;
+}
+
+int bt32v_setae2(const __UINT32_TYPE__ v, __UINT32_TYPE__ bitnum)
+{
+    return !((v >> (bitnum & 31)) & 1);
+}
+
+/* { dg-final { scan-assembler-times "btl" 4 } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr107671-2.c b/gcc/testsuite/gcc.target/i386/pr107671-2.c
new file mode 100644
index 0000000..c90faea
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr107671-2.c
@@ -0,0 +1,24 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2" } */
+
+int bt64v_setb(const __UINT64_TYPE__ v, __UINT64_TYPE__ bitnum)
+{
+    return ((v & (1LL << (bitnum & 63)))) != 0;
+}
+
+int bt64v_setb2(const __UINT64_TYPE__ v, __UINT64_TYPE__ bitnum)
+{
+    return (v >> (bitnum & 63)) & 1;
+}
+
+int bt64v_setae(const __UINT64_TYPE__ v, __UINT64_TYPE__ bitnum)
+{
+    return ((v & (1LL << (bitnum & 63)))) == 0;
+}
+
+int bt64v_setae2(const __UINT64_TYPE__ v, __UINT64_TYPE__ bitnum)
+{
+    return !((v >> (bitnum & 63)) & 1);
+}
+
+/* { dg-final { scan-assembler-times "btq" 4 } } */

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2023-08-07  9:45 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-08-07  7:37 PR target/107671: Make more use of btl/btq on x86_64 Roger Sayle
2023-08-07  9:45 ` Uros Bizjak

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).