diff options
author | Juzhe-Zhong <juzhe.zhong@rivai.ai> | 2024-02-01 17:02:52 +0800 |
---|---|---|
committer | Pan Li <pan2.li@intel.com> | 2024-02-19 16:19:41 +0800 |
commit | 6082024891e421bfd81d8f708a7411f4019d0d97 (patch) | |
tree | f84e48eeadaedf211cea62ce731b8cceae33e2e6 | |
parent | e42287eaed2c93f19f986c191607cec0011d84bd (diff) | |
download | gcc-6082024891e421bfd81d8f708a7411f4019d0d97.zip gcc-6082024891e421bfd81d8f708a7411f4019d0d97.tar.gz gcc-6082024891e421bfd81d8f708a7411f4019d0d97.tar.bz2 |
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.
-rw-r--r-- | gcc/config/riscv/riscv-vsetvl.cc | 25 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/rvv/vsetvl/pr113696.c | 26 |
2 files changed, 51 insertions, 0 deletions
diff --git a/gcc/config/riscv/riscv-vsetvl.cc b/gcc/config/riscv/riscv-vsetvl.cc index 32f262d..48ce757 100644 --- a/gcc/config/riscv/riscv-vsetvl.cc +++ b/gcc/config/riscv/riscv-vsetvl.cc @@ -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. */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/pr113696.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/pr113696.c new file mode 100644 index 0000000..5d7c5f5 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/pr113696.c @@ -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" } } } } */ |