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.
2024-12-06 Oliver Kozul <oliver.ko...@rt-rk.com> 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. CONFIDENTIALITY: The contents of this e-mail are confidential and intended only for the above addressee(s). If you are not the intended recipient, or the person responsible for delivering it to the intended recipient, copying or delivering it to anyone else or using it in any unauthorized manner is prohibited and may be unlawful. If you receive this e-mail by mistake, please notify the sender and the systems administrator at straym...@rt-rk.com immediately.
--- gcc/config/riscv/riscv.md | 21 +++++++++++++++++++++ gcc/testsuite/gcc.target/riscv/pr114087-1.c | 10 ++++++++++ 2 files changed, 31 insertions(+) create mode 100644 gcc/testsuite/gcc.target/riscv/pr114087-1.c diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 3a4cd1d93a0..add31bbf51c 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -858,6 +858,27 @@ [(set_attr "type" "arith") (set_attr "mode" "SI")]) +(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]) + 1) + && (INTVAL (operands[2]) & (-INTVAL (operands[3]))) + == (-INTVAL (operands[3]))" + "#" + "&& 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")]) + ;; ;; .................... ;; diff --git a/gcc/testsuite/gcc.target/riscv/pr114087-1.c b/gcc/testsuite/gcc.target/riscv/pr114087-1.c new file mode 100644 index 00000000000..5e40b5f7b5b --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/pr114087-1.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target rv64 } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d" } */ + +int pred1a(int x) { + return ((x & 0x55555FFF) == 0x14501DEF); +} + +/* { dg-final { scan-assembler {or\s*[a-x0-9]+,\s*[a-x0-9]+,\s*[a-x0-9]+} } } */ -- 2.43.0