Andrew Carlotti <andrew.carlo...@arm.com> writes: > When initialising intrinsics with `#pragma GCC aarch64 "arm_*.h"`, we > often set an explicit target, but currently leave current_target_pragma > unchanged. This results in the target pragma being applied to each > simulated intrinsic on top of our explicit target, which is clearly > undesirable. > > As far as I can tell this doesn't cause any bugs at the moment, because > none of the behaviour for builtin functions depends upon the function > specific target. However, the unintended target feature combinations > led to unwanted behaviour in an under-developement patch. > > This patch resolves the issue by extending aarch64_simd_switcher to > explicitly unset the current_target_pragma, and adapting it for to > support handle_arm_acle_h as well. I've also renamed the switcher classes > and instances, because I think the new names a slightly clearer. > > The chosen sets of features for arm_sve.h and arm_sme.h are not normally > valid, because they exclude FCMA and BF16. However, I don't think that > matters for the usage here. Alternatively, aarch64_target_switcher > could be modified to enable all the dependent features as well. > > > Bootstrapped and regression tested on aarch64. Ok for master (to enable the > dependant WIP patch)? > > gcc/ChangeLog: > > * config/aarch64/aarch64-builtins.cc > (aarch64_simd_switcher::aarch64_simd_switcher): Rename to... > (aarch64_target_switcher::aarch64_target_switcher): ...this, > remove default simd flags and save current_target_pragma. > (aarch64_simd_switcher::~aarch64_simd_switcher): Rename to... > (aarch64_target_switcher::~aarch64_target_switcher): ...this, > and restore current_target_pragma. > (handle_arm_acle_h): Use aarch64_target_switcher. > (handle_arm_neon_h): Rename switcher and pass explicit flags. > (aarch64_general_init_builtins): Ditto. > * config/aarch64/aarch64-protos.h > (class aarch64_simd_switcher): Rename to... > (class aarch64_target_switcher): ...this, and add pragma member. > * config/aarch64/aarch64-sve-builtins.cc > (sve_switcher::sve_switcher): Rename to... > (sve_target_switcher::sve_target_switcher): ...this. > (sve_switcher::~sve_switcher): Rename to... > (sve_target_switcher::~sve_target_switcher): ...this. > (init_builtins): Rename switcher. > (handle_arm_sve_h): Ditto. > (handle_arm_neon_sve_bridge_h): Ditto. > (handle_arm_sme_h): Ditto. > * config/aarch64/aarch64-sve-builtins.h > (class sve_switcher): Rename to... > (class sve_target_switcher): ...this. > (class sme_switcher): Rename to... > (class sme_target_switcher): ...this. > > > diff --git a/gcc/config/aarch64/aarch64-builtins.cc > b/gcc/config/aarch64/aarch64-builtins.cc > index > 128cc365d3d585e01cb69668f285318ee56a36fc..c1cb6cdcc81c6b45c0132250589bba0be42f195d > 100644 > --- a/gcc/config/aarch64/aarch64-builtins.cc > +++ b/gcc/config/aarch64/aarch64-builtins.cc > @@ -1877,23 +1877,25 @@ aarch64_scalar_builtin_type_p (aarch64_simd_type t) > return (t == Poly8_t || t == Poly16_t || t == Poly64_t || t == Poly128_t); > } > > -/* Enable AARCH64_FL_* flags EXTRA_FLAGS on top of the base Advanced SIMD > - set. */ > -aarch64_simd_switcher::aarch64_simd_switcher (aarch64_feature_flags > extra_flags) > +/* Temporarily set FLAGS as the enabled target features. */ > +aarch64_target_switcher::aarch64_target_switcher (aarch64_feature_flags > flags) > : m_old_asm_isa_flags (aarch64_asm_isa_flags), > - m_old_general_regs_only (TARGET_GENERAL_REGS_ONLY) > + m_old_general_regs_only (TARGET_GENERAL_REGS_ONLY), > + m_old_target_pragma (current_target_pragma) > { > /* Changing the ISA flags should be enough here. We shouldn't need to > pay the compile-time cost of a full target switch. */ > global_options.x_target_flags &= ~MASK_GENERAL_REGS_ONLY; > - aarch64_set_asm_isa_flags (AARCH64_FL_FP | AARCH64_FL_SIMD | extra_flags); > + aarch64_set_asm_isa_flags (flags);
This feels a bit inconsistent, in that it forces -mgeneral-regs off but doesn't force AARCH64_FL_FP on. I think it'd be better to keep this part of aarch64_simd_(target_)switcher (and continue to have sve_(target_)switcher derive from it) and make aarch64_target_switcher a new base class that just does the pragma bit. Thanks, Richard > + current_target_pragma = NULL_TREE; > } > > -aarch64_simd_switcher::~aarch64_simd_switcher () > +aarch64_target_switcher::~aarch64_target_switcher () > { > if (m_old_general_regs_only) > global_options.x_target_flags |= MASK_GENERAL_REGS_ONLY; > aarch64_set_asm_isa_flags (m_old_asm_isa_flags); > + current_target_pragma = m_old_target_pragma; > } > > /* Implement #pragma GCC aarch64 "arm_neon.h". > @@ -1903,7 +1905,7 @@ aarch64_simd_switcher::~aarch64_simd_switcher () > void > handle_arm_neon_h (void) > { > - aarch64_simd_switcher simd; > + aarch64_target_switcher switcher (AARCH64_FL_FP | AARCH64_FL_SIMD); > > /* Register the AdvSIMD vector tuple types. */ > for (unsigned int i = 0; i < ARM_NEON_H_TYPES_LAST; i++) > @@ -2353,6 +2355,8 @@ aarch64_init_data_intrinsics (void) > void > handle_arm_acle_h (void) > { > + aarch64_target_switcher switcher; > + > aarch64_init_ls64_builtins (); > aarch64_init_tme_builtins (); > aarch64_init_memtag_builtins (); > @@ -2446,7 +2450,7 @@ aarch64_general_init_builtins (void) > aarch64_init_bf16_types (); > > { > - aarch64_simd_switcher simd; > + aarch64_target_switcher switcher (AARCH64_FL_FP | AARCH64_FL_SIMD); > aarch64_init_simd_builtins (); > } > > diff --git a/gcc/config/aarch64/aarch64-protos.h > b/gcc/config/aarch64/aarch64-protos.h > index > 4235f4a0ca51af49c2852a420f1056727b24f345..cbae258a5bbb3feee80f14add6567f2440cc6927 > 100644 > --- a/gcc/config/aarch64/aarch64-protos.h > +++ b/gcc/config/aarch64/aarch64-protos.h > @@ -733,15 +733,16 @@ const unsigned int AARCH64_BUILTIN_CLASS = (1 << > AARCH64_BUILTIN_SHIFT) - 1; > > /* RAII class for enabling enough features to define built-in types > and implement the arm_neon.h pragma. */ > -class aarch64_simd_switcher > +class aarch64_target_switcher > { > public: > - aarch64_simd_switcher (aarch64_feature_flags extra_flags = 0); > - ~aarch64_simd_switcher (); > + aarch64_target_switcher (aarch64_feature_flags flags = 0); > + ~aarch64_target_switcher (); > > private: > aarch64_feature_flags m_old_asm_isa_flags; > bool m_old_general_regs_only; > + tree m_old_target_pragma; > }; > > /* Represents the ISA requirements of an intrinsic function, or of some > diff --git a/gcc/config/aarch64/aarch64-sve-builtins.h > b/gcc/config/aarch64/aarch64-sve-builtins.h > index > 54d213dfe6e0e1cd95e932fc4a04e9cd360f15f5..ea19cfe47bec042e0fb0b4f3c3820b2d37bb222f > 100644 > --- a/gcc/config/aarch64/aarch64-sve-builtins.h > +++ b/gcc/config/aarch64/aarch64-sve-builtins.h > @@ -824,11 +824,11 @@ public: > > /* RAII class for enabling enough SVE features to define the built-in > types and implement the arm_sve.h pragma. */ > -class sve_switcher : public aarch64_simd_switcher > +class sve_target_switcher : public aarch64_target_switcher > { > public: > - sve_switcher (aarch64_feature_flags = 0); > - ~sve_switcher (); > + sve_target_switcher (aarch64_feature_flags = 0); > + ~sve_target_switcher (); > > private: > unsigned int m_old_maximum_field_alignment; > @@ -836,10 +836,10 @@ private: > }; > > /* Extends sve_switch enough for defining arm_sme.h. */ > -class sme_switcher : public sve_switcher > +class sme_target_switcher : public sve_target_switcher > { > public: > - sme_switcher () : sve_switcher (AARCH64_FL_SME) {} > + sme_target_switcher () : sve_target_switcher (AARCH64_FL_SME) {} > }; > > extern const type_suffix_info type_suffixes[NUM_TYPE_SUFFIXES + 1]; > diff --git a/gcc/config/aarch64/aarch64-sve-builtins.cc > b/gcc/config/aarch64/aarch64-sve-builtins.cc > index > 5d2062726d6bab31652bc9fa4bbd597704ef46e5..0e3887db74a64326d036f0ef70a35f31dcb971b0 > 100644 > --- a/gcc/config/aarch64/aarch64-sve-builtins.cc > +++ b/gcc/config/aarch64/aarch64-sve-builtins.cc > @@ -1296,8 +1296,12 @@ registered_function_hasher::equal (value_type value, > const compare_type &key) > return value->instance == key; > } > > -sve_switcher::sve_switcher (aarch64_feature_flags flags) > - : aarch64_simd_switcher (AARCH64_FL_F16 | AARCH64_FL_SVE | flags) > +sve_target_switcher::sve_target_switcher (aarch64_feature_flags flags) > + : aarch64_target_switcher (AARCH64_FL_FP > + | AARCH64_FL_SIMD > + | AARCH64_FL_F16 > + | AARCH64_FL_SVE > + | flags) > { > /* Changing the ISA flags and have_regs_of_mode should be enough here. > We shouldn't need to pay the compile-time cost of a full target > @@ -1312,7 +1316,7 @@ sve_switcher::sve_switcher (aarch64_feature_flags flags) > have_regs_of_mode[i] = true; > } > > -sve_switcher::~sve_switcher () > +sve_target_switcher::~sve_target_switcher () > { > memcpy (have_regs_of_mode, m_old_have_regs_of_mode, > sizeof (have_regs_of_mode)); > @@ -4726,7 +4730,7 @@ register_builtin_types () > void > init_builtins () > { > - sve_switcher sve; > + sve_target_switcher switcher; > register_builtin_types (); > if (in_lto_p) > { > @@ -4842,7 +4846,7 @@ handle_arm_sve_h (bool function_nulls_p) > return; > } > > - sve_switcher sve; > + sve_target_switcher switcher; > > /* Define the vector and tuple types. */ > for (unsigned int type_i = 0; type_i < NUM_VECTOR_TYPES; ++type_i) > @@ -4873,6 +4877,8 @@ handle_arm_neon_sve_bridge_h (bool function_nulls_p) > if (initial_indexes[arm_sme_handle] == 0) > handle_arm_sme_h (true); > > + aarch64_target_switcher switcher; > + > /* Define the functions. */ > function_builder builder (arm_neon_sve_handle, function_nulls_p); > for (unsigned int i = 0; i < ARRAY_SIZE (neon_sve_function_groups); ++i) > @@ -4900,7 +4906,7 @@ handle_arm_sme_h (bool function_nulls_p) > return; > } > > - sme_switcher sme; > + sme_target_switcher switcher; > > function_builder builder (arm_sme_handle, function_nulls_p); > for (unsigned int i = 0; i < ARRAY_SIZE (sme_function_groups); ++i)