Two minor improvements on the H8 today.

First, the source operand of a SET could be a SYMBOL_REF.  That's valid for setting condition codes.  I'm guessing its primarily valuable when testing for weak symbols.  Either way, adding support for that in select_cc_mode allows the compiler to remove a few more comparisons.

Second, the H8 does not expose DImode operations, so generic parts of the compiler will arrange to synthesize DImode operations from SImode operations.  This is fine and good.  However, doing so does tend to generate some useless code.  For example (and:DI (reg:DI) (const_int 0xffffffff00000000) when synthesized via SImode operations generates an AND against -1 for the upper word which should simplify into a trivial copy.

But on the H8 we do not have SImode and DImode tieable.  So the costing model falls apart a bit and CSE thinks it's better to just leave things alone.  This patch adds a bit of smarts to the logical expander to avoid creating the obviously useless logical ops.  Note we don't have to handle everything here.  If the RHS would simplify to a constant, CSE would do the right thing.   So we just want to handle cases where the RHS is going to simplify into a simple register operand.  And in practice I've only seen this fire for AND.  Anyway, the twiddle to the expander eliminates a few more instructions, particularly in libgcc.

Anyway, these have both run through my tester and I'm committing this to the trunk.

Jeff
commit 629cbc682a773e64c4bcb800ea98fb3051cd810c
Author: Jeff Law <jeffreya...@gmail.com>
Date:   Fri Jun 18 18:02:16 2021 -0400

    [committed] More useless code elimination on the H8
    
    gcc/
            * config/h8300/h8300.c (h8300_select_cc_mode): Handle SYMBOL_REF.
            * config/h8300/logical.md (<code><mode>3 logcial expander): Generate
            more efficient code when the source can be trivially simplified.

diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c
index 1077a2b6ae0..2b88325d2f7 100644
--- a/gcc/config/h8300/h8300.c
+++ b/gcc/config/h8300/h8300.c
@@ -1950,7 +1950,7 @@ h8300_select_cc_mode (enum rtx_code cond, rtx op0, rtx 
op1)
           || GET_CODE (op0) == NEG || GET_CODE (op0) == AND
           || GET_CODE (op0) == IOR || GET_CODE (op0) == XOR
           || GET_CODE (op0) == NOT || GET_CODE (op0) == ASHIFT
-         || GET_CODE (op0) == MULT
+         || GET_CODE (op0) == MULT || GET_CODE (op0) == SYMBOL_REF
          || GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND
          || REG_P (op0) || MEM_P (op0)))
     return CCZNmode;
diff --git a/gcc/config/h8300/logical.md b/gcc/config/h8300/logical.md
index cb4c6384bdf..07d36cf0ef4 100644
--- a/gcc/config/h8300/logical.md
+++ b/gcc/config/h8300/logical.md
@@ -4,7 +4,27 @@
        (logicals:QHSI (match_operand:QHSI 1 "register_operand" "")
                       (match_operand:QHSI 2 "h8300_src_operand" "")))]
   ""
-  "")
+  "
+  {
+    enum machine_mode mode = GET_MODE (operands[0]);
+    /* DImodes are not considered tieable, as a result operations involving
+       subregs of DImode objects are considered expensive which can prevent
+       CSE from doing obvious simplifications.
+
+       We may ultimately change what is tieable, but this is an immediate
+       workaround while we evaluate changes to tieable modes.
+
+       The key in terms of what we want to handle is then the result of
+       the operation is not a constant.  */
+    if ((<CODE> == AND && operands[2] == CONSTM1_RTX (mode))
+       || (<CODE> == IOR && operands[2] == CONST0_RTX (mode))
+       || (<CODE> == XOR && operands[2] == CONST0_RTX (mode))
+       || ((<CODE> == AND || <CODE> == IOR) && operands[1] == operands[2]))
+      {
+       emit_move_insn (operands[0], operands[1]);
+       DONE;
+      }
+  }")
 
 ;; There's a ton of cleanup to do from here below.
 ;; ----------------------------------------------------------------------

Reply via email to