public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r13-255] Avoid andb %dil when optimizing for size.
@ 2022-05-10  8:46 Roger Sayle
  0 siblings, 0 replies; only message in thread
From: Roger Sayle @ 2022-05-10  8:46 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:5b7a9751f55bcdb7d9a69345e02f62aaa7035d6b

commit r13-255-g5b7a9751f55bcdb7d9a69345e02f62aaa7035d6b
Author: Roger Sayle <roger@nextmovesoftware.com>
Date:   Tue May 10 09:44:34 2022 +0100

    Avoid andb %dil when optimizing for size.
    
    The simple test case below has the unfortunate property that on x86_64,
    it is larger when compiled with -Os than when compiled with -O2.
    
    int foo(char x)
    {
      return (x & 123) != 0;
    }
    
    The issue is x86's complex instruction encoding, where andb $XX,%dil
    requires more bytes than andl $XX,%edi.  This patch adds logic to
    i386.md's *testqi_1_maybe_si and *andqi_2_maybe_si define_insn patterns
    to prefer the shorter SImode alternative when optimizing for size.
    
    2022-05-10  Uroš Bizjak  <ubizjak@gmail.com>
                Roger Sayle  <roger@nextmovesoftware.com>
    
    gcc/ChangeLog
            * config/i386/i386.md (*testqi_1_maybe_si): Prefer shorter SImode
            alternative when optimizing for size and the immediate operand is
            const_0_to_127_operand.
            (*andqi_2_maybe_si): Likewise.
            * config/i386/predicates.md (const_0_to_127_operand): New predicate.
    
    gcc/testsuite/ChangeLog
            * gcc.target/i386/and-1.c: New test case.

Diff:
---
 gcc/config/i386/i386.md               | 30 +++++++++++++++++++++++-------
 gcc/config/i386/predicates.md         |  5 +++++
 gcc/testsuite/gcc.target/i386/and-1.c |  9 +++++++++
 3 files changed, 37 insertions(+), 7 deletions(-)

diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index b321cda1f22..f9c06ff302a 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -9502,14 +9502,14 @@
   [(set (reg FLAGS_REG)
 	(compare
 	  (and:QI
-	    (match_operand:QI 0 "nonimmediate_operand" "%qm,*a,qm,r")
-	    (match_operand:QI 1 "nonmemory_operand" "q,n,n,n"))
+	    (match_operand:QI 0 "nonimmediate_operand" "%qm,qm,r")
+	    (match_operand:QI 1 "nonmemory_operand" "q,n,n"))
 	  (const_int 0)))]
   "ix86_match_ccmode (insn,
 		      CONST_INT_P (operands[1])
 		      && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
 {
-  if (which_alternative == 3)
+  if (get_attr_mode (insn) == MODE_SI)
     {
       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
 	operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
@@ -9518,8 +9518,16 @@
   return "test{b}\t{%1, %0|%0, %1}";
 }
   [(set_attr "type" "test")
-   (set_attr "mode" "QI,QI,QI,SI")
-   (set_attr "pent_pair" "uv,uv,np,np")])
+   (set (attr "mode")
+     (cond [(eq_attr "alternative" "2")
+	      (const_string "SI")
+	    (and (match_test "optimize_insn_for_size_p ()")
+		 (and (match_operand 0 "ext_QIreg_operand")
+		      (match_operand 1 "const_0_to_127_operand")))
+	      (const_string "SI")
+	   ]
+	   (const_string "QI")))
+   (set_attr "pent_pair" "uv,np,np")])
 
 (define_insn "*test<mode>_1"
   [(set (reg FLAGS_REG)
@@ -10110,7 +10118,7 @@
 			 CONST_INT_P (operands[2])
 			 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
 {
-  if (which_alternative == 2)
+  if (get_attr_mode (insn) == MODE_SI)
     {
       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
@@ -10119,7 +10127,15 @@
   return "and{b}\t{%2, %0|%0, %2}";
 }
   [(set_attr "type" "alu")
-   (set_attr "mode" "QI,QI,SI")
+   (set (attr "mode")
+     (cond [(eq_attr "alternative" "2")
+	      (const_string "SI")
+	    (and (match_test "optimize_insn_for_size_p ()")
+		 (and (match_operand 0 "ext_QIreg_operand")
+		      (match_operand 2 "const_0_to_127_operand")))
+	      (const_string "SI")
+	   ]
+	   (const_string "QI")))
    ;; Potential partial reg stall on alternative 2.
    (set (attr "preferred_for_speed")
      (cond [(eq_attr "alternative" "2")
diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md
index a8cc17a054d..848a79a8d16 100644
--- a/gcc/config/i386/predicates.md
+++ b/gcc/config/i386/predicates.md
@@ -906,6 +906,11 @@
   (and (match_code "const_int")
        (match_test "IN_RANGE (INTVAL (op), 0, 63)")))
 
+;; Match 0 to 127.
+(define_predicate "const_0_to_127_operand"
+  (and (match_code "const_int")
+       (match_test "IN_RANGE (INTVAL (op), 0, 127)")))
+
 ;; Match 0 to 255.
 (define_predicate "const_0_to_255_operand"
   (and (match_code "const_int")
diff --git a/gcc/testsuite/gcc.target/i386/and-1.c b/gcc/testsuite/gcc.target/i386/and-1.c
new file mode 100644
index 00000000000..11890d8fba3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/and-1.c
@@ -0,0 +1,9 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-Os" } */
+
+int foo(char x)
+{
+  return (x & 123) != 0;
+}
+
+/* { dg-final { scan-assembler-not "%dil" } } */


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-05-10  8:46 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-10  8:46 [gcc r13-255] Avoid andb %dil when optimizing for size Roger Sayle

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).