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