https://gcc.gnu.org/g:1b612139661e6c5ed9c727130d8d22e99b5512a1
commit r16-4643-g1b612139661e6c5ed9c727130d8d22e99b5512a1 Author: Guo Jie <[email protected]> Date: Sat Oct 25 15:24:37 2025 +0800 LoongArch: Optimize the non-zero check for both integers Before: sltu $r5,$r0,$r5 sltu $r4,$r0,$r4 and $r4,$r5,$r4 After: sltu $r4,$r0,$r4 maskeqz $r4,$r4,$r5 gcc/ChangeLog: * config/loongarch/loongarch.md (both_non_zero): New combiner. (both_non_zero_subreg): Ditto. gcc/testsuite/ChangeLog: * gcc.target/loongarch/compare-both-non-zero.c: New test. Diff: --- gcc/config/loongarch/loongarch.md | 32 ++++++++++++++++++++++ .../gcc.target/loongarch/compare-both-non-zero.c | 10 +++++++ 2 files changed, 42 insertions(+) diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md index 933db2c252d5..be9a2351dd6e 100644 --- a/gcc/config/loongarch/loongarch.md +++ b/gcc/config/loongarch/loongarch.md @@ -2523,6 +2523,38 @@ [(set_attr "type" "condmove") (set_attr "mode" "<GPR:MODE>")]) +(define_insn_and_split "both_non_zero" + [(set (match_operand:DI 0 "register_operand" "=r") + (and:DI (ne:DI (match_operand:DI 1 "register_operand" "r") + (const_int 0)) + (ne:DI (match_operand:DI 2 "register_operand" "r") + (const_int 0))))] + "TARGET_64BIT" + "#" + "&& true" + [(set (match_dup 0) + (ne:DI (match_dup 1) (const_int 0))) + (set (match_dup 0) + (if_then_else:DI (ne:DI (match_dup 2) (const_int 0)) + (match_dup 0) + (const_int 0)))]) + +(define_insn_and_split "both_non_zero_subreg" + [(set (match_operand:DI 0 "register_operand" "=r") + (and:DI (subreg:DI (ne:SI (match_operand:DI 1 "register_operand" "r") + (const_int 0)) 0) + (subreg:DI (ne:SI (match_operand:DI 2 "register_operand" "r") + (const_int 0)) 0)))] + "TARGET_64BIT" + "#" + "&& true" + [(set (match_dup 0) + (ne:DI (match_dup 1) (const_int 0))) + (set (match_dup 0) + (if_then_else:DI (ne:DI (match_dup 2) (const_int 0)) + (match_dup 0) + (const_int 0)))]) + ;; fsel copies the 3rd argument when the 1st is non-zero and the 2nd ;; argument if the 1st is zero. This means operand 2 and 3 are ;; inverted in the instruction. diff --git a/gcc/testsuite/gcc.target/loongarch/compare-both-non-zero.c b/gcc/testsuite/gcc.target/loongarch/compare-both-non-zero.c new file mode 100644 index 000000000000..b813df40454c --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/compare-both-non-zero.c @@ -0,0 +1,10 @@ +/* { dg-do compile { target { loongarch64*-*-* } } } */ +/* { dg-options "-O3" } */ + +int +test (int a, int b) +{ + return a && b; +} + +/* { dg-final { scan-assembler "maskeqz" } } */
