RISC-V: Suppress the vsetvl fusion for conflict successors
Update in v2: Add dump information. This patch fixes the following ineffective vsetvl insertion: void f (int32_t * restrict in, int32_t * restrict out, size_t n, size_t cond, size_t cond2) { for (size_t i = 0; i < n; i++) { if (i == cond) { vint8mf8_t v = *(vint8mf8_t*)(in + i + 100); *(vint8mf8_t*)(out + i + 100) = v; } else if (i == cond2) { vfloat32mf2_t v = *(vfloat32mf2_t*)(in + i + 200); *(vfloat32mf2_t*)(out + i + 200) = v; } else if (i == (cond2 - 1)) { vuint16mf2_t v = *(vuint16mf2_t*)(in + i + 300); *(vuint16mf2_t*)(out + i + 300) = v; } else { vint8mf4_t v = *(vint8mf4_t*)(in + i + 400); *(vint8mf4_t*)(out + i + 400) = v; } } } Before this patch: f: .LFB0: .cfi_startproc beq a2,zero,.L12 addi a7,a0,400 addi a6,a1,400 addi a0,a0,1600 addi a1,a1,1600 li a5,0 addi t6,a4,-1 vsetvli t3,zero,e8,mf8,ta,ma ---> ineffective uplift .L7: beq a3,a5,.L15 beq a4,a5,.L16 beq t6,a5,.L17 vsetvli t1,zero,e8,mf4,ta,ma vle8.v v1,0(a0) vse8.v v1,0(a1) vsetvli t3,zero,e8,mf8,ta,ma .L4: addi a5,a5,1 addi a7,a7,4 addi a6,a6,4 addi a0,a0,4 addi a1,a1,4 bne a2,a5,.L7 .L12: ret .L15: vle8.v v1,0(a7) vse8.v v1,0(a6) j .L4 .L17: vsetvli t1,zero,e8,mf4,ta,ma addi t5,a0,-400 addi t4,a1,-400 vle16.v v1,0(t5) vse16.v v1,0(t4) vsetvli t3,zero,e8,mf8,ta,ma j .L4 .L16: addi t5,a0,-800 addi t4,a1,-800 vle32.v v1,0(t5) vse32.v v1,0(t4) j .L4 It's obvious that we are hoisting the e8mf8 vsetvl to the top. It's ineffective since e8mf8 comes from low probability block which is if (i == cond). For this case, we disable such fusion. After this patch: f: beq a2,zero,.L12 addi a7,a0,400 addi a6,a1,400 addi a0,a0,1600 addi a1,a1,1600 li a5,0 addi t6,a4,-1 .L7: beq a3,a5,.L15 beq a4,a5,.L16 beq t6,a5,.L17 vsetvli t1,zero,e8,mf4,ta,ma vle8.v v1,0(a0) vse8.v v1,0(a1) .L4: addi a5,a5,1 addi a7,a7,4 addi a6,a6,4 addi a0,a0,4 addi a1,a1,4 bne a2,a5,.L7 .L12: ret .L15: vsetvli t3,zero,e8,mf8,ta,ma vle8.v v1,0(a7) vse8.v v1,0(a6) j .L4 .L17: addi t5,a0,-400 addi t4,a1,-400 vsetvli t1,zero,e8,mf4,ta,ma vle16.v v1,0(t5) vse16.v v1,0(t4) j .L4 .L16: addi t5,a0,-800 addi t4,a1,-800 vsetvli t3,zero,e32,mf2,ta,ma vle32.v v1,0(t5) vse32.v v1,0(t4) j .L4 Tested on both RV32/RV64 no regression. Ok for trunk ? PR target/113696 gcc/ChangeLog: * config/riscv/riscv-vsetvl.cc (pre_vsetvl::earliest_fuse_vsetvl_info): Suppress vsetvl fusion. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/vsetvl/pr113696.c: New test.
This commit is contained in:
parent
e42287eaed
commit
6082024891
2 changed files with 51 additions and 0 deletions
|
@ -3001,6 +3001,31 @@ pre_vsetvl::earliest_fuse_vsetvl_info (int iter)
|
|||
src_block_info.set_empty_info ();
|
||||
src_block_info.probability
|
||||
= profile_probability::uninitialized ();
|
||||
/* See PR113696, we should reset immediate dominator to
|
||||
empty since we may uplift ineffective vsetvl which
|
||||
locate at low probability block. */
|
||||
basic_block dom
|
||||
= get_immediate_dominator (CDI_DOMINATORS, eg->src);
|
||||
auto &dom_block_info = get_block_info (dom);
|
||||
if (dom_block_info.has_info ()
|
||||
&& !m_dem.compatible_p (
|
||||
dom_block_info.get_exit_info (), curr_info))
|
||||
{
|
||||
dom_block_info.set_empty_info ();
|
||||
dom_block_info.probability
|
||||
= profile_probability::uninitialized ();
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
{
|
||||
fprintf (dump_file,
|
||||
" Reset dominator bb %u:",
|
||||
dom->index);
|
||||
prev_info.dump (dump_file, " ");
|
||||
fprintf (dump_file,
|
||||
" due to (same probability or no "
|
||||
"compatible reaching):");
|
||||
curr_info.dump (dump_file, " ");
|
||||
}
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
/* Choose the one with higher probability. */
|
||||
|
|
26
gcc/testsuite/gcc.target/riscv/rvv/vsetvl/pr113696.c
Normal file
26
gcc/testsuite/gcc.target/riscv/rvv/vsetvl/pr113696.c
Normal file
|
@ -0,0 +1,26 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "--param=riscv-autovec-preference=scalable -march=rv64gcv -mabi=lp64d -O3" } */
|
||||
|
||||
#include "riscv_vector.h"
|
||||
|
||||
void f (int32_t * restrict in, int32_t * restrict out, size_t n, size_t cond, size_t cond2)
|
||||
{
|
||||
for (size_t i = 0; i < n; i++)
|
||||
{
|
||||
if (i == cond) {
|
||||
vint8mf8_t v = *(vint8mf8_t*)(in + i + 100);
|
||||
*(vint8mf8_t*)(out + i + 100) = v;
|
||||
} else if (i == cond2) {
|
||||
vfloat32mf2_t v = *(vfloat32mf2_t*)(in + i + 200);
|
||||
*(vfloat32mf2_t*)(out + i + 200) = v;
|
||||
} else if (i == (cond2 - 1)) {
|
||||
vuint16mf2_t v = *(vuint16mf2_t*)(in + i + 300);
|
||||
*(vuint16mf2_t*)(out + i + 300) = v;
|
||||
} else {
|
||||
vint8mf4_t v = *(vint8mf4_t*)(in + i + 400);
|
||||
*(vint8mf4_t*)(out + i + 400) = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler-times {vsetvli} 4 { target { no-opts "-O0" no-opts "-Os" no-opts "-Oz" no-opts "-funroll-loops" no-opts "-g" } } } } */
|
Loading…
Add table
Reference in a new issue