aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Carlotti <andrew.carlotti@arm.com>2024-04-03 23:35:08 +0100
committerAndrew Carlotti <andrew.carlotti@arm.com>2024-04-11 15:26:46 +0100
commit3ef14f56343ad3445f874638700f6b82f032a1ae (patch)
tree7f68041f23fda356e8acd91f2e6bcf0b5d677ace
parente33fc847d5457bd56734cad056955102a23f405b (diff)
downloadgcc-3ef14f56343ad3445f874638700f6b82f032a1ae.zip
gcc-3ef14f56343ad3445f874638700f6b82f032a1ae.tar.gz
gcc-3ef14f56343ad3445f874638700f6b82f032a1ae.tar.bz2
aarch64: Fix FMV array iteration bounds
There was an assumption in some places that the aarch64_fmv_feature_data array contained FEAT_MAX elements. While this assumption held up till now, it is safer and more flexible to use the array size directly. Also fix the lower bound in compare_feature_masks to use ">=0" instead of ">0", and add a test using the features at index 0 and 1. However, the test already passed, because the earlier popcount check makes it impossible to reach the loop if the masks differ in exactly one location. gcc/ChangeLog: * config/aarch64/aarch64.cc (compare_feature_masks): Use ARRAY_SIZE and >=0 for iteration bounds. (aarch64_mangle_decl_assembler_name): Use ARRAY_SIZE. gcc/testsuite/ChangeLog: * g++.target/aarch64/mv-1.C: New test.
-rw-r--r--gcc/config/aarch64/aarch64.cc8
-rw-r--r--gcc/testsuite/g++.target/aarch64/mv-1.C38
2 files changed, 43 insertions, 3 deletions
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index c763a8a..91481f9 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -19738,7 +19738,7 @@ aarch64_parse_fmv_features (const char *str, aarch64_feature_flags *isa_flags,
if (len == 0)
return AARCH_PARSE_MISSING_ARG;
- static const int num_features = ARRAY_SIZE (aarch64_fmv_feature_data);
+ int num_features = ARRAY_SIZE (aarch64_fmv_feature_data);
int i;
for (i = 0; i < num_features; i++)
{
@@ -19937,7 +19937,8 @@ compare_feature_masks (aarch64_fmv_feature_mask mask1,
auto diff_mask = mask1 ^ mask2;
if (diff_mask == 0ULL)
return 0;
- for (int i = FEAT_MAX - 1; i > 0; i--)
+ int num_features = ARRAY_SIZE (aarch64_fmv_feature_data);
+ for (int i = num_features - 1; i >= 0; i--)
{
auto bit_mask = aarch64_fmv_feature_data[i].feature_mask;
if (diff_mask & bit_mask)
@@ -20020,7 +20021,8 @@ aarch64_mangle_decl_assembler_name (tree decl, tree id)
name += "._";
- for (int i = 0; i < FEAT_MAX; i++)
+ int num_features = ARRAY_SIZE (aarch64_fmv_feature_data);
+ for (int i = 0; i < num_features; i++)
{
if (feature_mask & aarch64_fmv_feature_data[i].feature_mask)
{
diff --git a/gcc/testsuite/g++.target/aarch64/mv-1.C b/gcc/testsuite/g++.target/aarch64/mv-1.C
new file mode 100644
index 0000000..b4b0e5e
--- /dev/null
+++ b/gcc/testsuite/g++.target/aarch64/mv-1.C
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-require-ifunc "" } */
+/* { dg-options "-O0" } */
+
+__attribute__((target_version("default")))
+int foo ()
+{
+ return 1;
+}
+
+__attribute__((target_version("rng")))
+int foo ()
+{
+ return 1;
+}
+
+__attribute__((target_version("flagm")))
+int foo ()
+{
+ return 1;
+}
+
+__attribute__((target_version("rng+flagm")))
+int foo ()
+{
+ return 1;
+}
+
+int bar()
+{
+ return foo ();
+}
+
+/* Check usage of the first two FMV features, in case of off-by-one errors. */
+/* { dg-final { scan-assembler-times "\n_Z3foov\.default:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3foov\._Mrng:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3foov\._MrngMflagm:\n" 1 } } */
+/* { dg-final { scan-assembler-times "\n_Z3foov\._Mflagm:\n" 1 } } */