diff options
author | Pan Li <pan2.li@intel.com> | 2023-03-07 20:05:15 +0800 |
---|---|---|
committer | Kito Cheng <kito.cheng@sifive.com> | 2023-03-07 21:35:20 +0800 |
commit | 247cacc9e381d666a492dfa4ed61b7b19e2d008f (patch) | |
tree | 7cf4d11ae0b5103c63322753fc07d3257f82965b /gcc/genmodes.cc | |
parent | 59a72acbccf4c81a04b4d09760fc8b16992de106 (diff) | |
download | gcc-247cacc9e381d666a492dfa4ed61b7b19e2d008f.zip gcc-247cacc9e381d666a492dfa4ed61b7b19e2d008f.tar.gz gcc-247cacc9e381d666a492dfa4ed61b7b19e2d008f.tar.bz2 |
RISC-V: Bugfix for rvv bool mode precision adjustment
Fix the bug of the rvv bool mode precision with the adjustment.
The bits size of vbool*_t will be adjusted to
[1, 2, 4, 8, 16, 32, 64] according to the rvv spec 1.0 isa. The
adjusted mode precison of vbool*_t will help underlying pass to
make the right decision for both the correctness and optimization.
Given below sample code:
void test_1(int8_t * restrict in, int8_t * restrict out)
{
vbool8_t v2 = *(vbool8_t*)in;
vbool16_t v5 = *(vbool16_t*)in;
*(vbool16_t*)(out + 200) = v5;
*(vbool8_t*)(out + 100) = v2;
}
Before the precision adjustment:
addi a4,a1,100
vsetvli a5,zero,e8,m1,ta,ma
addi a1,a1,200
vlm.v v24,0(a0)
vsm.v v24,0(a4)
// Need one vsetvli and vlm.v for correctness here.
vsm.v v24,0(a1)
After the precision adjustment:
csrr t0,vlenb
slli t1,t0,1
csrr a3,vlenb
sub sp,sp,t1
slli a4,a3,1
add a4,a4,sp
sub a3,a4,a3
vsetvli a5,zero,e8,m1,ta,ma
addi a2,a1,200
vlm.v v24,0(a0)
vsm.v v24,0(a3)
addi a1,a1,100
vsetvli a4,zero,e8,mf2,ta,ma
csrr t0,vlenb
vlm.v v25,0(a3)
vsm.v v25,0(a2)
slli t1,t0,1
vsetvli a5,zero,e8,m1,ta,ma
vsm.v v24,0(a1)
add sp,sp,t1
jr ra
However, there may be some optimization opportunates after
the mode precision adjustment. It can be token care of in
the RISC-V backend in the underlying separted PR(s).
gcc/ChangeLog:
PR target/108185
PR target/108654
* config/riscv/riscv-modes.def (ADJUST_PRECISION): Adjust VNx*BI
modes.
* config/riscv/riscv.cc (riscv_v_adjust_precision): New.
* config/riscv/riscv.h (riscv_v_adjust_precision): New.
* genmodes.cc (adj_precision): New.
(ADJUST_PRECISION): New.
(emit_mode_adjustments): Handle ADJUST_PRECISION.
gcc/testsuite/ChangeLog:
PR target/108185
PR target/108654
* gcc.target/riscv/rvv/base/pr108185-1.c: New test.
* gcc.target/riscv/rvv/base/pr108185-2.c: New test.
* gcc.target/riscv/rvv/base/pr108185-3.c: New test.
* gcc.target/riscv/rvv/base/pr108185-4.c: New test.
* gcc.target/riscv/rvv/base/pr108185-5.c: New test.
* gcc.target/riscv/rvv/base/pr108185-6.c: New test.
* gcc.target/riscv/rvv/base/pr108185-7.c: New test.
* gcc.target/riscv/rvv/base/pr108185-8.c: New test.
Signed-off-by: Pan Li <pan2.li@intel.com>
Co-authored-by: Ju-Zhe Zhong <juzhe.zhong@rivai.ai>
Diffstat (limited to 'gcc/genmodes.cc')
-rw-r--r-- | gcc/genmodes.cc | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/gcc/genmodes.cc b/gcc/genmodes.cc index 2d418f0..715787b 100644 --- a/gcc/genmodes.cc +++ b/gcc/genmodes.cc @@ -114,6 +114,7 @@ static struct mode_adjust *adj_alignment; static struct mode_adjust *adj_format; static struct mode_adjust *adj_ibit; static struct mode_adjust *adj_fbit; +static struct mode_adjust *adj_precision; /* Mode class operations. */ static enum mode_class @@ -819,6 +820,7 @@ make_vector_mode (enum mode_class bclass, #define ADJUST_NUNITS(M, X) _ADD_ADJUST (nunits, M, X, RANDOM, RANDOM) #define ADJUST_BYTESIZE(M, X) _ADD_ADJUST (bytesize, M, X, RANDOM, RANDOM) #define ADJUST_ALIGNMENT(M, X) _ADD_ADJUST (alignment, M, X, RANDOM, RANDOM) +#define ADJUST_PRECISION(M, X) _ADD_ADJUST (precision, M, X, RANDOM, RANDOM) #define ADJUST_FLOAT_FORMAT(M, X) _ADD_ADJUST (format, M, X, FLOAT, FLOAT) #define ADJUST_IBIT(M, X) _ADD_ADJUST (ibit, M, X, ACCUM, UACCUM) #define ADJUST_FBIT(M, X) _ADD_ADJUST (fbit, M, X, FRACT, UACCUM) @@ -1794,6 +1796,7 @@ emit_real_format_for_mode (void) static void emit_mode_adjustments (void) { + int c; struct mode_adjust *a; struct mode_data *m; @@ -1829,8 +1832,9 @@ emit_mode_adjustments (void) " (mode_precision[E_%smode], mode_nunits[E_%smode]);\n", m->name, m->name); printf (" mode_precision[E_%smode] = ps * old_factor;\n", m->name); - printf (" mode_size[E_%smode] = exact_div (mode_precision[E_%smode]," - " BITS_PER_UNIT);\n", m->name, m->name); + printf (" if (!multiple_p (mode_precision[E_%smode]," + " BITS_PER_UNIT, &mode_size[E_%smode]))\n", m->name, m->name); + printf (" mode_size[E_%smode] = -1;\n", m->name); printf (" mode_nunits[E_%smode] = ps;\n", m->name); printf (" adjust_mode_mask (E_%smode);\n", m->name); printf (" }\n"); @@ -1963,6 +1967,26 @@ emit_mode_adjustments (void) printf ("\n /* %s:%d */\n REAL_MODE_FORMAT (E_%smode) = %s;\n", a->file, a->line, a->mode->name, a->adjustment); + /* Adjust precision to the actual bits size. */ + for (a = adj_precision; a; a = a->next) + switch (a->mode->cl) + { + case MODE_VECTOR_BOOL: + printf ("\n /* %s:%d. */\n ps = %s;\n", a->file, a->line, + a->adjustment); + printf (" mode_precision[E_%smode] = ps;\n", a->mode->name); + break; + default: + internal_error ("invalid use of ADJUST_PRECISION for mode %s", + a->mode->name); + /* NOTREACHED. */ + } + + /* Ensure there is no mode size equals -1. */ + for_all_modes (c, m) + printf ("\n gcc_assert (maybe_ne (mode_size[E_%smode], -1));\n", + m->name); + puts ("}"); } |