]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
LoongArch: Optimize the non-zero check for both integers
authorGuo Jie <guojie@loongson.cn>
Sat, 25 Oct 2025 07:24:37 +0000 (15:24 +0800)
committerLulu Cheng <chenglulu@loongson.cn>
Mon, 27 Oct 2025 09:44:37 +0000 (17:44 +0800)
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.

gcc/config/loongarch/loongarch.md
gcc/testsuite/gcc.target/loongarch/compare-both-non-zero.c [new file with mode: 0644]

index 933db2c252d59d4d84a644b139ccbc5d692fa752..be9a2351dd6e0a4d55a5713a6fa2e1033e1e4d6b 100644 (file)
   [(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 (file)
index 0000000..b813df4
--- /dev/null
@@ -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" } } */