aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorFei Yang <felix.yang@huawei.com>2020-04-22 18:24:59 +0100
committerRichard Sandiford <richard.sandiford@arm.com>2020-04-22 18:24:59 +0100
commit154ae7d4e921d704118d6a16ee5cc2a10b9047da (patch)
tree795c27f2c44b816d3f4a7e9ef1a788d109926978 /gcc
parent4c3351398644270eddb4db2028dabc8fe6287632 (diff)
downloadgcc-154ae7d4e921d704118d6a16ee5cc2a10b9047da.zip
gcc-154ae7d4e921d704118d6a16ee5cc2a10b9047da.tar.gz
gcc-154ae7d4e921d704118d6a16ee5cc2a10b9047da.tar.bz2
aarch64: unexpected result with -mgeneral-regs-only and sve [PR94678]
As the two testcases for PR94678 show, -mgeneral-regs-only is handled properly with SVE. We should issue an error message instead of expanding SVE builtin funtions when -mgeneral-regs-only option is specified. The middle end should never try to use vector patterns when the vector modes have been disabled by !have_regs_of_mode. But it's still wrong for the target to provide patterns that would inevitably lead to spill failure due to lack of registers. So we should also add check for !TARGET_GENERAL_REGS_ONLY in TARGET_SVE and other SVE related macros. 2020-04-22 Felix Yang <felix.yang@huawei.com> gcc/ PR target/94678 * config/aarch64/aarch64.h (TARGET_SVE): Add && !TARGET_GENERAL_REGS_ONLY. (TARGET_SVE2): Add && TARGET_SVE. (TARGET_SVE2_AES, TARGET_SVE2_BITPERM, TARGET_SVE2_SHA3, TARGET_SVE2_SM4): Add && TARGET_SVE2. * config/aarch64/aarch64-sve-builtins.h (sve_switcher::m_old_general_regs_only): New member. * config/aarch64/aarch64-sve-builtins.cc (check_required_registers): New function. (reported_missing_registers_p): New variable. (check_required_extensions): Call check_required_registers before return if all required extenstions are present. (sve_switcher::sve_switcher): Save TARGET_GENERAL_REGS_ONLY in m_old_general_regs_only and clear MASK_GENERAL_REGS_ONLY in global_options.x_target_flags. (sve_switcher::~sve_switcher): Set MASK_GENERAL_REGS_ONLY in global_options.x_target_flags if m_old_general_regs_only is true. gcc/testsuite/ PR target/94678 * gcc.target/aarch64/sve/acle/general/nosve_6.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog21
-rw-r--r--gcc/config/aarch64/aarch64-sve-builtins.cc34
-rw-r--r--gcc/config/aarch64/aarch64-sve-builtins.h1
-rw-r--r--gcc/config/aarch64/aarch64.h12
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/acle/general/nosve_6.c12
6 files changed, 78 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3b9af1c..085135c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,24 @@
+2020-04-22 Felix Yang <felix.yang@huawei.com>
+
+ PR target/94678
+ * config/aarch64/aarch64.h (TARGET_SVE):
+ Add && !TARGET_GENERAL_REGS_ONLY.
+ (TARGET_SVE2): Add && TARGET_SVE.
+ (TARGET_SVE2_AES, TARGET_SVE2_BITPERM, TARGET_SVE2_SHA3,
+ TARGET_SVE2_SM4): Add && TARGET_SVE2.
+ * config/aarch64/aarch64-sve-builtins.h
+ (sve_switcher::m_old_general_regs_only): New member.
+ * config/aarch64/aarch64-sve-builtins.cc (check_required_registers):
+ New function.
+ (reported_missing_registers_p): New variable.
+ (check_required_extensions): Call check_required_registers before
+ return if all required extenstions are present.
+ (sve_switcher::sve_switcher): Save TARGET_GENERAL_REGS_ONLY in
+ m_old_general_regs_only and clear MASK_GENERAL_REGS_ONLY in
+ global_options.x_target_flags.
+ (sve_switcher::~sve_switcher): Set MASK_GENERAL_REGS_ONLY in
+ global_options.x_target_flags if m_old_general_regs_only is true.
+
2020-04-22 Zackery Spytz <zspytz@gmail.com>
* doc/extend.exi: Add "free" to list of other builtin functions
diff --git a/gcc/config/aarch64/aarch64-sve-builtins.cc b/gcc/config/aarch64/aarch64-sve-builtins.cc
index ca4a0eb..8511382 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins.cc
+++ b/gcc/config/aarch64/aarch64-sve-builtins.cc
@@ -558,6 +558,10 @@ static hash_table<registered_function_hasher> *function_table;
when the required extension is disabled. */
static bool reported_missing_extension_p;
+/* True if we've already complained about attempts to use functions
+ which require registers that are missing. */
+static bool reported_missing_registers_p;
+
/* Record that TYPE is an ABI-defined SVE type that contains NUM_ZR SVE vectors
and NUM_PR SVE predicates. MANGLED_NAME, if nonnull, is the ABI-defined
mangling of the type. */
@@ -657,6 +661,29 @@ report_missing_extension (location_t location, tree fndecl,
reported_missing_extension_p = true;
}
+/* Check whether the registers required by SVE function fndecl are available.
+ Report an error against LOCATION and return false if not. */
+static bool
+check_required_registers (location_t location, tree fndecl)
+{
+ /* Avoid reporting a slew of messages for a single oversight. */
+ if (reported_missing_registers_p)
+ return false;
+
+ if (TARGET_GENERAL_REGS_ONLY)
+ {
+ /* SVE registers are not usable when -mgeneral-regs-only option
+ is specified. */
+ error_at (location,
+ "ACLE function %qD is incompatible with the use of %qs",
+ fndecl, "-mgeneral-regs-only");
+ reported_missing_registers_p = true;
+ return false;
+ }
+
+ return true;
+}
+
/* Check whether all the AARCH64_FL_* values in REQUIRED_EXTENSIONS are
enabled, given that those extensions are required for function FNDECL.
Report an error against LOCATION if not. */
@@ -666,7 +693,7 @@ check_required_extensions (location_t location, tree fndecl,
{
uint64_t missing_extensions = required_extensions & ~aarch64_isa_flags;
if (missing_extensions == 0)
- return true;
+ return check_required_registers (location, fndecl);
static const struct { uint64_t flag; const char *name; } extensions[] = {
#define AARCH64_OPT_EXTENSION(EXT_NAME, FLAG_CANONICAL, FLAGS_ON, FLAGS_OFF, \
@@ -851,6 +878,9 @@ sve_switcher::sve_switcher ()
aarch64_isa_flags = (AARCH64_FL_FP | AARCH64_FL_SIMD | AARCH64_FL_F16
| AARCH64_FL_SVE);
+ m_old_general_regs_only = TARGET_GENERAL_REGS_ONLY;
+ global_options.x_target_flags &= ~MASK_GENERAL_REGS_ONLY;
+
memcpy (m_old_have_regs_of_mode, have_regs_of_mode,
sizeof (have_regs_of_mode));
for (int i = 0; i < NUM_MACHINE_MODES; ++i)
@@ -862,6 +892,8 @@ sve_switcher::~sve_switcher ()
{
memcpy (have_regs_of_mode, m_old_have_regs_of_mode,
sizeof (have_regs_of_mode));
+ if (m_old_general_regs_only)
+ global_options.x_target_flags |= MASK_GENERAL_REGS_ONLY;
aarch64_isa_flags = m_old_isa_flags;
}
diff --git a/gcc/config/aarch64/aarch64-sve-builtins.h b/gcc/config/aarch64/aarch64-sve-builtins.h
index f7f06d2..526d9f5 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins.h
+++ b/gcc/config/aarch64/aarch64-sve-builtins.h
@@ -658,6 +658,7 @@ public:
private:
unsigned long m_old_isa_flags;
+ bool m_old_general_regs_only;
bool m_old_have_regs_of_mode[MAX_MACHINE_MODE];
};
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index 8f08bad..74236c3 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -309,22 +309,22 @@ extern unsigned aarch64_architecture_version;
#define TARGET_DOTPROD (TARGET_SIMD && AARCH64_ISA_DOTPROD)
/* SVE instructions, enabled through +sve. */
-#define TARGET_SVE (AARCH64_ISA_SVE)
+#define TARGET_SVE (!TARGET_GENERAL_REGS_ONLY && AARCH64_ISA_SVE)
/* SVE2 instructions, enabled through +sve2. */
-#define TARGET_SVE2 (AARCH64_ISA_SVE2)
+#define TARGET_SVE2 (TARGET_SVE && AARCH64_ISA_SVE2)
/* SVE2 AES instructions, enabled through +sve2-aes. */
-#define TARGET_SVE2_AES (AARCH64_ISA_SVE2_AES)
+#define TARGET_SVE2_AES (TARGET_SVE2 && AARCH64_ISA_SVE2_AES)
/* SVE2 BITPERM instructions, enabled through +sve2-bitperm. */
-#define TARGET_SVE2_BITPERM (AARCH64_ISA_SVE2_BITPERM)
+#define TARGET_SVE2_BITPERM (TARGET_SVE2 && AARCH64_ISA_SVE2_BITPERM)
/* SVE2 SHA3 instructions, enabled through +sve2-sha3. */
-#define TARGET_SVE2_SHA3 (AARCH64_ISA_SVE2_SHA3)
+#define TARGET_SVE2_SHA3 (TARGET_SVE2 && AARCH64_ISA_SVE2_SHA3)
/* SVE2 SM4 instructions, enabled through +sve2-sm4. */
-#define TARGET_SVE2_SM4 (AARCH64_ISA_SVE2_SM4)
+#define TARGET_SVE2_SM4 (TARGET_SVE2 && AARCH64_ISA_SVE2_SM4)
/* ARMv8.3-A features. */
#define TARGET_ARMV8_3 (AARCH64_ISA_V8_3)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b23a2dd..acd8b1a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2020-04-22 Felix Yang <felix.yang@huawei.com>
+
+ PR target/94678
+ * gcc.target/aarch64/sve/acle/general/nosve_6.c: New test.
+
2020-04-22 José Rui Faustino de Sousa <jrfsousa@gmail.com>
PR fortran/90350
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/nosve_6.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/nosve_6.c
new file mode 100644
index 0000000..d91ba40
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/nosve_6.c
@@ -0,0 +1,12 @@
+/* { dg-options "-march=armv8-a -mgeneral-regs-only" } */
+
+#pragma GCC aarch64 "arm_sve.h"
+
+#pragma GCC target "+sve"
+
+void
+f (svbool_t *x, svint8_t *y)
+{
+ *x = svptrue_b8 (); /* { dg-error {ACLE function '(svbool_t svptrue_b8\(\)|svptrue_b8)' is incompatible with the use of '-mgeneral-regs-only'} } */
+ *y = svadd_m (*x, *y, 1);
+}