https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118182

--- Comment #3 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Kito Cheng <k...@gcc.gnu.org>:

https://gcc.gnu.org/g:40ad10f708b19d3e88948ac820fbfb9f3c3689ae

commit r15-6906-g40ad10f708b19d3e88948ac820fbfb9f3c3689ae
Author: Kito Cheng <kito.ch...@sifive.com>
Date:   Mon Dec 23 23:23:44 2024 +0800

    RISC-V: Fix code gen for reduction with length 0 [PR118182]

    `.MASK_LEN_FOLD_LEFT_PLUS`(or `mask_len_fold_left_plus_m`) is expecting the
    return value will be the start value even if the length is 0.

    However current code gen in RISC-V backend is not meet that semantic, it
will
    result a random garbage value if length is 0.

    Let example by current code gen for MASK_LEN_FOLD_LEFT_PLUS with f64:
            # _148 = .MASK_LEN_FOLD_LEFT_PLUS (stmp__148.33_134,
vect__70.32_138, { -1, ... }, loop_len_161, 0);
            vsetvli zero,a5,e64,m1,ta,ma
            vfmv.s.f        v2,fa5     # insn 1
            vfredosum.vs    v1,v1,v2   # insn 2
            vfmv.f.s        fa5,v1     # insn 3

    insn 1:
    - vfmv.s.f won't do anything if VL=0, which means v2 will contain garbage
value.
    insn 2:
    - vfredosum.vs won't do anything if VL=0, and keep vd unchanged even TA.
    (v-spec say: `If vl=0, no operation is performed and the destination
register
     is not updated.`)
    insn 3:
    - vfmv.f.s will move the value from v1 even VL=0, so this is safe.

    So how we fix that? we need two fix for that:

    1. insn 1: need always execute with VL=1, so that we can guarantee it will
               always work as expect.
    2. insn 2: Add new pattern to force `vd` use same reg as `vs1` (start
value) for
               all reduction patterns, then we can guarantee vd[0] will contain
the
               start value when vl=0

    For 1, it's just a simple change to riscv_vector::expand_reduction, but for
2,
    we have to add _VL0_SAFE variant reduction to force `vd` use same reg as
`vs1`
    (start value).

    Change since V3:
    - Rename _AV to _VL0_SAFE for readability.
    - Use non-VL0_SAFE version if VL is const or VLMAX.
    - Only force VL=1 for vfmv.s.f when VL is non-const and non-VLMAX.
    - Two more testcase.

    gcc/ChangeLog:

            PR target/118182
            * config/riscv/autovec-opt.md (*widen_reduc_plus_scal_<mode>):
Adjust
            argument for expand_reduction.
            (*widen_reduc_plus_scal_<mode>): Ditto.
            (*fold_left_widen_plus_<mode>): Ditto.
            (*mask_len_fold_left_widen_plus_<mode>): Ditto.
            (*cond_widen_reduc_plus_scal_<mode>): Ditto.
            (*cond_len_widen_reduc_plus_scal_<mode>): Ditto.
            (*cond_widen_reduc_plus_scal_<mode>): Ditto.
            * config/riscv/autovec.md (reduc_plus_scal_<mode>): Adjust argument
for
            expand_reduction.
            (reduc_smax_scal_<mode>): Ditto.
            (reduc_umax_scal_<mode>): Ditto.
            (reduc_smin_scal_<mode>): Ditto.
            (reduc_umin_scal_<mode>): Ditto.
            (reduc_and_scal_<mode>): Ditto.
            (reduc_ior_scal_<mode>): Ditto.
            (reduc_xor_scal_<mode>): Ditto.
            (reduc_plus_scal_<mode>): Ditto.
            (reduc_smax_scal_<mode>): Ditto.
            (reduc_smin_scal_<mode>): Ditto.
            (reduc_fmax_scal_<mode>): Ditto.
            (reduc_fmin_scal_<mode>): Ditto.
            (fold_left_plus_<mode>): Ditto.
            (mask_len_fold_left_plus_<mode>): Ditto.
            * config/riscv/riscv-v.cc (expand_reduction): Add one more
            argument for reduction code for vl0-safe.
            * config/riscv/riscv-protos.h (expand_reduction): Ditto.
            * config/riscv/vector-iterators.md (unspec): Add _VL0_SAFE variant
of
            reduction.
            (ANY_REDUC_VL0_SAFE): New.
            (ANY_WREDUC_VL0_SAFE): Ditto.
            (ANY_FREDUC_VL0_SAFE): Ditto.
            (ANY_FREDUC_SUM_VL0_SAFE): Ditto.
            (ANY_FWREDUC_SUM_VL0_SAFE): Ditto.
            (reduc_op): Add _VL0_SAFE variant of reduction.
            (order) Ditto.
            * config/riscv/vector.md (@pred_<reduc_op><mode>): New.

    gcc/testsuite/ChangeLog:

            PR target/118182
            * gfortran.target/riscv/rvv/pr118182.f: New.
            * gcc.target/riscv/rvv/autovec/pr118182-1.c: New.
            * gcc.target/riscv/rvv/autovec/pr118182-2.c: New.

Reply via email to