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

Reply via email to