From: xuli <[email protected]>
Example as follows:
int main()
{
unsigned long arraya[128], arrayb[128], arrayc[128];
for (int i = 0; i < 128; i++)
{
arraya[i] = arrayb[i] + arrayc[i];
}
return 0;
}
Compiled with -march=rv32imafc_zve32f -mabi=ilp32f, it will cause a compilation
issue:
riscv_vector.h:40:25: error: ambiguating new declaration of 'vint64m4_t
__riscv_vle64(vbool16_t, const long long int*, unsigned int)'
40 | #pragma riscv intrinsic "vector"
| ^~~~~~~~
riscv_vector.h:40:25: note: old declaration 'vint64m1_t
__riscv_vle64(vbool64_t, const long long int*, unsigned int)'
With zvl=32b, vbool16_t is registered in init_builtins() with
type_common.precision=0x101 (nunits=2), mode_nunits[E_RVVMF16BI]=[2,2].
Normally, vbool64_t is only valid when TARGET_MIN_VLEN > 32, so vbool64_t
is not registered in init_builtins(), meaning vbool64_t=null.
In order to implement __attribute__((target("arch=+v"))), we must register
all vector types and all RVV intrinsics. Therefore, vbool64_t will be registered
by default with zvl=128b in reinit_builtins(), resulting in
type_common.precision=0x101 (nunits=2) and mode_nunits[E_RVVMF64BI]=[2,2].
We then get TYPE_VECTOR_SUBPARTS(vbool16_t) == TYPE_VECTOR_SUBPARTS(vbool64_t),
calculated using type_common.precision, resulting in 2. Since vbool16_t and
vbool64_t have the same element type (boolean_type), the compiler treats them
as the same type, leading to a re-declaration conflict.
After all types and intrinsics have been registered, processing
__attribute__((target("arch=+v"))) will update the parameters option and
init_adjust_machine_modes. Therefore, to avoid conflicts, we can choose
zvl=4096b for the null type reinit_builtins().
command option zvl=32b
type nunits
vbool64_t => null
vbool32_t=> [1,1]
vbool16_t=> [2,2]
vbool8_t=> [4,4]
vbool4_t=> [8,8]
vbool2_t=> [16,16]
vbool1_t=> [32,32]
reinit zvl=128b
vbool64_t => [2,2] conflict with zvl32b vbool16_t=> [2,2]
reinit zvl=256b
vbool64_t => [4,4] conflict with zvl32b vbool8_t=> [4,4]
reinit zvl=512b
vbool64_t => [8,8] conflict with zvl32b vbool4_t=> [8,8]
reinit zvl=1024b
vbool64_t => [16,16] conflict with zvl32b vbool2_t=> [16,16]
reinit zvl=2048b
vbool64_t => [32,32] conflict with zvl32b vbool1_t=> [32,32]
reinit zvl=4096b
vbool64_t => [64,64] zvl=4096b is ok
Signed-off-by: xuli <[email protected]>
PR target/116883
gcc/ChangeLog:
* config/riscv/riscv-c.cc (riscv_pragma_intrinsic_flags_pollute):choose
zvl4096b to initialize null type.
gcc/testsuite/ChangeLog:
* g++.target/riscv/rvv/base/pr116883.C: New test.
---
gcc/config/riscv/riscv-c.cc | 7 ++++++-
.../g++.target/riscv/rvv/base/pr116883.C | 15 +++++++++++++++
2 files changed, 21 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/g++.target/riscv/rvv/base/pr116883.C
diff --git a/gcc/config/riscv/riscv-c.cc b/gcc/config/riscv/riscv-c.cc
index 71112d9c66d..c59f408d3a8 100644
--- a/gcc/config/riscv/riscv-c.cc
+++ b/gcc/config/riscv/riscv-c.cc
@@ -59,7 +59,12 @@ riscv_pragma_intrinsic_flags_pollute (struct
pragma_intrinsic_flags *flags)
riscv_zvl_flags = riscv_zvl_flags
| MASK_ZVL32B
| MASK_ZVL64B
- | MASK_ZVL128B;
+ | MASK_ZVL128B
+ | MASK_ZVL256B
+ | MASK_ZVL512B
+ | MASK_ZVL1024B
+ | MASK_ZVL2048B
+ | MASK_ZVL4096B;
riscv_vector_elen_flags = riscv_vector_elen_flags
| MASK_VECTOR_ELEN_32
diff --git a/gcc/testsuite/g++.target/riscv/rvv/base/pr116883.C
b/gcc/testsuite/g++.target/riscv/rvv/base/pr116883.C
new file mode 100644
index 00000000000..15bbec40bdd
--- /dev/null
+++ b/gcc/testsuite/g++.target/riscv/rvv/base/pr116883.C
@@ -0,0 +1,15 @@
+/* Test that we do not have ice when compile */
+/* { dg-do compile } */
+/* { dg-options "-march=rv32imafc_zve32f -mabi=ilp32f" } */
+
+#include <riscv_vector.h>
+
+int main()
+{
+ unsigned long arraya[128], arrayb[128], arrayc[128];
+ for (int i; i < 128; i++)
+ {
+ arraya[i] = arrayb[i] + arrayc[i];
+ }
+ return 0;
+}
--
2.17.1