Another round of redundant test/compare elimination on the H8. This improves our ability to use QImode logicals.  Part of the problem we needed to resolve here was that we support generating the b* instructions which do not set condition codes as well as the usual and, ior, xor.

The approach taken was to bring the b* form into the define_insn_and_split and not split when the b* form can be used (they're only used when twiddling a single bit).  This seems to work reasonably well based on the code I've looked at -- it's consistently finding optimization opportunities resulting in notable decreases in the size of newlib/libgcc.

This in turn allows us to have a nice generic <code>qi<cczn> pattern which handles all the QImode logicals in the obvious and simple way.

This patch also adds support for the muls patterns generating condition codes.  I didn't find any real examples of this being used across newlib/libgcc, but it's trivial to do.  Note that mulu does not set condition codes, so while it may look inconsistent, it matches the hardware to the best of my knowledge.

Committing to the trunk (after a 21hr test cycle),

Jeff
commit 8a7d54b1e10b8f4fba1358260ed2e7056ed23cbd
Author: Jeff Law <jeffreya...@gmail.com>
Date:   Sun Jun 13 11:09:38 2021 -0400

    [committed] More improvements to H8 logicals for test/compare elimination
    
    gcc/
            * config/h8300/logical.md (<code>qi3_1<cczn>): New pattern.
            (andqi3_1<cczn>): Removed.
            (<ors>qi3_1): Do not split for IOR/XOR a single bit.
            (H8/SX bit logicals): Split out from other patterns.
            * config/h8300/multiply.md (mulqihi3_const<cczn>): Renamed from
            mulqihi3_const_clobber_flags.
            (mulqihi3<cczn>, mulhisi3_const<cczn>, mulhisi3<cczn>): Similarly

diff --git a/gcc/config/h8300/logical.md b/gcc/config/h8300/logical.md
index fae3c7cd0c5..cb4c6384bdf 100644
--- a/gcc/config/h8300/logical.md
+++ b/gcc/config/h8300/logical.md
@@ -69,14 +69,6 @@
   ""
   [(set_attr "length" "8,2")])
 
-(define_insn "*andqi3_1<cczn>"
-  [(set (match_operand:QI 0 "register_operand" "=r")
-       (and:QI (match_operand:QI 1 "register_operand" "%0")
-               (match_operand:QI 2 "h8300_src_operand" "rn")))
-   (clobber (reg:CC CC_REG))]
-  ""
-  "and  %X2,%X0"
-  [(set_attr "length" "2")])
 
 (define_insn_and_split "*andor<mode>3"
   [(set (match_operand:QHSI 0 "register_operand" "=r")
@@ -179,27 +171,49 @@
                (match_operand:QI 2 "h8300_src_operand" "Y2,rQi")))]
   "TARGET_H8300SX || register_operand (operands[0], QImode)
    || single_one_operand (operands[2], QImode)"
-  "#"
-  "&& reload_completed"
+  { return <CODE> == IOR ? "bset\\t%V2,%R0" : "bnot\\t%V2,%R0"; }
+  "&& reload_completed && !single_one_operand (operands[2], QImode)"
   [(parallel [(set (match_dup 0) (ors:QI (match_dup 1) (match_dup 2)))
-             (clobber (reg:CC CC_REG))])])
+             (clobber (reg:CC CC_REG))])]
+  ""
+  [(set_attr "length" "8")])
 
-(define_insn "<code>qi3_1_clobber_flags"
-  [(set (match_operand:QI 0 "bit_operand" "=U,rQ")
-       (ors:QI (match_operand:QI 1 "bit_operand" "%0,0")
-               (match_operand:QI 2 "h8300_src_operand" "Y2,rQi")))
+(define_insn "*<code>qi3_1<cczn>"
+  [(set (match_operand:QI 0 "bit_operand" "=rQ")
+       (ors:QI (match_operand:QI 1 "bit_operand" "%0")
+               (match_operand:QI 2 "h8300_src_operand" "rQi")))
    (clobber (reg:CC CC_REG))]
-  "TARGET_H8300SX || register_operand (operands[0], QImode)
-   || single_one_operand (operands[2], QImode)"
-  {
-    if (which_alternative == 0)
-      return <CODE> == IOR ? "bset\\t%V2,%R0" : "bnot\\t%V2,%R0";
-    else if (which_alternative == 1)
-      return <CODE> == IOR ? "or\\t%X2,%X0" : "xor\\t%X2,%X0";
-    gcc_unreachable ();
+  "TARGET_H8300SX"
+  { return <CODE> == IOR ? "or\\t%X2,%X0" : "xor\\t%X2,%X0"; }
+  [(set_attr "length" "*")
+   (set_attr "length_table" "logicb")])
+
+(define_insn "*<code>qi3_1<cczn>"
+  [(set (match_operand:QI 0 "register_operand" "=r")
+       (ors:QI (match_operand:QI 1 "register_operand" "%0")
+               (match_operand:QI 2 "h8300_src_operand" "ri")))
+   (clobber (reg:CC CC_REG))]
+  "TARGET_H8300SX"
+  { return <CODE> == IOR ? "or\\t%X2,%X0" : "xor\\t%X2,%X0"; }
+  [(set_attr "length" "*")
+   (set_attr "length_table" "logicb")])
+
+(define_insn "*<code>qi3_1<cczn>"
+  [(set (match_operand:QI 0 "register_operand" "=r")
+       (logicals:QI (match_operand:QI 1 "register_operand" "%0")
+                    (match_operand:QI 2 "h8300_src_operand" "rn")))
+   (clobber (reg:CC CC_REG))]
+  ""
+  { 
+    if (<CODE> == IOR)
+      return "or\\t%X2,%X0";
+    else if (<CODE> == XOR)
+      return "xor\\t%X2,%X0";
+    else if (<CODE> == AND)
+      return "and\\t%X2,%X0";
+   gcc_unreachable ();
   }
-  [(set_attr "length" "8,*")
-   (set_attr "length_table" "*,logicb")])
+  [(set_attr "length" "2")])
 
 ;; ----------------------------------------------------------------------
 ;; {AND,IOR,XOR}{HI3,SI3} PATTERNS
diff --git a/gcc/config/h8300/multiply.md b/gcc/config/h8300/multiply.md
index 1d56d4797a7..8b9328c1282 100644
--- a/gcc/config/h8300/multiply.md
+++ b/gcc/config/h8300/multiply.md
@@ -26,7 +26,7 @@
                   (mult:HI (sign_extend:HI (match_dup 1)) (match_dup 2)))
              (clobber (reg:CC CC_REG))])])
 
-(define_insn "*mulqihi3_const_clobber_flags"
+(define_insn "*mulqihi3_const<cczn>"
   [(set (match_operand:HI 0 "register_operand" "=r")
        (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
                 (match_operand:QI 2 "nibble_operand" "IP4>X")))
@@ -47,7 +47,7 @@
                            (sign_extend:HI (match_dup 2))))
              (clobber (reg:CC CC_REG))])])
 
-(define_insn "*mulqihi3_clobber_flags"
+(define_insn "*mulqihi3<cczn>"
   [(set (match_operand:HI 0 "register_operand" "=r")
        (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
                 (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))
@@ -78,7 +78,7 @@
                   (mult:SI (sign_extend:SI (match_dup 1)) (match_dup 2)))
              (clobber (reg:CC CC_REG))])])
 
-(define_insn "*mulhisi3_const_clobber_flags"
+(define_insn "*mulhisi3_const<cczn>"
   [(set (match_operand:SI 0 "register_operand" "=r")
        (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
                 (match_operand:SI 2 "nibble_operand" "IP4>X")))
@@ -99,7 +99,7 @@
                            (sign_extend:SI (match_dup 2))))
              (clobber (reg:CC CC_REG))])])
 
-(define_insn "*mulhisi3_clobber_flags"
+(define_insn "*mulhisi3<cczn>"
   [(set (match_operand:SI 0 "register_operand" "=r")
        (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
                 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))

Reply via email to