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 | 32 +++++++++++++++++++
.../loongarch/compare-both-non-zero.c | 10 ++++++
2 files changed, 42 insertions(+)
create mode 100644 gcc/testsuite/gcc.target/loongarch/compare-both-non-zero.c
diff --git a/gcc/config/loongarch/loongarch.md
b/gcc/config/loongarch/loongarch.md
index a275a2d0158..c130ff1c289 100644
--- a/gcc/config/loongarch/loongarch.md
+++ b/gcc/config/loongarch/loongarch.md
@@ -2523,6 +2523,38 @@ (define_insn "*sel<code><GPR:mode>_using_<X:mode>"
[(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 00000000000..b813df40454
--- /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" } } */
--
2.50.0