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); }