Skip to content

Commit 5590018

Browse files
RISC-V: Fix one bug for floating-point static frm
This patch would like to fix one bug to align below items of spec. RVV floating-point instructions always (implicitly) use the dynamic rounding mode. This implies that rounding is performed according to the rounding mode set in the FRM register. The FRM register itself only holds proper rounding modes and never the dynamic rounding mode. Signed-off-by: Pan Li <[email protected]> Co-Authored-By: Robin Dapp <[email protected]> gcc/ChangeLog: * config/riscv/riscv.cc (riscv_emit_mode_set): Avoid emit insn when FRM_MODE_DYN. (riscv_mode_entry): Take FRM_MODE_DYN as entry mode. (riscv_mode_exit): Likewise for exit mode. (riscv_mode_needed): Likewise for needed mode. (riscv_mode_after): Likewise for after mode. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/base/float-point-frm-insert-6.c: New test.
1 parent f58819c commit 5590018

File tree

2 files changed

+53
-5
lines changed

2 files changed

+53
-5
lines changed

gcc/config/riscv/riscv.cc

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7670,8 +7670,19 @@ riscv_emit_mode_set (int entity, int mode, int prev_mode,
76707670
emit_insn (gen_vxrmsi (gen_int_mode (mode, SImode)));
76717671
break;
76727672
case RISCV_FRM:
7673-
if (mode != FRM_MODE_NONE && mode != prev_mode)
7673+
/* Switching to the dynamic rounding mode is not necessary. When an
7674+
instruction requests it, it effectively uses the rounding mode already
7675+
set in the FRM register. All other rounding modes require us to
7676+
switch the rounding mode via the FRM register. */
7677+
if (mode != FRM_MODE_DYN && mode != prev_mode)
76747678
{
7679+
/* TODO: By design, FRM_MODE_xxx used by mode switch which is
7680+
different from the FRM value like FRM_RTZ defined in
7681+
riscv-protos.h. When mode switching we actually need a conversion
7682+
function to convert the mode of mode switching to the actual
7683+
FRM value like FRM_RTZ. For now, the value between the mode of
7684+
mode swith and the FRM value in riscv-protos.h take the same value,
7685+
and then we leverage this assumption when emit. */
76757686
rtx scaler = gen_reg_rtx (SImode);
76767687
rtx imm = gen_int_mode (mode, SImode);
76777688

@@ -7697,7 +7708,10 @@ riscv_mode_needed (int entity, rtx_insn *insn)
76977708
case RISCV_VXRM:
76987709
return code >= 0 ? get_attr_vxrm_mode (insn) : VXRM_MODE_NONE;
76997710
case RISCV_FRM:
7700-
return code >= 0 ? get_attr_frm_mode (insn) : FRM_MODE_NONE;
7711+
/* TODO: Here we may return FRM_MODE_NONE from get_attr_frm_mode, as well
7712+
as FRM_MODE_DYN as default. It is kind of inconsistent and we will
7713+
take care of it after dynamic rounding mode. */
7714+
return code >= 0 ? get_attr_frm_mode (insn) : FRM_MODE_DYN;
77017715
default:
77027716
gcc_unreachable ();
77037717
}
@@ -7757,7 +7771,7 @@ riscv_mode_after (int entity, int mode, rtx_insn *insn)
77577771
case RISCV_FRM:
77587772
return riscv_entity_mode_after (FRM_REGNUM, insn, mode,
77597773
(int (*)(rtx_insn *)) get_attr_frm_mode,
7760-
FRM_MODE_NONE);
7774+
FRM_MODE_DYN);
77617775
default:
77627776
gcc_unreachable ();
77637777
}
@@ -7774,7 +7788,10 @@ riscv_mode_entry (int entity)
77747788
case RISCV_VXRM:
77757789
return VXRM_MODE_NONE;
77767790
case RISCV_FRM:
7777-
return FRM_MODE_NONE;
7791+
/* According to RVV 1.0 spec, all vector floating-point operations use
7792+
the dynamic rounding mode in the frm register. Likewise in other
7793+
similar places. */
7794+
return FRM_MODE_DYN;
77787795
default:
77797796
gcc_unreachable ();
77807797
}
@@ -7791,7 +7808,7 @@ riscv_mode_exit (int entity)
77917808
case RISCV_VXRM:
77927809
return VXRM_MODE_NONE;
77937810
case RISCV_FRM:
7794-
return FRM_MODE_NONE;
7811+
return FRM_MODE_DYN;
77957812
default:
77967813
gcc_unreachable ();
77977814
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/* { dg-do compile } */
2+
/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */
3+
4+
#include "riscv_vector.h"
5+
6+
typedef float float32_t;
7+
8+
vfloat32m1_t
9+
test_riscv_vfadd_vv_f32m1_rm (vfloat32m1_t op1, vfloat32m1_t op2, size_t vl) {
10+
return __riscv_vfadd_vv_f32m1_rm (op1, op2, 7, vl);
11+
}
12+
13+
vfloat32m1_t
14+
test_vfadd_vv_f32m1_m_rm(vbool32_t mask, vfloat32m1_t op1, vfloat32m1_t op2,
15+
size_t vl) {
16+
return __riscv_vfadd_vv_f32m1_m_rm(mask, op1, op2, 7, vl);
17+
}
18+
19+
vfloat32m1_t
20+
test_vfadd_vf_f32m1_rm(vfloat32m1_t op1, float32_t op2, size_t vl) {
21+
return __riscv_vfadd_vf_f32m1_rm(op1, op2, 7, vl);
22+
}
23+
24+
vfloat32m1_t
25+
test_vfadd_vf_f32m1_m_rm(vbool32_t mask, vfloat32m1_t op1, float32_t op2,
26+
size_t vl) {
27+
return __riscv_vfadd_vf_f32m1_m_rm(mask, op1, op2, 7, vl);
28+
}
29+
30+
/* { dg-final { scan-assembler-times {vfadd\.v[vf]\s+v[0-9]+,\s*v[0-9]+,\s*[fav]+[0-9]+} 4 } } */
31+
/* { dg-final { scan-assembler-not {fsrm\s+[ax][0-9]+,\s*[ax][0-9]+} } } */

0 commit comments

Comments
 (0)