This is a minor bug in the CRC code for RISC-V.

Essentially in the expander we have an operand without a predicate. So it matches anything. But that operand really has to be a CONST_INT. So this patch adds the missing predicate. I noticed we had constraints on our define_expand. It doesn't hurt anything, but they're never used and can easily get out of date, so this removes the unnecessary constraints.

Tested on riscv32-elf and riscv64-elf. Bootstrap & regression test on the Pioneer is in flight and should finish in the next few hours.

Pushing to the trunk once CI confirms it's OK.

jeff

        PR target/122106
gcc/
        * config/riscv/riscv.md (crc expanders): Add predicate for
        polynomial argument.  Drop unnecessary constraints.

gcc/testsuite/

        * gcc.target/riscv/pr122106.c: New test.
diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
index 5fd139ac9c14..59b71ed263b0 100644
--- a/gcc/config/riscv/bitmanip.md
+++ b/gcc/config/riscv/bitmanip.md
@@ -1218,13 +1218,13 @@ (define_insn "riscv_clmulr_<mode>"
 ;; Reversed CRC 8, 16, 32 for TARGET_64
 (define_expand "crc_rev<ANYI1:mode><ANYI:mode>4"
        ;; return value (calculated CRC)
-  [(set (match_operand:ANYI 0 "register_operand" "=r")
+  [(set (match_operand:ANYI 0 "register_operand")
                      ;; initial CRC
-       (unspec:ANYI [(match_operand:ANYI 1 "register_operand" "r")
+       (unspec:ANYI [(match_operand:ANYI 1 "register_operand")
                      ;; data
-                     (match_operand:ANYI1 2 "register_operand" "r")
+                     (match_operand:ANYI1 2 "register_operand")
                      ;; polynomial without leading 1
-                     (match_operand:ANYI 3)]
+                     (match_operand:ANYI 3 "const_int_operand")]
                      UNSPEC_CRC_REV))]
   /* We don't support the case when data's size is bigger than CRC's size.  */
   "<ANYI:MODE>mode >= <ANYI1:MODE>mode"
@@ -1258,13 +1258,13 @@ (define_expand "crc_rev<ANYI1:mode><ANYI:mode>4"
 ;; CRC 8, 16, (32 for TARGET_64)
 (define_expand "crc<SUBX1:mode><SUBX:mode>4"
        ;; return value (calculated CRC)
-  [(set (match_operand:SUBX 0 "register_operand" "=r")
+  [(set (match_operand:SUBX 0 "register_operand")
                      ;; initial CRC
-       (unspec:SUBX [(match_operand:SUBX 1 "register_operand" "r")
+       (unspec:SUBX [(match_operand:SUBX 1 "register_operand")
                      ;; data
-                     (match_operand:SUBX1 2 "register_operand" "r")
+                     (match_operand:SUBX1 2 "register_operand")
                      ;; polynomial without leading 1
-                     (match_operand:SUBX 3)]
+                     (match_operand:SUBX 3 "const_int_operand")]
                      UNSPEC_CRC))]
   /* We don't support the case when data's size is bigger than CRC's size.  */
   "(TARGET_ZBKC || TARGET_ZBC || TARGET_ZVBC)
diff --git a/gcc/testsuite/gcc.target/riscv/pr122106.c 
b/gcc/testsuite/gcc.target/riscv/pr122106.c
new file mode 100644
index 000000000000..b0345b029701
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr122106.c
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+
+short foo() { return __builtin_rev_crc16_data16(0, 0, 0); }

Reply via email to