We already have a use of "(reg:SI FRM_REGNUM)" within the pattern, is it not enough? I believe the answer is not enough so you propose this patch, so could you explain a few more about what happened?
(define_insn "@pred_single_widen_<plus_minus:optab><mode>_scalar" [(set (match_operand:VWEXTF 0 "register_operand" "=vd, vd, vr, vr") (if_then_else:VWEXTF (unspec:<VM> [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1,Wc1") (match_operand 5 "vector_length_operand" "rvl,rvl,rvl,rvl") (match_operand 6 "const_int_operand" " i, i, i, i") (match_operand 7 "const_int_operand" " i, i, i, i") (match_operand 8 "const_int_operand" " i, i, i, i") (match_operand 9 "const_int_operand" " i, i, i, i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM) (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE) <-------------here (plus_minus:VWEXTF (match_operand:VWEXTF 3 "register_operand" " vr, vr, vr, vr") (float_extend:VWEXTF (vec_duplicate:<V_DOUBLE_TRUNC> (match_operand:<VSUBEL> 4 "register_operand" " f, f, f, f")))) (match_operand:VWEXTF 2 "vector_merge_operand" " vu, 0, vu, 0")))] On Tue, Feb 18, 2025 at 7:14 PM Jin Ma <ji...@linux.alibaba.com> wrote: > > We overlooked the side effects of the rounding mode in the pattern, > which can impact the result of float_extend and lead to incorrect > optimizations in the final program. This issue likely affects nearly > all similar patterns that involve rounding modes, and the tests in > this patch only highlight one example. It seems challenging to address, > and I only implemented a simple fix, which is not a good way to solve > the problem. > > Any comments on this? > > gcc/ChangeLog: > > * config/riscv/vector-iterators.md (UNSPEC_VRM): New. > * config/riscv/vector.md: Use UNSPEC for float_extend. > > gcc/testsuite/ChangeLog: > > * gcc.target/riscv/rvv/base/bug-11.c: New test. > > Reported-by: CunJian Huang <huangcunjian.hu...@alibaba-inc.com> > Signed-off-by: Jin Ma <ji...@linux.alibaba.com> > --- > gcc/config/riscv/vector-iterators.md | 3 +++ > gcc/config/riscv/vector.md | 6 +++-- > .../gcc.target/riscv/rvv/base/bug-11.c | 24 +++++++++++++++++++ > 3 files changed, 31 insertions(+), 2 deletions(-) > create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/bug-11.c > > diff --git a/gcc/config/riscv/vector-iterators.md > b/gcc/config/riscv/vector-iterators.md > index c1bd7397441..bd592f736e2 100644 > --- a/gcc/config/riscv/vector-iterators.md > +++ b/gcc/config/riscv/vector-iterators.md > @@ -120,6 +120,9 @@ (define_c_enum "unspec" [ > > UNSPEC_SF_VFNRCLIP > UNSPEC_SF_VFNRCLIPU > + > + ;; Side effects of rounding mode > + UNSPEC_VRM > ]) > > (define_c_enum "unspecv" [ > diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md > index 8ee43cf0ce1..e971dcdc973 100644 > --- a/gcc/config/riscv/vector.md > +++ b/gcc/config/riscv/vector.md > @@ -7135,8 +7135,10 @@ (define_insn > "@pred_single_widen_<plus_minus:optab><mode>_scalar" > (plus_minus:VWEXTF > (match_operand:VWEXTF 3 "register_operand" " vr, vr, > vr, vr") > (float_extend:VWEXTF > - (vec_duplicate:<V_DOUBLE_TRUNC> > - (match_operand:<VSUBEL> 4 "register_operand" " f, f, > f, f")))) > + (unspec:VWEXTF > + [(vec_duplicate:<V_DOUBLE_TRUNC> > + (match_operand:<VSUBEL> 4 "register_operand" " f, f, > f, f")) > + (reg:SI FRM_REGNUM)] UNSPEC_VRM))) > (match_operand:VWEXTF 2 "vector_merge_operand" " vu, 0, > vu, 0")))] > "TARGET_VECTOR" > "vfw<insn>.wf\t%0,%3,%4%p1" > diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/bug-11.c > b/gcc/testsuite/gcc.target/riscv/rvv/base/bug-11.c > new file mode 100644 > index 00000000000..52d940cb57a > --- /dev/null > +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/bug-11.c > @@ -0,0 +1,24 @@ > +/* { dg-do run { target { riscv_v } } } */ > +/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64d -O2" } */ > + > +#include <riscv_vector.h> > + > +int main () > +{ > + float data_store = 0; > + int8_t mask = 1; > + size_t vl = 1; > + float data_load = 0.0; > + _Float16 data_sub = 0.0; > + vint8mf8_t mask_value = __riscv_vle8_v_i8mf8 (&mask, vl); > + vbool64_t vmask = __riscv_vmseq_vx_i8mf8_b64 (mask_value, 1, vl); > + vfloat32mf2_t vd_load = __riscv_vfmv_v_f_f32mf2 (0, > __riscv_vsetvlmax_e32mf2 ()); > + vfloat32mf2_t vreg_memory = __riscv_vle32_v_f32mf2_tu (vd_load, > &data_load, vl); > + vfloat32mf2_t vreg = __riscv_vfwsub_wf_f32mf2_rm_tum (vmask, vreg_memory, > vreg_memory, data_sub, __RISCV_FRM_RDN, vl); > + __riscv_vse32_v_f32mf2 (&data_store, vreg, vl); > + > + __builtin_printf ("%f\n", data_store); > + return 0; > +} > + > +/* { dg-output "-0.000000\\s+\n" } */ > -- > 2.25.1 >