[gcc/devel/jlaw/pr56096] Two new patterns to help code for pr56096
Jeff Law
law@gcc.gnu.org
Mon Mar 16 00:41:55 GMT 2026
https://gcc.gnu.org/g:80e1798ffce5fb1602aeccc1ca836e3606740472
commit 80e1798ffce5fb1602aeccc1ca836e3606740472
Author: Jeff Law <jeffrey.law@oss.qualcomm.com>
Date: Sat Mar 14 11:38:11 2026 -0600
Two new patterns to help code for pr56096
Diff:
---
gcc/config/riscv/riscv.md | 56 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 56 insertions(+)
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 3fe0ad0ccdf4..6cf673b80b63 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -3166,6 +3166,62 @@
[(set_attr "type" "shift")
(set_attr "mode" "DI")])
+;; Handle logical AND feeding an equality test against zero where an operand
+;; to the AND is a constant requiring synthesis. Because we only care about
+;; zero/nonzero state afte the AND, we may be able to shift both operands
+;; of the AND to the right and eliminate the need for constant synthesis.
+;;
+;; Once mvconst_internal goes away, this likely turns into a simple splitter.
+(define_insn_and_split ""
+ [(set (match_operand:X 0 "register_operand" "=r")
+ (any_eq:X (and:X (match_operand:X 1 "register_operand" "r")
+ (match_operand 2 "shifted_const_arith_operand"))
+ (const_int 0)))
+ (clobber (match_scratch:X 3 "=&r"))]
+ ""
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 3) (ashiftrt:X (match_dup 1) (match_dup 4)))
+ (set (match_dup 3) (and:X (match_dup 3) (match_dup 2)))
+ (set (match_dup 0) (any_eq:X (match_dup 3) (const_int 0)))]
+{
+ HOST_WIDE_INT shift = ctz_hwi (INTVAL (operands[2]));
+ operands[4] = gen_int_mode (shift, QImode);
+ operands[2] = gen_int_mode (INTVAL (operands[2]) >> shift, word_mode);
+}
+ [(set_attr "type" "shift")])
+
+;; The pattern above is a bridge to this pattern. Essentially a select
+;; between 0 and 2^n based on the zero/nonzero status of the AND.
+;;
+;; It's no fewer instructions, but the resulting code has fewer data
+;; dependencies and may compress better depending on 2^n.
+(define_insn_and_split ""
+ [(set (match_operand:X 0 "register_operand" "=r")
+ (ashift:X (any_eq:X
+ (and:X (match_operand:X 1 "register_operand" "r")
+ (match_operand 2 "shifted_const_arith_operand"))
+ (const_int 0))
+ (match_operand 3 "const_int_operand")))
+ (clobber (match_scratch:X 4 "=&r"))
+ (clobber (match_scratch:X 5 "=&r"))]
+ "TARGET_ZICOND && TARGET_ZBS"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 4) (ashiftrt:X (match_dup 1) (match_dup 6)))
+ (set (match_dup 4) (and:X (match_dup 4) (match_dup 2)))
+ (set (match_dup 5) (match_dup 3))
+ (set (match_dup 0) (if_then_else:X (any_eq:X (match_dup 4) (const_int 0))
+ (match_dup 5)
+ (const_int 0)))]
+{
+ HOST_WIDE_INT shift = ctz_hwi (INTVAL (operands[2]));
+ operands[3] = gen_int_mode (HOST_WIDE_INT_1U << INTVAL (operands[3]), word_mode);
+ operands[6] = gen_int_mode (shift, QImode);
+ operands[2] = gen_int_mode (INTVAL (operands[2]) >> shift, word_mode);
+}
+ [(set_attr "type" "shift")])
+
;;
;; ....................
;;
More information about the Gcc-cvs
mailing list