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