mirror of
https://github.com/gcc-mirror/gcc.git
synced 2024-11-21 13:40:47 +00:00
RISC-V: Optimize SELECT_VL codegen when length is known as smaller than VF
While trying to fix bugs of PR113097, notice this following situation we generate redundant vsetvli _255 = SELECT_VL (3, POLY_INT_CST [4, 4]); COND_LEN (..., _255) Before this patch: vsetivli a5, 3... ... vadd.vv (use a5) After this patch: ... vadd.vv (use AVL = 3) The reason we can do this is because known_ge (3, [4,4]) is true. It's safe to apply such optimization Tested on both RV32 and RV64 full coverage testing, no regression. PR target/113087 gcc/ChangeLog: * config/riscv/riscv-v.cc (expand_select_vl): Optimize SELECT_VL. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/pr113087-2.c: New test.
This commit is contained in:
parent
d82bb518fa
commit
008b80e42e
@ -3750,6 +3750,16 @@ void
|
|||||||
expand_select_vl (rtx *ops)
|
expand_select_vl (rtx *ops)
|
||||||
{
|
{
|
||||||
poly_int64 nunits = rtx_to_poly_int64 (ops[2]);
|
poly_int64 nunits = rtx_to_poly_int64 (ops[2]);
|
||||||
|
if (CONST_INT_P (ops[1]) && known_le (INTVAL (ops[1]), nunits))
|
||||||
|
{
|
||||||
|
/* If length is known <= VF, we just use the length directly instead
|
||||||
|
of using vsetvli.
|
||||||
|
|
||||||
|
E.g. _255 = .SELECT_VL (3, POLY_INT_CST [4, 4]);
|
||||||
|
We move 3 into _255 intead of using explicit vsetvl. */
|
||||||
|
emit_move_insn (ops[0], ops[1]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
/* We arbitrary picked QImode as inner scalar mode to get vector mode.
|
/* We arbitrary picked QImode as inner scalar mode to get vector mode.
|
||||||
since vsetvl only demand ratio. We let VSETVL PASS to optimize it. */
|
since vsetvl only demand ratio. We let VSETVL PASS to optimize it. */
|
||||||
scalar_int_mode mode = QImode;
|
scalar_int_mode mode = QImode;
|
||||||
|
61
gcc/testsuite/gcc.target/riscv/rvv/autovec/pr113087-2.c
Normal file
61
gcc/testsuite/gcc.target/riscv/rvv/autovec/pr113087-2.c
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/* { dg-do compile } */
|
||||||
|
/* { dg-options "-march=rv64gcv -mabi=lp64d -O3" } */
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
int (e) (int g, int h) { return h > 0x10 || g > 0xFFFFFFFF >> h ? g : g << h; }
|
||||||
|
struct i
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
int l : 1;
|
||||||
|
};
|
||||||
|
struct m
|
||||||
|
{
|
||||||
|
char k;
|
||||||
|
int n;
|
||||||
|
};
|
||||||
|
char o;
|
||||||
|
char p;
|
||||||
|
short s;
|
||||||
|
int q;
|
||||||
|
struct m r;
|
||||||
|
int v;
|
||||||
|
int t;
|
||||||
|
short z;
|
||||||
|
long ac;
|
||||||
|
int ad;
|
||||||
|
int ae;
|
||||||
|
|
||||||
|
static void
|
||||||
|
ai (struct i bf)
|
||||||
|
{
|
||||||
|
for (; v; v++)
|
||||||
|
r.k = 0;
|
||||||
|
do
|
||||||
|
ac ^= bf.j;
|
||||||
|
while (bf.j < 0);
|
||||||
|
s = 0;
|
||||||
|
if (bf.l)
|
||||||
|
q |= 0x800;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
struct i aw = {0xE00, 1};
|
||||||
|
o = 4;
|
||||||
|
s = p;
|
||||||
|
ai (aw);
|
||||||
|
t = 1;
|
||||||
|
++p;
|
||||||
|
for (; t <= 7; t++)
|
||||||
|
{
|
||||||
|
ad &= 1;
|
||||||
|
(o &= 1 - e (0x40000012, ++ae)) & (z |= 1);
|
||||||
|
}
|
||||||
|
for (; r.n;)
|
||||||
|
;
|
||||||
|
assert (o == 4);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* { dg-final { scan-assembler-not {vsetivli\s+[a-x0-9]+,\s*3} } } */
|
Loading…
Reference in New Issue
Block a user