Yeah I didn't know how to articulate it (and perhaps this still requires
clarification)
Say we have following
// reduced version of gcc.target/riscv/rvv/base/float-point-frm-run-1.c
main
set_frm (4); // orig global FRM update
test_float_point_frm_run_1 (op1, op2, vl)
set_frm (0);
result = __riscv_vfadd_vv_f32m1_rm (op1, result, 1, vl);
assert_equal (1, get_frm ())
// restore global 4 before returning
assert_equal (4, get_frm () <-- here call restores global
vs.
// reduced version of gcc.target/riscv/rvv/base/float-point-frm-run-5.c
main
set_frm (1); // orig global FRM update
test_float_point_frm_run_1 (op1, op2, vl)
other_function()
set_frm (2); // also global update
assert_equal (2, get_frm () <-- here call doesn't restore
There's no explicit annotation or anything about the FRM, yet in 2nd example
other_function () we consider frm write a global event but not in
test_float_point_frm_run_1 () in 1st example: I'm missing words how to explain
that :-)
AFAIR the general idea is that every function can potentially "clobber", i.e.
set FRM globally.
The intent of the first test is to save and restore the global rounding mode
because we modify it locally by a rounding-mode changing intrinsic.
However, as you note, the set_frm at the beginning of
test_float_point_frm_run_1 has no effect. What should intuitively(?) happen is
that it sets a new global FRM that we restore upon exit. We, however, restore
the previous global FRM. I believe that's because set_frm is an inline
assembly, inlined into test_float_point_frm_run_1 and we expect inline
assemblies to _not_ change the rounding mode. That was one of my concerns
during the review some time in 2023. If set_frm were a non-inlined function
we'd need to assume it changes the rounding mode and restore the value it has
after the set_frm call.
And that's also what is different in frm-run-5.c (your second snippet). We
wrap the set_frm call in another non-inlinable call. Thus, we need to assume
the global rounding mode changes and save/restore.
I guess it was a deliberate decision to handle asm snippets different. At
least as long as they are in the same visible scope it's obvious when they're
changing the rounding mode. One could argue that users doing that are on their
own. Not sure that argument has worked very well, historically, though ;)
--
Regards
Robin