The pattern mistakenly believes that fsflags can use immediate numbers,
but in fact it does not support it. Immediate numbers should use fsflagsi.
For example:
__builtin_riscv_fsflags(4);
The following error occurred.
/tmp/ccoWdWqT.s: Assembler messages:
/tmp/ccoWdWqT.s:14: Error: illegal operands `fsflags 4'
gcc/ChangeLog:
* config/riscv/riscv.md: Likewise.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/fsflags.c: New test.
"frcsr\t%0")
(define_insn "riscv_fscsr"
- [(unspec_volatile [(match_operand:SI 0 "csr_operand" "rK")] UNSPECV_FSCSR)]
+ [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_FSCSR)]
"TARGET_HARD_FLOAT || TARGET_ZFINX"
"fscsr\t%0")
(define_insn "riscv_fsflags"
[(unspec_volatile [(match_operand:SI 0 "csr_operand" "rK")] UNSPECV_FSFLAGS)]
"TARGET_HARD_FLOAT || TARGET_ZFINX"
- "fsflags\t%0")
+ "fsflags%i0\t%0")
(define_insn "*riscv_fsnvsnan<mode>2"
[(unspec_volatile [(match_operand:ANYF 0 "register_operand" "f")
--- /dev/null
+/* Verify that fsflags is using the correct register or immediate. */
+/* { dg-do compile } */
+/* { dg-require-effective-target hard_float } */
+/* { dg-options "-O" } */
+
+void foo1 (int a)
+{
+ __builtin_riscv_fsflags(a);
+}
+void foo2 ()
+{
+ __builtin_riscv_fsflags(4);
+}
+
+/* { dg-final { scan-assembler-times "fsflags\t" 1 } } */
+/* { dg-final { scan-assembler-times "fsflagsi\t" 1 } } */