From: Xi Ruoyao <[email protected]>

Here operands[0] is written before the instruction is finished using
operands[2] so it cannot lie in a register that is read by the
instruction.  Thus it should be an earlyclobber operand.  As operands[1]
is only used before the early result is written, it can be tied to the
earlyclobber operand so explicitly allow doing so.

Defer the split after reload as constrants do not apply to pseudos.

        PR target/127153

gcc/

        * config/loongarch/loongarch.md (both_non_zero): Defer the split
        post reload and add constraint to ensure operands[0] and
        operands[2] are in different hard registers.
        (both_non_zero_subreg): Likewise.

gcc/testsuite/

        * c-c++-common/pr127153.c: New test.
---

Bootstrapped and regtested on loongarch64-linux-gnu.  Ok for trunk and
releases/gcc-16?

Resend from another email server because loongson.cn mail server seems
blocking the server I normally use.

 gcc/config/loongarch/loongarch.md     | 12 +++++------
 gcc/testsuite/c-c++-common/pr127153.c | 31 +++++++++++++++++++++++++++
 2 files changed, 37 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/c-c++-common/pr127153.c

diff --git a/gcc/config/loongarch/loongarch.md 
b/gcc/config/loongarch/loongarch.md
index 37ae5a2223e..ecf1563270f 100644
--- a/gcc/config/loongarch/loongarch.md
+++ b/gcc/config/loongarch/loongarch.md
@@ -2755,14 +2755,14 @@ (define_insn "*sel<code><GPR:mode>_using_<X:mode>"
    (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")
+  [(set (match_operand:DI 0 "register_operand" "=&r")
+       (and:DI (ne:DI (match_operand:DI 1 "register_operand" "r0")
                       (const_int 0))
                (ne:DI (match_operand:DI 2 "register_operand" "r")
                       (const_int 0))))]
   "TARGET_64BIT"
   "#"
-  "&& true"
+  "&& reload_completed"
   [(set (match_dup 0)
        (ne:DI (match_dup 1) (const_int 0)))
    (set (match_dup 0)
@@ -2771,14 +2771,14 @@ (define_insn_and_split "both_non_zero"
                         (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")
+  [(set (match_operand:DI 0 "register_operand" "=&r")
+       (and:DI (subreg:DI (ne:SI (match_operand:DI 1 "register_operand" "r0")
                                  (const_int 0)) 0)
                (subreg:DI (ne:SI (match_operand:DI 2 "register_operand" "r")
                                  (const_int 0)) 0)))]
   "TARGET_64BIT"
   "#"
-  "&& true"
+  "&& reload_completed"
   [(set (match_dup 0)
        (ne:DI (match_dup 1) (const_int 0)))
    (set (match_dup 0)
diff --git a/gcc/testsuite/c-c++-common/pr127153.c 
b/gcc/testsuite/c-c++-common/pr127153.c
new file mode 100644
index 00000000000..5c8422d9b56
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr127153.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+__attribute__ ((noipa)) static int
+a ()
+{
+  return 0;
+}
+
+__attribute__ ((noipa)) static int
+b ()
+{
+  return 1;
+}
+
+__attribute__ ((noipa)) static int
+calc (int cond)
+{
+  int v = a ();
+  if (cond)
+    return b () && v;
+  return v;
+}
+
+int
+main ()
+{
+  int r = calc (1);
+  if (r)
+    __builtin_trap ();
+}
-- 
2.55.0

Reply via email to