On 10/2/24 6:27 AM, Dusan Stojkovic wrote:
This patch is a new version of:
https://gcc.gnu.org/pipermail/gcc-patches/2024-September/662745.html <https://gcc.gnu.org/pipermail/gcc-patches/2024-September/662745.html>

 > Can you elaborate a bit on that?  Rearranging the CFG shouldn't matter
 > in general and relying on the specific TARGET_SFB_ALU feels overly
 > specific.
 > Why does the same register in the if_then_else and interfere with vsetvl?

When ce1 pass transforms CFG in the case of the conditional move, it deletes
then and else basic blocks and in their place adds the conditional move which
uses the same pseudo-register as the original vsetvl.

This interferes with vsetvl pass precisely because of the merge policy. Use by non rvv flag limits the cases where merging might still be possible. This patch
tries to addresses one such issue.

Agreed. I have removed TARGET_SFB_ALU flag from the condition.

 > BTW Bohan Lei has since fixed a bug regarding non-RVV uses.  Does the
 > situation change with that applied?

Repeated the testing for sifive-7-series as well as rocket. The same tests are still effected positively: vsetvlmax-9, vsetvlmax-10, vsetvlmax-11, vsetvlmax-15
on sifive-7-series.

2024-10-2  Dusan Stojkovic  <dusan.stojko...@rt-rk.com>

         PR target/113035

gcc/ChangeLog:

        * config/riscv/riscv-vsetvl.cc (pre_vsetvl::earliest_fuse_vsetvl_info):
           New fuse condition.

gcc/testsuite/ChangeLog:

         * gcc.target/riscv/rvv/vsetvl/vsetvlmax-15.c: Updated
           scan-assembler-times num parameter.
So I spent a few minutes looking at the dumps here.

So to give a little more detail on Dusan's note about how the ce1 pass changes things with/without the sifive tuning flag...

Normally we have this sequence:
(insn # # # 2 (set (reg/v:SI 135 [ vl ])
        (const_int 55 [0x37])) "j.c":12:8# {*movsi_internal}
     (nil))
(jump_insn # # # 2 (set (pc)
        (if_then_else (eq (reg/v:SI 145 [ cond ])
                (const_int 0 [0]))
            (label_ref:SI #)
            (pc))) "j.c":9:6# {*branchsi}
     (expr_list:REG_DEAD (reg/v:SI 145 [ cond ])
        (int_list:REG_BR_PROB 536870916 (nil)))
 -> 17)
(note # # # 3 [bb 3] NOTE_INSN_BASIC_BLOCK)
(insn # # # 3 (set (reg/v:SI 135 [ vl ])
        (unspec:SI [
                (reg/v:SI 146 [ avl ])
                (const_int 8 [0x8])
                (const_int 6 [0x6])
                (const_int 2 [0x2]) repeated x2
            ] UNSPEC_VSETVL)) "j.c":10:10# {vsetvlsi_no_side_effects}
     (expr_list:REG_DEAD (reg/v:SI 146 [ avl ])
        (nil)))


(insn # # # 3 (set (reg/v:SI 135 [ vl ])
(unspec:SI [ (reg/v:SI 146 [ avl ])
                (const_int 8 [0x8])
                (const_int 6 [0x6])
                (const_int 2 [0x2]) repeated x2
            ] UNSPEC_VSETVL)) "j.c":10:10# {vsetvlsi_no_side_effects}
     (expr_list:REG_DEAD (reg/v:SI 146 [ avl ])
(nil)))

(reg 135) is only subsequently used by vector instructions.

When tuning for sifive we if-convert that sequence generating:

(insn # # # 2 (set (reg:SI 148)
        (const_int 55 [0x37])) "j.c":10:10# {*movsi_internal}
(nil)) (insn # # # 2 (set (reg:SI 147)
        (unspec:SI [
                (reg/v:SI 146 [ avl ])
                (const_int 8 [0x8])
                (const_int 6 [0x6])
                (const_int 2 [0x2]) repeated x2
            ] UNSPEC_VSETVL)) "j.c":10:10# {vsetvlsi_no_side_effects}
     (nil))
(insn # # # 2 (set (reg/v:SI 135 [ vl ])
        (if_then_else:SI (ne (reg/v:SI 145 [ cond ])
                (const_int 0 [0]))
            (reg:SI 147)
            (reg:SI 148))) "j.c":10:10# {*movsisicc}
(nil))
Note how the output of the vsetvl (reg:SI 147) is used by the non-vector conditional move. That in turn changes the behavior of the vsetvl pass (see how vl_used_by_non_rvv_insn_p is used).

Still investigating, but at least that part of my question has been answered.

jeff

Reply via email to