https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110748
--- Comment #3 from Vineet Gupta <vineetg at gcc dot gnu.org> --- Indeed the constraint already exists (define_insn "*movdf_hardfloat_rv64" [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*r, *r,*r,*m") ^^ (match_operand:DF 1 "move_operand" " f,G,m,f,G,*r,*f,*r*G,*m,*r") ^^ )] At expand time: gen_movdf() -> riscv_legitimize_move forces a reg, as reg_or_0_operand () returns false. Breakpoint 7, riscv_legitimize_move (mode=E_DFmode, dest=0x7ffff6db9af8, src=0x7ffff6c0c050) at ../../gcc/gcc/config/riscv/riscv.cc:2162 2162 { (gdb) call debug_rtx(dest) (mem:DF (reg/v/f:DI 134 [ d ]) [1 *d_2(D)+0 S8 A64]) (gdb) call debug_rtx(src) (const_double:DF 0.0 [0x0.0p+0]) 2232 if (!register_operand (dest, mode) && !reg_or_0_operand (src, mode)) (gdb) n 2257 reg = force_reg (mode, src); (gdb) 2258 riscv_emit_move (dest, reg); (gdb) 2259 return true; While for int 0, reg_or_0_operand returns true.