The register_operand predicate can match subreg, then we'd have a subreg
of subreg and it's invalid.  Use lowpart_subreg to avoid the nested
 subreg.

gcc/ChangeLog:

        * config/loongarch/loongarch.md (crc_combine): Avoid nested
        subreg.

gcc/testsuite/ChangeLog:

        * gcc.c-torture/compile/pr120708.c: New test.
---

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

 gcc/config/loongarch/loongarch.md             |  3 ++-
 .../gcc.c-torture/compile/pr120708.c          | 20 +++++++++++++++++++
 2 files changed, 22 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr120708.c

diff --git a/gcc/config/loongarch/loongarch.md 
b/gcc/config/loongarch/loongarch.md
index a13398fdff4..8cf2ac90c64 100644
--- a/gcc/config/loongarch/loongarch.md
+++ b/gcc/config/loongarch/loongarch.md
@@ -4603,9 +4603,10 @@ (define_insn_and_split "*crc_combine"
   "&& true"
   [(set (match_dup 3) (match_dup 2))
    (set (match_dup 0)
-       (unspec:SI [(match_dup 3) (subreg:SI (match_dup 1) 0)] CRC))]
+       (unspec:SI [(match_dup 3) (match_dup 1)] CRC))]
   {
     operands[3] = gen_reg_rtx (<MODE>mode);
+    operands[1] = lowpart_subreg (SImode, operands[1], DImode);
   })
 
 ;; With normal or medium code models, if the only use of a pc-relative
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr120708.c 
b/gcc/testsuite/gcc.c-torture/compile/pr120708.c
new file mode 100644
index 00000000000..9b37e608d7f
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr120708.c
@@ -0,0 +1,20 @@
+typedef __UINT8_TYPE__ uint8_t;
+typedef __UINT32_TYPE__ uint32_t;
+
+typedef struct
+{
+  uint32_t dword[2];
+  uint8_t byte[8];
+} reg64_t;
+reg64_t TestF20F_opgd, TestF20F_oped;
+
+void
+TestF20F ()
+{
+  TestF20F_opgd.dword[0] ^= TestF20F_oped.byte[0];
+  for (int i = 0; i < 8; i++)
+    if (TestF20F_opgd.dword[0] & 1)
+      TestF20F_opgd.dword[0] = TestF20F_opgd.dword[0] >> 1 ^ 
(uint32_t)2197175160UL;
+    else
+      TestF20F_opgd.dword[0] = TestF20F_opgd.dword[0] >> 1;
+}
-- 
2.50.0

Reply via email to