aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/riscv
diff options
context:
space:
mode:
authorOliver Kozul <Oliver.Kozul@rt-rk.com>2024-12-17 07:44:33 -0700
committerJeff Law <jlaw@ventanamicro.com>2024-12-17 07:44:33 -0700
commitd17b09c07a1da0e3950718aabc2cbdb90cae402b (patch)
tree5e943a12f18f19bb67ba9ef024d0ff420a4c5f96 /gcc/config/riscv
parentd24a5e2d381b290d4def659ed83e969b65d07f02 (diff)
downloadgcc-d17b09c07a1da0e3950718aabc2cbdb90cae402b.zip
gcc-d17b09c07a1da0e3950718aabc2cbdb90cae402b.tar.gz
gcc-d17b09c07a1da0e3950718aabc2cbdb90cae402b.tar.bz2
[PATCH] RISC-V: optimization on checking certain bits set ((x & mask) == val)
The patch optimizes code generation for comparisons of the form X & C1 == C2 by converting them to (X | ~C1) == (C2 | ~C1). C1 is a constant that requires li and addi to be loaded, while ~C1 requires a single lui instruction. As the values of C1 and C2 are not visible within the equality expression, a plus pattern is matched instead.       PR target/114087 gcc/ChangeLog: * config/riscv/riscv.md (*lui_constraint<ANYI:mode>_and_to_or): New pattern gcc/testsuite/ChangeLog: * gcc.target/riscv/pr114087-1.c: New test.
Diffstat (limited to 'gcc/config/riscv')
-rw-r--r--gcc/config/riscv/riscv.md28
1 files changed, 28 insertions, 0 deletions
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 1eec51c..6c6155c 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -858,6 +858,34 @@
[(set_attr "type" "arith")
(set_attr "mode" "SI")])
+;; Transform (X & C1) + C2 into (X | ~C1) - (-C2 | ~C1)
+;; Where C1 is not a LUI operand, but ~C1 is a LUI operand
+
+(define_insn_and_split "*lui_constraint<ANYI:mode>_and_to_or"
+ [(set (match_operand:ANYI 0 "register_operand" "=r")
+ (plus:ANYI (and:ANYI (match_operand:ANYI 1 "register_operand" "r")
+ (match_operand 2 "const_int_operand"))
+ (match_operand 3 "const_int_operand")))
+ (clobber (match_scratch:X 4 "=&r"))]
+ "LUI_OPERAND (~INTVAL (operands[2]))
+ && ((INTVAL (operands[2]) & (-INTVAL (operands[3])))
+ == (-INTVAL (operands[3])))
+ && riscv_const_insns (operands[3], false)
+ && (riscv_const_insns
+ (GEN_INT (~INTVAL (operands[2]) | -INTVAL (operands[3])), false)
+ <= riscv_const_insns (operands[3], false))"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 4) (match_dup 5))
+ (set (match_dup 0) (ior:X (match_dup 1) (match_dup 4)))
+ (set (match_dup 4) (match_dup 6))
+ (set (match_dup 0) (minus:X (match_dup 0) (match_dup 4)))]
+ {
+ operands[5] = GEN_INT (~INTVAL (operands[2]));
+ operands[6] = GEN_INT ((~INTVAL (operands[2])) | (-INTVAL (operands[3])));
+ }
+ [(set_attr "type" "arith")])
+
;;
;; ....................
;;