https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120404
Bug ID: 120404 Summary: RISC-V: inline asm FRM write ignored by FRM save/restore machinery Product: gcc Version: 15.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: vineetg at gcc dot gnu.org Reporter: vineetg at gcc dot gnu.org CC: jeffreyalaw at gmail dot com, pan2.li at intel dot com, rdapp at gcc dot gnu.org Target Milestone: --- This is extracted from gcc/testsuite/gcc.target/riscv/rvv/base/float-point-frm-run-1.c which passes but I think is wrong. static void set_frm (int frm) { __asm__ volatile ( "fsrm %0" : :"r"(frm) : "frm"); } main set_frm (4); test_float_point_frm_run_1 (op1, op2, vl); assert_equal (4, get_frm (), "Outer: frm should be equal"); # prints 4 != 0 vfloat32m1_t __attribute__ ((noinline)) test_float_point_frm_run_1 (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl) { vfloat32m1_t result; # upon entry global frm is 4 set_frm (0); # global frm set to 0 result = __riscv_vfadd_vv_f32m1_rm (op1, result, 1, vl); # local clobber 1 assert_equal (1, get_frm (), "Inner: frm should be equal"); return result; # expected to restore frm 4 } the save/restore in function ignores the inline asm setting it to 0. inline asm is the only way global frm state is set in RISC-V, so it being ignored for the "prev" global seems weird. I believe this happened because of current implementation (gcc 15 release) which generates an unconditional early/eager FRM save on function entry which captured the global state at the start and not when really needed. My FRM removes the early/eager save and hence fails this test. Per discussions with Robin this behaviour is 1. Wrong 2. Implementation driven thus needs to be changed.