RTL can contain:

        (set D (if_then_else:GPR (eq:X OP 0) OP 0))

Both outcomes are zero.  Fold this expression to a move of zero.

gcc/ChangeLog:

        * config/loongarch/loongarch.md: New split.

gcc/testsuite/ChangeLog:

        * gcc.target/loongarch/maskeqz-opt.c: New test.

---
 gcc/config/loongarch/loongarch.md             | 15 +++++++++++++++
 .../gcc.target/loongarch/maskeqz-opt.c        | 19 +++++++++++++++++++
 2 files changed, 34 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/loongarch/maskeqz-opt.c

diff --git a/gcc/config/loongarch/loongarch.md 
b/gcc/config/loongarch/loongarch.md
index ceacc5995e6..16b452379ae 100644
--- a/gcc/config/loongarch/loongarch.md
+++ b/gcc/config/loongarch/loongarch.md
@@ -2754,6 +2754,21 @@ (define_insn "*sel<code><GPR:mode>_using_<X:mode>"
   [(set_attr "type" "condmove")
    (set_attr "mode" "<GPR:MODE>")])
 
+;; Fold (OP == 0 ? OP : 0), whose value is always zero.
+(define_split
+  [(set (match_operand:GPR 0 "register_operand")
+       (if_then_else:GPR
+         (eq:GPR (match_operand:GPR 1 "register_operand")
+               (const_int 0))
+         (match_dup 1)
+         (const_int 0)))]
+  ""
+  [(const_int 0)]
+{
+  loongarch_emit_move (operands[0], const0_rtx);
+  DONE;
+})
+
 (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" "r0")
diff --git a/gcc/testsuite/gcc.target/loongarch/maskeqz-opt.c 
b/gcc/testsuite/gcc.target/loongarch/maskeqz-opt.c
new file mode 100644
index 00000000000..d1b8424a0d5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/maskeqz-opt.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+/* { dg-final { scan-assembler-not "\tmasknez" } } */
+
+void
+func2 (int c)
+{
+  int mask;
+
+  if (c < 0 || c > 32 || c == 1)
+    return;
+
+  if (c == 0)
+    mask = 0;
+  else
+    mask = ~(((int)1 << (32 - c)) - 1);
+
+  __asm__ volatile("" : : "r"(mask));
+}
-- 
2.55.0

Reply via email to