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.

Reply via email to