aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Dapp <rdapp@ventanamicro.com>2023-12-13 16:42:28 +0100
committerRobin Dapp <rdapp@ventanamicro.com>2023-12-14 17:51:45 +0100
commite5e1999aa664333f766f3e6cc6996f769d50ae7a (patch)
tree0ad03fc22253d37f358567da5529a0c09f7503cf
parent0a5170b5f596bb5fcedf25d93952b979d02d1f56 (diff)
downloadgcc-e5e1999aa664333f766f3e6cc6996f769d50ae7a.zip
gcc-e5e1999aa664333f766f3e6cc6996f769d50ae7a.tar.gz
gcc-e5e1999aa664333f766f3e6cc6996f769d50ae7a.tar.bz2
expmed: Compare unit_precision for better mode.
In extract_bit_field_1 we try to get a better vector mode before extracting from it. Better refers to the case when the requested target mode does not equal the inner mode of the vector to extract from and we have an equivalent tieable vector mode with a fitting inner mode. On riscv this triggered an ICE (PR112999) because we would take the detour of extracting from a mask-mode vector via a vector integer mode. One element of that mode could be subreg-punned with TImode which, in turn, would need to be operated on in DImode chunks. This patch adds && known_eq (bitsize, GET_MODE_UNIT_PRECISION (new_mode)) && multiple_p (bitnum, GET_MODE_UNIT_PRECISION (new_mode)) to the list of criteria for a better mode. gcc/ChangeLog: PR target/112999 * expmed.cc (extract_bit_field_1): Ensure better mode has fitting unit_precision. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/pr112999.c: New test.
-rw-r--r--gcc/expmed.cc2
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112999.c17
2 files changed, 19 insertions, 0 deletions
diff --git a/gcc/expmed.cc b/gcc/expmed.cc
index d753140..05331dd 100644
--- a/gcc/expmed.cc
+++ b/gcc/expmed.cc
@@ -1745,6 +1745,8 @@ extract_bit_field_1 (rtx str_rtx, poly_uint64 bitsize, poly_uint64 bitnum,
FOR_EACH_MODE_FROM (new_mode, new_mode)
if (known_eq (GET_MODE_SIZE (new_mode), GET_MODE_SIZE (GET_MODE (op0)))
&& known_eq (GET_MODE_UNIT_SIZE (new_mode), GET_MODE_SIZE (tmode))
+ && known_eq (bitsize, GET_MODE_UNIT_PRECISION (new_mode))
+ && multiple_p (bitnum, GET_MODE_UNIT_PRECISION (new_mode))
&& targetm.vector_mode_supported_p (new_mode)
&& targetm.modes_tieable_p (GET_MODE (op0), new_mode))
break;
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112999.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112999.c
new file mode 100644
index 0000000..c049c5a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr112999.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl512b -mabi=lp64d --param=riscv-autovec-lmul=m8 --param=riscv-autovec-preference=fixed-vlmax -O3 -fno-vect-cost-model -fno-tree-loop-distribute-patterns" } */
+
+int a[1024];
+int b[1024];
+
+_Bool
+fn1 ()
+{
+ _Bool tem;
+ for (int i = 0; i < 1024; ++i)
+ {
+ tem = !a[i];
+ b[i] = tem;
+ }
+ return tem;
+}