aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJuzhe-Zhong <juzhe.zhong@rivai.ai>2023-12-11 19:58:43 +0800
committerLehua Ding <lehua.ding@rivai.ai>2023-12-11 20:13:44 +0800
commit4db744149b6ed46314107187bb25e142c729f442 (patch)
tree910af8defcb7f598d040f472ff93881d45429b51 /gcc
parent61f5b64ae6481e4adb69d007bd1112987bde67ce (diff)
downloadgcc-4db744149b6ed46314107187bb25e142c729f442.zip
gcc-4db744149b6ed46314107187bb25e142c729f442.tar.gz
gcc-4db744149b6ed46314107187bb25e142c729f442.tar.bz2
RISC-V: Robostify shuffle index used by vrgather and fix regression
Notice there are some regression FAILs: FAIL: gcc.target/riscv/rvv/autovec/pr110950.c -O3 -ftree-vectorize scan-assembler-times vslide1up\\.vx 1 FAIL: gcc.target/riscv/rvv/autovec/vls-vlmax/perm-4.c -std=c99 -O3 -ftree-vectorize --param riscv-autovec-preference=fixed-vlmax scan-assembler-times vrgather\\.vv\\tv[0-9]+,\\s*v[0-9]+,\\s*v[0-9]+ 19 FAIL: gcc.target/riscv/rvv/autovec/vls-vlmax/perm-4.c -std=c99 -O3 -ftree-vectorize --param riscv-autovec-preference=fixed-vlmax scan-assembler-times vrgatherei16\\.vv\\tv[0-9]+,\\s*v[0-9]+,\\s*v[0-9]+ 12 FAIL: gcc.target/riscv/rvv/autovec/vls/perm-4.c -O3 -ftree-vectorize --param riscv-autovec-preference=scalable scan-assembler-times vrgather\\.vv\\tv[0-9]+,\\s*v[0-9]+,\\s*v[0-9]+ 19 FAIL: gcc.target/riscv/rvv/autovec/vls/perm-4.c -O3 -ftree-vectorize --param riscv-autovec-preference=scalable scan-assembler-times vrgatherei16\\.vv\\tv[0-9]+,\\s*v[0-9]+,\\s*v[0-9]+ 12 pr110950 is not a regression, adapt testcase is enough. The rest FAILs which is caused by this patch: https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=d9dd06ad51b7479f09acb88adf404664a1e18b2a need to be recovered back. Robostify the gather index to fixe those FAILs. gcc/ChangeLog: * config/riscv/riscv-v.cc (get_gather_index_mode): New function. (shuffle_series_patterns): Robostify shuffle index. (shuffle_generic_patterns): Ditto. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/pr110950.c: Adapt test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/riscv/riscv-v.cc80
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/pr110950.c2
2 files changed, 49 insertions, 33 deletions
diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index 484c690..944b37b 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -2923,6 +2923,39 @@ struct expand_vec_perm_d
bool testing_p;
};
+/* Return the appropriate index mode for gather instructions. */
+opt_machine_mode
+get_gather_index_mode (struct expand_vec_perm_d *d)
+{
+ machine_mode sel_mode = related_int_vector_mode (d->vmode).require ();
+ poly_uint64 nunits = GET_MODE_NUNITS (d->vmode);
+
+ if (GET_MODE_INNER (d->vmode) == QImode)
+ {
+ if (nunits.is_constant ())
+ {
+ /* If indice is LMUL8 CONST_VECTOR and any element value
+ exceed the range of 0 ~ 255, Forbid such permutation
+ since we need vector HI mode to hold such indice and
+ we don't have it. */
+ if (!d->perm.all_in_range_p (0, 255)
+ && !get_vector_mode (HImode, nunits).exists (&sel_mode))
+ return opt_machine_mode ();
+ }
+ else
+ {
+ /* Permuting two SEW8 variable-length vectors need vrgatherei16.vv.
+ Otherwise, it could overflow the index range. */
+ if (!get_vector_mode (HImode, nunits).exists (&sel_mode))
+ return opt_machine_mode ();
+ }
+ }
+ else if (riscv_get_v_regno_alignment (sel_mode) > 1
+ && GET_MODE_INNER (sel_mode) != HImode)
+ sel_mode = get_vector_mode (HImode, nunits).require ();
+ return sel_mode;
+}
+
/* Recognize the patterns that we can use merge operation to shuffle the
vectors. The value of Each element (index i) in selector can only be
either i or nunits + i. We will check the pattern is actually monotonic.
@@ -3428,12 +3461,10 @@ shuffle_series_patterns (struct expand_vec_perm_d *d)
if (!have_series)
return false;
- /* Get a vector int-mode to be used for the permute selector. */
- machine_mode sel_mode = related_int_vector_mode (d->vmode).require ();
- insn_code icode = optab_handler (vec_shl_insert_optab, sel_mode);
-
- /* We need to be able to insert an element and shift the vector. */
- if (need_insert && icode == CODE_FOR_nothing)
+ /* Disable shuffle if we can't find an appropriate integer index mode for
+ gather. */
+ machine_mode sel_mode;
+ if (!get_gather_index_mode (d).exists (&sel_mode))
return false;
/* Success! */
@@ -3448,7 +3479,12 @@ shuffle_series_patterns (struct expand_vec_perm_d *d)
/* Insert the remaining element if necessary. */
if (need_insert)
- emit_insn (GEN_FCN (icode) (series, series, gen_int_mode (el1, eltmode)));
+ {
+ insn_code icode = code_for_pred_slide (UNSPEC_VSLIDE1UP, sel_mode);
+ rtx ops[]
+ = {series, series, gen_int_mode (el1, GET_MODE_INNER (sel_mode))};
+ emit_vlmax_insn (icode, BINARY_OP, ops);
+ }
emit_vlmax_gather_insn (d->target, d->op0, series);
@@ -3460,36 +3496,16 @@ shuffle_series_patterns (struct expand_vec_perm_d *d)
static bool
shuffle_generic_patterns (struct expand_vec_perm_d *d)
{
- machine_mode sel_mode = related_int_vector_mode (d->vmode).require ();
- poly_uint64 nunits = GET_MODE_NUNITS (d->vmode);
+ machine_mode sel_mode;
/* We don't enable SLP for non-power of 2 NPATTERNS. */
if (!pow2p_hwi (d->perm.encoding().npatterns ()))
return false;
- if (GET_MODE_INNER (d->vmode) == QImode)
- {
- if (nunits.is_constant ())
- {
- /* If indice is LMUL8 CONST_VECTOR and any element value
- exceed the range of 0 ~ 255, Forbid such permutation
- since we need vector HI mode to hold such indice and
- we don't have it. */
- if (!d->perm.all_in_range_p (0, 255)
- && !get_vector_mode (HImode, nunits).exists (&sel_mode))
- return false;
- }
- else
- {
- /* Permuting two SEW8 variable-length vectors need vrgatherei16.vv.
- Otherwise, it could overflow the index range. */
- if (!get_vector_mode (HImode, nunits).exists (&sel_mode))
- return false;
- }
- }
- else if (riscv_get_v_regno_alignment (sel_mode) > 1
- && GET_MODE_INNER (sel_mode) != HImode)
- sel_mode = get_vector_mode (HImode, nunits).require ();
+ /* Disable shuffle if we can't find an appropriate integer index mode for
+ gather. */
+ if (!get_gather_index_mode (d).exists (&sel_mode))
+ return false;
/* Success! */
if (d->testing_p)
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr110950.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr110950.c
index b927f1e..17dd439 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr110950.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr110950.c
@@ -9,4 +9,4 @@ void b() {
c[a] = d[-a];
}
-/* { dg-final { scan-assembler-times {vslide1up\.vx} 1 } } */
+/* { dg-final { scan-assembler-times {vrgather} 1 } } */