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.
This commit is contained in:
Fei Yang 2020-04-22 18:24:59 +01:00 committed by Richard Sandiford
parent 4c33513986
commit 154ae7d4e9
6 changed files with 78 additions and 7 deletions

View file

@ -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

View file

@ -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;
}

View file

@ -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];
};

View file

@ -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)

View file

@ -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

View file

@ -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);
}