diff options
author | Martin Liska <mliska@suse.cz> | 2022-10-04 12:04:54 +0200 |
---|---|---|
committer | Martin Liska <mliska@suse.cz> | 2022-10-04 12:04:54 +0200 |
commit | da0970e441345f8349522ff1abac5c223044ebb1 (patch) | |
tree | 17c2091a83c584a1eae4f8e219a460f85c5d3fd8 /gcc | |
parent | 54f3cfaf3a6f50958c71d79c85206a6c722e1a22 (diff) | |
parent | e886ebd17965d78f609b62479f4f48085108389c (diff) | |
download | gcc-da0970e441345f8349522ff1abac5c223044ebb1.zip gcc-da0970e441345f8349522ff1abac5c223044ebb1.tar.gz gcc-da0970e441345f8349522ff1abac5c223044ebb1.tar.bz2 |
Merge branch 'master' into devel/sphinx
Diffstat (limited to 'gcc')
225 files changed, 5580 insertions, 2065 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 25721e8..48397ff 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,605 @@ +2022-10-03 Sergei Trofimovich <siarheit@google.com> + + * config/i386/t-i386: Add build-time dependencies against + i386-builtin-types.inc to i386-builtins.o, i386-expand.o, + i386-features.o. + +2022-10-03 Andrew Stubbs <ams@codesourcery.com> + + * config/gcn/gcn-valu.md (while_ultsidi): Limit mask length using + operand 3. + * doc/md.texi (while_ult): Document new operand 3 usage. + * internal-fn.cc (expand_while_optab_fn): Set operand 3 when lhs_type + maps to a non-vector mode. + +2022-10-03 Andrew MacLeod <amacleod@redhat.com> + + PR tree-optimization/107109 + * range-op.cc (adjust_op1_for_overflow): Don't process undefined. + +2022-10-03 Christophe Lyon <christophe.lyon@arm.com> + + * config/arm/mve.md (mve_vrev64q_m_<supf><mode>): Add early + clobber. + (mve_vrev64q_m_f<mode>): Likewise. + +2022-10-03 Aldy Hernandez <aldyh@redhat.com> + + * value-range.cc (irange::set_nonzero_bits): Do not pessimize range. + (range_tests_nonzero_bits): New test. + +2022-10-03 Aldy Hernandez <aldyh@redhat.com> + + * value-range.cc (irange::operator==): Early bail on m_num_ranges + equal to 0. + +2022-10-03 Aldy Hernandez <aldyh@redhat.com> + + * value-range.cc (irange::legacy_equal_p): Remove nonozero mask + check when comparing VR_VARYING ranges. + +2022-10-03 Aldy Hernandez <aldyh@redhat.com> + + * ipa-prop.cc (struct ipa_vr_ggc_hash_traits): Do not compare + incompatible ranges in ipa-prop. + +2022-10-02 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/107121 + * tree-cfg.cc (verify_gimple_call): Fix a typo in diagnostics, + DEFFERED_INIT -> DEFERRED_INIT. + +2022-10-02 Marc Poulhiès <poulhies@adacore.com> + + * config/vxworks-driver.cc: New. + * config.gcc (*vxworks*): Add vxworks-driver.o in extra_gcc_objs. + * config/t-vxworks: Add vxworks-driver.o. + * config/vxworks.h (GCC_DRIVER_HOST_INITIALIZATION): New. + +2022-10-02 Olivier Hainque <hainque@adacore.com> + + * config/vxworks.h (VX_CRTBEGIN_SPEC, VX_CRTEND_SPEC): If + HAVE_INITFINI_ARRAY_SUPPORT, pick crtstuff objects regardless + of ENABLE_SHARED_LIBGCC. + +2022-10-01 Stafford Horne <shorne@gmail.com> + + * config/or1k/or1k.cc (TARGET_HAVE_TLS): Only define if + HAVE_AS_TLS is defined. + +2022-10-01 Julian Brown <julian@codesourcery.com> + + * gimplify.cc (omp_group_base): Fix IF_PRESENT (no_create) + handling. + +2022-10-01 Jeff Law <jeffreyalaw@gmail.com> + + * config/h8300/h8300.md (HSI2): New iterator. + (eqne_invert): Similarly. + * config/h8300/testcompare.md (testhi_upper_z): New pattern. + (cmpqi_z, cmphi_z, cmpsi_z): Likewise. + (store_z_qi, store_z_i_qi, store_z_hi, store_z_hi_sb): New + define_insn_and_splits and/or define_insns. + (store_z_hi_neg, store_z_hi_and, store_z_<mode>): Likewise. + (store_z_<mode>_neg, store_z_<mode>_and, store_z): Likewise. + +2022-10-01 Jeff Law <jeffreyalaw@gmail.com> + + * tree-ssa-dom.cc (record_edge_info): Install correct version of + patch. + +2022-10-01 Eugene Rozenfeld <erozen@microsoft.com> + + * dwarf2out.cc (add_call_src_coords_attributes): Emit discriminators for inlined call sites. + +2022-09-30 Jeff Law <jeffreyalaw@gmail.com> + + * tree-ssa-dom.cc (single_block_loop_p): New function. + (record_edge_info): Also record equivalences for the outgoing + edge of a single block loop where the condition is an invariant. + +2022-09-30 Jeff Law <jeffreyalaw@gmail.com> + + * tree-ssa-dom.cc (free_dom_edge_info): Clear e->aux too. + (free_all_edge_infos): Do not clear e->aux here. + +2022-09-30 H.J. Lu <hjl.tools@gmail.com> + + * target.def (TARGET_C_EXCESS_PRECISION): Document + -fexcess-precision=16. + +2022-09-30 Palmer Dabbelt <palmer@rivosinc.com> + + * doc/tm.texi (TARGET_C_EXCESS_PRECISION): Add 16. + +2022-09-30 Palmer Dabbelt <palmer@rivosinc.com> + + PR target/106815 + * config/riscv/riscv.cc (riscv_excess_precision): Add support + for EXCESS_PRECISION_TYPE_FLOAT16. + +2022-09-30 Jakub Jelinek <jakub@redhat.com> + + PR c++/107080 + * config/arm/arm.cc (arm_mangle_type): Mangle just __fp16 as Dh + and _Float16 as DF16_. + * config/csky/csky.cc (csky_init_builtins): Fix a comment typo. + (csky_mangle_type): Mangle __fp16 as Dh and _Float16 as DF16_ + rather than mangling __fp16 as __fp16. + +2022-09-30 Lewis Hyatt <lhyatt@gmail.com> + + PR preprocessor/69543 + * tree-ssa-uninit.cc (warn_uninit): Stop stripping macro tracking + information away from the diagnostic location. + (maybe_warn_read_write_only): Likewise. + (maybe_warn_operand): Likewise. + +2022-09-30 Jakub Jelinek <jakub@redhat.com> + + PR c++/107080 + * config/aarch64/aarch64.cc (aarch64_mangle_type): Mangle just __fp16 + as Dh and _Float16 as DF16_. + +2022-09-30 Jakub Jelinek <jakub@redhat.com> + + PR c++/107080 + * config/i386/i386.cc (ix86_mangle_type): Always return NULL + for float128_type_node or float64x_type_node, don't check + float128t_type_node later on. + * config/ia64/ia64.cc (ia64_mangle_type): Always return NULL + for float128_type_node or float64x_type_node. + * config/rs6000/rs6000.cc (rs6000_mangle_type): Likewise. + Don't check float128_type_node later on. + * config/s390/s390.cc (s390_mangle_type): Don't use + TYPE_MAIN_VARIANT on type which was set to TYPE_MAIN_VARIANT + a few lines earlier. + +2022-09-30 Torbjörn SVENSSON <torbjorn.svensson@foss.st.com> + Yvan ROUX <yvan.roux@foss.st.com> + + * doc/sourcebuild.texi: Document new vma_equals_lma effective + target check. + +2022-09-30 Jiawei <jiawei@iscas.ac.cn> + + * config/riscv/riscv.cc (riscv_file_start): New .option. + * config/riscv/riscv.opt: New options. + * doc/invoke.texi: New definations. + +2022-09-30 Kewen Lin <linkw@linux.ibm.com> + + PR target/99888 + PR target/105649 + * doc/invoke.texi (option -fpatchable-function-entry): Adjust the + documentation for PowerPC ELFv2 ABI dual entry points. + * config/rs6000/rs6000-internal.h + (rs6000_print_patchable_function_entry): New function declaration. + * config/rs6000/rs6000-logue.cc (rs6000_output_function_prologue): + Support patchable-function-entry by emitting nops before and after + local entry for the function that needs global entry. + * config/rs6000/rs6000.cc (rs6000_print_patchable_function_entry): Skip + the function that needs global entry till global entry has been + emitted. + * config/rs6000/rs6000.h (struct machine_function): New bool member + global_entry_emitted. + +2022-09-30 Richard Biener <rguenther@suse.de> + + PR tree-optimization/107095 + * tree-ssa-dse.cc (initialize_ao_ref_for_dse): Use data arg + for .MASK_STORE size. + +2022-09-29 Andrew MacLeod <amacleod@redhat.com> + + * range-op.cc (plus_minus_ranges): New. + (adjust_op1_for_overflow): New. + (operator_plus::op1_range): Use new adjustment. + (operator_plus::op2_range): Ditto. + (operator_minus::op1_range): Ditto. + * value-relation.h (relation_lt_le_gt_ge_p): New. + +2022-09-29 Andrew MacLeod <amacleod@redhat.com> + + * gimple-range-gori.cc (gori_compute::refine_using_relation): New. + (gori_compute::compute_operand1_range): Invoke + refine_using_relation when applicable. + (gori_compute::compute_operand2_range): Ditto. + * gimple-range-gori.h (class gori_compute): Adjust prototypes. + +2022-09-29 Andrew MacLeod <amacleod@redhat.com> + + * gimple-range-gori.cc (ori_compute::compute_operand_range): + Create a relation record and pass it along when possible. + (gori_compute::compute_operand1_range): Pass relation along. + (gori_compute::compute_operand2_range): Ditto. + (gori_compute::compute_operand1_and_operand2_range): Ditto. + * gimple-range-gori.h (class gori_compute): Adjust prototypes. + * gimple-range-op.cc (gimple_range_op_handler::calc_op1): Pass + relation to op1_range call. + (gimple_range_op_handler::calc_op2): Pass relation to op2_range call. + * gimple-range-op.h (class gimple_range_op_handler): Adjust + prototypes. + +2022-09-29 Andrew MacLeod <amacleod@redhat.com> + + * value-relation.cc (class value_relation): Move to .h file. + (value_relation::set_relation): Ditto. + (value_relation::value_relation): ditto. + * value-relation.h (class value_relation): Move from .cc file. + (value_relation::set_relation): Ditto + (value_relation::value_relation): Ditto. + +2022-09-29 Andrew MacLeod <amacleod@redhat.com> + + * range-op.cc (operator_minus::op2_range): Check for undefined. + (operator_mult::op1_range): Ditto. + (operator_exact_divide::op1_range): Ditto. + (operator_lshift::op1_range): Ditto. + (operator_rshift::op1_range): Ditto. + (operator_cast::op1_range): Ditto. + (operator_bitwise_and::op1_range): Ditto. + (operator_bitwise_or::op1_range): Ditto. + (operator_trunc_mod::op1_range): Ditto. + (operator_trunc_mod::op2_range): Ditto. + (operator_bitwise_not::op1_range): Ditto. + (pointer_or_operator::op1_range): Ditto. + (range_op_handler::op1_range): Ditto. + (range_op_handler::op2_range): Ditto. + +2022-09-29 Andrew Stubbs <ams@codesourcery.com> + + * config/gcn/gcn.cc (gcn_simd_clone_compute_vecsize_and_simdlen): + Remove unused elt_bits variable. + +2022-09-29 Olivier Hainque <hainque@adacore.com> + + * config/vxworks.h: Add comment on our use of + HAVE_INITFINI_ARRAY_SUPPORT. + +2022-09-29 Olivier Hainque <hainque@adacore.com> + + * config/aarch64/t-aarch64-vxworks: Request multilib + variants for mcmodel=large. + +2022-09-29 Olivier Hainque <hainque@adacore.com> + + * config/rs6000/vxworks.h (TARGET_FLOAT128_ENABLE_TYPE): Remove + resetting to 0. + +2022-09-29 Olivier Hainque <hainque@adacore.com> + + * config/vx-common.h (DWARF2_UNWIND_INFO): #define to 0 + when ARM_UNWIND_INFO is set. + +2022-09-29 Julian Brown <julian@codesourcery.com> + + PR middle-end/107028 + * gimplify.cc (omp_check_mapping_compatibility, + oacc_resolve_clause_dependencies): New functions. + (omp_accumulate_sibling_list): Remove redundant duplicate clause + detection for OpenACC. + (build_struct_sibling_lists): Skip deleted groups. Don't build sibling + list for struct variables that are fully mapped on the same directive + for OpenACC. + (gimplify_scan_omp_clauses): Call oacc_resolve_clause_dependencies. + +2022-09-29 Jose E. Marchesi <jose.marchesi@oracle.com> + + PR middle-end/25521 + * varasm.cc (categorize_decl_for_section): Place `const volatile' + objects in read-only sections. + (default_select_section): Likewise. + +2022-09-29 Richard Sandiford <richard.sandiford@arm.com> + + * tree-data-ref.cc (dr_may_alias_p): Use to_poly_widest instead + of to_widest. + +2022-09-29 Richard Sandiford <richard.sandiford@arm.com> + + * config/aarch64/aarch64.h (TARGET_CRYPTO, TARGET_SHA3, TARGET_SM4) + (TARGET_DOTPROD): Don't depend on TARGET_SIMD. + (TARGET_AES, TARGET_SHA2): Likewise. Remove TARGET_CRYPTO test. + (TARGET_FP_F16INST): Don't depend on TARGET_FLOAT. + (TARGET_SVE2, TARGET_SVE_F32MM, TARGET_SVE_F64MM): Don't depend + on TARGET_SVE. + (TARGET_SVE2_AES, TARGET_SVE2_BITPERM, TARGET_SVE2_SHA3) + (TARGET_SVE2_SM4): Don't depend on TARGET_SVE2. + (TARGET_F32MM, TARGET_F64MM): Delete. + * config/aarch64/aarch64-c.cc (aarch64_update_cpp_builtins): Guard + float macros with just TARGET_FLOAT rather than TARGET_FLOAT + || TARGET_SIMD. + * config/aarch64/aarch64-simd.md (copysign<mode>3): Depend + only on TARGET_SIMD, rather than TARGET_FLOAT && TARGET_SIMD. + (aarch64_crypto_aes<aes_op>v16qi): Depend only on TARGET_AES, + rather than TARGET_SIMD && TARGET_AES. + (aarch64_crypto_aes<aesmc_op>v16qi): Likewise. + (*aarch64_crypto_aese_fused): Likewise. + (*aarch64_crypto_aesd_fused): Likewise. + (aarch64_crypto_pmulldi): Likewise. + (aarch64_crypto_pmullv2di): Likewise. + (aarch64_crypto_sha1hsi): Likewise TARGET_SHA2. + (aarch64_crypto_sha1hv4si): Likewise. + (aarch64_be_crypto_sha1hv4si): Likewise. + (aarch64_crypto_sha1su1v4si): Likewise. + (aarch64_crypto_sha1<sha1_op>v4si): Likewise. + (aarch64_crypto_sha1su0v4si): Likewise. + (aarch64_crypto_sha256h<sha256_op>v4si): Likewise. + (aarch64_crypto_sha256su0v4si): Likewise. + (aarch64_crypto_sha256su1v4si): Likewise. + (aarch64_crypto_sha512h<sha512_op>qv2di): Likewise TARGET_SHA3. + (aarch64_crypto_sha512su0qv2di): Likewise. + (aarch64_crypto_sha512su1qv2di, eor3q<mode>4): Likewise. + (aarch64_rax1qv2di, aarch64_xarqv2di, bcaxq<mode>4): Likewise. + (aarch64_sm3ss1qv4si): Likewise TARGET_SM4. + (aarch64_sm3tt<sm3tt_op>qv4si): Likewise. + (aarch64_sm3partw<sm3part_op>qv4si): Likewise. + (aarch64_sm4eqv4si, aarch64_sm4ekeyqv4si): Likewise. + * config/aarch64/aarch64.md (<FLOATUORS:optab>dihf2) + (copysign<GPF:mode>3, copysign<GPF:mode>3_insn) + (xorsign<mode>3): Remove redundant TARGET_FLOAT condition. + +2022-09-29 Richard Sandiford <richard.sandiford@arm.com> + + * config/aarch64/aarch64.opt (aarch64_asm_isa_flags): New variable. + * config/aarch64/aarch64.h (aarch64_asm_isa_flags) + (aarch64_isa_flags): Redefine as read-only macros. + (TARGET_SIMD, TARGET_FLOAT, TARGET_SVE): Don't depend on + !TARGET_GENERAL_REGS_ONLY. + * common/config/aarch64/aarch64-common.cc + (aarch64_set_asm_isa_flags): New function. + (aarch64_handle_option): Call it when updating -mgeneral-regs. + * config/aarch64/aarch64-protos.h (aarch64_simd_switcher): Replace + m_old_isa_flags with m_old_asm_isa_flags. + (aarch64_set_asm_isa_flags): Declare. + * config/aarch64/aarch64-builtins.cc + (aarch64_simd_switcher::aarch64_simd_switcher) + (aarch64_simd_switcher::~aarch64_simd_switcher): Save and restore + aarch64_asm_isa_flags instead of aarch64_isa_flags. + * config/aarch64/aarch64-sve-builtins.cc + (check_required_extensions): Use aarch64_asm_isa_flags instead + of aarch64_isa_flags. + * config/aarch64/aarch64.cc (aarch64_set_asm_isa_flags): New function. + (aarch64_override_options, aarch64_handle_attr_arch) + (aarch64_handle_attr_cpu, aarch64_handle_attr_isa_flags): Use + aarch64_set_asm_isa_flags to set the ISA flags. + (aarch64_option_print, aarch64_declare_function_name) + (aarch64_start_file): Use aarch64_asm_isa_flags instead + of aarch64_isa_flags. + (aarch64_can_inline_p): Check aarch64_asm_isa_flags as well as + aarch64_isa_flags. + +2022-09-29 Richard Sandiford <richard.sandiford@arm.com> + + * common/config/aarch64/aarch64-common.cc (all_extensions): + Include the feature flag in flags_on and flags_off. + (aarch64_parse_extension): Update accordingly. + (aarch64_get_extension_string_for_isa_flags): Likewise. + +2022-09-29 Richard Sandiford <richard.sandiford@arm.com> + + * common/config/aarch64/aarch64-common.cc: Use aarch64_feature_flags + for feature flags throughout. + * config/aarch64/aarch64-protos.h: Likewise. + * config/aarch64/aarch64-sve-builtins.h: Likewise. + * config/aarch64/aarch64-sve-builtins.cc: Likewise. + * config/aarch64/aarch64.cc: Likewise. + * config/aarch64/aarch64.opt: Likewise. + * config/aarch64/driver-aarch64.cc: Likewise. + +2022-09-29 Richard Sandiford <richard.sandiford@arm.com> + + * common/config/aarch64/aarch64-common.cc (aarch64_option_extension) + (processor_name_to_arch, arch_to_arch_name): Remove const from + member variables. + (all_extensions, all_cores, all_architectures): Make a constexpr. + * config/aarch64/aarch64.cc (processor): Remove const from + member variables. + (all_architectures): Make a constexpr. + * config/aarch64/driver-aarch64.cc (aarch64_core_data) + (aarch64_arch_driver_info): Remove const from member variables. + (aarch64_cpu_data, aarch64_arches): Make a constexpr. + (get_arch_from_id): Return a pointer to const. + (host_detect_local_cpu): Update accordingly. + +2022-09-29 Richard Sandiford <richard.sandiford@arm.com> + + * common/config/aarch64/aarch64-common.cc (processor_name_to_arch) + (arch_to_arch_name): Use const char * instead of std::string. + +2022-09-29 Richard Sandiford <richard.sandiford@arm.com> + + * common/config/aarch64/aarch64-common.cc + (TARGET_OPTION_INIT_STRUCT): Delete. + (aarch64_option_extension): Remove is_synthetic_flag. + (all_extensions): Update accordingly. + (all_extensions_by_on, opt_ext, opt_ext_cmp): Delete. + (aarch64_option_init_struct, aarch64_contains_opt): Delete. + (aarch64_get_extension_string_for_isa_flags): Rewrite to use + all_extensions instead of all_extensions_on. + +2022-09-29 Richard Sandiford <richard.sandiford@arm.com> + + * config/aarch64/aarch64-option-extensions.def: Switch to a new format. + * config/aarch64/aarch64-cores.def: Use the same format to specify + lists of features. + * config/aarch64/aarch64-arches.def: Likewise, moving that information + from aarch64.h. + * config/aarch64/aarch64-opts.h (aarch64_feature_flags): New typedef. + * config/aarch64/aarch64.h (aarch64_feature): New class enum. + Turn AARCH64_FL_* macros into constexprs, getting the definitions + from aarch64-option-extensions.def. Remove AARCH64_FL_FOR_* macros. + * common/config/aarch64/aarch64-common.cc: Include + aarch64-feature-deps.h. + (all_extensions): Update for new .def format. + (all_extensions_by_on, all_cores, all_architectures): Likewise. + * config/aarch64/driver-aarch64.cc: Include aarch64-feature-deps.h. + (aarch64_extensions): Update for new .def format. + (aarch64_cpu_data, aarch64_arches): Likewise. + * config/aarch64/aarch64.cc: Include aarch64-feature-deps.h. + (all_architectures, all_cores): Update for new .def format. + * config/aarch64/aarch64-sve-builtins.cc + (check_required_extensions): Likewise. + * config/aarch64/aarch64-feature-deps.h: New file. + +2022-09-29 Richard Sandiford <richard.sandiford@arm.com> + + * config/aarch64/aarch64-option-extensions.def: Move crypto + after sha2. + +2022-09-29 Richard Sandiford <richard.sandiford@arm.com> + + * config/aarch64/aarch64-option-extensions.def (dotprod): Depend + on fp as well as simd. + (sha3): Likewise. + (aes): Likewise. Make +noaes disable crypto. + (sha2): Likewise +nosha2. Also make +nosha2 disable sha3 and + sve2-sha3. + (sve2-sha3): Depend on sha2 as well as sha3. + +2022-09-29 Richard Sandiford <richard.sandiford@arm.com> + + PR target/107025 + * config/aarch64/aarch64.h (oAARCH64_FL_RCPC8_4): Delete. + (AARCH64_FL_FOR_V8_4A): Update accordingly. + (AARCH64_ISA_RCPC8_4): Use AARCH64_FL_V8_4A directly. + * config/aarch64/aarch64-cores.def (thunderx3t110): Remove + AARCH64_FL_RCPC8_4. + +2022-09-29 Richard Sandiford <richard.sandiford@arm.com> + + * config/aarch64/aarch64-cores.def: Remove AARCH64_FL_FOR_<ARCH> + from the flags field. + * common/config/aarch64/aarch64-common.cc (all_cores): Add it + here instead. + * config/aarch64/aarch64.cc (all_cores): Likewise. + * config/aarch64/driver-aarch64.cc (all_cores): Likewise. + +2022-09-29 Richard Sandiford <richard.sandiford@arm.com> + + * config.gcc: Remove dead aarch64-option-extensions.def code. + * config/aarch64/aarch64-arches.def: Update comment. + +2022-09-29 Richard Sandiford <richard.sandiford@arm.com> + + * config/aarch64/aarch64-arches.def: Add a leading "V" to the + ARCH_IDENT fields. + * config/aarch64/aarch64-cores.def: Update accordingly. + * common/config/aarch64/aarch64-common.cc (all_cores): Likewise. + * config/aarch64/aarch64.cc (all_cores): Likewise. + * config/aarch64/driver-aarch64.cc (aarch64_arches): Skip the + leading "V". + +2022-09-29 Richard Sandiford <richard.sandiford@arm.com> + + * config/aarch64/aarch64.h (AARCH64_FL_FOR_ARCH8): Rename to... + (AARCH64_FL_FOR_V8A): ...this. + (AARCH64_FL_FOR_ARCH8_1): Rename to... + (AARCH64_FL_FOR_V8_1A): ...this. + (AARCH64_FL_FOR_ARCH8_2): Rename to... + (AARCH64_FL_FOR_V8_2A): ...this. + (AARCH64_FL_FOR_ARCH8_3): Rename to... + (AARCH64_FL_FOR_V8_3A): ...this. + (AARCH64_FL_FOR_ARCH8_4): Rename to... + (AARCH64_FL_FOR_V8_4A): ...this. + (AARCH64_FL_FOR_ARCH8_5): Rename to... + (AARCH64_FL_FOR_V8_5A): ...this. + (AARCH64_FL_FOR_ARCH8_6): Rename to... + (AARCH64_FL_FOR_V8_6A): ...this. + (AARCH64_FL_FOR_ARCH8_7): Rename to... + (AARCH64_FL_FOR_V8_7A): ...this. + (AARCH64_FL_FOR_ARCH8_8): Rename to... + (AARCH64_FL_FOR_V8_8A): ...this. + (AARCH64_FL_FOR_ARCH8_R): Rename to... + (AARCH64_FL_FOR_V8R): ...this. + (AARCH64_FL_FOR_ARCH9): Rename to... + (AARCH64_FL_FOR_V9A): ...this. + (AARCH64_FL_FOR_ARCH9_1): Rename to... + (AARCH64_FL_FOR_V9_1A): ...this. + (AARCH64_FL_FOR_ARCH9_2): Rename to... + (AARCH64_FL_FOR_V9_2A): ...this. + (AARCH64_FL_FOR_ARCH9_3): Rename to... + (AARCH64_FL_FOR_V9_3A): ...this. + * common/config/aarch64/aarch64-common.cc (all_cores): Update + accordingly. + * config/aarch64/aarch64-arches.def: Likewise. + * config/aarch64/aarch64-cores.def: Likewise. + * config/aarch64/aarch64.cc (all_cores): Likewise. + +2022-09-29 Richard Sandiford <richard.sandiford@arm.com> + + * config/aarch64/aarch64.h (AARCH64_FL_V8_1, AARCH64_FL_V8_2) + (AARCH64_FL_V8_3, AARCH64_FL_V8_4, AARCH64_FL_V8_5, AARCH64_FL_V8_6) + (AARCH64_FL_V9, AARCH64_FL_V8_7, AARCH64_FL_V8_8, AARCH64_FL_V9_1) + (AARCH64_FL_V9_2, AARCH64_FL_V9_3): Add "A" to the end of the name. + (AARCH64_FL_V8_R): Rename to AARCH64_FL_V8R. + (AARCH64_FL_FOR_ARCH8_1, AARCH64_FL_FOR_ARCH8_2): Update accordingly. + (AARCH64_FL_FOR_ARCH8_3, AARCH64_FL_FOR_ARCH8_4): Likewise. + (AARCH64_FL_FOR_ARCH8_5, AARCH64_FL_FOR_ARCH8_6): Likewise. + (AARCH64_FL_FOR_ARCH8_7, AARCH64_FL_FOR_ARCH8_8): Likewise. + (AARCH64_FL_FOR_ARCH8_R, AARCH64_FL_FOR_ARCH9): Likewise. + (AARCH64_FL_FOR_ARCH9_1, AARCH64_FL_FOR_ARCH9_2): Likewise. + (AARCH64_FL_FOR_ARCH9_3, AARCH64_ISA_V8_2A, AARCH64_ISA_V8_3A) + (AARCH64_ISA_V8_4A, AARCH64_ISA_V8_5A, AARCH64_ISA_V8_6A): Likewise. + (AARCH64_ISA_V8R, AARCH64_ISA_V9A, AARCH64_ISA_V9_1A): Likewise. + (AARCH64_ISA_V9_2A, AARCH64_ISA_V9_3A): Likewise. + +2022-09-29 Richard Sandiford <richard.sandiford@arm.com> + + * config/aarch64/aarch64.h (AARCH64_ISA_V8_2, AARCH64_ISA_V8_3) + (AARCH64_ISA_V8_4, AARCH64_ISA_V8_5, AARCH64_ISA_V8_6) + (AARCH64_ISA_V9, AARCH64_ISA_V9_1, AARCH64_ISA_V9_2) + (AARCH64_ISA_V9_3): Add "A" to the end of the name. + (AARCH64_ISA_V8_R): Rename to AARCH64_ISA_V8R. + (TARGET_ARMV8_3, TARGET_JSCVT, TARGET_FRINT, TARGET_MEMTAG): Update + accordingly. + * common/config/aarch64/aarch64-common.cc + (aarch64_get_extension_string_for_isa_flags): Likewise. + * config/aarch64/aarch64-c.cc + (aarch64_define_unconditional_macros): Likewise. + +2022-09-29 Richard Sandiford <richard.sandiford@arm.com> + + * Makefile.in (GTFILES): Add OPTIONS_H_EXTRA. + +2022-09-29 Jakub Jelinek <jakub@redhat.com> + + PR bootstrap/107059 + * cppdefault.cc (cpp_include_defaults): If SYSROOT_HEADERS_SUFFIX_SPEC + isn't defined, add FIXED_INCLUDE_DIR entry with multilib flag 2 + before FIXED_INCLUDE_DIR entry with multilib flag 0. + * gcc.cc (do_spec_1): If multiarch_dir, add + include-fixed/multiarch_dir paths before include-fixed paths. + +2022-09-29 Martin Liska <mliska@suse.cz> + + PR driver/106897 + * common.opt: Add -gz=zstd value. + * configure.ac: Detect --compress-debug-sections=zstd + for both linker and assembler. + * configure: Regenerate. + * gcc.cc (LINK_COMPRESS_DEBUG_SPEC): Handle -gz=zstd. + (ASM_COMPRESS_DEBUG_SPEC): Likewise. + +2022-09-29 Richard Biener <rguenther@suse.de> + + PR tree-optimization/105646 + * tree-ssa-uninit.cc (warn_uninitialized_vars): Pre-compute + the set of fallthru reachable blocks from function entry + and use that to determine wlims.always_executed. + +2022-09-29 liuhongt <hongtao.liu@intel.com> + + PR tree-optimization/107055 + * tree-vect-loop-manip.cc (vect_can_advance_ivs_p): Check for + nonlinear induction variables. + * tree-vect-loop.cc (vect_can_peel_nonlinear_iv_p): New + functions. + (vectorizable_nonlinear_induction): Put part codes into + vect_can_peel_nonlinear_iv_p. + * tree-vectorizer.h (vect_can_peel_nonlinear_iv_p): Declare. + 2022-09-28 Eugene Rozenfeld <erozen@microsoft.com> * basic-block.h: Remove discriminator from basic blocks. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index ea4b4d1..59c7fe2 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20220929 +20221004 diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 59b67d9..c1d0438 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -2661,6 +2661,7 @@ s-match: build/genmatch$(build_exeext) $(srcdir)/match.pd cfn-operators.pd GTFILES = $(CPPLIB_H) $(srcdir)/input.h $(srcdir)/coretypes.h \ $(host_xm_file_list) \ + $(OPTIONS_H_EXTRA) \ $(tm_file_list) $(HASHTAB_H) $(SPLAY_TREE_H) $(srcdir)/bitmap.h \ $(srcdir)/wide-int.h $(srcdir)/alias.h \ $(srcdir)/coverage.cc $(srcdir)/rtl.h \ diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index db4ac0d..be8371d 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,24 @@ +2022-09-29 Ronan Desplanques <desplanques@adacore.com> + + * einfo.ads: remove documentation duplicate + +2022-09-29 Eric Botcazou <ebotcazou@adacore.com> + + * contracts.adb (Build_Subprogram_Contract_Wrapper): Put back the + extended return statement if the result type is built-in-place. + * sem_attr.adb (Analyze_Attribute_Old_Result): Also expect an + extended return statement. + +2022-09-29 Bob Duff <duff@adacore.com> + + * exp_ch5.adb + (Expand_Assign_Array_Loop_Or_Bitfield): Make the checks for + volatile and independent objects more precise. + +2022-09-29 Piotr Trojanek <trojanek@adacore.com> + + * sem_util.adb (Collect_Visible_States): Ignore package renamings. + 2022-09-26 Ghjuvan Lacambre <lacambre@adacore.com> * doc/gnat_rm/implementation_defined_attributes.rst: Rename Valid_Image. diff --git a/gcc/ada/contracts.adb b/gcc/ada/contracts.adb index dd573d3..a300d73 100644 --- a/gcc/ada/contracts.adb +++ b/gcc/ada/contracts.adb @@ -30,6 +30,7 @@ with Einfo.Entities; use Einfo.Entities; with Einfo.Utils; use Einfo.Utils; with Elists; use Elists; with Errout; use Errout; +with Exp_Ch6; use Exp_Ch6; with Exp_Prag; use Exp_Prag; with Exp_Tss; use Exp_Tss; with Exp_Util; use Exp_Util; @@ -1609,7 +1610,7 @@ package body Contracts is -- preserving the result for the purpose of evaluating postconditions, -- contracts, type invariants, etc. - -- In the case of a function, generate: + -- In the case of a regular function, generate: -- -- function Original_Func (X : in out Integer) return Typ is -- <prologue renamings> @@ -1641,7 +1642,27 @@ package body Contracts is -- Note that an extended return statement does not yield the same result -- because the copy of the return object is not elided by GNAT for now. - -- Or, in the case of a procedure: + -- Or else, in the case of a BIP function, generate: + + -- function Original_Func (X : in out Integer) return Typ is + -- <prologue renamings> + -- <preconditions> + -- + -- function _Wrapped_Statements return Typ is + -- <original declarations> + -- begin + -- <original statements> + -- end; + -- + -- begin + -- return + -- Result_Obj : constant Typ := _Wrapped_Statements + -- do + -- <postconditions statments> + -- end return; + -- end; + + -- Or else, in the case of a procedure, generate: -- -- procedure Original_Proc (X : in out Integer) is -- <prologue renamings> @@ -1657,7 +1678,6 @@ package body Contracts is -- _Wrapped_Statements; -- <postconditions statments> -- end; - -- -- Create Identifier @@ -1716,6 +1736,26 @@ package body Contracts is Set_Statements (Handled_Statement_Sequence (Body_Decl), Stmts); + -- Generate the post-execution statements and the extended return + -- when the subprogram being wrapped is a BIP function. + + elsif Is_Build_In_Place_Result_Type (Ret_Type) then + Set_Statements (Handled_Statement_Sequence (Body_Decl), New_List ( + Make_Extended_Return_Statement (Loc, + Return_Object_Declarations => New_List ( + Make_Object_Declaration (Loc, + Defining_Identifier => Result, + Constant_Present => True, + Object_Definition => + New_Occurrence_Of (Ret_Type, Loc), + Expression => + Make_Function_Call (Loc, + Name => + New_Occurrence_Of (Wrapper_Id, Loc)))), + Handled_Statement_Sequence => + Make_Handled_Sequence_Of_Statements (Loc, + Statements => Stmts)))); + -- Declare a renaming of the result of the call to the wrapper and -- append a return of the result of the call when the subprogram is -- a function, after manually removing the side effects. Note that diff --git a/gcc/ada/einfo.ads b/gcc/ada/einfo.ads index 7ac8cf6..e350f13 100644 --- a/gcc/ada/einfo.ads +++ b/gcc/ada/einfo.ads @@ -222,10 +222,9 @@ package Einfo is -- on the actions triggered by a freeze node, which include the construction -- of initialization procedures and dispatch tables. --- b) The presence of a freeze node on an entity is used by the back end to --- defer elaboration of the entity until its freeze node is seen. In the --- absence of an explicit freeze node, an entity is frozen (and elaborated) --- at the point of declaration. +-- b) The flag is used by the back end to defer elaboration of the entity +-- until its freeze node is seen. In the absence of an explicit freeze node, +-- an entity is frozen (and elaborated) at the point of declaration. -- For object declarations, the flag is set when an address clause for the -- object is encountered. Legality checks on the address expression only take @@ -4825,39 +4824,6 @@ package Einfo is -- The front-end does not store explicitly the fact that Z renames X. --------------------------------------- --- Delayed Freezing and Elaboration -- --------------------------------------- - --- The flag Has_Delayed_Freeze indicates that an entity carries an explicit --- freeze node, which appears later in the expanded tree. - --- a) The flag is used by the front-end to trigger expansion actions --- which include the generation of that freeze node. Typically this happens at --- the end of the current compilation unit, or before the first subprogram --- body is encountered in the current unit. See files freeze and exp_ch13 for --- details on the actions triggered by a freeze node, which include the --- construction of initialization procedures and dispatch tables. - --- b) The flag is used by the backend to defer elaboration of the entity until --- its freeze node is seen. In the absence of an explicit freeze node, an --- entity is frozen (and elaborated) at the point of declaration. - --- For object declarations, the flag is set when an address clause for the --- object is encountered. Legality checks on the address expression only --- take place at the freeze point of the object. - --- Most types have an explicit freeze node, because they cannot be elaborated --- until all representation and operational items that apply to them have been --- analyzed. Private types and incomplete types have the flag set as well, as --- do task and protected types. - --- Implicit base types created for type derivations, as well as classwide --- types created for all tagged types, have the flag set. - --- If a subprogram has an access parameter whose designated type is incomplete --- the subprogram has the flag set. - ------------------ -- Access Kinds -- ------------------ diff --git a/gcc/ada/exp_ch5.adb b/gcc/ada/exp_ch5.adb index 2e14c97..209741c 100644 --- a/gcc/ada/exp_ch5.adb +++ b/gcc/ada/exp_ch5.adb @@ -1594,35 +1594,86 @@ package body Exp_Ch5 is Rev : Boolean) return Node_Id is + function Volatile_Or_Independent + (Exp : Node_Id; Typ : Entity_Id) return Boolean; + -- Exp is an expression of type Typ, or if there is no expression + -- involved, Exp is Empty. True if there are any volatile or independent + -- objects that should disable the optimization. We check the object + -- itself, all subcomponents, and if Exp is a slice of a component or + -- slice, we check the prefix and its type. + -- + -- We disable the optimization when there are relevant volatile or + -- independent objects, because Copy_Bitfield can read and write bits + -- that are not part of the objects being copied. + + ----------------------------- + -- Volatile_Or_Independent -- + ----------------------------- + + function Volatile_Or_Independent + (Exp : Node_Id; Typ : Entity_Id) return Boolean + is + begin + -- Initially, Exp is the left- or right-hand side. In recursive + -- calls, Exp is Empty if we're just checking a component type, and + -- Exp is the prefix if we're checking the prefix of a slice. + + if Present (Exp) + and then (Is_Volatile_Object_Ref (Exp) + or else Is_Independent_Object (Exp)) + then + return True; + end if; + + if Has_Volatile_Components (Typ) + or else Has_Independent_Components (Typ) + then + return True; + end if; + + if Is_Array_Type (Typ) then + return Volatile_Or_Independent (Empty, Component_Type (Typ)); + elsif Is_Record_Type (Typ) then + declare + Comp : Entity_Id := First_Component (Typ); + begin + while Present (Comp) loop + if Volatile_Or_Independent (Empty, Comp) then + return True; + end if; + + Next_Component (Comp); + end loop; + end; + end if; + + if Nkind (Exp) = N_Slice + and then Nkind (Prefix (Exp)) in + N_Selected_Component | N_Indexed_Component | N_Slice + then + if Volatile_Or_Independent (Prefix (Exp), Etype (Prefix (Exp))) + then + return True; + end if; + end if; + + return False; + end Volatile_Or_Independent; + L : constant Node_Id := Name (N); R : constant Node_Id := Expression (N); -- Left- and right-hand sides of the assignment statement Slices : constant Boolean := Nkind (L) = N_Slice or else Nkind (R) = N_Slice; - L_Prefix_Comp : constant Boolean := - -- True if the left-hand side is a slice of a component or slice - Nkind (L) = N_Slice - and then Nkind (Prefix (L)) in - N_Selected_Component | N_Indexed_Component | N_Slice; - R_Prefix_Comp : constant Boolean := - -- Likewise for the right-hand side - Nkind (R) = N_Slice - and then Nkind (Prefix (R)) in - N_Selected_Component | N_Indexed_Component | N_Slice; + + -- Start of processing for Expand_Assign_Array_Loop_Or_Bitfield begin -- Determine whether Copy_Bitfield or Fast_Copy_Bitfield is appropriate -- (will work, and will be more efficient than component-by-component -- copy). Copy_Bitfield doesn't work for reversed storage orders. It is - -- efficient for slices of bit-packed arrays. Copy_Bitfield can read and - -- write bits that are not part of the objects being copied, so we don't - -- want to use it if there are volatile or independent components. If - -- the Prefix of the slice is a component or slice, then it might be a - -- part of an object with some other volatile or independent components, - -- so we disable the optimization in that case as well. We could - -- complicate this code by actually looking for such volatile and - -- independent components. + -- efficient for slices of bit-packed arrays. if Is_Bit_Packed_Array (L_Type) and then Is_Bit_Packed_Array (R_Type) @@ -1630,12 +1681,8 @@ package body Exp_Ch5 is and then not Reverse_Storage_Order (R_Type) and then Ndim = 1 and then Slices - and then not Has_Volatile_Component (L_Type) - and then not Has_Volatile_Component (R_Type) - and then not Has_Independent_Components (L_Type) - and then not Has_Independent_Components (R_Type) - and then not L_Prefix_Comp - and then not R_Prefix_Comp + and then not Volatile_Or_Independent (L, L_Type) + and then not Volatile_Or_Independent (R, R_Type) then -- Here if Copy_Bitfield can work (except for the Rev test below). -- Determine whether to call Fast_Copy_Bitfield instead. If we diff --git a/gcc/ada/sem_attr.adb b/gcc/ada/sem_attr.adb index 0c88be7..d27d956 100644 --- a/gcc/ada/sem_attr.adb +++ b/gcc/ada/sem_attr.adb @@ -1454,10 +1454,12 @@ package body Sem_Attr is Subp_Decl := Find_Related_Declaration_Or_Body (Prag); end if; - -- 'Old objects appear in block statements as part of the expansion - -- of contract wrappers. + -- 'Old objects appear in block and extended return statements as + -- part of the expansion of contract wrappers. - if Nkind (Subp_Decl) = N_Block_Statement then + if Nkind (Subp_Decl) in N_Block_Statement + | N_Extended_Return_Statement + then Subp_Decl := Parent (Parent (Subp_Decl)); end if; diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb index 9ae082c..25e886e 100644 --- a/gcc/ada/sem_util.adb +++ b/gcc/ada/sem_util.adb @@ -6018,8 +6018,11 @@ package body Sem_Util is Append_New_Elmt (Item_Id, States); -- Recursively gather the visible states of a nested package + -- except for nested package renamings. - elsif Ekind (Item_Id) = E_Package then + elsif Ekind (Item_Id) = E_Package + and then No (Renamed_Entity (Item_Id)) + then Collect_Visible_States (Item_Id, States); end if; diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index a9ed2f0..ea4b254 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,31 @@ +2022-10-03 Patrick Palka <ppalka@redhat.com> + + * c-common.cc (c_common_reswords): Use RID_IS_SAME instead of + RID_IS_SAME_AS. + +2022-10-03 Joseph Myers <joseph@codesourcery.com> + + * c-cppbuiltin.cc (builtin_define_float_constants): Do not + special-case __*_EPSILON__ setting for IBM long double for C2x. + +2022-09-30 Patrick Palka <ppalka@redhat.com> + + * c-common.cc (c_common_reswords): Use cp/cp-trait.def to handle + C++ traits. + * c-common.h (enum rid): Likewise. + +2022-09-29 Joseph Myers <joseph@codesourcery.com> + + * c-lex.cc (c_common_has_attribute): Handle noreturn attribute for + C. + +2022-09-29 Patrick Palka <ppalka@redhat.com> + + * c-common.cc (c_common_reswords): Add __remove_cv, + __remove_reference and __remove_cvref. + * c-common.h (enum rid): Add RID_REMOVE_CV, RID_REMOVE_REFERENCE + and RID_REMOVE_CVREF. + 2022-09-27 Marek Polacek <polacek@redhat.com> PR c++/101165 diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc index cda6910..4f9878d 100644 --- a/gcc/c-family/c-common.cc +++ b/gcc/c-family/c-common.cc @@ -378,7 +378,6 @@ const struct c_common_resword c_common_reswords[] = { "__attribute", RID_ATTRIBUTE, 0 }, { "__attribute__", RID_ATTRIBUTE, 0 }, { "__auto_type", RID_AUTO_TYPE, D_CONLY }, - { "__bases", RID_BASES, D_CXXONLY }, { "__builtin_addressof", RID_ADDRESSOF, D_CXXONLY }, { "__builtin_bit_cast", RID_BUILTIN_BIT_CAST, D_CXXONLY }, { "__builtin_call_with_static_chain", @@ -401,44 +400,12 @@ const struct c_common_resword c_common_reswords[] = { "__const__", RID_CONST, 0 }, { "__constinit", RID_CONSTINIT, D_CXXONLY }, { "__decltype", RID_DECLTYPE, D_CXXONLY }, - { "__direct_bases", RID_DIRECT_BASES, D_CXXONLY }, { "__extension__", RID_EXTENSION, 0 }, { "__func__", RID_C99_FUNCTION_NAME, 0 }, - { "__has_nothrow_assign", RID_HAS_NOTHROW_ASSIGN, D_CXXONLY }, - { "__has_nothrow_constructor", RID_HAS_NOTHROW_CONSTRUCTOR, D_CXXONLY }, - { "__has_nothrow_copy", RID_HAS_NOTHROW_COPY, D_CXXONLY }, - { "__has_trivial_assign", RID_HAS_TRIVIAL_ASSIGN, D_CXXONLY }, - { "__has_trivial_constructor", RID_HAS_TRIVIAL_CONSTRUCTOR, D_CXXONLY }, - { "__has_trivial_copy", RID_HAS_TRIVIAL_COPY, D_CXXONLY }, - { "__has_trivial_destructor", RID_HAS_TRIVIAL_DESTRUCTOR, D_CXXONLY }, - { "__has_unique_object_representations", RID_HAS_UNIQUE_OBJ_REPRESENTATIONS, - D_CXXONLY }, - { "__has_virtual_destructor", RID_HAS_VIRTUAL_DESTRUCTOR, D_CXXONLY }, { "__imag", RID_IMAGPART, 0 }, { "__imag__", RID_IMAGPART, 0 }, { "__inline", RID_INLINE, 0 }, { "__inline__", RID_INLINE, 0 }, - { "__is_abstract", RID_IS_ABSTRACT, D_CXXONLY }, - { "__is_aggregate", RID_IS_AGGREGATE, D_CXXONLY }, - { "__is_base_of", RID_IS_BASE_OF, D_CXXONLY }, - { "__is_class", RID_IS_CLASS, D_CXXONLY }, - { "__is_empty", RID_IS_EMPTY, D_CXXONLY }, - { "__is_enum", RID_IS_ENUM, D_CXXONLY }, - { "__is_final", RID_IS_FINAL, D_CXXONLY }, - { "__is_layout_compatible", RID_IS_LAYOUT_COMPATIBLE, D_CXXONLY }, - { "__is_literal_type", RID_IS_LITERAL_TYPE, D_CXXONLY }, - { "__is_pointer_interconvertible_base_of", - RID_IS_POINTER_INTERCONVERTIBLE_BASE_OF, D_CXXONLY }, - { "__is_pod", RID_IS_POD, D_CXXONLY }, - { "__is_polymorphic", RID_IS_POLYMORPHIC, D_CXXONLY }, - { "__is_same", RID_IS_SAME_AS, D_CXXONLY }, - { "__is_same_as", RID_IS_SAME_AS, D_CXXONLY }, - { "__is_standard_layout", RID_IS_STD_LAYOUT, D_CXXONLY }, - { "__is_trivial", RID_IS_TRIVIAL, D_CXXONLY }, - { "__is_trivially_assignable", RID_IS_TRIVIALLY_ASSIGNABLE, D_CXXONLY }, - { "__is_trivially_constructible", RID_IS_TRIVIALLY_CONSTRUCTIBLE, D_CXXONLY }, - { "__is_trivially_copyable", RID_IS_TRIVIALLY_COPYABLE, D_CXXONLY }, - { "__is_union", RID_IS_UNION, D_CXXONLY }, { "__label__", RID_LABEL, 0 }, { "__null", RID_NULL, 0 }, { "__real", RID_REALPART, 0 }, @@ -453,7 +420,6 @@ const struct c_common_resword c_common_reswords[] = { "__transaction_cancel", RID_TRANSACTION_CANCEL, 0 }, { "__typeof", RID_TYPEOF, 0 }, { "__typeof__", RID_TYPEOF, 0 }, - { "__underlying_type", RID_UNDERLYING_TYPE, D_CXXONLY }, { "__volatile", RID_VOLATILE, 0 }, { "__volatile__", RID_VOLATILE, 0 }, { "__GIMPLE", RID_GIMPLE, D_CONLY }, @@ -537,16 +503,13 @@ const struct c_common_resword c_common_reswords[] = { "volatile", RID_VOLATILE, 0 }, { "wchar_t", RID_WCHAR, D_CXXONLY }, { "while", RID_WHILE, 0 }, - { "__is_assignable", RID_IS_ASSIGNABLE, D_CXXONLY }, - { "__is_constructible", RID_IS_CONSTRUCTIBLE, D_CXXONLY }, - { "__is_nothrow_assignable", RID_IS_NOTHROW_ASSIGNABLE, D_CXXONLY }, - { "__is_nothrow_constructible", RID_IS_NOTHROW_CONSTRUCTIBLE, D_CXXONLY }, - { "__is_convertible", RID_IS_CONVERTIBLE, D_CXXONLY }, - { "__is_nothrow_convertible", RID_IS_NOTHROW_CONVERTIBLE, D_CXXONLY }, - { "__reference_constructs_from_temporary", RID_REF_CONSTRUCTS_FROM_TEMPORARY, - D_CXXONLY }, - { "__reference_converts_from_temporary", RID_REF_CONVERTS_FROM_TEMPORARY, - D_CXXONLY }, + +#define DEFTRAIT(TCC, CODE, NAME, ARITY) \ + { NAME, RID_##CODE, D_CXXONLY }, +#include "cp/cp-trait.def" +#undef DEFTRAIT + /* An alias for __is_same. */ + { "__is_same_as", RID_IS_SAME, D_CXXONLY }, /* C++ transactional memory. */ { "synchronized", RID_SYNCHRONIZED, D_CXX_OBJC | D_TRANSMEM }, diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index 50a4691..5f470d9 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -163,30 +163,14 @@ enum rid RID_CONSTCAST, RID_DYNCAST, RID_REINTCAST, RID_STATCAST, /* C++ extensions */ - RID_ADDRESSOF, RID_BASES, - RID_BUILTIN_LAUNDER, RID_DIRECT_BASES, - RID_HAS_NOTHROW_ASSIGN, RID_HAS_NOTHROW_CONSTRUCTOR, - RID_HAS_NOTHROW_COPY, RID_HAS_TRIVIAL_ASSIGN, - RID_HAS_TRIVIAL_CONSTRUCTOR, RID_HAS_TRIVIAL_COPY, - RID_HAS_TRIVIAL_DESTRUCTOR, RID_HAS_UNIQUE_OBJ_REPRESENTATIONS, - RID_HAS_VIRTUAL_DESTRUCTOR, RID_BUILTIN_BIT_CAST, - RID_IS_ABSTRACT, RID_IS_AGGREGATE, - RID_IS_BASE_OF, RID_IS_CLASS, - RID_IS_EMPTY, RID_IS_ENUM, - RID_IS_FINAL, RID_IS_LAYOUT_COMPATIBLE, - RID_IS_LITERAL_TYPE, - RID_IS_POINTER_INTERCONVERTIBLE_BASE_OF, - RID_IS_POD, RID_IS_POLYMORPHIC, - RID_IS_SAME_AS, - RID_IS_STD_LAYOUT, RID_IS_TRIVIAL, - RID_IS_TRIVIALLY_ASSIGNABLE, RID_IS_TRIVIALLY_CONSTRUCTIBLE, - RID_IS_TRIVIALLY_COPYABLE, - RID_IS_UNION, RID_UNDERLYING_TYPE, - RID_IS_ASSIGNABLE, RID_IS_CONSTRUCTIBLE, - RID_IS_NOTHROW_ASSIGNABLE, RID_IS_NOTHROW_CONSTRUCTIBLE, - RID_IS_CONVERTIBLE, RID_IS_NOTHROW_CONVERTIBLE, - RID_REF_CONSTRUCTS_FROM_TEMPORARY, - RID_REF_CONVERTS_FROM_TEMPORARY, + RID_ADDRESSOF, + RID_BUILTIN_LAUNDER, + RID_BUILTIN_BIT_CAST, + +#define DEFTRAIT(TCC, CODE, NAME, ARITY) \ + RID_##CODE, +#include "cp/cp-trait.def" +#undef DEFTRAIT /* C++11 */ RID_CONSTEXPR, RID_DECLTYPE, RID_NOEXCEPT, RID_NULLPTR, RID_STATIC_ASSERT, diff --git a/gcc/c-family/c-cppbuiltin.cc b/gcc/c-family/c-cppbuiltin.cc index d4de5a0..4b8486c 100644 --- a/gcc/c-family/c-cppbuiltin.cc +++ b/gcc/c-family/c-cppbuiltin.cc @@ -279,7 +279,7 @@ builtin_define_float_constants (const char *name_prefix, /* The difference between 1 and the least value greater than 1 that is representable in the given floating point type, b**(1-p). */ sprintf (name, "__%s_EPSILON__", name_prefix); - if (fmt->pnan < fmt->p) + if (fmt->pnan < fmt->p && (c_dialect_cxx () || !flag_isoc2x)) /* This is an IBM extended double format, so 1.0 + any double is representable precisely. */ sprintf (buf, "0x1p%d", fmt->emin - fmt->p); diff --git a/gcc/c-family/c-lex.cc b/gcc/c-family/c-lex.cc index 4d2252f..d4e448a 100644 --- a/gcc/c-family/c-lex.cc +++ b/gcc/c-family/c-lex.cc @@ -389,6 +389,9 @@ c_common_has_attribute (cpp_reader *pfile, bool std_syntax) result = 202003; else if (is_attribute_p ("maybe_unused", attr_name)) result = 202106; + else if (is_attribute_p ("noreturn", attr_name) + || is_attribute_p ("_Noreturn", attr_name)) + result = 202202; } if (result) attr_name = NULL_TREE; diff --git a/gcc/c-family/c-omp.cc b/gcc/c-family/c-omp.cc index 7a97c40..5bb1035 100644 --- a/gcc/c-family/c-omp.cc +++ b/gcc/c-family/c-omp.cc @@ -3112,8 +3112,8 @@ const struct c_omp_directive c_omp_directives[] = { C_OMP_DIR_STANDALONE, false }, { "begin", "assumes", nullptr, PRAGMA_OMP_BEGIN, C_OMP_DIR_INFORMATIONAL, false }, - /* { "begin", "declare", "target", PRAGMA_OMP_BEGIN, - C_OMP_DIR_DECLARATIVE, false }, */ + { "begin", "declare", "target", PRAGMA_OMP_BEGIN, + C_OMP_DIR_DECLARATIVE, false }, /* { "begin", "declare", "variant", PRAGMA_OMP_BEGIN, C_OMP_DIR_DECLARATIVE, false }, */ /* { "begin", "metadirective", nullptr, PRAGMA_OMP_BEGIN, diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 7b29d78..f5c9a59 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,8 @@ +2022-09-29 Joseph Myers <joseph@codesourcery.com> + + * c-decl.cc (handle_std_noreturn_attribute): New function. + (std_attribute_table): Add _Noreturn and noreturn. + 2022-09-27 Jakub Jelinek <jakub@redhat.com> * c-lang.h (current_omp_begin_assumes): Declare. diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index 740982e..ffa63dc 100644 --- a/gcc/c/c-decl.cc +++ b/gcc/c/c-decl.cc @@ -153,9 +153,9 @@ static int warn_about_return_type; static bool undef_nested_function; -/* If non-zero, implicit "omp declare target" attribute is added into the - attribute lists. */ -int current_omp_declare_target_attribute; +/* Vector of implicit "omp declare target" attributes to be added into + the attribute lists. */ +vec<c_omp_declare_target_attr, va_gc> *current_omp_declare_target_attribute; /* If non-zero, we are inside of #pragma omp begin assumes ... #pragma omp end assumes region. */ @@ -4480,11 +4480,34 @@ handle_nodiscard_attribute (tree *node, tree name, tree /*args*/, } return NULL_TREE; } + +/* Handle the standard [[noreturn]] attribute. */ + +static tree +handle_std_noreturn_attribute (tree *node, tree name, tree args, + int flags, bool *no_add_attrs) +{ + /* Unlike GNU __attribute__ ((noreturn)), the standard [[noreturn]] + only applies to functions, not function pointers. */ + if (TREE_CODE (*node) == FUNCTION_DECL) + return handle_noreturn_attribute (node, name, args, flags, no_add_attrs); + else + { + pedwarn (input_location, OPT_Wattributes, + "standard %qE attribute can only be applied to functions", + name); + *no_add_attrs = true; + return NULL_TREE; + } +} + /* Table of supported standard (C2x) attributes. */ const struct attribute_spec std_attribute_table[] = { /* { name, min_len, max_len, decl_req, type_req, fn_type_req, affects_type_identity, handler, exclude } */ + { "_Noreturn", 0, 0, false, false, false, false, + handle_std_noreturn_attribute, NULL }, { "deprecated", 0, 1, false, false, false, false, handle_deprecated_attribute, NULL }, { "fallthrough", 0, 0, false, false, false, false, @@ -4493,6 +4516,8 @@ const struct attribute_spec std_attribute_table[] = handle_unused_attribute, NULL }, { "nodiscard", 0, 1, false, false, false, false, handle_nodiscard_attribute, NULL }, + { "noreturn", 0, 0, false, false, false, false, + handle_std_noreturn_attribute, NULL }, { NULL, 0, 0, false, false, false, false, NULL, NULL } }; @@ -5080,7 +5105,7 @@ static tree c_decl_attributes (tree *node, tree attributes, int flags) { /* Add implicit "omp declare target" attribute if requested. */ - if (current_omp_declare_target_attribute + if (vec_safe_length (current_omp_declare_target_attribute) && ((VAR_P (*node) && is_global_var (*node)) || TREE_CODE (*node) == FUNCTION_DECL)) { @@ -5094,6 +5119,22 @@ c_decl_attributes (tree *node, tree attributes, int flags) attributes = tree_cons (get_identifier ("omp declare target block"), NULL_TREE, attributes); } + if (TREE_CODE (*node) == FUNCTION_DECL) + { + int device_type + = current_omp_declare_target_attribute->last ().device_type; + device_type = MAX (device_type, 0); + if ((device_type & OMP_CLAUSE_DEVICE_TYPE_HOST) != 0 + && !lookup_attribute ("omp declare target host", attributes)) + attributes + = tree_cons (get_identifier ("omp declare target host"), + NULL_TREE, attributes); + if ((device_type & OMP_CLAUSE_DEVICE_TYPE_NOHOST) != 0 + && !lookup_attribute ("omp declare target nohost", attributes)) + attributes + = tree_cons (get_identifier ("omp declare target nohost"), + NULL_TREE, attributes); + } } /* Look up the current declaration with all the attributes merged diff --git a/gcc/c/c-lang.h b/gcc/c/c-lang.h index 861abe8..49a5ec3 100644 --- a/gcc/c/c-lang.h +++ b/gcc/c/c-lang.h @@ -60,9 +60,14 @@ struct GTY(()) language_function { int warn_about_return_type; }; +struct GTY(()) c_omp_declare_target_attr { + int device_type; +}; + /* If non-zero, implicit "omp declare target" attribute is added into the attribute lists. */ -extern GTY(()) int current_omp_declare_target_attribute; +extern GTY(()) vec<c_omp_declare_target_attr, va_gc> + *current_omp_declare_target_attribute; /* Similarly whether we are in between #pragma omp begin assumes and #pragma omp end assumes (and how many times when nested). */ extern GTY(()) int current_omp_begin_assumes; diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc index f2498dc..f6a94ba 100644 --- a/gcc/c/c-parser.cc +++ b/gcc/c/c-parser.cc @@ -1675,18 +1675,22 @@ c_parser_translation_unit (c_parser *parser) if (DECL_SIZE (decl) == NULL_TREE && TREE_TYPE (decl) != error_mark_node) error ("storage size of %q+D isn%'t known", decl); - if (current_omp_declare_target_attribute) + if (vec_safe_length (current_omp_declare_target_attribute)) { + c_omp_declare_target_attr + a = current_omp_declare_target_attribute->pop (); if (!errorcount) - error ("%<#pragma omp declare target%> without corresponding " - "%<#pragma omp end declare target%>"); - current_omp_declare_target_attribute = 0; + error ("%qs without corresponding %qs", + a.device_type >= 0 ? "#pragma omp begin declare target" + : "#pragma omp declare target", + "#pragma omp end declare target"); + vec_safe_truncate (current_omp_declare_target_attribute, 0); } if (current_omp_begin_assumes) { if (!errorcount) - error ("%<#pragma omp begin assumes%> without corresponding " - "%<#pragma omp end assumes%>"); + error ("%qs without corresponding %qs", + "#pragma omp begin assumes", "#pragma omp end assumes"); current_omp_begin_assumes = 0; } } @@ -16818,8 +16822,8 @@ c_parser_omp_clause_device_type (c_parser *parser, tree list) else goto invalid_kind; - /* check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE, - "device_type"); */ + check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE, + "device_type"); c_parser_consume_token (parser); parens.skip_until_found_close (parser); c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE_TYPE); @@ -22351,7 +22355,8 @@ c_parser_omp_declare_target (c_parser *parser) else { c_parser_skip_to_pragma_eol (parser); - current_omp_declare_target_attribute++; + c_omp_declare_target_attr attr = { -1 }; + vec_safe_push (current_omp_declare_target_attribute, attr); return; } for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c)) @@ -22429,12 +22434,17 @@ c_parser_omp_declare_target (c_parser *parser) } } if (device_type && only_device_type) - warning_at (OMP_CLAUSE_LOCATION (clauses), 0, - "directive with only %<device_type%> clauses ignored"); + error_at (OMP_CLAUSE_LOCATION (clauses), + "directive with only %<device_type%> clause"); } /* OpenMP 5.1 - #pragma omp begin assumes clauses[optseq] new-line */ + #pragma omp begin assumes clauses[optseq] new-line + + #pragma omp begin declare target clauses[optseq] new-line */ + +#define OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK \ + (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE) static void c_parser_omp_begin (c_parser *parser) @@ -22443,7 +22453,33 @@ c_parser_omp_begin (c_parser *parser) c_parser_consume_pragma (parser); if (c_parser_next_token_is (parser, CPP_NAME)) p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); - if (strcmp (p, "assumes") == 0) + if (strcmp (p, "declare") == 0) + { + c_parser_consume_token (parser); + p = ""; + if (c_parser_next_token_is (parser, CPP_NAME)) + p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); + if (strcmp (p, "target") == 0) + { + c_parser_consume_token (parser); + tree clauses + = c_parser_omp_all_clauses (parser, + OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK, + "#pragma omp begin declare target"); + int device_type = 0; + for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c)) + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE) + device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c); + c_omp_declare_target_attr attr = { device_type }; + vec_safe_push (current_omp_declare_target_attribute, attr); + } + else + { + c_parser_error (parser, "expected %<target%>"); + c_parser_skip_to_pragma_eol (parser); + } + } + else if (strcmp (p, "assumes") == 0) { c_parser_consume_token (parser); c_parser_omp_assumption_clauses (parser, false); @@ -22451,7 +22487,7 @@ c_parser_omp_begin (c_parser *parser) } else { - c_parser_error (parser, "expected %<assumes%>"); + c_parser_error (parser, "expected %<declare target%> or %<assumes%>"); c_parser_skip_to_pragma_eol (parser); } } @@ -22484,19 +22520,20 @@ c_parser_omp_end (c_parser *parser) return; } c_parser_skip_to_pragma_eol (parser); - if (!current_omp_declare_target_attribute) + if (!vec_safe_length (current_omp_declare_target_attribute)) error_at (loc, "%<#pragma omp end declare target%> without " - "corresponding %<#pragma omp declare target%>"); + "corresponding %<#pragma omp declare target%> or " + "%<#pragma omp begin declare target%>"); else - current_omp_declare_target_attribute--; + current_omp_declare_target_attribute->pop (); } else if (strcmp (p, "assumes") == 0) { c_parser_consume_token (parser); c_parser_skip_to_pragma_eol (parser); if (!current_omp_begin_assumes) - error_at (loc, "%<#pragma omp end assumes%> without " - "corresponding %<#pragma omp begin assumes%>"); + error_at (loc, "%qs without corresponding %qs", + "#pragma omp end assumes", "#pragma omp begin assumes"); else current_omp_begin_assumes--; } diff --git a/gcc/common.opt b/gcc/common.opt index 296d6f1..58dc1a0 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -3419,7 +3419,10 @@ EnumValue Enum(compressed_debug_sections) String(zlib) Value(1) EnumValue -Enum(compressed_debug_sections) String(zlib-gnu) Value(2) +Enum(compressed_debug_sections) String(zstd) Value(2) + +EnumValue +Enum(compressed_debug_sections) String(zlib-gnu) Value(3) gz Common Driver diff --git a/gcc/common/config/aarch64/aarch64-common.cc b/gcc/common/config/aarch64/aarch64-common.cc index 7fac90d..6100783 100644 --- a/gcc/common/config/aarch64/aarch64-common.cc +++ b/gcc/common/config/aarch64/aarch64-common.cc @@ -30,6 +30,7 @@ #include "opts.h" #include "flags.h" #include "diagnostic.h" +#include "config/aarch64/aarch64-feature-deps.h" #ifdef TARGET_BIG_ENDIAN_DEFAULT #undef TARGET_DEFAULT_TARGET_FLAGS @@ -41,8 +42,6 @@ #undef TARGET_OPTION_OPTIMIZATION_TABLE #define TARGET_OPTION_OPTIMIZATION_TABLE aarch_option_optimization_table -#undef TARGET_OPTION_INIT_STRUCT -#define TARGET_OPTION_INIT_STRUCT aarch64_option_init_struct /* Set default optimization options. */ static const struct default_options aarch_option_optimization_table[] = @@ -65,6 +64,17 @@ static const struct default_options aarch_option_optimization_table[] = { OPT_LEVELS_NONE, 0, NULL, 0 } }; +/* Set OPTS->x_aarch64_asm_isa_flags to FLAGS and update + OPTS->x_aarch64_isa_flags accordingly. */ +void +aarch64_set_asm_isa_flags (gcc_options *opts, aarch64_feature_flags flags) +{ + opts->x_aarch64_asm_isa_flags = flags; + opts->x_aarch64_isa_flags = flags; + if (opts->x_target_flags & MASK_GENERAL_REGS_ONLY) + opts->x_aarch64_isa_flags &= ~feature_deps::get_flags_off (AARCH64_FL_FP); +} + /* Implement TARGET_HANDLE_OPTION. This function handles the target specific options for CPU/target selection. @@ -99,6 +109,7 @@ aarch64_handle_option (struct gcc_options *opts, case OPT_mgeneral_regs_only: opts->x_target_flags |= MASK_GENERAL_REGS_ONLY; + aarch64_set_asm_isa_flags (opts, opts->x_aarch64_asm_isa_flags); return true; case OPT_mfix_cortex_a53_835769: @@ -128,64 +139,52 @@ aarch64_handle_option (struct gcc_options *opts, /* An ISA extension in the co-processor and main instruction set space. */ struct aarch64_option_extension { - const char *const name; - const uint64_t flag_canonical; - const uint64_t flags_on; - const uint64_t flags_off; - const bool is_synthetic; + const char *name; + aarch64_feature_flags flag_canonical; + aarch64_feature_flags flags_on; + aarch64_feature_flags flags_off; }; /* ISA extensions in AArch64. */ -static const struct aarch64_option_extension all_extensions[] = -{ -#define AARCH64_OPT_EXTENSION(NAME, FLAG_CANONICAL, FLAGS_ON, FLAGS_OFF, \ - SYNTHETIC, Z) \ - {NAME, FLAG_CANONICAL, FLAGS_ON, FLAGS_OFF, SYNTHETIC}, -#include "config/aarch64/aarch64-option-extensions.def" - {NULL, 0, 0, 0, false} -}; - -/* A copy of the ISA extensions list for AArch64 sorted by the popcount of - bits and extension turned on. Cached for efficiency. */ -static struct aarch64_option_extension all_extensions_by_on[] = +static constexpr aarch64_option_extension all_extensions[] = { -#define AARCH64_OPT_EXTENSION(NAME, FLAG_CANONICAL, FLAGS_ON, FLAGS_OFF, \ - SYNTHETIC, Z) \ - {NAME, FLAG_CANONICAL, FLAGS_ON, FLAGS_OFF, SYNTHETIC}, +#define AARCH64_OPT_EXTENSION(NAME, IDENT, C, D, E, F) \ + {NAME, AARCH64_FL_##IDENT, feature_deps::IDENT ().explicit_on, \ + feature_deps::get_flags_off (feature_deps::root_off_##IDENT)}, #include "config/aarch64/aarch64-option-extensions.def" - {NULL, 0, 0, 0, false} + {NULL, 0, 0, 0} }; struct processor_name_to_arch { - const std::string processor_name; - const enum aarch64_arch arch; - const uint64_t flags; + const char *processor_name; + aarch64_arch arch; + aarch64_feature_flags flags; }; struct arch_to_arch_name { - const enum aarch64_arch arch; - const std::string arch_name; - const uint64_t flags; + aarch64_arch arch; + const char *arch_name; + aarch64_feature_flags flags; }; /* Map processor names to the architecture revision they implement and the default set of architectural feature flags they support. */ -static const struct processor_name_to_arch all_cores[] = +static constexpr processor_name_to_arch all_cores[] = { -#define AARCH64_CORE(NAME, X, IDENT, ARCH_IDENT, FLAGS, COSTS, IMP, PART, VARIANT) \ - {NAME, AARCH64_ARCH_##ARCH_IDENT, FLAGS}, +#define AARCH64_CORE(NAME, CORE_IDENT, C, ARCH_IDENT, E, F, G, H, I) \ + {NAME, AARCH64_ARCH_##ARCH_IDENT, feature_deps::cpu_##CORE_IDENT}, #include "config/aarch64/aarch64-cores.def" - {"generic", AARCH64_ARCH_8A, AARCH64_FL_FOR_ARCH8}, + {"generic", AARCH64_ARCH_V8A, feature_deps::V8A ().enable}, {"", aarch64_no_arch, 0} }; /* Map architecture revisions to their string representation. */ -static const struct arch_to_arch_name all_architectures[] = +static constexpr arch_to_arch_name all_architectures[] = { -#define AARCH64_ARCH(NAME, CORE, ARCH_IDENT, ARCH, FLAGS) \ - {AARCH64_ARCH_##ARCH_IDENT, NAME, FLAGS}, +#define AARCH64_ARCH(NAME, B, ARCH_IDENT, D, E) \ + {AARCH64_ARCH_##ARCH_IDENT, NAME, feature_deps::ARCH_IDENT ().enable}, #include "config/aarch64/aarch64-arches.def" {aarch64_no_arch, "", 0} }; @@ -197,7 +196,7 @@ static const struct arch_to_arch_name all_architectures[] = a copy of the string is created and stored to INVALID_EXTENSION. */ enum aarch64_parse_opt_result -aarch64_parse_extension (const char *str, uint64_t *isa_flags, +aarch64_parse_extension (const char *str, aarch64_feature_flags *isa_flags, std::string *invalid_extension) { /* The extension string is parsed left to right. */ @@ -239,9 +238,9 @@ aarch64_parse_extension (const char *str, uint64_t *isa_flags, { /* Add or remove the extension. */ if (adding_ext) - *isa_flags |= (opt->flags_on | opt->flag_canonical); + *isa_flags |= opt->flags_on; else - *isa_flags &= ~(opt->flags_off | opt->flag_canonical); + *isa_flags &= ~opt->flags_off; break; } } @@ -270,78 +269,6 @@ aarch64_get_all_extension_candidates (auto_vec<const char *> *candidates) candidates->safe_push (opt->name); } -/* Comparer to sort aarch64's feature extensions by population count. Largest - first. */ - -typedef const struct aarch64_option_extension opt_ext; - -int opt_ext_cmp (const void* a, const void* b) -{ - opt_ext *opt_a = (opt_ext *)a; - opt_ext *opt_b = (opt_ext *)b; - - /* We consider the total set of bits an options turns on to be the union of - the singleton set containing the option itself and the set of options it - turns on as a dependency. As an example +dotprod turns on FL_DOTPROD and - FL_SIMD. As such the set of bits represented by this option is - {FL_DOTPROD, FL_SIMD}. */ - uint64_t total_flags_a = opt_a->flag_canonical & opt_a->flags_on; - uint64_t total_flags_b = opt_b->flag_canonical & opt_b->flags_on; - int popcnt_a = popcount_hwi ((HOST_WIDE_INT)total_flags_a); - int popcnt_b = popcount_hwi ((HOST_WIDE_INT)total_flags_b); - int order = popcnt_b - popcnt_a; - - /* If they have the same amount of bits set, give it a more - deterministic ordering by using the value of the bits themselves. */ - if (order != 0) - return order; - - if (total_flags_a != total_flags_b) - return total_flags_a < total_flags_b ? 1 : -1; - - return 0; -} - -/* Implement TARGET_OPTION_INIT_STRUCT. */ - -static void -aarch64_option_init_struct (struct gcc_options *opts ATTRIBUTE_UNUSED) -{ - /* Sort the extensions based on how many bits they set, order the larger - counts first. We sort the list because this makes processing the - feature bits O(n) instead of O(n^2). While n is small, the function - to calculate the feature strings is called on every options push, - pop and attribute change (arm_neon headers, lto etc all cause this to - happen quite frequently). It is a trade-off between time and space and - so time won. */ - int n_extensions = ARRAY_SIZE (all_extensions); - qsort (&all_extensions_by_on, n_extensions, - sizeof (struct aarch64_option_extension), opt_ext_cmp); -} - -/* Checks to see if enough bits from the option OPT are enabled in - ISA_FLAG_BITS to be able to replace the individual options with the - canonicalized version of the option. This is done based on two rules: - - 1) Synthetic groups, such as +crypto we only care about the bits that are - turned on. e.g. +aes+sha2 can be replaced with +crypto. - - 2) Options that themselves have a bit, such as +rdma, in this case, all the - feature bits they turn on must be available and the bit for the option - itself must be. In this case it's effectively a reduction rather than a - grouping. e.g. +fp+simd is not enough to turn on +rdma, for that you would - need +rdma+fp+simd which is reduced down to +rdma. -*/ - -static bool -aarch64_contains_opt (uint64_t isa_flag_bits, opt_ext *opt) -{ - uint64_t flags_check - = opt->is_synthetic ? opt->flags_on : opt->flag_canonical; - - return (isa_flag_bits & flags_check) == flags_check; -} - /* Return a string representation of ISA_FLAGS. DEFAULT_ARCH_FLAGS gives the default set of flags which are implied by whatever -march we'd put out. Our job is to figure out the minimal set of "+" and @@ -349,121 +276,63 @@ aarch64_contains_opt (uint64_t isa_flag_bits, opt_ext *opt) that all the "+" flags come before the "+no" flags. */ std::string -aarch64_get_extension_string_for_isa_flags (uint64_t isa_flags, - uint64_t default_arch_flags) +aarch64_get_extension_string_for_isa_flags + (aarch64_feature_flags isa_flags, + aarch64_feature_flags default_arch_flags) { - const struct aarch64_option_extension *opt = NULL; std::string outstr = ""; - uint64_t isa_flag_bits = isa_flags; - - /* Pass one: Minimize the search space by reducing the set of options - to the smallest set that still turns on the same features as before in - conjunction with the bits that are turned on by default for the selected - architecture. */ - for (opt = all_extensions_by_on; opt->name != NULL; opt++) + aarch64_feature_flags current_flags = default_arch_flags; + + /* As a special case, do not assume that the assembler will enable CRC + even if it is the default for the architecture. This is required + because some CPUs had an incorrect specification in older assemblers: + even though CRC should be the default for these cases the -mcpu + values would not turn it on. + + However, assemblers with Armv8-R AArch64 support should not have this + issue, so we don't need this fix when targeting Armv8-R. */ + auto explicit_flags = (!(current_flags & AARCH64_FL_V8R) + ? AARCH64_FL_CRC : 0); + + /* Add the features in isa_flags & ~current_flags using the smallest + possible number of extensions. We can do this by iterating over the + array in reverse order, since the array is sorted topologically. + But in order to make the output more readable, it seems better + to add the strings in definition order. */ + aarch64_feature_flags added = 0; + for (unsigned int i = ARRAY_SIZE (all_extensions); i-- > 0; ) { - /* If the bit is on by default, then all the options it turns on are also - on by default due to the transitive dependencies. - - If the option is enabled explicitly in the set then we need to emit - an option for it. Since this list is sorted by extensions setting the - largest number of featers first, we can be sure that nothing else will - ever need to set the bits we already set. Consider the following - situation: - - Feat1 = A + B + C - Feat2 = A + B - Feat3 = A + D - Feat4 = B + C - Feat5 = C - - The following results are expected: - - A + C = A + Feat5 - B + C = Feat4 - Feat4 + A = Feat1 - Feat2 + Feat5 = Feat1 - Feat1 + C = Feat1 - Feat3 + Feat4 = Feat1 + D - - This search assumes that all invidual feature bits are use visible, - in other words the user must be able to do +A, +B, +C and +D. */ - if (aarch64_contains_opt (isa_flag_bits | default_arch_flags, opt)) - { - /* We remove all the dependent bits, to prevent them from being turned - on twice. This only works because we assume that all there are - individual options to set all bits standalone. */ - - /* PR target/94396. - - For flags which would already imply a bit that's on by default (e.g - fp16fml which implies +fp,+fp16) we must emit the flags that are not - on by default. i.e. in Armv8.4-a +fp16fml is default if +fp16. So - if a user passes armv8.4-a+fp16 (or +fp16fml) then we need to emit - +fp16. But if +fp16fml is used in an architecture where it is - completely optional we only have to emit the canonical flag. */ - uint64_t toggle_bits = opt->flags_on & default_arch_flags; - /* Now check to see if the canonical flag is on by default. If it - is not then enabling it will enable all bits in flags_on. */ - if ((opt->flag_canonical & default_arch_flags) == 0) - toggle_bits = opt->flags_on; - - isa_flag_bits &= ~toggle_bits; - isa_flag_bits |= opt->flag_canonical; - } - } + auto &opt = all_extensions[i]; - /* By toggling bits on and off, we may have set bits on that are already - enabled by default. So we mask the default set out so we don't emit an - option for them. Instead of checking for this each time during Pass One - we just mask all default bits away at the end. */ - isa_flag_bits &= ~default_arch_flags; - - /* We now have the smallest set of features we need to process. A subsequent - linear scan of the bits in isa_flag_bits will allow us to print the ext - names. However as a special case if CRC was enabled before, always print - it. This is required because some CPUs have an incorrect specification - in older assemblers. Even though CRC should be the default for these - cases the -mcpu values won't turn it on. - - Note that assemblers with Armv8-R AArch64 support should not have this - issue, so we don't need this fix when targeting Armv8-R. */ - if ((isa_flags & AARCH64_ISA_CRC) && !AARCH64_ISA_V8_R) - isa_flag_bits |= AARCH64_ISA_CRC; - - /* Pass Two: - Print the option names that we're sure we must turn on. These are only - optional extension names. Mandatory ones have already been removed and - ones we explicitly want off have been too. */ - for (opt = all_extensions_by_on; opt->name != NULL; opt++) - { - if (isa_flag_bits & opt->flag_canonical) - { - outstr += "+"; - outstr += opt->name; - } - } + /* As a special case, emit +crypto rather than +aes+sha2, + in order to support assemblers that predate the separate + per-feature crypto flags. */ + auto flags = opt.flag_canonical; + if (flags == AARCH64_FL_CRYPTO) + flags = AARCH64_FL_AES | AARCH64_FL_SHA2; - /* Pass Three: - Print out a +no for any mandatory extension that we are - turning off. By this point aarch64_parse_extension would have ensured - that any optional extensions are turned off. The only things left are - things that can't be turned off usually, e.g. something that is on by - default because it's mandatory and we want it off. For turning off bits - we don't guarantee the smallest set of flags, but instead just emit all - options the user has specified. - - The assembler requires all +<opts> to be printed before +no<opts>. */ - for (opt = all_extensions_by_on; opt->name != NULL; opt++) - { - if ((~isa_flags) & opt->flag_canonical - && !((~default_arch_flags) & opt->flag_canonical)) + if ((flags & isa_flags & (explicit_flags | ~current_flags)) == flags) { - outstr += "+no"; - outstr += opt->name; + current_flags |= opt.flags_on; + added |= opt.flag_canonical; } } + for (auto &opt : all_extensions) + if (added & opt.flag_canonical) + { + outstr += "+"; + outstr += opt.name; + } + + /* Remove the features in current_flags & ~isa_flags. */ + for (auto &opt : all_extensions) + if (opt.flag_canonical & current_flags & ~isa_flags) + { + current_flags &= ~opt.flags_off; + outstr += "+no"; + outstr += opt.name; + } return outstr; } @@ -517,7 +386,7 @@ aarch64_rewrite_selected_cpu (const char *name) || a_to_an->arch == aarch64_no_arch) fatal_error (input_location, "unknown value %qs for %<-mcpu%>", name); - uint64_t extensions = p_to_a->flags; + aarch64_feature_flags extensions = p_to_a->flags; aarch64_parse_extension (extension_str.c_str (), &extensions, NULL); std::string outstr = a_to_an->arch_name diff --git a/gcc/config.gcc b/gcc/config.gcc index 7eb0787..35dfc00 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -1021,6 +1021,8 @@ case ${target} in extra_headers="${extra_headers} ../vxworks/vxworks-predef.h" target_has_targetcm="yes" + extra_gcc_objs="vxworks-driver.o" + # This private header exposes a consistent interface for checks on # the VxWorks version our runtime header files need to perform, based on # what the system headers adverstise: @@ -4100,14 +4102,6 @@ case "${target}" in options_parsed="`$ac_cv_prog_CPP -D"$opt_macro" -x c \ ${srcdir}/config/aarch64/aarch64-option-extensions.def`" - # Match one element inside AARCH64_OPT_EXTENSION, we - # consume anything that's not a ,. - elem="[ ]*\([^,]\+\)[ ]*" - - # Repeat the pattern for the number of entries in the - # AARCH64_OPT_EXTENSION, currently 6 times. - sed_patt="^$elem,$elem,$elem,$elem,$elem,$elem" - while [ x"$ext_val" != x ] do ext_val=`echo $ext_val | sed -e 's/\+//'` diff --git a/gcc/config/aarch64/aarch64-arches.def b/gcc/config/aarch64/aarch64-arches.def index 6150448..9f82466 100644 --- a/gcc/config/aarch64/aarch64-arches.def +++ b/gcc/config/aarch64/aarch64-arches.def @@ -28,21 +28,21 @@ ARCH_REV is an integer specifying the architecture major revision. FLAGS are the flags implied by the architecture. Due to the assumptions about the positions of these fields in config.gcc, - the NAME should be kept as the first argument and FLAGS as the last. */ - -AARCH64_ARCH("armv8-a", generic, 8A, 8, AARCH64_FL_FOR_ARCH8) -AARCH64_ARCH("armv8.1-a", generic, 8_1A, 8, AARCH64_FL_FOR_ARCH8_1) -AARCH64_ARCH("armv8.2-a", generic, 8_2A, 8, AARCH64_FL_FOR_ARCH8_2) -AARCH64_ARCH("armv8.3-a", generic, 8_3A, 8, AARCH64_FL_FOR_ARCH8_3) -AARCH64_ARCH("armv8.4-a", generic, 8_4A, 8, AARCH64_FL_FOR_ARCH8_4) -AARCH64_ARCH("armv8.5-a", generic, 8_5A, 8, AARCH64_FL_FOR_ARCH8_5) -AARCH64_ARCH("armv8.6-a", generic, 8_6A, 8, AARCH64_FL_FOR_ARCH8_6) -AARCH64_ARCH("armv8.7-a", generic, 8_7A, 8, AARCH64_FL_FOR_ARCH8_7) -AARCH64_ARCH("armv8.8-a", generic, 8_8A, 8, AARCH64_FL_FOR_ARCH8_8) -AARCH64_ARCH("armv8-r", generic, 8R , 8, AARCH64_FL_FOR_ARCH8_R) -AARCH64_ARCH("armv9-a", generic, 9A , 9, AARCH64_FL_FOR_ARCH9) -AARCH64_ARCH("armv9.1-a", generic, 9_1A, 9, AARCH64_FL_FOR_ARCH9_1) -AARCH64_ARCH("armv9.2-a", generic, 9_2A, 9, AARCH64_FL_FOR_ARCH9_2) -AARCH64_ARCH("armv9.3-a", generic, 9_3A, 9, AARCH64_FL_FOR_ARCH9_3) + NAME should be kept as the first argument. */ + +AARCH64_ARCH("armv8-a", generic, V8A, 8, (SIMD)) +AARCH64_ARCH("armv8.1-a", generic, V8_1A, 8, (V8A, LSE, CRC, RDMA)) +AARCH64_ARCH("armv8.2-a", generic, V8_2A, 8, (V8_1A)) +AARCH64_ARCH("armv8.3-a", generic, V8_3A, 8, (V8_2A, PAUTH)) +AARCH64_ARCH("armv8.4-a", generic, V8_4A, 8, (V8_3A, F16FML, DOTPROD, FLAGM)) +AARCH64_ARCH("armv8.5-a", generic, V8_5A, 8, (V8_4A, SB, SSBS, PREDRES)) +AARCH64_ARCH("armv8.6-a", generic, V8_6A, 8, (V8_5A, I8MM, BF16)) +AARCH64_ARCH("armv8.7-a", generic, V8_7A, 8, (V8_6A, LS64)) +AARCH64_ARCH("armv8.8-a", generic, V8_8A, 8, (V8_7A, MOPS)) +AARCH64_ARCH("armv8-r", generic, V8R , 8, (V8_4A)) +AARCH64_ARCH("armv9-a", generic, V9A , 9, (V8_5A, SVE2)) +AARCH64_ARCH("armv9.1-a", generic, V9_1A, 9, (V8_6A, V9A)) +AARCH64_ARCH("armv9.2-a", generic, V9_2A, 9, (V8_7A, V9_1A)) +AARCH64_ARCH("armv9.3-a", generic, V9_3A, 9, (V8_8A, V9_2A)) #undef AARCH64_ARCH diff --git a/gcc/config/aarch64/aarch64-builtins.cc b/gcc/config/aarch64/aarch64-builtins.cc index 5eef5aa..b533082 100644 --- a/gcc/config/aarch64/aarch64-builtins.cc +++ b/gcc/config/aarch64/aarch64-builtins.cc @@ -1549,20 +1549,20 @@ aarch64_scalar_builtin_type_p (aarch64_simd_type t) /* Enable AARCH64_FL_* flags EXTRA_FLAGS on top of the base Advanced SIMD set. */ aarch64_simd_switcher::aarch64_simd_switcher (unsigned int extra_flags) - : m_old_isa_flags (aarch64_isa_flags), + : m_old_asm_isa_flags (aarch64_asm_isa_flags), m_old_general_regs_only (TARGET_GENERAL_REGS_ONLY) { /* Changing the ISA flags should be enough here. We shouldn't need to pay the compile-time cost of a full target switch. */ - aarch64_isa_flags = AARCH64_FL_FP | AARCH64_FL_SIMD | extra_flags; global_options.x_target_flags &= ~MASK_GENERAL_REGS_ONLY; + aarch64_set_asm_isa_flags (AARCH64_FL_FP | AARCH64_FL_SIMD | extra_flags); } aarch64_simd_switcher::~aarch64_simd_switcher () { if (m_old_general_regs_only) global_options.x_target_flags |= MASK_GENERAL_REGS_ONLY; - aarch64_isa_flags = m_old_isa_flags; + aarch64_set_asm_isa_flags (m_old_asm_isa_flags); } /* Implement #pragma GCC aarch64 "arm_neon.h". diff --git a/gcc/config/aarch64/aarch64-c.cc b/gcc/config/aarch64/aarch64-c.cc index 52ed4a2..592af8c 100644 --- a/gcc/config/aarch64/aarch64-c.cc +++ b/gcc/config/aarch64/aarch64-c.cc @@ -64,7 +64,7 @@ aarch64_define_unconditional_macros (cpp_reader *pfile) builtin_define ("__ARM_ARCH_8A"); builtin_define_with_int_value ("__ARM_ARCH_PROFILE", - AARCH64_ISA_V8_R ? 'R' : 'A'); + AARCH64_ISA_V8R ? 'R' : 'A'); builtin_define ("__ARM_FEATURE_CLZ"); builtin_define ("__ARM_FEATURE_IDIV"); builtin_define ("__ARM_FEATURE_UNALIGNED"); @@ -82,7 +82,7 @@ aarch64_update_cpp_builtins (cpp_reader *pfile) { aarch64_def_or_undef (flag_unsafe_math_optimizations, "__ARM_FP_FAST", pfile); - builtin_define_with_int_value ("__ARM_ARCH", AARCH64_ISA_V9 ? 9 : 8); + builtin_define_with_int_value ("__ARM_ARCH", AARCH64_ISA_V9A ? 9 : 8); builtin_define_with_int_value ("__ARM_SIZEOF_MINIMAL_ENUM", flag_short_enums ? 1 : 4); @@ -92,7 +92,7 @@ aarch64_update_cpp_builtins (cpp_reader *pfile) aarch64_def_or_undef (TARGET_FLOAT, "__ARM_FEATURE_FMA", pfile); - if (TARGET_FLOAT || TARGET_SIMD) + if (TARGET_FLOAT) { builtin_define_with_int_value ("__ARM_FP", 0x0E); builtin_define ("__ARM_FP16_FORMAT_IEEE"); diff --git a/gcc/config/aarch64/aarch64-cores.def b/gcc/config/aarch64/aarch64-cores.def index 0402bfb..6029916 100644 --- a/gcc/config/aarch64/aarch64-cores.def +++ b/gcc/config/aarch64/aarch64-cores.def @@ -46,132 +46,132 @@ /* ARMv8-A Architecture Processors. */ /* ARM ('A') cores. */ -AARCH64_CORE("cortex-a34", cortexa34, cortexa53, 8A, AARCH64_FL_FOR_ARCH8 | AARCH64_FL_CRC, cortexa35, 0x41, 0xd02, -1) -AARCH64_CORE("cortex-a35", cortexa35, cortexa53, 8A, AARCH64_FL_FOR_ARCH8 | AARCH64_FL_CRC, cortexa35, 0x41, 0xd04, -1) -AARCH64_CORE("cortex-a53", cortexa53, cortexa53, 8A, AARCH64_FL_FOR_ARCH8 | AARCH64_FL_CRC, cortexa53, 0x41, 0xd03, -1) -AARCH64_CORE("cortex-a57", cortexa57, cortexa57, 8A, AARCH64_FL_FOR_ARCH8 | AARCH64_FL_CRC, cortexa57, 0x41, 0xd07, -1) -AARCH64_CORE("cortex-a72", cortexa72, cortexa57, 8A, AARCH64_FL_FOR_ARCH8 | AARCH64_FL_CRC, cortexa72, 0x41, 0xd08, -1) -AARCH64_CORE("cortex-a73", cortexa73, cortexa57, 8A, AARCH64_FL_FOR_ARCH8 | AARCH64_FL_CRC, cortexa73, 0x41, 0xd09, -1) +AARCH64_CORE("cortex-a34", cortexa34, cortexa53, V8A, (CRC), cortexa35, 0x41, 0xd02, -1) +AARCH64_CORE("cortex-a35", cortexa35, cortexa53, V8A, (CRC), cortexa35, 0x41, 0xd04, -1) +AARCH64_CORE("cortex-a53", cortexa53, cortexa53, V8A, (CRC), cortexa53, 0x41, 0xd03, -1) +AARCH64_CORE("cortex-a57", cortexa57, cortexa57, V8A, (CRC), cortexa57, 0x41, 0xd07, -1) +AARCH64_CORE("cortex-a72", cortexa72, cortexa57, V8A, (CRC), cortexa72, 0x41, 0xd08, -1) +AARCH64_CORE("cortex-a73", cortexa73, cortexa57, V8A, (CRC), cortexa73, 0x41, 0xd09, -1) /* Cavium ('C') cores. */ -AARCH64_CORE("thunderx", thunderx, thunderx, 8A, AARCH64_FL_FOR_ARCH8 | AARCH64_FL_CRC | AARCH64_FL_CRYPTO, thunderx, 0x43, 0x0a0, -1) +AARCH64_CORE("thunderx", thunderx, thunderx, V8A, (CRC, CRYPTO), thunderx, 0x43, 0x0a0, -1) /* Do not swap around "thunderxt88p1" and "thunderxt88", this order is required to handle variant correctly. */ -AARCH64_CORE("thunderxt88p1", thunderxt88p1, thunderx, 8A, AARCH64_FL_FOR_ARCH8 | AARCH64_FL_CRC | AARCH64_FL_CRYPTO, thunderxt88, 0x43, 0x0a1, 0) -AARCH64_CORE("thunderxt88", thunderxt88, thunderx, 8A, AARCH64_FL_FOR_ARCH8 | AARCH64_FL_CRC | AARCH64_FL_CRYPTO, thunderxt88, 0x43, 0x0a1, -1) +AARCH64_CORE("thunderxt88p1", thunderxt88p1, thunderx, V8A, (CRC, CRYPTO), thunderxt88, 0x43, 0x0a1, 0) +AARCH64_CORE("thunderxt88", thunderxt88, thunderx, V8A, (CRC, CRYPTO), thunderxt88, 0x43, 0x0a1, -1) /* OcteonTX is the official name for T81/T83. */ -AARCH64_CORE("octeontx", octeontx, thunderx, 8A, AARCH64_FL_FOR_ARCH8 | AARCH64_FL_CRC | AARCH64_FL_CRYPTO, thunderx, 0x43, 0x0a0, -1) -AARCH64_CORE("octeontx81", octeontxt81, thunderx, 8A, AARCH64_FL_FOR_ARCH8 | AARCH64_FL_CRC | AARCH64_FL_CRYPTO, thunderx, 0x43, 0x0a2, -1) -AARCH64_CORE("octeontx83", octeontxt83, thunderx, 8A, AARCH64_FL_FOR_ARCH8 | AARCH64_FL_CRC | AARCH64_FL_CRYPTO, thunderx, 0x43, 0x0a3, -1) +AARCH64_CORE("octeontx", octeontx, thunderx, V8A, (CRC, CRYPTO), thunderx, 0x43, 0x0a0, -1) +AARCH64_CORE("octeontx81", octeontxt81, thunderx, V8A, (CRC, CRYPTO), thunderx, 0x43, 0x0a2, -1) +AARCH64_CORE("octeontx83", octeontxt83, thunderx, V8A, (CRC, CRYPTO), thunderx, 0x43, 0x0a3, -1) -AARCH64_CORE("thunderxt81", thunderxt81, thunderx, 8A, AARCH64_FL_FOR_ARCH8 | AARCH64_FL_CRC | AARCH64_FL_CRYPTO, thunderx, 0x43, 0x0a2, -1) -AARCH64_CORE("thunderxt83", thunderxt83, thunderx, 8A, AARCH64_FL_FOR_ARCH8 | AARCH64_FL_CRC | AARCH64_FL_CRYPTO, thunderx, 0x43, 0x0a3, -1) +AARCH64_CORE("thunderxt81", thunderxt81, thunderx, V8A, (CRC, CRYPTO), thunderx, 0x43, 0x0a2, -1) +AARCH64_CORE("thunderxt83", thunderxt83, thunderx, V8A, (CRC, CRYPTO), thunderx, 0x43, 0x0a3, -1) /* Ampere Computing ('\xC0') cores. */ -AARCH64_CORE("ampere1", ampere1, cortexa57, 8_6A, AARCH64_FL_FOR_ARCH8_6, ampere1, 0xC0, 0xac3, -1) +AARCH64_CORE("ampere1", ampere1, cortexa57, V8_6A, (), ampere1, 0xC0, 0xac3, -1) /* Do not swap around "emag" and "xgene1", this order is required to handle variant correctly. */ -AARCH64_CORE("emag", emag, xgene1, 8A, AARCH64_FL_FOR_ARCH8 | AARCH64_FL_CRC | AARCH64_FL_CRYPTO, emag, 0x50, 0x000, 3) +AARCH64_CORE("emag", emag, xgene1, V8A, (CRC, CRYPTO), emag, 0x50, 0x000, 3) /* APM ('P') cores. */ -AARCH64_CORE("xgene1", xgene1, xgene1, 8A, AARCH64_FL_FOR_ARCH8, xgene1, 0x50, 0x000, -1) +AARCH64_CORE("xgene1", xgene1, xgene1, V8A, (), xgene1, 0x50, 0x000, -1) /* Qualcomm ('Q') cores. */ -AARCH64_CORE("falkor", falkor, falkor, 8A, AARCH64_FL_FOR_ARCH8 | AARCH64_FL_CRC | AARCH64_FL_CRYPTO | AARCH64_FL_RDMA, qdf24xx, 0x51, 0xC00, -1) -AARCH64_CORE("qdf24xx", qdf24xx, falkor, 8A, AARCH64_FL_FOR_ARCH8 | AARCH64_FL_CRC | AARCH64_FL_CRYPTO | AARCH64_FL_RDMA, qdf24xx, 0x51, 0xC00, -1) +AARCH64_CORE("falkor", falkor, falkor, V8A, (CRC, CRYPTO, RDMA), qdf24xx, 0x51, 0xC00, -1) +AARCH64_CORE("qdf24xx", qdf24xx, falkor, V8A, (CRC, CRYPTO, RDMA), qdf24xx, 0x51, 0xC00, -1) /* Samsung ('S') cores. */ -AARCH64_CORE("exynos-m1", exynosm1, exynosm1, 8A, AARCH64_FL_FOR_ARCH8 | AARCH64_FL_CRC | AARCH64_FL_CRYPTO, exynosm1, 0x53, 0x001, -1) +AARCH64_CORE("exynos-m1", exynosm1, exynosm1, V8A, (CRC, CRYPTO), exynosm1, 0x53, 0x001, -1) /* HXT ('h') cores. */ -AARCH64_CORE("phecda", phecda, falkor, 8A, AARCH64_FL_FOR_ARCH8 | AARCH64_FL_CRC | AARCH64_FL_CRYPTO, qdf24xx, 0x68, 0x000, -1) +AARCH64_CORE("phecda", phecda, falkor, V8A, (CRC, CRYPTO), qdf24xx, 0x68, 0x000, -1) /* ARMv8.1-A Architecture Processors. */ /* Broadcom ('B') cores. */ -AARCH64_CORE("thunderx2t99p1", thunderx2t99p1, thunderx2t99, 8_1A, AARCH64_FL_FOR_ARCH8_1 | AARCH64_FL_CRYPTO, thunderx2t99, 0x42, 0x516, -1) -AARCH64_CORE("vulcan", vulcan, thunderx2t99, 8_1A, AARCH64_FL_FOR_ARCH8_1 | AARCH64_FL_CRYPTO, thunderx2t99, 0x42, 0x516, -1) +AARCH64_CORE("thunderx2t99p1", thunderx2t99p1, thunderx2t99, V8_1A, (CRYPTO), thunderx2t99, 0x42, 0x516, -1) +AARCH64_CORE("vulcan", vulcan, thunderx2t99, V8_1A, (CRYPTO), thunderx2t99, 0x42, 0x516, -1) /* Cavium ('C') cores. */ -AARCH64_CORE("thunderx2t99", thunderx2t99, thunderx2t99, 8_1A, AARCH64_FL_FOR_ARCH8_1 | AARCH64_FL_CRYPTO, thunderx2t99, 0x43, 0x0af, -1) +AARCH64_CORE("thunderx2t99", thunderx2t99, thunderx2t99, V8_1A, (CRYPTO), thunderx2t99, 0x43, 0x0af, -1) /* ARMv8.2-A Architecture Processors. */ /* ARM ('A') cores. */ -AARCH64_CORE("cortex-a55", cortexa55, cortexa53, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD, cortexa53, 0x41, 0xd05, -1) -AARCH64_CORE("cortex-a75", cortexa75, cortexa57, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD, cortexa73, 0x41, 0xd0a, -1) -AARCH64_CORE("cortex-a76", cortexa76, cortexa57, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD, neoversen1, 0x41, 0xd0b, -1) -AARCH64_CORE("cortex-a76ae", cortexa76ae, cortexa57, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD | AARCH64_FL_SSBS, neoversen1, 0x41, 0xd0e, -1) -AARCH64_CORE("cortex-a77", cortexa77, cortexa57, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD | AARCH64_FL_SSBS, neoversen1, 0x41, 0xd0d, -1) -AARCH64_CORE("cortex-a78", cortexa78, cortexa57, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD | AARCH64_FL_SSBS | AARCH64_FL_PROFILE, neoversen1, 0x41, 0xd41, -1) -AARCH64_CORE("cortex-a78ae", cortexa78ae, cortexa57, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD | AARCH64_FL_SSBS | AARCH64_FL_PROFILE, neoversen1, 0x41, 0xd42, -1) -AARCH64_CORE("cortex-a78c", cortexa78c, cortexa57, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD | AARCH64_FL_SSBS | AARCH64_FL_PROFILE | AARCH64_FL_FLAGM | AARCH64_FL_PAUTH, neoversen1, 0x41, 0xd4b, -1) -AARCH64_CORE("cortex-a65", cortexa65, cortexa53, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD | AARCH64_FL_SSBS, cortexa73, 0x41, 0xd06, -1) -AARCH64_CORE("cortex-a65ae", cortexa65ae, cortexa53, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD | AARCH64_FL_SSBS, cortexa73, 0x41, 0xd43, -1) -AARCH64_CORE("cortex-x1", cortexx1, cortexa57, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD | AARCH64_FL_SSBS | AARCH64_FL_PROFILE, neoversen1, 0x41, 0xd44, -1) -AARCH64_CORE("ares", ares, cortexa57, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD | AARCH64_FL_PROFILE, neoversen1, 0x41, 0xd0c, -1) -AARCH64_CORE("neoverse-n1", neoversen1, cortexa57, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD | AARCH64_FL_PROFILE, neoversen1, 0x41, 0xd0c, -1) -AARCH64_CORE("neoverse-e1", neoversee1, cortexa53, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD | AARCH64_FL_SSBS, cortexa73, 0x41, 0xd4a, -1) +AARCH64_CORE("cortex-a55", cortexa55, cortexa53, V8_2A, (F16, RCPC, DOTPROD), cortexa53, 0x41, 0xd05, -1) +AARCH64_CORE("cortex-a75", cortexa75, cortexa57, V8_2A, (F16, RCPC, DOTPROD), cortexa73, 0x41, 0xd0a, -1) +AARCH64_CORE("cortex-a76", cortexa76, cortexa57, V8_2A, (F16, RCPC, DOTPROD), neoversen1, 0x41, 0xd0b, -1) +AARCH64_CORE("cortex-a76ae", cortexa76ae, cortexa57, V8_2A, (F16, RCPC, DOTPROD, SSBS), neoversen1, 0x41, 0xd0e, -1) +AARCH64_CORE("cortex-a77", cortexa77, cortexa57, V8_2A, (F16, RCPC, DOTPROD, SSBS), neoversen1, 0x41, 0xd0d, -1) +AARCH64_CORE("cortex-a78", cortexa78, cortexa57, V8_2A, (F16, RCPC, DOTPROD, SSBS, PROFILE), neoversen1, 0x41, 0xd41, -1) +AARCH64_CORE("cortex-a78ae", cortexa78ae, cortexa57, V8_2A, (F16, RCPC, DOTPROD, SSBS, PROFILE), neoversen1, 0x41, 0xd42, -1) +AARCH64_CORE("cortex-a78c", cortexa78c, cortexa57, V8_2A, (F16, RCPC, DOTPROD, SSBS, PROFILE, FLAGM, PAUTH), neoversen1, 0x41, 0xd4b, -1) +AARCH64_CORE("cortex-a65", cortexa65, cortexa53, V8_2A, (F16, RCPC, DOTPROD, SSBS), cortexa73, 0x41, 0xd06, -1) +AARCH64_CORE("cortex-a65ae", cortexa65ae, cortexa53, V8_2A, (F16, RCPC, DOTPROD, SSBS), cortexa73, 0x41, 0xd43, -1) +AARCH64_CORE("cortex-x1", cortexx1, cortexa57, V8_2A, (F16, RCPC, DOTPROD, SSBS, PROFILE), neoversen1, 0x41, 0xd44, -1) +AARCH64_CORE("ares", ares, cortexa57, V8_2A, (F16, RCPC, DOTPROD, PROFILE), neoversen1, 0x41, 0xd0c, -1) +AARCH64_CORE("neoverse-n1", neoversen1, cortexa57, V8_2A, (F16, RCPC, DOTPROD, PROFILE), neoversen1, 0x41, 0xd0c, -1) +AARCH64_CORE("neoverse-e1", neoversee1, cortexa53, V8_2A, (F16, RCPC, DOTPROD, SSBS), cortexa73, 0x41, 0xd4a, -1) /* Cavium ('C') cores. */ -AARCH64_CORE("octeontx2", octeontx2, cortexa57, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_CRYPTO | AARCH64_FL_PROFILE, cortexa57, 0x43, 0x0b0, -1) -AARCH64_CORE("octeontx2t98", octeontx2t98, cortexa57, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_CRYPTO | AARCH64_FL_PROFILE, cortexa57, 0x43, 0x0b1, -1) -AARCH64_CORE("octeontx2t96", octeontx2t96, cortexa57, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_CRYPTO | AARCH64_FL_PROFILE, cortexa57, 0x43, 0x0b2, -1) +AARCH64_CORE("octeontx2", octeontx2, cortexa57, V8_2A, (CRYPTO, PROFILE), cortexa57, 0x43, 0x0b0, -1) +AARCH64_CORE("octeontx2t98", octeontx2t98, cortexa57, V8_2A, (CRYPTO, PROFILE), cortexa57, 0x43, 0x0b1, -1) +AARCH64_CORE("octeontx2t96", octeontx2t96, cortexa57, V8_2A, (CRYPTO, PROFILE), cortexa57, 0x43, 0x0b2, -1) /* Note OcteonTX2 T93 is an alias to OcteonTX2 T96. */ -AARCH64_CORE("octeontx2t93", octeontx2t93, cortexa57, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_CRYPTO | AARCH64_FL_PROFILE, cortexa57, 0x43, 0x0b2, -1) -AARCH64_CORE("octeontx2f95", octeontx2f95, cortexa57, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_CRYPTO | AARCH64_FL_PROFILE, cortexa57, 0x43, 0x0b3, -1) -AARCH64_CORE("octeontx2f95n", octeontx2f95n, cortexa57, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_CRYPTO | AARCH64_FL_PROFILE, cortexa57, 0x43, 0x0b4, -1) -AARCH64_CORE("octeontx2f95mm", octeontx2f95mm, cortexa57, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_CRYPTO | AARCH64_FL_PROFILE, cortexa57, 0x43, 0x0b5, -1) +AARCH64_CORE("octeontx2t93", octeontx2t93, cortexa57, V8_2A, (CRYPTO, PROFILE), cortexa57, 0x43, 0x0b2, -1) +AARCH64_CORE("octeontx2f95", octeontx2f95, cortexa57, V8_2A, (CRYPTO, PROFILE), cortexa57, 0x43, 0x0b3, -1) +AARCH64_CORE("octeontx2f95n", octeontx2f95n, cortexa57, V8_2A, (CRYPTO, PROFILE), cortexa57, 0x43, 0x0b4, -1) +AARCH64_CORE("octeontx2f95mm", octeontx2f95mm, cortexa57, V8_2A, (CRYPTO, PROFILE), cortexa57, 0x43, 0x0b5, -1) /* Fujitsu ('F') cores. */ -AARCH64_CORE("a64fx", a64fx, a64fx, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_F16 | AARCH64_FL_SVE, a64fx, 0x46, 0x001, -1) +AARCH64_CORE("a64fx", a64fx, a64fx, V8_2A, (F16, SVE), a64fx, 0x46, 0x001, -1) /* HiSilicon ('H') cores. */ -AARCH64_CORE("tsv110", tsv110, tsv110, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_CRYPTO | AARCH64_FL_F16 | AARCH64_FL_AES | AARCH64_FL_SHA2, tsv110, 0x48, 0xd01, -1) +AARCH64_CORE("tsv110", tsv110, tsv110, V8_2A, (CRYPTO, F16), tsv110, 0x48, 0xd01, -1) /* ARMv8.3-A Architecture Processors. */ /* Marvell cores (TX3). */ -AARCH64_CORE("thunderx3t110", thunderx3t110, thunderx3t110, 8_3A, AARCH64_FL_FOR_ARCH8_3 | AARCH64_FL_CRYPTO | AARCH64_FL_RCPC | AARCH64_FL_SM4 | AARCH64_FL_SHA3 | AARCH64_FL_F16FML | AARCH64_FL_RCPC8_4, thunderx3t110, 0x43, 0x0b8, 0x0a) +AARCH64_CORE("thunderx3t110", thunderx3t110, thunderx3t110, V8_3A, (CRYPTO, RCPC, SM4, SHA3, F16FML), thunderx3t110, 0x43, 0x0b8, 0x0a) /* ARMv8.4-A Architecture Processors. */ /* Arm ('A') cores. */ -AARCH64_CORE("zeus", zeus, cortexa57, 8_4A, AARCH64_FL_FOR_ARCH8_4 | AARCH64_FL_SVE | AARCH64_FL_RCPC | AARCH64_FL_I8MM | AARCH64_FL_BF16 | AARCH64_FL_F16 | AARCH64_FL_PROFILE | AARCH64_FL_SSBS | AARCH64_FL_RNG, neoversev1, 0x41, 0xd40, -1) -AARCH64_CORE("neoverse-v1", neoversev1, cortexa57, 8_4A, AARCH64_FL_FOR_ARCH8_4 | AARCH64_FL_SVE | AARCH64_FL_RCPC | AARCH64_FL_I8MM | AARCH64_FL_BF16 | AARCH64_FL_F16 | AARCH64_FL_PROFILE | AARCH64_FL_SSBS | AARCH64_FL_RNG, neoversev1, 0x41, 0xd40, -1) -AARCH64_CORE("neoverse-512tvb", neoverse512tvb, cortexa57, 8_4A, AARCH64_FL_FOR_ARCH8_4 | AARCH64_FL_SVE | AARCH64_FL_RCPC | AARCH64_FL_I8MM | AARCH64_FL_BF16 | AARCH64_FL_F16 | AARCH64_FL_PROFILE | AARCH64_FL_SSBS | AARCH64_FL_RNG, neoverse512tvb, INVALID_IMP, INVALID_CORE, -1) +AARCH64_CORE("zeus", zeus, cortexa57, V8_4A, (SVE, RCPC, I8MM, BF16, PROFILE, SSBS, RNG), neoversev1, 0x41, 0xd40, -1) +AARCH64_CORE("neoverse-v1", neoversev1, cortexa57, V8_4A, (SVE, RCPC, I8MM, BF16, PROFILE, SSBS, RNG), neoversev1, 0x41, 0xd40, -1) +AARCH64_CORE("neoverse-512tvb", neoverse512tvb, cortexa57, V8_4A, (SVE, RCPC, I8MM, BF16, PROFILE, SSBS, RNG), neoverse512tvb, INVALID_IMP, INVALID_CORE, -1) /* Qualcomm ('Q') cores. */ -AARCH64_CORE("saphira", saphira, saphira, 8_4A, AARCH64_FL_FOR_ARCH8_4 | AARCH64_FL_CRYPTO | AARCH64_FL_RCPC, saphira, 0x51, 0xC01, -1) +AARCH64_CORE("saphira", saphira, saphira, V8_4A, (CRYPTO, RCPC), saphira, 0x51, 0xC01, -1) /* ARMv8-A big.LITTLE implementations. */ -AARCH64_CORE("cortex-a57.cortex-a53", cortexa57cortexa53, cortexa53, 8A, AARCH64_FL_FOR_ARCH8 | AARCH64_FL_CRC, cortexa57, 0x41, AARCH64_BIG_LITTLE (0xd07, 0xd03), -1) -AARCH64_CORE("cortex-a72.cortex-a53", cortexa72cortexa53, cortexa53, 8A, AARCH64_FL_FOR_ARCH8 | AARCH64_FL_CRC, cortexa72, 0x41, AARCH64_BIG_LITTLE (0xd08, 0xd03), -1) -AARCH64_CORE("cortex-a73.cortex-a35", cortexa73cortexa35, cortexa53, 8A, AARCH64_FL_FOR_ARCH8 | AARCH64_FL_CRC, cortexa73, 0x41, AARCH64_BIG_LITTLE (0xd09, 0xd04), -1) -AARCH64_CORE("cortex-a73.cortex-a53", cortexa73cortexa53, cortexa53, 8A, AARCH64_FL_FOR_ARCH8 | AARCH64_FL_CRC, cortexa73, 0x41, AARCH64_BIG_LITTLE (0xd09, 0xd03), -1) +AARCH64_CORE("cortex-a57.cortex-a53", cortexa57cortexa53, cortexa53, V8A, (CRC), cortexa57, 0x41, AARCH64_BIG_LITTLE (0xd07, 0xd03), -1) +AARCH64_CORE("cortex-a72.cortex-a53", cortexa72cortexa53, cortexa53, V8A, (CRC), cortexa72, 0x41, AARCH64_BIG_LITTLE (0xd08, 0xd03), -1) +AARCH64_CORE("cortex-a73.cortex-a35", cortexa73cortexa35, cortexa53, V8A, (CRC), cortexa73, 0x41, AARCH64_BIG_LITTLE (0xd09, 0xd04), -1) +AARCH64_CORE("cortex-a73.cortex-a53", cortexa73cortexa53, cortexa53, V8A, (CRC), cortexa73, 0x41, AARCH64_BIG_LITTLE (0xd09, 0xd03), -1) /* ARM DynamIQ big.LITTLE configurations. */ -AARCH64_CORE("cortex-a75.cortex-a55", cortexa75cortexa55, cortexa53, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD, cortexa73, 0x41, AARCH64_BIG_LITTLE (0xd0a, 0xd05), -1) -AARCH64_CORE("cortex-a76.cortex-a55", cortexa76cortexa55, cortexa53, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD, neoversen1, 0x41, AARCH64_BIG_LITTLE (0xd0b, 0xd05), -1) +AARCH64_CORE("cortex-a75.cortex-a55", cortexa75cortexa55, cortexa53, V8_2A, (F16, RCPC, DOTPROD), cortexa73, 0x41, AARCH64_BIG_LITTLE (0xd0a, 0xd05), -1) +AARCH64_CORE("cortex-a76.cortex-a55", cortexa76cortexa55, cortexa53, V8_2A, (F16, RCPC, DOTPROD), neoversen1, 0x41, AARCH64_BIG_LITTLE (0xd0b, 0xd05), -1) /* Armv8-R Architecture Processors. */ -AARCH64_CORE("cortex-r82", cortexr82, cortexa53, 8R, AARCH64_FL_FOR_ARCH8_R, cortexa53, 0x41, 0xd15, -1) +AARCH64_CORE("cortex-r82", cortexr82, cortexa53, V8R, (), cortexa53, 0x41, 0xd15, -1) /* Armv9.0-A Architecture Processors. */ /* Arm ('A') cores. */ -AARCH64_CORE("cortex-a510", cortexa510, cortexa55, 9A, AARCH64_FL_FOR_ARCH9 | AARCH64_FL_SVE2_BITPERM | AARCH64_FL_MEMTAG | AARCH64_FL_I8MM | AARCH64_FL_BF16, cortexa53, 0x41, 0xd46, -1) +AARCH64_CORE("cortex-a510", cortexa510, cortexa55, V9A, (SVE2_BITPERM, MEMTAG, I8MM, BF16), cortexa53, 0x41, 0xd46, -1) -AARCH64_CORE("cortex-a710", cortexa710, cortexa57, 9A, AARCH64_FL_FOR_ARCH9 | AARCH64_FL_SVE2_BITPERM | AARCH64_FL_MEMTAG | AARCH64_FL_I8MM | AARCH64_FL_BF16, neoversen2, 0x41, 0xd47, -1) +AARCH64_CORE("cortex-a710", cortexa710, cortexa57, V9A, (SVE2_BITPERM, MEMTAG, I8MM, BF16), neoversen2, 0x41, 0xd47, -1) -AARCH64_CORE("cortex-x2", cortexx2, cortexa57, 9A, AARCH64_FL_FOR_ARCH9 | AARCH64_FL_SVE2_BITPERM | AARCH64_FL_MEMTAG | AARCH64_FL_I8MM | AARCH64_FL_BF16, neoversen2, 0x41, 0xd48, -1) +AARCH64_CORE("cortex-x2", cortexx2, cortexa57, V9A, (SVE2_BITPERM, MEMTAG, I8MM, BF16), neoversen2, 0x41, 0xd48, -1) -AARCH64_CORE("neoverse-n2", neoversen2, cortexa57, 9A, AARCH64_FL_FOR_ARCH9 | AARCH64_FL_I8MM | AARCH64_FL_BF16 | AARCH64_FL_SVE2_BITPERM | AARCH64_FL_RNG | AARCH64_FL_MEMTAG | AARCH64_FL_PROFILE, neoversen2, 0x41, 0xd49, -1) +AARCH64_CORE("neoverse-n2", neoversen2, cortexa57, V9A, (I8MM, BF16, SVE2_BITPERM, RNG, MEMTAG, PROFILE), neoversen2, 0x41, 0xd49, -1) -AARCH64_CORE("demeter", demeter, cortexa57, 9A, AARCH64_FL_FOR_ARCH9 | AARCH64_FL_I8MM | AARCH64_FL_BF16 | AARCH64_FL_SVE2_BITPERM | AARCH64_FL_RNG | AARCH64_FL_MEMTAG | AARCH64_FL_PROFILE, neoversev2, 0x41, 0xd4f, -1) -AARCH64_CORE("neoverse-v2", neoversev2, cortexa57, 9A, AARCH64_FL_FOR_ARCH9 | AARCH64_FL_I8MM | AARCH64_FL_BF16 | AARCH64_FL_SVE2_BITPERM | AARCH64_FL_RNG | AARCH64_FL_MEMTAG | AARCH64_FL_PROFILE, neoversev2, 0x41, 0xd4f, -1) +AARCH64_CORE("demeter", demeter, cortexa57, V9A, (I8MM, BF16, SVE2_BITPERM, RNG, MEMTAG, PROFILE), neoversev2, 0x41, 0xd4f, -1) +AARCH64_CORE("neoverse-v2", neoversev2, cortexa57, V9A, (I8MM, BF16, SVE2_BITPERM, RNG, MEMTAG, PROFILE), neoversev2, 0x41, 0xd4f, -1) #undef AARCH64_CORE diff --git a/gcc/config/aarch64/aarch64-feature-deps.h b/gcc/config/aarch64/aarch64-feature-deps.h new file mode 100644 index 0000000..3e33cb2 --- /dev/null +++ b/gcc/config/aarch64/aarch64-feature-deps.h @@ -0,0 +1,121 @@ +/* Feature dependency helpers for AArch64. + Copyright (C) 2022 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + +#ifndef AARCH64_FEATURE_DEPS_H +#define AARCH64_FEATURE_DEPS_H 1 + +namespace { +namespace feature_deps { + +/* Together, these definitions of get_flags take a list of + feature names (representing functions that are defined below) + and return the set of associated flags. */ +constexpr aarch64_feature_flags get_flags () { return 0; } + +template<typename T1, typename ...Ts> +constexpr aarch64_feature_flags +get_flags (T1 i, Ts... args) +{ + return i ().flag | get_flags (args...); +} + +/* Like get_flags, but return the transitive closure of those features + and the ones that they rely on. */ +constexpr aarch64_feature_flags get_enable () { return 0; } + +template<typename T1, typename ...Ts> +constexpr aarch64_feature_flags +get_enable (T1 i, Ts... args) +{ + return i ().enable | get_enable (args...); +} + +/* Define info<FEATURE> such that it has the following static constant + variables: + + - flag: the aarch64_feature_flags bit associated with FEATURE + + - enable: the transitive closure of the features that FEATURE requires, + plus FLAG itself + + - explicit_on: the transitive closure of the features that an + explicit +FEATURE enables, including FLAG itself. This is + always a superset of ENABLE + + Also define a function FEATURE () that returns an info<FEATURE> + (which is an empty structure, since all members are static). + + Building up the list feature-by-feature ensures that the definition + files are in topological order. */ +template<aarch64_feature> struct info; + +#define HANDLE(IDENT, REQUIRES, EXPLICIT_ON) \ + template<> struct info<aarch64_feature::IDENT> { \ + static constexpr auto flag = AARCH64_FL_##IDENT; \ + static constexpr auto enable = flag | get_enable REQUIRES; \ + static constexpr auto explicit_on = enable | get_enable EXPLICIT_ON; \ + }; \ + constexpr info<aarch64_feature::IDENT> IDENT () \ + { \ + return info<aarch64_feature::IDENT> (); \ + } +#define AARCH64_OPT_EXTENSION(A, IDENT, REQUIRES, EXPLICIT_ON, E, F) \ + HANDLE (IDENT, REQUIRES, EXPLICIT_ON) +#define AARCH64_ARCH(A, B, IDENT, D, REQUIRES) HANDLE (IDENT, REQUIRES, ()) +#include "config/aarch64/aarch64-option-extensions.def" +#include "config/aarch64/aarch64-arches.def" +#undef HANDLE + +/* Return the set of all features that would need to be disabled if + the features in MASK are disabled. + + Note that the size of the expression varies linearly with the number + of features, which means that invoking this function once per feature + is quadratic in the number of features. However, collecting the same + information at compiler start-up is likely to be quadratic too, so + we're better off paying the cost once per compiler build rather than + once per compiler run. */ +constexpr aarch64_feature_flags +get_flags_off (aarch64_feature_flags mask) +{ + return (0 +#define AARCH64_OPT_EXTENSION(A, IDENT, C, D, E, F) \ + | (feature_deps::IDENT ().enable & mask ? AARCH64_FL_##IDENT : 0) +#include "config/aarch64/aarch64-option-extensions.def" + ); +} + +/* Define root_off_<IDENT> variables for each feature, giving the set of + features that must be turned off by +noIDENT. This set is not transitively + closed; use get_flags_off to complete the closure. */ +#define AARCH64_OPT_EXTENSION(A, IDENT, C, D, EXPLICIT_OFF, F) \ + constexpr auto root_off_##IDENT \ + = AARCH64_FL_##IDENT | get_flags EXPLICIT_OFF; +#include "config/aarch64/aarch64-option-extensions.def" + +/* Define cpu_<NAME> variables for each CPU, giving the transitive + closure of all the features that the CPU supports. */ +#define AARCH64_CORE(A, CORE_IDENT, C, ARCH_IDENT, FEATURES, F, G, H, I) \ + constexpr auto cpu_##CORE_IDENT = ARCH_IDENT ().enable | get_enable FEATURES; +#include "config/aarch64/aarch64-cores.def" + +} +} + +#endif diff --git a/gcc/config/aarch64/aarch64-option-extensions.def b/gcc/config/aarch64/aarch64-option-extensions.def index b4d0ac8..bdf4baf 100644 --- a/gcc/config/aarch64/aarch64-option-extensions.def +++ b/gcc/config/aarch64/aarch64-option-extensions.def @@ -21,23 +21,34 @@ Before using #include to read this file, define a macro: - AARCH64_OPT_EXTENSION(EXT_NAME, FLAG_CANONICAL, FLAGS_ON, FLAGS_OFF, - SYNTHETIC, FEATURE_STRING) - - - EXT_NAME is the name of the extension, represented as a string constant. - - FLAGS_CANONICAL is the canonical internal name for this flag. - - FLAGS_ON are the bitwise-or of the features that enabling the extension - adds, or zero if enabling this extension has no effect on other features. - - FLAGS_OFF are the bitwise-or of the features that disabling the extension - removes, or zero if disabling this extension has no effect on other - features. - - SYNTHETIC is a boolean to indicate whether the option is a purely synthetic - grouping of options and that the option itself has no feature bit (e.g. - crypto). This is used to determine when sum of the individual options in - FLAGS_ON can be replaced by FLAG_CANONICAL in options minimization. If the - group is synthetic then they can be replaced when all options in FLAGS_ON - are enabled, otherwise they can only be replaced when - FLAGS_ON | FLAG_CANONICAL are enabled. + AARCH64_OPT_EXTENSION(NAME, IDENT, REQUIRES, EXPLICIT_ON, + EXPLICIT_OFF, FEATURE_STRING) + + - NAME is the name of the extension, represented as a string constant. + + - IDENT is the canonical internal name for this flag. + + - REQUIRES is a list of features that must be enabled whenever this + feature is enabled. The relationship is implicitly transitive: + if A appears in B's REQUIRES and B appears in C's REQUIRES then + A and B must be enabled whenever C is. Thus, turning on C also + turns on A and B, while turning off A or B also turns off C. + + - EXPLICIT_ON is a list of features that are enabled by an explicit + +NAME specification, in addition to those listed in REQUIRES. + Usually this is an empty list; comments below explain the exceptions. + The list is implicitly transitively closed wrt REQUIRES (but *not* + to EXPLICIT_ON, since NAME is the only thing explicit in +NAME). + Thus if A is in B's REQUIRES and B is in C's EXPLICIT_ON, +C will + enable both B and A. B's EXPLICIT_ON has no effect on +C. + + - EXPLICIT_OFF is a list of features that are disabled by an explicit + +noNAME specification, in addition to the features that are transitively + dependent on NAME (according to REQUIRES). As with EXPLICIT_ON, + this is usually an empty list; comments below explain the exceptions. + If a feature A appears in this list then the list implicitly includes + any features that are transitively dependent on A (according to REQUIRES). + - FEAT_STRING is a string containing the entries in the 'Features' field of /proc/cpuinfo on a GNU/Linux system that correspond to this architecture extension being available. Sometimes multiple entries are needed to enable @@ -47,195 +58,95 @@ that are required. Their order is not important. An empty string means do not detect this feature during auto detection. - NOTE: Any changes to the AARCH64_OPT_EXTENSION macro need to be mirrored in - config.gcc. */ - -/* Enabling "fp" just enables "fp". - Disabling "fp" also disables "simd", "crypto", "fp16", "aes", "sha2", - "sha3", sm3/sm4, "sve", "sve2", "sve2-aes", "sve2-sha3", "sve2-sm4", - "sve2-bitperm", "i8mm", "f32mm", "f64mm", and "bf16". */ -AARCH64_OPT_EXTENSION("fp", AARCH64_FL_FP, 0, AARCH64_FL_SIMD | \ - AARCH64_FL_CRYPTO | AARCH64_FL_F16 | AARCH64_FL_AES | \ - AARCH64_FL_SHA2 | AARCH64_FL_SHA3 | AARCH64_FL_SM4 | \ - AARCH64_FL_SVE | AARCH64_FL_SVE2 | AARCH64_FL_SVE2_AES | \ - AARCH64_FL_SVE2_SHA3 | AARCH64_FL_SVE2_SM4 | \ - AARCH64_FL_SVE2_BITPERM | AARCH64_FL_I8MM | \ - AARCH64_FL_F32MM | AARCH64_FL_F64MM | AARCH64_FL_BF16, - false, "fp") - -/* Enabling "simd" also enables "fp". - Disabling "simd" also disables "crypto", "dotprod", "aes", "sha2", "sha3", - "sm3/sm4", "sve", "sve2", "sve2-aes", "sve2-sha3", "sve2-sm4", - "sve2-bitperm", "i8mm", "f32mm" and "f64mm". */ -AARCH64_OPT_EXTENSION("simd", AARCH64_FL_SIMD, AARCH64_FL_FP, \ - AARCH64_FL_CRYPTO | AARCH64_FL_DOTPROD | \ - AARCH64_FL_AES | AARCH64_FL_SHA2 | AARCH64_FL_SHA3 | \ - AARCH64_FL_SM4 | AARCH64_FL_SVE | AARCH64_FL_SVE2 | \ - AARCH64_FL_SVE2_AES | AARCH64_FL_SVE2_SHA3 | \ - AARCH64_FL_SVE2_SM4 | AARCH64_FL_SVE2_BITPERM | \ - AARCH64_FL_I8MM | AARCH64_FL_F32MM | AARCH64_FL_F64MM, \ - false, "asimd") - -/* Enabling "crypto" also enables "fp", "simd", "aes" and "sha2". - Disabling "crypto" disables "crypto", "aes", "sha2", "sha3" and "sm3/sm4", - "sve2-aes", "sve2-sha3", "sve2-sm4". */ -AARCH64_OPT_EXTENSION("crypto", AARCH64_FL_CRYPTO, AARCH64_FL_FP | \ - AARCH64_FL_SIMD | AARCH64_FL_AES | AARCH64_FL_SHA2, \ - AARCH64_FL_AES | AARCH64_FL_SHA2 | AARCH64_FL_SHA3 | \ - AARCH64_FL_SM4 | AARCH64_FL_SVE2_AES | \ - AARCH64_FL_SVE2_SHA3 | AARCH64_FL_SVE2_SM4, true, \ + The list of features must follow topological order wrt REQUIRES + and EXPLICIT_ON. For example, if A is in B's REQUIRES list, A must + come before B. This is enforced by aarch64-feature-deps.h. + + NOTE: Any changes to the AARCH64_OPT_EXTENSION macro need to be mirrored in + config.gcc. */ + +AARCH64_OPT_EXTENSION("fp", FP, (), (), (), "fp") + +AARCH64_OPT_EXTENSION("simd", SIMD, (FP), (), (), "asimd") + +AARCH64_OPT_EXTENSION("crc", CRC, (), (), (), "crc32") + +AARCH64_OPT_EXTENSION("lse", LSE, (), (), (), "atomics") + +/* +nofp16 disables an implicit F16FML, even though an implicit F16FML + does not imply F16. See F16FML for more details. */ +AARCH64_OPT_EXTENSION("fp16", F16, (FP), (), (F16FML), "fphp asimdhp") + +AARCH64_OPT_EXTENSION("rcpc", RCPC, (), (), (), "lrcpc") + +/* An explicit +rdma implies +simd, but +rdma+nosimd still enables scalar + RDMA instructions. */ +AARCH64_OPT_EXTENSION("rdma", RDMA, (), (SIMD), (), "asimdrdm") + +AARCH64_OPT_EXTENSION("dotprod", DOTPROD, (SIMD), (), (), "asimddp") + +AARCH64_OPT_EXTENSION("aes", AES, (SIMD), (), (), "aes") + +AARCH64_OPT_EXTENSION("sha2", SHA2, (SIMD), (), (), "sha1 sha2") + +/* +nocrypto disables AES, SHA2 and SM4, and anything that depends on them + (such as SHA3 and the SVE2 crypto extensions). */ +AARCH64_OPT_EXTENSION("crypto", CRYPTO, (AES, SHA2), (), (AES, SHA2, SM4), "aes pmull sha1 sha2") -/* Enabling or disabling "crc" only changes "crc". */ -AARCH64_OPT_EXTENSION("crc", AARCH64_FL_CRC, 0, 0, false, "crc32") - -/* Enabling or disabling "lse" only changes "lse". */ -AARCH64_OPT_EXTENSION("lse", AARCH64_FL_LSE, 0, 0, false, "atomics") - -/* Enabling "fp16" also enables "fp". - Disabling "fp16" disables "fp16", "fp16fml", "sve", "sve2", - "sve2-aes", "sve2-sha3", "sve2-sm4", "sve2-bitperm", "f32mm" and - "f64mm". */ -AARCH64_OPT_EXTENSION("fp16", AARCH64_FL_F16, AARCH64_FL_FP, \ - AARCH64_FL_F16FML | AARCH64_FL_SVE | AARCH64_FL_F32MM | \ - AARCH64_FL_F64MM | AARCH64_FL_SVE2 | \ - AARCH64_FL_SVE2_AES | AARCH64_FL_SVE2_SHA3 | \ - AARCH64_FL_SVE2_SM4 | AARCH64_FL_SVE2_BITPERM, false, \ - "fphp asimdhp") - -/* Enabling or disabling "rcpc" only changes "rcpc". */ -AARCH64_OPT_EXTENSION("rcpc", AARCH64_FL_RCPC, 0, 0, false, "lrcpc") - -/* Enabling "rdma" also enables "fp", "simd". - Disabling "rdma" just disables "rdma". */ -AARCH64_OPT_EXTENSION("rdma", AARCH64_FL_RDMA, \ - AARCH64_FL_FP | AARCH64_FL_SIMD, 0, false, "asimdrdm") - -/* Enabling "dotprod" also enables "simd". - Disabling "dotprod" only disables "dotprod". */ -AARCH64_OPT_EXTENSION("dotprod", AARCH64_FL_DOTPROD, AARCH64_FL_SIMD, 0, \ - false, "asimddp") - -/* Enabling "aes" also enables "simd". - Disabling "aes" disables "aes" and "sve2-aes'. */ -AARCH64_OPT_EXTENSION("aes", AARCH64_FL_AES, AARCH64_FL_SIMD, \ - AARCH64_FL_SVE2_AES, false, "aes") - -/* Enabling "sha2" also enables "simd". - Disabling "sha2" just disables "sha2". */ -AARCH64_OPT_EXTENSION("sha2", AARCH64_FL_SHA2, AARCH64_FL_SIMD, 0, false, \ - "sha1 sha2") - -/* Enabling "sha3" enables "simd" and "sha2". - Disabling "sha3" disables "sha3" and "sve2-sha3". */ -AARCH64_OPT_EXTENSION("sha3", AARCH64_FL_SHA3, AARCH64_FL_SIMD | \ - AARCH64_FL_SHA2, AARCH64_FL_SVE2_SHA3, false, \ - "sha3 sha512") - -/* Enabling "sm4" also enables "simd". - Disabling "sm4" disables "sm4" and "sve2-sm4". */ -AARCH64_OPT_EXTENSION("sm4", AARCH64_FL_SM4, AARCH64_FL_SIMD, \ - AARCH64_FL_SVE2_SM4, false, "sm3 sm4") - -/* Enabling "fp16fml" also enables "fp" and "fp16". - Disabling "fp16fml" just disables "fp16fml". */ -AARCH64_OPT_EXTENSION("fp16fml", AARCH64_FL_F16FML, \ - AARCH64_FL_FP | AARCH64_FL_F16, 0, false, "asimdfhm") - -/* Enabling "sve" also enables "fp16", "fp" and "simd". - Disabling "sve" disables "sve", "f32mm", "f64mm", "sve2", "sve2-aes", - "sve2-sha3", "sve2-sm4" and "sve2-bitperm". */ -AARCH64_OPT_EXTENSION("sve", AARCH64_FL_SVE, AARCH64_FL_FP | AARCH64_FL_SIMD | \ - AARCH64_FL_F16, AARCH64_FL_F32MM | AARCH64_FL_F64MM | \ - AARCH64_FL_SVE2 | AARCH64_FL_SVE2_AES | \ - AARCH64_FL_SVE2_SHA3 | AARCH64_FL_SVE2_SM4 | \ - AARCH64_FL_SVE2_BITPERM, false, "sve") - -/* Enabling/Disabling "profile" does not enable/disable any other feature. */ -AARCH64_OPT_EXTENSION("profile", AARCH64_FL_PROFILE, 0, 0, false, "") - -/* Enabling/Disabling "rng" only changes "rng". */ -AARCH64_OPT_EXTENSION("rng", AARCH64_FL_RNG, 0, 0, false, "rng") - -/* Enabling/Disabling "memtag" only changes "memtag". */ -AARCH64_OPT_EXTENSION("memtag", AARCH64_FL_MEMTAG, 0, 0, false, "") - -/* Enabling/Disabling "sb" only changes "sb". */ -AARCH64_OPT_EXTENSION("sb", AARCH64_FL_SB, 0, 0, false, "sb") - -/* Enabling/Disabling "ssbs" only changes "ssbs". */ -AARCH64_OPT_EXTENSION("ssbs", AARCH64_FL_SSBS, 0, 0, false, "ssbs") - -/* Enabling/Disabling "predres" only changes "predres". */ -AARCH64_OPT_EXTENSION("predres", AARCH64_FL_PREDRES, 0, 0, false, "") - -/* Enabling "sve2" also enables "sve", "fp16", "fp", and "simd". - Disabling "sve2" disables "sve2", "sve2-aes", "sve2-sha3", "sve2-sm4", and - "sve2-bitperm". */ -AARCH64_OPT_EXTENSION("sve2", AARCH64_FL_SVE2, AARCH64_FL_SVE | \ - AARCH64_FL_FP | AARCH64_FL_SIMD | AARCH64_FL_F16, \ - AARCH64_FL_SVE2_AES | AARCH64_FL_SVE2_SHA3 | \ - AARCH64_FL_SVE2_SM4 | AARCH64_FL_SVE2_BITPERM, false, "sve2") - -/* Enabling "sve2-sm4" also enables "sm4", "simd", "fp16", "fp", "sve", and - "sve2". Disabling "sve2-sm4" just disables "sve2-sm4". */ -AARCH64_OPT_EXTENSION("sve2-sm4", AARCH64_FL_SVE2_SM4, AARCH64_FL_SM4 | \ - AARCH64_FL_SIMD | AARCH64_FL_F16 | AARCH64_FL_FP | \ - AARCH64_FL_SVE | AARCH64_FL_SVE2, 0, false, "svesm4") - -/* Enabling "sve2-aes" also enables "aes", "simd", "fp16", "fp", "sve", and - "sve2". Disabling "sve2-aes" just disables "sve2-aes". */ -AARCH64_OPT_EXTENSION("sve2-aes", AARCH64_FL_SVE2_AES, AARCH64_FL_AES | \ - AARCH64_FL_SIMD | AARCH64_FL_F16 | AARCH64_FL_FP | \ - AARCH64_FL_SVE | AARCH64_FL_SVE2, 0, false, "sveaes") - -/* Enabling "sve2-sha3" also enables "sha3", "simd", "fp16", "fp", "sve", and - "sve2". Disabling "sve2-sha3" just disables "sve2-sha3". */ -AARCH64_OPT_EXTENSION("sve2-sha3", AARCH64_FL_SVE2_SHA3, AARCH64_FL_SHA3 | \ - AARCH64_FL_SIMD | AARCH64_FL_F16 | AARCH64_FL_FP | \ - AARCH64_FL_SVE | AARCH64_FL_SVE2, 0, false, "svesha3") - -/* Enabling "sve2-bitperm" also enables "simd", "fp16", "fp", "sve", and - "sve2". Disabling "sve2-bitperm" just disables "sve2-bitperm". */ -AARCH64_OPT_EXTENSION("sve2-bitperm", AARCH64_FL_SVE2_BITPERM, AARCH64_FL_SIMD | \ - AARCH64_FL_F16 | AARCH64_FL_FP | AARCH64_FL_SVE | \ - AARCH64_FL_SVE2, 0, false, "svebitperm") - -/* Enabling or disabling "tme" only changes "tme". */ -AARCH64_OPT_EXTENSION("tme", AARCH64_FL_TME, 0, 0, false, "") - -/* Enabling "i8mm" also enables "simd" and "fp". - Disabling "i8mm" only disables "i8mm". */ -AARCH64_OPT_EXTENSION("i8mm", AARCH64_FL_I8MM, \ - AARCH64_FL_SIMD | AARCH64_FL_FP, 0, false, "i8mm") - -/* Enabling "f32mm" also enables "sve", "fp16", "fp", and "simd". - Disabling "f32mm" only disables "f32mm". */ -AARCH64_OPT_EXTENSION("f32mm", AARCH64_FL_F32MM, \ - AARCH64_FL_SVE | AARCH64_FL_F16 | AARCH64_FL_FP | \ - AARCH64_FL_SIMD, 0, false, "f32mm") - -/* Enabling "f64mm" also enables "sve", "fp16", "fp", and "simd". - Disabling "f64mm" only disables "f64mm". */ -AARCH64_OPT_EXTENSION("f64mm", AARCH64_FL_F64MM, \ - AARCH64_FL_SVE | AARCH64_FL_F16 | AARCH64_FL_FP | \ - AARCH64_FL_SIMD, 0, false, "f64mm") - -/* Enabling "bf16" also enables "simd" and "fp". - Disabling "bf16" only disables "bf16". */ -AARCH64_OPT_EXTENSION("bf16", AARCH64_FL_BF16, \ - AARCH64_FL_SIMD | AARCH64_FL_FP, 0, false, "bf16") - -/* Enabling/Disabling "flagm" only changes "flagm". */ -AARCH64_OPT_EXTENSION("flagm", AARCH64_FL_FLAGM, 0, 0, false, "flagm") - -/* Enabling/Disabling "pauth" only changes "pauth". */ -AARCH64_OPT_EXTENSION("pauth", AARCH64_FL_PAUTH, 0, 0, false, "paca pacg") - -/* Enabling/Disabling "ls64" only changes "ls64". */ -AARCH64_OPT_EXTENSION("ls64", AARCH64_FL_LS64, 0, 0, false, "") - -/* Enabling/disabling "mops" only changes "mops". */ -AARCH64_OPT_EXTENSION("mops", AARCH64_FL_MOPS, 0, 0, false, "") +AARCH64_OPT_EXTENSION("sha3", SHA3, (SHA2), (), (), "sha3 sha512") + +AARCH64_OPT_EXTENSION("sm4", SM4, (SIMD), (), (), "sm3 sm4") + +/* An explicit +fp16fml implies +fp16, but a dependence on it does not. + Thus -march=armv8.4-a implies F16FML but not F16. -march=armv8.4-a+fp16 + and -march=armv8.4-a+fp16fml are equivalent and enable both F16FML and F16. + -march=armv8.4-a+nofp16+fp16 enables F16 but not F16FML. */ +AARCH64_OPT_EXTENSION("fp16fml", F16FML, (), (F16), (), "asimdfhm") + +AARCH64_OPT_EXTENSION("sve", SVE, (SIMD, F16), (), (), "sve") + +AARCH64_OPT_EXTENSION("profile", PROFILE, (), (), (), "") + +AARCH64_OPT_EXTENSION("rng", RNG, (), (), (), "rng") + +AARCH64_OPT_EXTENSION("memtag", MEMTAG, (), (), (), "") + +AARCH64_OPT_EXTENSION("sb", SB, (), (), (), "sb") + +AARCH64_OPT_EXTENSION("ssbs", SSBS, (), (), (), "ssbs") + +AARCH64_OPT_EXTENSION("predres", PREDRES, (), (), (), "") + +AARCH64_OPT_EXTENSION("sve2", SVE2, (SVE), (), (), "sve2") + +AARCH64_OPT_EXTENSION("sve2-sm4", SVE2_SM4, (SVE2, SM4), (), (), "svesm4") + +AARCH64_OPT_EXTENSION("sve2-aes", SVE2_AES, (SVE2, AES), (), (), "sveaes") + +AARCH64_OPT_EXTENSION("sve2-sha3", SVE2_SHA3, (SVE2, SHA3), (), (), "svesha3") + +AARCH64_OPT_EXTENSION("sve2-bitperm", SVE2_BITPERM, (SVE2), (), (), + "svebitperm") + +AARCH64_OPT_EXTENSION("tme", TME, (), (), (), "") + +AARCH64_OPT_EXTENSION("i8mm", I8MM, (SIMD), (), (), "i8mm") + +AARCH64_OPT_EXTENSION("f32mm", F32MM, (SVE), (), (), "f32mm") + +AARCH64_OPT_EXTENSION("f64mm", F64MM, (SVE), (), (), "f64mm") + +/* An explicit +bf16 implies +simd, but +bf16+nosimd still enables scalar BF16 + instructions. */ +AARCH64_OPT_EXTENSION("bf16", BF16, (FP), (SIMD), (), "bf16") + +AARCH64_OPT_EXTENSION("flagm", FLAGM, (), (), (), "flagm") + +AARCH64_OPT_EXTENSION("pauth", PAUTH, (), (), (), "paca pacg") + +AARCH64_OPT_EXTENSION("ls64", LS64, (), (), (), "") + +AARCH64_OPT_EXTENSION("mops", MOPS, (), (), (), "") #undef AARCH64_OPT_EXTENSION diff --git a/gcc/config/aarch64/aarch64-opts.h b/gcc/config/aarch64/aarch64-opts.h index 421648a..ba23c90 100644 --- a/gcc/config/aarch64/aarch64-opts.h +++ b/gcc/config/aarch64/aarch64-opts.h @@ -22,6 +22,10 @@ #ifndef GCC_AARCH64_OPTS_H #define GCC_AARCH64_OPTS_H +#ifndef USED_FOR_TARGET +typedef uint64_t aarch64_feature_flags; +#endif + /* The various cores that implement AArch64. */ enum aarch64_processor { diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h index 5ecdb8a..1a71f02 100644 --- a/gcc/config/aarch64/aarch64-protos.h +++ b/gcc/config/aarch64/aarch64-protos.h @@ -747,7 +747,7 @@ public: ~aarch64_simd_switcher (); private: - unsigned long m_old_isa_flags; + unsigned long m_old_asm_isa_flags; bool m_old_general_regs_only; }; @@ -1029,15 +1029,19 @@ extern bool aarch64_classify_address (struct aarch64_address_info *, rtx, machine_mode, bool, aarch64_addr_query_type = ADDR_QUERY_M); +void aarch64_set_asm_isa_flags (aarch64_feature_flags); + /* Defined in common/config/aarch64-common.cc. */ +void aarch64_set_asm_isa_flags (gcc_options *, aarch64_feature_flags); bool aarch64_handle_option (struct gcc_options *, struct gcc_options *, const struct cl_decoded_option *, location_t); const char *aarch64_rewrite_selected_cpu (const char *name); enum aarch64_parse_opt_result aarch64_parse_extension (const char *, - uint64_t *, + aarch64_feature_flags *, std::string *); void aarch64_get_all_extension_candidates (auto_vec<const char *> *candidates); -std::string aarch64_get_extension_string_for_isa_flags (uint64_t, uint64_t); +std::string aarch64_get_extension_string_for_isa_flags (aarch64_feature_flags, + aarch64_feature_flags); rtl_opt_pass *make_pass_fma_steering (gcc::context *); rtl_opt_pass *make_pass_track_speculation (gcc::context *); diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md index dc80f82..5386043 100644 --- a/gcc/config/aarch64/aarch64-simd.md +++ b/gcc/config/aarch64/aarch64-simd.md @@ -716,7 +716,7 @@ [(match_operand:VHSDF 0 "register_operand") (match_operand:VHSDF 1 "register_operand") (match_operand:VHSDF 2 "register_operand")] - "TARGET_FLOAT && TARGET_SIMD" + "TARGET_SIMD" { rtx v_bitmask = gen_reg_rtx (<V_INT_EQUIV>mode); int bits = GET_MODE_UNIT_BITSIZE (<MODE>mode) - 1; @@ -8097,7 +8097,7 @@ (match_operand:V16QI 1 "register_operand" "%0") (match_operand:V16QI 2 "register_operand" "w"))] CRYPTO_AES))] - "TARGET_SIMD && TARGET_AES" + "TARGET_AES" "aes<aes_op>\\t%0.16b, %2.16b" [(set_attr "type" "crypto_aese")] ) @@ -8106,7 +8106,7 @@ [(set (match_operand:V16QI 0 "register_operand" "=w") (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "w")] CRYPTO_AESMC))] - "TARGET_SIMD && TARGET_AES" + "TARGET_AES" "aes<aesmc_op>\\t%0.16b, %1.16b" [(set_attr "type" "crypto_aesmc")] ) @@ -8125,7 +8125,7 @@ (match_operand:V16QI 2 "register_operand" "w"))] UNSPEC_AESE)] UNSPEC_AESMC))] - "TARGET_SIMD && TARGET_AES + "TARGET_AES && aarch64_fusion_enabled_p (AARCH64_FUSE_AES_AESMC)" "aese\\t%0.16b, %2.16b\;aesmc\\t%0.16b, %0.16b" [(set_attr "type" "crypto_aese") @@ -8146,7 +8146,7 @@ (match_operand:V16QI 2 "register_operand" "w"))] UNSPEC_AESD)] UNSPEC_AESIMC))] - "TARGET_SIMD && TARGET_AES + "TARGET_AES && aarch64_fusion_enabled_p (AARCH64_FUSE_AES_AESMC)" "aesd\\t%0.16b, %2.16b\;aesimc\\t%0.16b, %0.16b" [(set_attr "type" "crypto_aese") @@ -8160,7 +8160,7 @@ (unspec:SI [(match_operand:SI 1 "register_operand" "w")] UNSPEC_SHA1H))] - "TARGET_SIMD && TARGET_SHA2" + "TARGET_SHA2" "sha1h\\t%s0, %s1" [(set_attr "type" "crypto_sha1_fast")] ) @@ -8170,7 +8170,7 @@ (unspec:SI [(vec_select:SI (match_operand:V4SI 1 "register_operand" "w") (parallel [(const_int 0)]))] UNSPEC_SHA1H))] - "TARGET_SIMD && TARGET_SHA2 && !BYTES_BIG_ENDIAN" + "TARGET_SHA2 && !BYTES_BIG_ENDIAN" "sha1h\\t%s0, %s1" [(set_attr "type" "crypto_sha1_fast")] ) @@ -8180,7 +8180,7 @@ (unspec:SI [(vec_select:SI (match_operand:V4SI 1 "register_operand" "w") (parallel [(const_int 3)]))] UNSPEC_SHA1H))] - "TARGET_SIMD && TARGET_SHA2 && BYTES_BIG_ENDIAN" + "TARGET_SHA2 && BYTES_BIG_ENDIAN" "sha1h\\t%s0, %s1" [(set_attr "type" "crypto_sha1_fast")] ) @@ -8190,7 +8190,7 @@ (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0") (match_operand:V4SI 2 "register_operand" "w")] UNSPEC_SHA1SU1))] - "TARGET_SIMD && TARGET_SHA2" + "TARGET_SHA2" "sha1su1\\t%0.4s, %2.4s" [(set_attr "type" "crypto_sha1_fast")] ) @@ -8201,7 +8201,7 @@ (match_operand:SI 2 "register_operand" "w") (match_operand:V4SI 3 "register_operand" "w")] CRYPTO_SHA1))] - "TARGET_SIMD && TARGET_SHA2" + "TARGET_SHA2" "sha1<sha1_op>\\t%q0, %s2, %3.4s" [(set_attr "type" "crypto_sha1_slow")] ) @@ -8212,7 +8212,7 @@ (match_operand:V4SI 2 "register_operand" "w") (match_operand:V4SI 3 "register_operand" "w")] UNSPEC_SHA1SU0))] - "TARGET_SIMD && TARGET_SHA2" + "TARGET_SHA2" "sha1su0\\t%0.4s, %2.4s, %3.4s" [(set_attr "type" "crypto_sha1_xor")] ) @@ -8225,7 +8225,7 @@ (match_operand:V4SI 2 "register_operand" "w") (match_operand:V4SI 3 "register_operand" "w")] CRYPTO_SHA256))] - "TARGET_SIMD && TARGET_SHA2" + "TARGET_SHA2" "sha256h<sha256_op>\\t%q0, %q2, %3.4s" [(set_attr "type" "crypto_sha256_slow")] ) @@ -8235,7 +8235,7 @@ (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0") (match_operand:V4SI 2 "register_operand" "w")] UNSPEC_SHA256SU0))] - "TARGET_SIMD && TARGET_SHA2" + "TARGET_SHA2" "sha256su0\\t%0.4s, %2.4s" [(set_attr "type" "crypto_sha256_fast")] ) @@ -8246,7 +8246,7 @@ (match_operand:V4SI 2 "register_operand" "w") (match_operand:V4SI 3 "register_operand" "w")] UNSPEC_SHA256SU1))] - "TARGET_SIMD && TARGET_SHA2" + "TARGET_SHA2" "sha256su1\\t%0.4s, %2.4s, %3.4s" [(set_attr "type" "crypto_sha256_slow")] ) @@ -8259,7 +8259,7 @@ (match_operand:V2DI 2 "register_operand" "w") (match_operand:V2DI 3 "register_operand" "w")] CRYPTO_SHA512))] - "TARGET_SIMD && TARGET_SHA3" + "TARGET_SHA3" "sha512h<sha512_op>\\t%q0, %q2, %3.2d" [(set_attr "type" "crypto_sha512")] ) @@ -8269,7 +8269,7 @@ (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "0") (match_operand:V2DI 2 "register_operand" "w")] UNSPEC_SHA512SU0))] - "TARGET_SIMD && TARGET_SHA3" + "TARGET_SHA3" "sha512su0\\t%0.2d, %2.2d" [(set_attr "type" "crypto_sha512")] ) @@ -8280,7 +8280,7 @@ (match_operand:V2DI 2 "register_operand" "w") (match_operand:V2DI 3 "register_operand" "w")] UNSPEC_SHA512SU1))] - "TARGET_SIMD && TARGET_SHA3" + "TARGET_SHA3" "sha512su1\\t%0.2d, %2.2d, %3.2d" [(set_attr "type" "crypto_sha512")] ) @@ -8294,7 +8294,7 @@ (match_operand:VQ_I 2 "register_operand" "w") (match_operand:VQ_I 3 "register_operand" "w")) (match_operand:VQ_I 1 "register_operand" "w")))] - "TARGET_SIMD && TARGET_SHA3" + "TARGET_SHA3" "eor3\\t%0.16b, %1.16b, %2.16b, %3.16b" [(set_attr "type" "crypto_sha3")] ) @@ -8306,7 +8306,7 @@ (match_operand:V2DI 2 "register_operand" "w") (const_int 1)) (match_operand:V2DI 1 "register_operand" "w")))] - "TARGET_SIMD && TARGET_SHA3" + "TARGET_SHA3" "rax1\\t%0.2d, %1.2d, %2.2d" [(set_attr "type" "crypto_sha3")] ) @@ -8318,7 +8318,7 @@ (match_operand:V2DI 1 "register_operand" "%w") (match_operand:V2DI 2 "register_operand" "w")) (match_operand:SI 3 "aarch64_simd_shift_imm_di" "Usd")))] - "TARGET_SIMD && TARGET_SHA3" + "TARGET_SHA3" "xar\\t%0.2d, %1.2d, %2.2d, %3" [(set_attr "type" "crypto_sha3")] ) @@ -8330,7 +8330,7 @@ (not:VQ_I (match_operand:VQ_I 3 "register_operand" "w")) (match_operand:VQ_I 2 "register_operand" "w")) (match_operand:VQ_I 1 "register_operand" "w")))] - "TARGET_SIMD && TARGET_SHA3" + "TARGET_SHA3" "bcax\\t%0.16b, %1.16b, %2.16b, %3.16b" [(set_attr "type" "crypto_sha3")] ) @@ -8343,7 +8343,7 @@ (match_operand:V4SI 2 "register_operand" "w") (match_operand:V4SI 3 "register_operand" "w")] UNSPEC_SM3SS1))] - "TARGET_SIMD && TARGET_SM4" + "TARGET_SM4" "sm3ss1\\t%0.4s, %1.4s, %2.4s, %3.4s" [(set_attr "type" "crypto_sm3")] ) @@ -8356,7 +8356,7 @@ (match_operand:V4SI 3 "register_operand" "w") (match_operand:SI 4 "aarch64_imm2" "Ui2")] CRYPTO_SM3TT))] - "TARGET_SIMD && TARGET_SM4" + "TARGET_SM4" "sm3tt<sm3tt_op>\\t%0.4s, %2.4s, %3.4s[%4]" [(set_attr "type" "crypto_sm3")] ) @@ -8367,7 +8367,7 @@ (match_operand:V4SI 2 "register_operand" "w") (match_operand:V4SI 3 "register_operand" "w")] CRYPTO_SM3PART))] - "TARGET_SIMD && TARGET_SM4" + "TARGET_SM4" "sm3partw<sm3part_op>\\t%0.4s, %2.4s, %3.4s" [(set_attr "type" "crypto_sm3")] ) @@ -8379,7 +8379,7 @@ (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0") (match_operand:V4SI 2 "register_operand" "w")] UNSPEC_SM4E))] - "TARGET_SIMD && TARGET_SM4" + "TARGET_SM4" "sm4e\\t%0.4s, %2.4s" [(set_attr "type" "crypto_sm4")] ) @@ -8389,7 +8389,7 @@ (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "w") (match_operand:V4SI 2 "register_operand" "w")] UNSPEC_SM4EKEY))] - "TARGET_SIMD && TARGET_SM4" + "TARGET_SM4" "sm4ekey\\t%0.4s, %1.4s, %2.4s" [(set_attr "type" "crypto_sm4")] ) @@ -8975,7 +8975,7 @@ (unspec:TI [(match_operand:DI 1 "register_operand" "w") (match_operand:DI 2 "register_operand" "w")] UNSPEC_PMULL))] - "TARGET_SIMD && TARGET_AES" + "TARGET_AES" "pmull\\t%0.1q, %1.1d, %2.1d" [(set_attr "type" "crypto_pmull")] ) @@ -8985,7 +8985,7 @@ (unspec:TI [(match_operand:V2DI 1 "register_operand" "w") (match_operand:V2DI 2 "register_operand" "w")] UNSPEC_PMULL2))] - "TARGET_SIMD && TARGET_AES" + "TARGET_AES" "pmull2\\t%0.1q, %1.2d, %2.2d" [(set_attr "type" "crypto_pmull")] ) diff --git a/gcc/config/aarch64/aarch64-sve-builtins.cc b/gcc/config/aarch64/aarch64-sve-builtins.cc index 12d9bee..a70e3a6 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins.cc +++ b/gcc/config/aarch64/aarch64-sve-builtins.cc @@ -82,7 +82,7 @@ public: /* The architecture extensions that the function requires, as a set of AARCH64_FL_* flags. */ - uint64_t required_extensions; + aarch64_feature_flags required_extensions; /* True if the decl represents an overloaded function that needs to be resolved by function_resolver. */ @@ -694,16 +694,18 @@ check_required_registers (location_t location, tree fndecl) Report an error against LOCATION if not. */ static bool check_required_extensions (location_t location, tree fndecl, - uint64_t required_extensions) + aarch64_feature_flags required_extensions) { - uint64_t missing_extensions = required_extensions & ~aarch64_isa_flags; + auto missing_extensions = required_extensions & ~aarch64_asm_isa_flags; if (missing_extensions == 0) 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, \ - SYNTHETIC, FEATURE_STRING) \ - { FLAG_CANONICAL, EXT_NAME }, + static const struct { + aarch64_feature_flags flag; + const char *name; + } extensions[] = { +#define AARCH64_OPT_EXTENSION(EXT_NAME, IDENT, C, D, E, F) \ + { AARCH64_FL_##IDENT, EXT_NAME }, #include "aarch64-option-extensions.def" }; @@ -993,7 +995,7 @@ function_builder::get_attributes (const function_instance &instance) registered_function & function_builder::add_function (const function_instance &instance, const char *name, tree fntype, tree attrs, - uint64_t required_extensions, + aarch64_feature_flags required_extensions, bool overloaded_p, bool placeholder_p) { @@ -1035,11 +1037,12 @@ function_builder::add_function (const function_instance &instance, one-to-one mapping between "short" and "full" names, and if standard overload resolution therefore isn't necessary. */ void -function_builder::add_unique_function (const function_instance &instance, - tree return_type, - vec<tree> &argument_types, - uint64_t required_extensions, - bool force_direct_overloads) +function_builder:: +add_unique_function (const function_instance &instance, + tree return_type, + vec<tree> &argument_types, + aarch64_feature_flags required_extensions, + bool force_direct_overloads) { /* Add the function under its full (unique) name. */ char *name = get_name (instance, false); @@ -1082,8 +1085,9 @@ function_builder::add_unique_function (const function_instance &instance, features are available as part of resolving the function to the relevant unique function. */ void -function_builder::add_overloaded_function (const function_instance &instance, - uint64_t required_extensions) +function_builder:: +add_overloaded_function (const function_instance &instance, + aarch64_feature_flags required_extensions) { char *name = get_name (instance, true); if (registered_function **map_value = m_overload_names.get (name)) diff --git a/gcc/config/aarch64/aarch64-sve-builtins.h b/gcc/config/aarch64/aarch64-sve-builtins.h index 24594d5..63d1db7 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins.h +++ b/gcc/config/aarch64/aarch64-sve-builtins.h @@ -263,7 +263,7 @@ struct function_group_info /* The architecture extensions that the functions require, as a set of AARCH64_FL_* flags. */ - uint64_t required_extensions; + aarch64_feature_flags required_extensions; }; /* Describes a single fully-resolved function (i.e. one that has a @@ -321,8 +321,9 @@ public: ~function_builder (); void add_unique_function (const function_instance &, tree, - vec<tree> &, uint64_t, bool); - void add_overloaded_function (const function_instance &, uint64_t); + vec<tree> &, aarch64_feature_flags, bool); + void add_overloaded_function (const function_instance &, + aarch64_feature_flags); void add_overloaded_functions (const function_group_info &, mode_suffix_index); @@ -338,7 +339,7 @@ private: registered_function &add_function (const function_instance &, const char *, tree, tree, - uint64_t, bool, bool); + aarch64_feature_flags, bool, bool); /* The function type to use for functions that are resolved by function_resolver. */ diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index b4971bd..a8845a5 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -81,6 +81,7 @@ #include "rtlanal.h" #include "tree-dfa.h" #include "asan.h" +#include "aarch64-feature-deps.h" /* This file should be included last. */ #include "target-def.h" @@ -2670,19 +2671,20 @@ aarch64_tuning_override_functions[] = /* A processor implementing AArch64. */ struct processor { - const char *const name; - enum aarch64_processor ident; - enum aarch64_processor sched_core; - enum aarch64_arch arch; - const uint64_t flags; - const struct tune_params *const tune; + const char *name; + aarch64_processor ident; + aarch64_processor sched_core; + aarch64_arch arch; + aarch64_feature_flags flags; + const tune_params *tune; }; /* Architectures implementing AArch64. */ -static const struct processor all_architectures[] = +static constexpr processor all_architectures[] = { -#define AARCH64_ARCH(NAME, CORE, ARCH_IDENT, ARCH_REV, FLAGS) \ - {NAME, CORE, CORE, AARCH64_ARCH_##ARCH_IDENT, FLAGS, NULL}, +#define AARCH64_ARCH(NAME, CORE, ARCH_IDENT, D, E) \ + {NAME, CORE, CORE, AARCH64_ARCH_##ARCH_IDENT, \ + feature_deps::ARCH_IDENT ().enable, NULL}, #include "aarch64-arches.def" {NULL, aarch64_none, aarch64_none, aarch64_no_arch, 0, NULL} }; @@ -2690,12 +2692,12 @@ static const struct processor all_architectures[] = /* Processor cores implementing AArch64. */ static const struct processor all_cores[] = { -#define AARCH64_CORE(NAME, IDENT, SCHED, ARCH, FLAGS, COSTS, IMP, PART, VARIANT) \ - {NAME, IDENT, SCHED, AARCH64_ARCH_##ARCH, \ - FLAGS, &COSTS##_tunings}, +#define AARCH64_CORE(NAME, IDENT, SCHED, ARCH, E, COSTS, G, H, I) \ + {NAME, IDENT, SCHED, AARCH64_ARCH_##ARCH, \ + feature_deps::cpu_##IDENT, &COSTS##_tunings}, #include "aarch64-cores.def" - {"generic", generic, cortexa53, AARCH64_ARCH_8A, - AARCH64_FL_FOR_ARCH8, &generic_tunings}, + {"generic", generic, cortexa53, AARCH64_ARCH_V8A, + feature_deps::V8A ().enable, &generic_tunings}, {NULL, aarch64_none, aarch64_none, aarch64_no_arch, 0, NULL} }; @@ -17119,7 +17121,8 @@ static void initialize_aarch64_code_model (struct gcc_options *); static enum aarch64_parse_opt_result aarch64_parse_arch (const char *to_parse, const struct processor **res, - uint64_t *isa_flags, std::string *invalid_extension) + aarch64_feature_flags *isa_flags, + std::string *invalid_extension) { const char *ext; const struct processor *arch; @@ -17142,7 +17145,7 @@ aarch64_parse_arch (const char *to_parse, const struct processor **res, if (strlen (arch->name) == len && strncmp (arch->name, to_parse, len) == 0) { - uint64_t isa_temp = arch->flags; + auto isa_temp = arch->flags; if (ext != NULL) { @@ -17174,7 +17177,8 @@ aarch64_parse_arch (const char *to_parse, const struct processor **res, static enum aarch64_parse_opt_result aarch64_parse_cpu (const char *to_parse, const struct processor **res, - uint64_t *isa_flags, std::string *invalid_extension) + aarch64_feature_flags *isa_flags, + std::string *invalid_extension) { const char *ext; const struct processor *cpu; @@ -17196,8 +17200,7 @@ aarch64_parse_cpu (const char *to_parse, const struct processor **res, { if (strlen (cpu->name) == len && strncmp (cpu->name, to_parse, len) == 0) { - uint64_t isa_temp = cpu->flags; - + auto isa_temp = cpu->flags; if (ext != NULL) { @@ -17828,7 +17831,7 @@ aarch64_print_hint_for_extensions (const std::string &str) static bool aarch64_validate_mcpu (const char *str, const struct processor **res, - uint64_t *isa_flags) + aarch64_feature_flags *isa_flags) { std::string invalid_extension; enum aarch64_parse_opt_result parse_res @@ -18042,7 +18045,7 @@ aarch64_validate_mbranch_protection (const char *const_str) static bool aarch64_validate_march (const char *str, const struct processor **res, - uint64_t *isa_flags) + aarch64_feature_flags *isa_flags) { std::string invalid_extension; enum aarch64_parse_opt_result parse_res @@ -18127,19 +18130,28 @@ aarch64_convert_sve_vector_bits (aarch64_sve_vector_bits_enum value) return (int) value / 64; } +/* Set the global aarch64_asm_isa_flags to FLAGS and update + aarch64_isa_flags accordingly. */ + +void +aarch64_set_asm_isa_flags (aarch64_feature_flags flags) +{ + aarch64_set_asm_isa_flags (&global_options, flags); +} + /* Implement TARGET_OPTION_OVERRIDE. This is called once in the beginning and is used to parse the -m{cpu,tune,arch} strings and setup the initial tuning structs. In particular it must set selected_tune and - aarch64_isa_flags that define the available ISA features and tuning + aarch64_asm_isa_flags that define the available ISA features and tuning decisions. It must also set selected_arch as this will be used to output the .arch asm tags for each function. */ static void aarch64_override_options (void) { - uint64_t cpu_isa = 0; - uint64_t arch_isa = 0; - aarch64_isa_flags = 0; + aarch64_feature_flags cpu_isa = 0; + aarch64_feature_flags arch_isa = 0; + aarch64_set_asm_isa_flags (0); const struct processor *cpu = NULL; const struct processor *arch = NULL; @@ -18179,25 +18191,25 @@ aarch64_override_options (void) } selected_arch = arch->arch; - aarch64_isa_flags = arch_isa; + aarch64_set_asm_isa_flags (arch_isa); } else if (cpu) { selected_arch = cpu->arch; - aarch64_isa_flags = cpu_isa; + aarch64_set_asm_isa_flags (cpu_isa); } else if (arch) { cpu = &all_cores[arch->ident]; selected_arch = arch->arch; - aarch64_isa_flags = arch_isa; + aarch64_set_asm_isa_flags (arch_isa); } else { /* No -mcpu or -march specified, so use the default CPU. */ cpu = &all_cores[TARGET_CPU_DEFAULT]; selected_arch = cpu->arch; - aarch64_isa_flags = cpu->flags; + aarch64_set_asm_isa_flags (cpu->flags); } selected_tune = tune ? tune->ident : cpu->ident; @@ -18339,7 +18351,7 @@ aarch64_option_print (FILE *file, int indent, struct cl_target_option *ptr) = aarch64_get_tune_cpu (ptr->x_selected_tune); const struct processor *arch = aarch64_get_arch (ptr->x_selected_arch); std::string extension - = aarch64_get_extension_string_for_isa_flags (ptr->x_aarch64_isa_flags, + = aarch64_get_extension_string_for_isa_flags (ptr->x_aarch64_asm_isa_flags, arch->flags); fprintf (file, "%*sselected tune = %s\n", indent, "", cpu->name); @@ -18447,13 +18459,15 @@ aarch64_handle_attr_arch (const char *str) { const struct processor *tmp_arch = NULL; std::string invalid_extension; + aarch64_feature_flags tmp_flags; enum aarch64_parse_opt_result parse_res - = aarch64_parse_arch (str, &tmp_arch, &aarch64_isa_flags, &invalid_extension); + = aarch64_parse_arch (str, &tmp_arch, &tmp_flags, &invalid_extension); if (parse_res == AARCH64_PARSE_OK) { gcc_assert (tmp_arch); selected_arch = tmp_arch->arch; + aarch64_set_asm_isa_flags (tmp_flags); return true; } @@ -18485,14 +18499,16 @@ aarch64_handle_attr_cpu (const char *str) { const struct processor *tmp_cpu = NULL; std::string invalid_extension; + aarch64_feature_flags tmp_flags; enum aarch64_parse_opt_result parse_res - = aarch64_parse_cpu (str, &tmp_cpu, &aarch64_isa_flags, &invalid_extension); + = aarch64_parse_cpu (str, &tmp_cpu, &tmp_flags, &invalid_extension); if (parse_res == AARCH64_PARSE_OK) { gcc_assert (tmp_cpu); selected_tune = tmp_cpu->ident; selected_arch = tmp_cpu->arch; + aarch64_set_asm_isa_flags (tmp_flags); return true; } @@ -18586,7 +18602,7 @@ static bool aarch64_handle_attr_isa_flags (char *str) { enum aarch64_parse_opt_result parse_res; - uint64_t isa_flags = aarch64_isa_flags; + auto isa_flags = aarch64_asm_isa_flags; /* We allow "+nothing" in the beginning to clear out all architectural features if the user wants to handpick specific features. */ @@ -18601,7 +18617,7 @@ aarch64_handle_attr_isa_flags (char *str) if (parse_res == AARCH64_PARSE_OK) { - aarch64_isa_flags = isa_flags; + aarch64_set_asm_isa_flags (isa_flags); return true; } @@ -18858,7 +18874,7 @@ aarch64_process_target_attr (tree args) { /* Check if token is possibly an arch extension without leading '+'. */ - uint64_t isa_temp = 0; + aarch64_feature_flags isa_temp = 0; auto with_plus = std::string ("+") + token; enum aarch64_parse_opt_result ext_res = aarch64_parse_extension (with_plus.c_str (), &isa_temp, nullptr); @@ -19011,8 +19027,12 @@ aarch64_can_inline_p (tree caller, tree callee) : target_option_default_node); /* Callee's ISA flags should be a subset of the caller's. */ + if ((caller_opts->x_aarch64_asm_isa_flags + & callee_opts->x_aarch64_asm_isa_flags) + != callee_opts->x_aarch64_asm_isa_flags) + return false; if ((caller_opts->x_aarch64_isa_flags & callee_opts->x_aarch64_isa_flags) - != callee_opts->x_aarch64_isa_flags) + != callee_opts->x_aarch64_isa_flags) return false; /* Allow non-strict aligned functions inlining into strict @@ -20644,6 +20664,8 @@ aarch64_mangle_type (const_tree type) /* Half-precision floating point types. */ if (TREE_CODE (type) == REAL_TYPE && TYPE_PRECISION (type) == 16) { + if (TYPE_MAIN_VARIANT (type) == float16_type_node) + return NULL; if (TYPE_MODE (type) == BFmode) return "u6__bf16"; else @@ -22474,7 +22496,7 @@ aarch64_declare_function_name (FILE *stream, const char* name, const struct processor *this_arch = aarch64_get_arch (targ_options->x_selected_arch); - uint64_t isa_flags = targ_options->x_aarch64_isa_flags; + auto isa_flags = targ_options->x_aarch64_asm_isa_flags; std::string extension = aarch64_get_extension_string_for_isa_flags (isa_flags, this_arch->flags); @@ -22578,7 +22600,7 @@ aarch64_start_file (void) const struct processor *default_arch = aarch64_get_arch (default_options->x_selected_arch); - uint64_t default_isa_flags = default_options->x_aarch64_isa_flags; + auto default_isa_flags = default_options->x_aarch64_asm_isa_flags; std::string extension = aarch64_get_extension_string_for_isa_flags (default_isa_flags, default_arch->flags); diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h index f790de1..2d62218 100644 --- a/gcc/config/aarch64/aarch64.h +++ b/gcc/config/aarch64/aarch64.h @@ -22,6 +22,17 @@ #ifndef GCC_AARCH64_H #define GCC_AARCH64_H +/* Make these flags read-only so that all uses go via + aarch64_set_asm_isa_flags. */ +#ifndef GENERATOR_FILE +#undef aarch64_asm_isa_flags +#define aarch64_asm_isa_flags \ + ((aarch64_feature_flags) global_options.x_aarch64_asm_isa_flags) +#undef aarch64_isa_flags +#define aarch64_isa_flags \ + ((aarch64_feature_flags) global_options.x_aarch64_isa_flags) +#endif + /* Target CPU builtins. */ #define TARGET_CPU_CPP_BUILTINS() \ aarch64_cpu_cpp_builtins (pfile) @@ -51,8 +62,8 @@ /* AdvSIMD is supported in the default configuration, unless disabled by -mgeneral-regs-only or by the +nosimd extension. */ -#define TARGET_SIMD (!TARGET_GENERAL_REGS_ONLY && AARCH64_ISA_SIMD) -#define TARGET_FLOAT (!TARGET_GENERAL_REGS_ONLY && AARCH64_ISA_FP) +#define TARGET_SIMD (AARCH64_ISA_SIMD) +#define TARGET_FLOAT (AARCH64_ISA_FP) #define UNITS_PER_WORD 8 @@ -144,150 +155,27 @@ #define PCC_BITFIELD_TYPE_MATTERS 1 -/* Instruction tuning/selection flags. */ - -/* Bit values used to identify processor capabilities. */ -#define AARCH64_FL_SIMD (1 << 0) /* Has SIMD instructions. */ -#define AARCH64_FL_FP (1 << 1) /* Has FP. */ -#define AARCH64_FL_CRYPTO (1 << 2) /* Has crypto. */ -#define AARCH64_FL_CRC (1 << 3) /* Has CRC. */ -/* ARMv8.1-A architecture extensions. */ -#define AARCH64_FL_LSE (1 << 4) /* Has Large System Extensions. */ -#define AARCH64_FL_RDMA (1 << 5) /* Has Round Double Multiply Add. */ -#define AARCH64_FL_V8_1 (1 << 6) /* Has ARMv8.1-A extensions. */ -/* Armv8-R. */ -#define AARCH64_FL_V8_R (1 << 7) /* Armv8-R AArch64. */ -/* ARMv8.2-A architecture extensions. */ -#define AARCH64_FL_V8_2 (1 << 8) /* Has ARMv8.2-A features. */ -#define AARCH64_FL_F16 (1 << 9) /* Has ARMv8.2-A FP16 extensions. */ -#define AARCH64_FL_SVE (1 << 10) /* Has Scalable Vector Extensions. */ -/* ARMv8.3-A architecture extensions. */ -#define AARCH64_FL_V8_3 (1 << 11) /* Has ARMv8.3-A features. */ -#define AARCH64_FL_RCPC (1 << 12) /* Has support for RCpc model. */ -#define AARCH64_FL_DOTPROD (1 << 13) /* Has ARMv8.2-A Dot Product ins. */ -/* New flags to split crypto into aes and sha2. */ -#define AARCH64_FL_AES (1 << 14) /* Has Crypto AES. */ -#define AARCH64_FL_SHA2 (1 << 15) /* Has Crypto SHA2. */ -/* ARMv8.4-A architecture extensions. */ -#define AARCH64_FL_V8_4 (1 << 16) /* Has ARMv8.4-A features. */ -#define AARCH64_FL_SM4 (1 << 17) /* Has ARMv8.4-A SM3 and SM4. */ -#define AARCH64_FL_SHA3 (1 << 18) /* Has ARMv8.4-a SHA3 and SHA512. */ -#define AARCH64_FL_F16FML (1 << 19) /* Has ARMv8.4-a FP16 extensions. */ -#define AARCH64_FL_RCPC8_4 (1 << 20) /* Has ARMv8.4-a RCPC extensions. */ - -/* Statistical Profiling extensions. */ -#define AARCH64_FL_PROFILE (1 << 21) - -/* ARMv8.5-A architecture extensions. */ -#define AARCH64_FL_V8_5 (1 << 22) /* Has ARMv8.5-A features. */ -#define AARCH64_FL_RNG (1 << 23) /* ARMv8.5-A Random Number Insns. */ -#define AARCH64_FL_MEMTAG (1 << 24) /* ARMv8.5-A Memory Tagging - Extensions. */ - -/* Speculation Barrier instruction supported. */ -#define AARCH64_FL_SB (1 << 25) - -/* Speculative Store Bypass Safe instruction supported. */ -#define AARCH64_FL_SSBS (1 << 26) - -/* Execution and Data Prediction Restriction instructions supported. */ -#define AARCH64_FL_PREDRES (1 << 27) - -/* SVE2 instruction supported. */ -#define AARCH64_FL_SVE2 (1 << 28) -#define AARCH64_FL_SVE2_AES (1 << 29) -#define AARCH64_FL_SVE2_SM4 (1 << 30) -#define AARCH64_FL_SVE2_SHA3 (1ULL << 31) -#define AARCH64_FL_SVE2_BITPERM (1ULL << 32) - -/* Transactional Memory Extension. */ -#define AARCH64_FL_TME (1ULL << 33) /* Has TME instructions. */ - -/* Armv8.6-A architecture extensions. */ -#define AARCH64_FL_V8_6 (1ULL << 34) - -/* 8-bit Integer Matrix Multiply (I8MM) extensions. */ -#define AARCH64_FL_I8MM (1ULL << 35) - -/* Brain half-precision floating-point (BFloat16) Extension. */ -#define AARCH64_FL_BF16 (1ULL << 36) - -/* 32-bit Floating-point Matrix Multiply (F32MM) extensions. */ -#define AARCH64_FL_F32MM (1ULL << 37) - -/* 64-bit Floating-point Matrix Multiply (F64MM) extensions. */ -#define AARCH64_FL_F64MM (1ULL << 38) - -/* Flag Manipulation Instructions (FLAGM) extension. */ -#define AARCH64_FL_FLAGM (1ULL << 39) - -/* Pointer Authentication (PAUTH) extension. */ -#define AARCH64_FL_PAUTH (1ULL << 40) - -/* Armv9.0-A. */ -#define AARCH64_FL_V9 (1ULL << 41) /* Armv9.0-A Architecture. */ - -/* 64-byte atomic load/store extensions. */ -#define AARCH64_FL_LS64 (1ULL << 42) - -/* Armv8.7-a architecture extensions. */ -#define AARCH64_FL_V8_7 (1ULL << 43) - -/* Hardware memory operation instructions. */ -#define AARCH64_FL_MOPS (1ULL << 44) - -/* Armv8.8-a architecture extensions. */ -#define AARCH64_FL_V8_8 (1ULL << 45) - -/* Armv9.1-A. */ -#define AARCH64_FL_V9_1 (1ULL << 46) - -/* Armv9.2-A. */ -#define AARCH64_FL_V9_2 (1ULL << 47) - -/* Armv9.3-A. */ -#define AARCH64_FL_V9_3 (1ULL << 48) - -/* Has FP and SIMD. */ -#define AARCH64_FL_FPSIMD (AARCH64_FL_FP | AARCH64_FL_SIMD) - -/* Has FP without SIMD. */ -#define AARCH64_FL_FPQ16 (AARCH64_FL_FP & ~AARCH64_FL_SIMD) - -/* Architecture flags that effect instruction selection. */ -#define AARCH64_FL_FOR_ARCH8 (AARCH64_FL_FPSIMD) -#define AARCH64_FL_FOR_ARCH8_1 \ - (AARCH64_FL_FOR_ARCH8 | AARCH64_FL_LSE | AARCH64_FL_CRC \ - | AARCH64_FL_RDMA | AARCH64_FL_V8_1) -#define AARCH64_FL_FOR_ARCH8_2 \ - (AARCH64_FL_FOR_ARCH8_1 | AARCH64_FL_V8_2) -#define AARCH64_FL_FOR_ARCH8_3 \ - (AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_V8_3 | AARCH64_FL_PAUTH) -#define AARCH64_FL_FOR_ARCH8_4 \ - (AARCH64_FL_FOR_ARCH8_3 | AARCH64_FL_V8_4 | AARCH64_FL_F16FML \ - | AARCH64_FL_DOTPROD | AARCH64_FL_RCPC8_4 | AARCH64_FL_FLAGM) -#define AARCH64_FL_FOR_ARCH8_5 \ - (AARCH64_FL_FOR_ARCH8_4 | AARCH64_FL_V8_5 \ - | AARCH64_FL_SB | AARCH64_FL_SSBS | AARCH64_FL_PREDRES) -#define AARCH64_FL_FOR_ARCH8_6 \ - (AARCH64_FL_FOR_ARCH8_5 | AARCH64_FL_V8_6 | AARCH64_FL_FPSIMD \ - | AARCH64_FL_I8MM | AARCH64_FL_BF16) -#define AARCH64_FL_FOR_ARCH8_7 \ - (AARCH64_FL_FOR_ARCH8_6 | AARCH64_FL_V8_7 | AARCH64_FL_LS64) -#define AARCH64_FL_FOR_ARCH8_8 \ - (AARCH64_FL_FOR_ARCH8_7 | AARCH64_FL_V8_8 | AARCH64_FL_MOPS) - -#define AARCH64_FL_FOR_ARCH8_R \ - (AARCH64_FL_FOR_ARCH8_4 | AARCH64_FL_V8_R) -#define AARCH64_FL_FOR_ARCH9 \ - (AARCH64_FL_FOR_ARCH8_5 | AARCH64_FL_SVE | AARCH64_FL_SVE2 | AARCH64_FL_V9 \ - | AARCH64_FL_F16) -#define AARCH64_FL_FOR_ARCH9_1 \ - (AARCH64_FL_FOR_ARCH9 | AARCH64_FL_FOR_ARCH8_6 | AARCH64_FL_V9_1) -#define AARCH64_FL_FOR_ARCH9_2 \ - (AARCH64_FL_FOR_ARCH9_1 | AARCH64_FL_FOR_ARCH8_7 | AARCH64_FL_V9_2) -#define AARCH64_FL_FOR_ARCH9_3 \ - (AARCH64_FL_FOR_ARCH9_2 | AARCH64_FL_FOR_ARCH8_8 | AARCH64_FL_V9_3) +#ifndef USED_FOR_TARGET + +/* Define an enum of all features (architectures and extensions). */ +enum class aarch64_feature : unsigned char { +#define AARCH64_OPT_EXTENSION(A, IDENT, C, D, E, F) IDENT, +#define AARCH64_ARCH(A, B, IDENT, D, E) IDENT, +#include "aarch64-option-extensions.def" +#include "aarch64-arches.def" +}; + +/* Define unique flags for each of the above. */ +#define HANDLE(IDENT) \ + constexpr auto AARCH64_FL_##IDENT \ + = aarch64_feature_flags (1) << int (aarch64_feature::IDENT); +#define AARCH64_OPT_EXTENSION(A, IDENT, C, D, E, F) HANDLE (IDENT) +#define AARCH64_ARCH(A, B, IDENT, D, E) HANDLE (IDENT) +#include "aarch64-option-extensions.def" +#include "aarch64-arches.def" +#undef HANDLE + +#endif /* Macros to test ISA flags. */ @@ -297,7 +185,7 @@ #define AARCH64_ISA_SIMD (aarch64_isa_flags & AARCH64_FL_SIMD) #define AARCH64_ISA_LSE (aarch64_isa_flags & AARCH64_FL_LSE) #define AARCH64_ISA_RDMA (aarch64_isa_flags & AARCH64_FL_RDMA) -#define AARCH64_ISA_V8_2 (aarch64_isa_flags & AARCH64_FL_V8_2) +#define AARCH64_ISA_V8_2A (aarch64_isa_flags & AARCH64_FL_V8_2A) #define AARCH64_ISA_F16 (aarch64_isa_flags & AARCH64_FL_F16) #define AARCH64_ISA_SVE (aarch64_isa_flags & AARCH64_FL_SVE) #define AARCH64_ISA_SVE2 (aarch64_isa_flags & AARCH64_FL_SVE2) @@ -305,48 +193,48 @@ #define AARCH64_ISA_SVE2_BITPERM (aarch64_isa_flags & AARCH64_FL_SVE2_BITPERM) #define AARCH64_ISA_SVE2_SHA3 (aarch64_isa_flags & AARCH64_FL_SVE2_SHA3) #define AARCH64_ISA_SVE2_SM4 (aarch64_isa_flags & AARCH64_FL_SVE2_SM4) -#define AARCH64_ISA_V8_3 (aarch64_isa_flags & AARCH64_FL_V8_3) +#define AARCH64_ISA_V8_3A (aarch64_isa_flags & AARCH64_FL_V8_3A) #define AARCH64_ISA_DOTPROD (aarch64_isa_flags & AARCH64_FL_DOTPROD) #define AARCH64_ISA_AES (aarch64_isa_flags & AARCH64_FL_AES) #define AARCH64_ISA_SHA2 (aarch64_isa_flags & AARCH64_FL_SHA2) -#define AARCH64_ISA_V8_4 (aarch64_isa_flags & AARCH64_FL_V8_4) +#define AARCH64_ISA_V8_4A (aarch64_isa_flags & AARCH64_FL_V8_4A) #define AARCH64_ISA_SM4 (aarch64_isa_flags & AARCH64_FL_SM4) #define AARCH64_ISA_SHA3 (aarch64_isa_flags & AARCH64_FL_SHA3) #define AARCH64_ISA_F16FML (aarch64_isa_flags & AARCH64_FL_F16FML) -#define AARCH64_ISA_RCPC8_4 (aarch64_isa_flags & AARCH64_FL_RCPC8_4) +#define AARCH64_ISA_RCPC8_4 (aarch64_isa_flags & AARCH64_FL_V8_4A) #define AARCH64_ISA_RNG (aarch64_isa_flags & AARCH64_FL_RNG) -#define AARCH64_ISA_V8_5 (aarch64_isa_flags & AARCH64_FL_V8_5) +#define AARCH64_ISA_V8_5A (aarch64_isa_flags & AARCH64_FL_V8_5A) #define AARCH64_ISA_TME (aarch64_isa_flags & AARCH64_FL_TME) #define AARCH64_ISA_MEMTAG (aarch64_isa_flags & AARCH64_FL_MEMTAG) -#define AARCH64_ISA_V8_6 (aarch64_isa_flags & AARCH64_FL_V8_6) +#define AARCH64_ISA_V8_6A (aarch64_isa_flags & AARCH64_FL_V8_6A) #define AARCH64_ISA_I8MM (aarch64_isa_flags & AARCH64_FL_I8MM) #define AARCH64_ISA_F32MM (aarch64_isa_flags & AARCH64_FL_F32MM) #define AARCH64_ISA_F64MM (aarch64_isa_flags & AARCH64_FL_F64MM) #define AARCH64_ISA_BF16 (aarch64_isa_flags & AARCH64_FL_BF16) #define AARCH64_ISA_SB (aarch64_isa_flags & AARCH64_FL_SB) -#define AARCH64_ISA_V8_R (aarch64_isa_flags & AARCH64_FL_V8_R) +#define AARCH64_ISA_V8R (aarch64_isa_flags & AARCH64_FL_V8R) #define AARCH64_ISA_PAUTH (aarch64_isa_flags & AARCH64_FL_PAUTH) -#define AARCH64_ISA_V9 (aarch64_isa_flags & AARCH64_FL_V9) -#define AARCH64_ISA_V9_1 (aarch64_isa_flags & AARCH64_FL_V9_1) -#define AARCH64_ISA_V9_2 (aarch64_isa_flags & AARCH64_FL_V9_2) -#define AARCH64_ISA_V9_3 (aarch64_isa_flags & AARCH64_FL_V9_3) +#define AARCH64_ISA_V9A (aarch64_isa_flags & AARCH64_FL_V9A) +#define AARCH64_ISA_V9_1A (aarch64_isa_flags & AARCH64_FL_V9_1A) +#define AARCH64_ISA_V9_2A (aarch64_isa_flags & AARCH64_FL_V9_2A) +#define AARCH64_ISA_V9_3A (aarch64_isa_flags & AARCH64_FL_V9_3A) #define AARCH64_ISA_MOPS (aarch64_isa_flags & AARCH64_FL_MOPS) #define AARCH64_ISA_LS64 (aarch64_isa_flags & AARCH64_FL_LS64) /* Crypto is an optional extension to AdvSIMD. */ -#define TARGET_CRYPTO (TARGET_SIMD && AARCH64_ISA_CRYPTO) +#define TARGET_CRYPTO (AARCH64_ISA_CRYPTO) /* SHA2 is an optional extension to AdvSIMD. */ -#define TARGET_SHA2 ((TARGET_SIMD && AARCH64_ISA_SHA2) || TARGET_CRYPTO) +#define TARGET_SHA2 (AARCH64_ISA_SHA2) /* SHA3 is an optional extension to AdvSIMD. */ -#define TARGET_SHA3 (TARGET_SIMD && AARCH64_ISA_SHA3) +#define TARGET_SHA3 (AARCH64_ISA_SHA3) /* AES is an optional extension to AdvSIMD. */ -#define TARGET_AES ((TARGET_SIMD && AARCH64_ISA_AES) || TARGET_CRYPTO) +#define TARGET_AES (AARCH64_ISA_AES) /* SM is an optional extension to AdvSIMD. */ -#define TARGET_SM4 (TARGET_SIMD && AARCH64_ISA_SM4) +#define TARGET_SM4 (AARCH64_ISA_SM4) /* FP16FML is an optional extension to AdvSIMD. */ #define TARGET_F16FML (TARGET_SIMD && AARCH64_ISA_F16FML && TARGET_FP_F16INST) @@ -358,41 +246,41 @@ #define TARGET_LSE (AARCH64_ISA_LSE) /* ARMv8.2-A FP16 support that can be enabled through the +fp16 extension. */ -#define TARGET_FP_F16INST (TARGET_FLOAT && AARCH64_ISA_F16) +#define TARGET_FP_F16INST (AARCH64_ISA_F16) #define TARGET_SIMD_F16INST (TARGET_SIMD && AARCH64_ISA_F16) /* Dot Product is an optional extension to AdvSIMD enabled through +dotprod. */ -#define TARGET_DOTPROD (TARGET_SIMD && AARCH64_ISA_DOTPROD) +#define TARGET_DOTPROD (AARCH64_ISA_DOTPROD) /* SVE instructions, enabled through +sve. */ -#define TARGET_SVE (!TARGET_GENERAL_REGS_ONLY && AARCH64_ISA_SVE) +#define TARGET_SVE (AARCH64_ISA_SVE) /* SVE2 instructions, enabled through +sve2. */ -#define TARGET_SVE2 (TARGET_SVE && AARCH64_ISA_SVE2) +#define TARGET_SVE2 (AARCH64_ISA_SVE2) /* SVE2 AES instructions, enabled through +sve2-aes. */ -#define TARGET_SVE2_AES (TARGET_SVE2 && AARCH64_ISA_SVE2_AES) +#define TARGET_SVE2_AES (AARCH64_ISA_SVE2_AES) /* SVE2 BITPERM instructions, enabled through +sve2-bitperm. */ -#define TARGET_SVE2_BITPERM (TARGET_SVE2 && AARCH64_ISA_SVE2_BITPERM) +#define TARGET_SVE2_BITPERM (AARCH64_ISA_SVE2_BITPERM) /* SVE2 SHA3 instructions, enabled through +sve2-sha3. */ -#define TARGET_SVE2_SHA3 (TARGET_SVE2 && AARCH64_ISA_SVE2_SHA3) +#define TARGET_SVE2_SHA3 (AARCH64_ISA_SVE2_SHA3) /* SVE2 SM4 instructions, enabled through +sve2-sm4. */ -#define TARGET_SVE2_SM4 (TARGET_SVE2 && AARCH64_ISA_SVE2_SM4) +#define TARGET_SVE2_SM4 (AARCH64_ISA_SVE2_SM4) /* ARMv8.3-A features. */ -#define TARGET_ARMV8_3 (AARCH64_ISA_V8_3) +#define TARGET_ARMV8_3 (AARCH64_ISA_V8_3A) /* Javascript conversion instruction from Armv8.3-a. */ -#define TARGET_JSCVT (TARGET_FLOAT && AARCH64_ISA_V8_3) +#define TARGET_JSCVT (TARGET_FLOAT && AARCH64_ISA_V8_3A) /* Armv8.3-a Complex number extension to AdvSIMD extensions. */ #define TARGET_COMPLEX (TARGET_SIMD && TARGET_ARMV8_3) /* Floating-point rounding instructions from Armv8.5-a. */ -#define TARGET_FRINT (AARCH64_ISA_V8_5 && TARGET_FLOAT) +#define TARGET_FRINT (AARCH64_ISA_V8_5A && TARGET_FLOAT) /* TME instructions are enabled. */ #define TARGET_TME (AARCH64_ISA_TME) @@ -401,19 +289,17 @@ #define TARGET_RNG (AARCH64_ISA_RNG) /* Memory Tagging instructions optional to Armv8.5 enabled through +memtag. */ -#define TARGET_MEMTAG (AARCH64_ISA_V8_5 && AARCH64_ISA_MEMTAG) +#define TARGET_MEMTAG (AARCH64_ISA_V8_5A && AARCH64_ISA_MEMTAG) /* I8MM instructions are enabled through +i8mm. */ #define TARGET_I8MM (AARCH64_ISA_I8MM) #define TARGET_SVE_I8MM (TARGET_SVE && AARCH64_ISA_I8MM) /* F32MM instructions are enabled through +f32mm. */ -#define TARGET_F32MM (AARCH64_ISA_F32MM) -#define TARGET_SVE_F32MM (TARGET_SVE && AARCH64_ISA_F32MM) +#define TARGET_SVE_F32MM (AARCH64_ISA_F32MM) /* F64MM instructions are enabled through +f64mm. */ -#define TARGET_F64MM (AARCH64_ISA_F64MM) -#define TARGET_SVE_F64MM (TARGET_SVE && AARCH64_ISA_F64MM) +#define TARGET_SVE_F64MM (AARCH64_ISA_F64MM) /* BF16 instructions are enabled through +bf16. */ #define TARGET_BF16_FP (AARCH64_ISA_BF16) diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 3f8e40a..0a7633e 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -6468,7 +6468,7 @@ (define_expand "<optab>dihf2" [(set (match_operand:HF 0 "register_operand") (FLOATUORS:HF (match_operand:DI 1 "register_operand")))] - "TARGET_FLOAT && (TARGET_FP_F16INST || TARGET_SIMD)" + "TARGET_FP_F16INST || TARGET_SIMD" { if (TARGET_FP_F16INST) emit_insn (gen_aarch64_fp16_<optab>dihf2 (operands[0], operands[1])); @@ -6727,7 +6727,7 @@ [(match_operand:GPF 0 "register_operand") (match_operand:GPF 1 "register_operand") (match_operand:GPF 2 "register_operand")] - "TARGET_FLOAT && TARGET_SIMD" + "TARGET_SIMD" { rtx bitmask = gen_reg_rtx (<V_INT_EQUIV>mode); emit_move_insn (bitmask, GEN_INT (HOST_WIDE_INT_M1U @@ -6744,7 +6744,7 @@ (match_operand:GPF 2 "register_operand" "w,w,0,0") (match_operand:<V_INT_EQUIV> 3 "register_operand" "0,w,w,X")] UNSPEC_COPYSIGN))] - "TARGET_FLOAT && TARGET_SIMD" + "TARGET_SIMD" "@ bsl\\t%0.<Vbtype>, %2.<Vbtype>, %1.<Vbtype> bit\\t%0.<Vbtype>, %2.<Vbtype>, %3.<Vbtype> @@ -6765,7 +6765,7 @@ [(match_operand:GPF 0 "register_operand") (match_operand:GPF 1 "register_operand") (match_operand:GPF 2 "register_operand")] - "TARGET_FLOAT && TARGET_SIMD" + "TARGET_SIMD" { machine_mode imode = <V_INT_EQUIV>mode; diff --git a/gcc/config/aarch64/aarch64.opt b/gcc/config/aarch64/aarch64.opt index d8e1f42..b89b204 100644 --- a/gcc/config/aarch64/aarch64.opt +++ b/gcc/config/aarch64/aarch64.opt @@ -28,7 +28,10 @@ TargetVariable enum aarch64_arch selected_arch = aarch64_no_arch TargetVariable -uint64_t aarch64_isa_flags = 0 +aarch64_feature_flags aarch64_asm_isa_flags = 0 + +TargetVariable +aarch64_feature_flags aarch64_isa_flags = 0 TargetVariable unsigned aarch64_enable_bti = 2 diff --git a/gcc/config/aarch64/driver-aarch64.cc b/gcc/config/aarch64/driver-aarch64.cc index 8073a07..52ff537 100644 --- a/gcc/config/aarch64/driver-aarch64.cc +++ b/gcc/config/aarch64/driver-aarch64.cc @@ -26,17 +26,17 @@ #include "coretypes.h" #include "tm.h" #include "aarch64-protos.h" +#include "aarch64-feature-deps.h" struct aarch64_arch_extension { const char *ext; - uint64_t flag; + aarch64_feature_flags flag; const char *feat_string; }; -#define AARCH64_OPT_EXTENSION(EXT_NAME, FLAG_CANONICAL, FLAGS_ON, FLAGS_OFF, \ - SYNTHETIC, FEATURE_STRING) \ - { EXT_NAME, FLAG_CANONICAL, FEATURE_STRING }, +#define AARCH64_OPT_EXTENSION(EXT_NAME, IDENT, C, D, E, FEATURE_STRING) \ + { EXT_NAME, AARCH64_FL_##IDENT, FEATURE_STRING }, static struct aarch64_arch_extension aarch64_extensions[] = { #include "aarch64-option-extensions.def" @@ -50,7 +50,7 @@ struct aarch64_core_data unsigned char implementer_id; /* Exactly 8 bits */ unsigned int part_no; /* 12 bits + 12 bits */ unsigned variant; - const uint64_t flags; + aarch64_feature_flags flags; }; #define AARCH64_BIG_LITTLE(BIG, LITTLE) \ @@ -62,9 +62,9 @@ struct aarch64_core_data #define DEFAULT_ARCH "8A" #define AARCH64_CORE(CORE_NAME, CORE_IDENT, SCHED, ARCH, FLAGS, COSTS, IMP, PART, VARIANT) \ - { CORE_NAME, #ARCH, IMP, PART, VARIANT, FLAGS }, + { CORE_NAME, #ARCH, IMP, PART, VARIANT, feature_deps::cpu_##CORE_IDENT }, -static struct aarch64_core_data aarch64_cpu_data[] = +static constexpr aarch64_core_data aarch64_cpu_data[] = { #include "aarch64-cores.def" { NULL, NULL, INVALID_IMP, INVALID_CORE, ALL_VARIANTS, 0 } @@ -75,13 +75,14 @@ struct aarch64_arch_driver_info { const char* id; const char* name; - const uint64_t flags; + aarch64_feature_flags flags; }; +/* Skip the leading "V" in the architecture name. */ #define AARCH64_ARCH(NAME, CORE, ARCH_IDENT, ARCH_REV, FLAGS) \ - { #ARCH_IDENT, NAME, FLAGS }, + { #ARCH_IDENT + 1, NAME, feature_deps::ARCH_IDENT ().enable }, -static struct aarch64_arch_driver_info aarch64_arches[] = +static constexpr aarch64_arch_driver_info aarch64_arches[] = { #include "aarch64-arches.def" {NULL, NULL, 0} @@ -91,7 +92,7 @@ static struct aarch64_arch_driver_info aarch64_arches[] = /* Return an aarch64_arch_driver_info for the architecture described by ID, or NULL if ID describes something we don't know about. */ -static struct aarch64_arch_driver_info* +static const aarch64_arch_driver_info * get_arch_from_id (const char* id) { unsigned int i = 0; @@ -260,8 +261,8 @@ host_detect_local_cpu (int argc, const char **argv) unsigned int variants[2] = { ALL_VARIANTS, ALL_VARIANTS }; unsigned int n_variants = 0; bool processed_exts = false; - uint64_t extension_flags = 0; - uint64_t default_flags = 0; + aarch64_feature_flags extension_flags = 0; + aarch64_feature_flags default_flags = 0; std::string buf; size_t sep_pos = -1; char *fcpu_info; @@ -395,8 +396,7 @@ host_detect_local_cpu (int argc, const char **argv) if (aarch64_cpu_data[i].name == NULL) { - aarch64_arch_driver_info* arch_info - = get_arch_from_id (DEFAULT_ARCH); + auto arch_info = get_arch_from_id (DEFAULT_ARCH); gcc_assert (arch_info); @@ -406,7 +406,7 @@ host_detect_local_cpu (int argc, const char **argv) else if (arch) { const char *arch_id = aarch64_cpu_data[i].arch; - aarch64_arch_driver_info* arch_info = get_arch_from_id (arch_id); + auto arch_info = get_arch_from_id (arch_id); /* We got some arch indentifier that's not in aarch64-arches.def? */ if (!arch_info) diff --git a/gcc/config/aarch64/t-aarch64-vxworks b/gcc/config/aarch64/t-aarch64-vxworks index f9f6ede..e672bb3 100644 --- a/gcc/config/aarch64/t-aarch64-vxworks +++ b/gcc/config/aarch64/t-aarch64-vxworks @@ -20,3 +20,8 @@ MULTILIB_OPTIONS += mrtp MULTILIB_DIRNAMES += mrtp + +# Setup a separate multilib for mcmodel=large, for which +# we may not have shared lib support unlike with -mrtp alone. +MULTILIB_OPTIONS += mcmodel=large +MULTILIB_DIRNAMES += large diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc index 1a37536..ee8f1ba 100644 --- a/gcc/config/arm/arm.cc +++ b/gcc/config/arm/arm.cc @@ -30359,6 +30359,8 @@ arm_mangle_type (const_tree type) /* Half-precision floating point types. */ if (TREE_CODE (type) == REAL_TYPE && TYPE_PRECISION (type) == 16) { + if (TYPE_MAIN_VARIANT (type) == float16_type_node) + return NULL; if (TYPE_MODE (type) == BFmode) return "u6__bf16"; else diff --git a/gcc/config/arm/mve.md b/gcc/config/arm/mve.md index 7141786..62186f1 100644 --- a/gcc/config/arm/mve.md +++ b/gcc/config/arm/mve.md @@ -3503,7 +3503,7 @@ ;; (define_insn "mve_vrev64q_m_<supf><mode>" [ - (set (match_operand:MVE_2 0 "s_register_operand" "=w") + (set (match_operand:MVE_2 0 "s_register_operand" "=&w") (unspec:MVE_2 [(match_operand:MVE_2 1 "s_register_operand" "0") (match_operand:MVE_2 2 "s_register_operand" "w") (match_operand:<MVE_VPRED> 3 "vpr_register_operand" "Up")] @@ -4598,7 +4598,7 @@ ;; (define_insn "mve_vrev64q_m_f<mode>" [ - (set (match_operand:MVE_0 0 "s_register_operand" "=w") + (set (match_operand:MVE_0 0 "s_register_operand" "=&w") (unspec:MVE_0 [(match_operand:MVE_0 1 "s_register_operand" "0") (match_operand:MVE_0 2 "s_register_operand" "w") (match_operand:<MVE_VPRED> 3 "vpr_register_operand" "Up")] diff --git a/gcc/config/csky/csky.cc b/gcc/config/csky/csky.cc index 4dc74d8..f7b2bf8 100644 --- a/gcc/config/csky/csky.cc +++ b/gcc/config/csky/csky.cc @@ -7300,7 +7300,7 @@ csky_init_cumulative_args (CUMULATIVE_ARGS *pcum, tree fntype, void csky_init_builtins (void) { - /* Inint fp16. */ + /* Init fp16. */ static tree csky_floatHF_type_node = make_node (REAL_TYPE); TYPE_PRECISION (csky_floatHF_type_node) = GET_MODE_PRECISION (HFmode); layout_type (csky_floatHF_type_node); @@ -7313,10 +7313,10 @@ csky_init_builtins (void) static const char * csky_mangle_type (const_tree type) { - if (TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL - && DECL_NAME (TYPE_NAME (type)) - && !strcmp (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))), "__fp16")) - return "__fp16"; + if (TREE_CODE (type) == REAL_TYPE + && TYPE_PRECISION (type) == 16 + && TYPE_MAIN_VARIANT (type) != float16_type_node) + return "Dh"; /* Use the default mangling. */ return NULL; diff --git a/gcc/config/gcn/gcn-valu.md b/gcc/config/gcn/gcn-valu.md index 3bfdf82..dec81e8 100644 --- a/gcc/config/gcn/gcn-valu.md +++ b/gcc/config/gcn/gcn-valu.md @@ -3052,7 +3052,8 @@ (define_expand "while_ultsidi" [(match_operand:DI 0 "register_operand") (match_operand:SI 1 "") - (match_operand:SI 2 "")] + (match_operand:SI 2 "") + (match_operand:SI 3 "")] "" { if (GET_CODE (operands[1]) != CONST_INT @@ -3077,6 +3078,11 @@ : ~((unsigned HOST_WIDE_INT)-1 << diff)); emit_move_insn (operands[0], gen_rtx_CONST_INT (VOIDmode, mask)); } + if (INTVAL (operands[3]) < 64) + emit_insn (gen_anddi3 (operands[0], operands[0], + gen_rtx_CONST_INT (VOIDmode, + ~((unsigned HOST_WIDE_INT)-1 + << INTVAL (operands[3]))))); DONE; }) diff --git a/gcc/config/gcn/gcn.cc b/gcc/config/gcn/gcn.cc index eb822e2..c27ee91 100644 --- a/gcc/config/gcn/gcn.cc +++ b/gcc/config/gcn/gcn.cc @@ -4674,8 +4674,6 @@ gcn_simd_clone_compute_vecsize_and_simdlen (struct cgraph_node *ARG_UNUSED (node tree base_type, int ARG_UNUSED (num)) { - unsigned int elt_bits = GET_MODE_BITSIZE (SCALAR_TYPE_MODE (base_type)); - if (known_eq (clonei->simdlen, 0U)) clonei->simdlen = 64; else if (maybe_ne (clonei->simdlen, 64U)) diff --git a/gcc/config/h8300/h8300.md b/gcc/config/h8300/h8300.md index 2da7e7d..f592af1 100644 --- a/gcc/config/h8300/h8300.md +++ b/gcc/config/h8300/h8300.md @@ -221,6 +221,7 @@ (define_mode_iterator QHI [QI HI]) (define_mode_iterator HSI [HI SI]) +(define_mode_iterator HSI2 [HI SI]) (define_mode_iterator QHSI [QI HI SI]) (define_mode_iterator QHSI2 [QI HI SI]) @@ -236,6 +237,7 @@ (define_code_iterator ors [ior xor]) (define_code_iterator eqne [eq ne]) +(define_code_attr eqne_invert [(eq "ne") (ne "eq")]) ;; For storing the C flag, map from the unsigned comparison to the right ;; code for testing the C bit. diff --git a/gcc/config/h8300/testcompare.md b/gcc/config/h8300/testcompare.md index 0ee3e36..81dce1d 100644 --- a/gcc/config/h8300/testcompare.md +++ b/gcc/config/h8300/testcompare.md @@ -61,6 +61,15 @@ "mov.b %t0,%t0" [(set_attr "length" "2")]) +(define_insn "*tsthi_upper_z" + [(set (reg:CCZ CC_REG) + (compare (and:HI (match_operand:HI 0 "register_operand" "r") + (const_int -256)) + (const_int 0)))] + "reload_completed" + "mov.b %t0,%t0" + [(set_attr "length" "2")]) + (define_insn "*tstsi_upper" [(set (reg:CCZN CC_REG) (compare (and:SI (match_operand:SI 0 "register_operand" "r") @@ -86,6 +95,30 @@ } [(set_attr "length_table" "add")]) +(define_insn "*cmpqi_z" + [(set (reg:CCZ CC_REG) + (eq (match_operand:QI 0 "h8300_dst_operand" "rQ") + (match_operand:QI 1 "h8300_src_operand" "rQi")))] + "reload_completed" + { return "cmp.b %X1,%X0"; } + [(set_attr "length_table" "add")]) + +(define_insn "*cmphi_z" + [(set (reg:CCZ CC_REG) + (eq (match_operand:HI 0 "h8300_dst_operand" "rQ") + (match_operand:HI 1 "h8300_src_operand" "rQi")))] + "reload_completed" + { return "cmp.w %T1,%T0"; } + [(set_attr "length_table" "add")]) + +(define_insn "*cmpsi_z" + [(set (reg:CCZ CC_REG) + (eq (match_operand:SI 0 "h8300_dst_operand" "rQ") + (match_operand:SI 1 "h8300_src_operand" "rQi")))] + "reload_completed" + { return "cmp.l %S1,%S0"; } + [(set_attr "length_table" "add")]) + (define_insn "*cmpqi" [(set (reg:CC CC_REG) (compare (match_operand:QI 0 "h8300_dst_operand" "rQ") @@ -209,6 +242,8 @@ return "xor.l\t%S0,%S0\;bist\t#0,%w0"; gcc_unreachable (); } + else + gcc_unreachable (); } [(set (attr "length") (symbol_ref "<MODE>mode == SImode ? 6 : 4"))]) @@ -340,3 +375,235 @@ (ashift:QHSI (<geultu_to_c>:QHSI (reg:CCC CC_REG) (const_int 0)) (match_dup 3)))]) +;; Storing Z into a QImode destination is fairly easy on the H8/S and +;; newer as the stc; shift; mask is just 3 insns/6 bytes. On the H8/300H +;; it is 4 insns/8 bytes which is a speed improvement, but a size +;; regression relative to the branchy sequence +;; +;; Storing inverted Z in QImode is not profitable on the H8/300H, but +;; is a speed improvement on the H8S. +(define_insn_and_split "*store_z_qi" + [(set (match_operand:QI 0 "register_operand" "=r") + (eq:QI (match_operand:HI 1 "register_operand" "r") + (match_operand:HI 2 "register_operand" "r")))] + "TARGET_H8300S || !optimize_size" + "#" + "&& reload_completed" + [(set (reg:CCZ CC_REG) + (eq:CCZ (match_dup 1) (match_dup 2))) + (set (match_dup 0) + (ne:QI (reg:CCZ CC_REG) (const_int 0)))]) + +(define_insn_and_split "*store_z_i_qi" + [(set (match_operand:QI 0 "register_operand" "=r") + (ne:QI (match_operand:HI 1 "register_operand" "r") + (match_operand:HI 2 "register_operand" "r")))] + "TARGET_H8300S" + "#" + "&& reload_completed" + [(set (reg:CCZ CC_REG) + (eq:CCZ (match_dup 1) (match_dup 2))) + (set (match_dup 0) + (eq:QI (reg:CCZ CC_REG) (const_int 0)))]) + +(define_insn "*store_z_qi" + [(set (match_operand:QI 0 "register_operand" "=r") + (ne:QI (reg:CCZ CC_REG) (const_int 0)))] + "(TARGET_H8300S || !optimize_size) && reload_completed" + { + if (TARGET_H8300S) + return "stc\tccr,%X0\;shar\t#2,%X0\;and\t#0x1,%X0"; + else + return "stc\tccr,%X0\;shar\t%X0\;shar\t%X0\;and\t#0x1,%X0"; + } + [(set (attr "length") (symbol_ref "TARGET_H8300S ? 6 : 8"))]) + +(define_insn "*store_z_i_qi" + [(set (match_operand:QI 0 "register_operand" "=r") + (eq:QI (reg:CCZ CC_REG) (const_int 0)))] + "(TARGET_H8300S || !optimize_size) && reload_completed" + "stc\tccr,%X0\;bld\t#2,%X0\;xor.w\t%T0,%T0\;bist\t#0,%X0"; + [(set_attr "length" "8")]) + +;; Storing Z or an inverted Z into a HImode destination is +;; profitable on the H8/S and older variants, but not on the +;; H8/SX where the branchy sequence can use the two-byte +;; mov-immediate that is specific to the H8/SX +(define_insn_and_split "*store_z_hi" + [(set (match_operand:HSI 0 "register_operand" "=r") + (eqne:HSI (match_operand:HSI2 1 "register_operand" "r") + (match_operand:HSI2 2 "register_operand" "r")))] + "!TARGET_H8300SX" + "#" + "&& reload_completed" + [(set (reg:CCZ CC_REG) + (eq:CCZ (match_dup 1) (match_dup 2))) + (set (match_dup 0) + (<eqne_invert>:HSI (reg:CCZ CC_REG) (const_int 0)))]) + +;; Similar, but putting the result into the sign bit +(define_insn_and_split "*store_z_hi_sb" + [(set (match_operand:HSI 0 "register_operand" "=r") + (ashift:HSI (eqne:HSI (match_operand:HSI2 1 "register_operand" "r") + (match_operand:HSI2 2 "register_operand" "r")) + (const_int 15)))] + "!TARGET_H8300SX" + "#" + "&& reload_completed" + [(set (reg:CCZ CC_REG) + (eq:CCZ (match_dup 1) (match_dup 2))) + (set (match_dup 0) + (ashift:HSI (<eqne_invert>:HSI (reg:CCZ CC_REG) (const_int 0)) + (const_int 15)))]) + +;; Similar, but negating the result +(define_insn_and_split "*store_z_hi_neg" + [(set (match_operand:HSI 0 "register_operand" "=r") + (neg:HSI (eqne:HSI (match_operand:HSI2 1 "register_operand" "r") + (match_operand:HSI2 2 "register_operand" "r"))))] + "!TARGET_H8300SX" + "#" + "&& reload_completed" + [(set (reg:CCZ CC_REG) + (eq:CCZ (match_dup 1) (match_dup 2))) + (set (match_dup 0) + (neg:HSI (<eqne_invert>:HSI (reg:CCZ CC_REG) (const_int 0))))]) + +(define_insn_and_split "*store_z_hi_and" + [(set (match_operand:HSI 0 "register_operand" "=r") + (and:HSI (eqne:HSI (match_operand:HSI2 1 "register_operand" "r") + (match_operand:HSI2 2 "register_operand" "r")) + (match_operand:HSI 3 "register_operand" "r")))] + "!TARGET_H8300SX" + "#" + "&& reload_completed" + [(set (reg:CCZ CC_REG) + (eq:CCZ (match_dup 1) (match_dup 2))) + (set (match_dup 0) + (and:HSI (<eqne_invert>:HSI (reg:CCZ CC_REG) (const_int 0)) + (match_dup 3)))]) + +(define_insn "*store_z_<mode>" + [(set (match_operand:HSI 0 "register_operand" "=r") + (eqne:HSI (reg:CCZ CC_REG) (const_int 0)))] + "!TARGET_H8300SX" + { + if (<MODE>mode == HImode) + { + if (<CODE> == NE) + { + if (TARGET_H8300S) + return "stc\tccr,%X0\;shlr.b\t#2,%X0\;and.w\t#1,%T0"; + return "stc\tccr,%X0\;bld\t#2,%X0\;xor.w\t%T0,%T0\;bst\t#0,%X0"; + } + else + return "stc\tccr,%X0\;bld\t#2,%X0\;xor.w\t%T0,%T0\;bist\t#0,%X0"; + } + else if (<MODE>mode == SImode) + { + if (<CODE> == NE) + { + if (TARGET_H8300S) + return "stc\tccr,%X0\;shlr.b\t#2,%X0\;and.l\t#1,%S0"; + return "stc\tccr,%X0\;bld\t#2,%X0\;xor.l\t%S0,%S0\;bst\t#0,%X0"; + } + else + return "stc\tccr,%X0\;bld\t#2,%X0\;xor.l\t%S0,%S0\;bist\t#0,%X0"; + } + gcc_unreachable (); + } +;; XXXSImode is 2 bytes longer + [(set_attr "length" "8")]) + +(define_insn "*store_z_<mode>_sb" + [(set (match_operand:HSI 0 "register_operand" "=r") + (ashift:HSI (eqne:HSI (reg:CCZ CC_REG) (const_int 0)) + (const_int 15)))] + "!TARGET_H8300SX" + { + if (<MODE>mode == HImode) + { + if (<CODE> == NE) + return "stc\tccr,%X0\;bld\t#2,%X0\;xor.w\t%T0,%T0\;bst\t#7,%t0"; + else + return "stc\tccr,%X0\;bld\t#2,%X0\;xor.w\t%T0,%T0\;bist\t#7,%t0"; + } + else if (<MODE>mode == SImode) + { + if (<CODE> == NE) + return "stc\tccr,%X0\;bld\t#2,%X0\;xor.l\t%T0,%T0\;rotxr.l\t%S0"; + else + return "stc\tccr,%X0\;bild\t#2,%X0\;xor.l\t%T0,%T0\;rotxr.l\t%S0"; + } + gcc_unreachable (); + } + ;; XXX SImode is larger + [(set_attr "length" "8")]) + +(define_insn "*store_z_<mode>_neg" + [(set (match_operand:HSI 0 "register_operand" "=r") + (neg:HSI (eqne:HSI (reg:CCZ CC_REG) (const_int 0))))] + "!TARGET_H8300SX" + { + if (<MODE>mode == HImode) + { + if (<CODE> == NE) + return "stc\tccr,%X0\;bld\t#2,%X0\;subx.b\t%X0,%X0\;exts.w\t%T0"; + else + return "stc\tccr,%X0\;bild\t#2,%X0\;subx.b\t%X0,%X0\;exts.w\t%T0"; + } + else if (<MODE>mode == SImode) + { + if (<CODE> == NE) + return "stc\tccr,%X0\;bld\t#2,%X0\;subx.b\t%X0,%X0\;exts.w\t%T0\;exts.l\t%S0"; + else + return "stc\tccr,%X0\;bild\t#2,%X0\;subx.b\t%X0,%X0\;exts.w\t%T0\;exts.l\t%S0"; + } + gcc_unreachable (); + } + ;; XXX simode is an instruction longer + [(set_attr "length" "8")]) + +(define_insn "*store_z_<mode>_and" + [(set (match_operand:HSI 0 "register_operand" "=r") + (and:HSI (eqne:HSI (reg:CCZ CC_REG) (const_int 0)) + (match_operand:HSI 1 "register_operand" "r")))] + "!TARGET_H8300SX" + { + if (<MODE>mode == HImode) + { + if (<CODE> == NE) + return "bld\t#0,%X1\;stc\tccr,%X0\;band\t#2,%X0\;xor.w\t%T0,%T0\;bst\t#0,%X0"; + else + return "bild\t#0,%X1\;stc\tccr,%X0\;band\t#2,%X0\;xor.w\t%T0,%T0\;bist\t#0,X0"; + } + else if (<MODE>mode == SImode) + { + if (<CODE> == NE) + return "bld\t#0,%X1\;stc\tccr,%X0\;band\t#2,%X0\;xor.l\t%S0,%S0\;bst\t#0,%X0"; + else + return "bild\t#0,%X1\;stc\tccr,%X0\;band\t#2,%X0\;xor.l\t%S0,%S0\;bist\t#0,X0"; + } + gcc_unreachable (); + } + ;; XXX simode is an instruction longer + [(set_attr "length" "8")]) + +;; We can test the upper byte of a HImode register and the upper word +;; of a SImode register + +;; We can test the upper byte of a HImode register and the upper word +;; of a SImode register +(define_insn_and_split "*store_z" + [(set (match_operand:HI 0 "register_operand" "=r") + (eqne:HI (and:HI (match_operand:HI 1 "register_operand" "r") + (const_int -256)) + (const_int 0)))] + "!TARGET_H8300SX" + "#" + "&& reload_completed" + [(set (reg:CCZ CC_REG) + (compare (and:HI (match_dup 1) (const_int -256)) + (const_int 0))) + (set (match_dup 0) + (<eqne_invert>:HI (reg:CCZ CC_REG) (const_int 0)))]) diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc index 4386caf..ff4de2d 100644 --- a/gcc/config/i386/i386.cc +++ b/gcc/config/i386/i386.cc @@ -22725,6 +22725,9 @@ ix86_mangle_type (const_tree type) && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE) return NULL; + if (type == float128_type_node || type == float64x_type_node) + return NULL; + switch (TYPE_MODE (type)) { case E_BFmode: @@ -22735,10 +22738,7 @@ ix86_mangle_type (const_tree type) return "DF16_"; case E_TFmode: /* __float128 is "g". */ - if (type == float128t_type_node) - return "g"; - /* _Float128 should mangle as "DF128_" done in generic code. */ - return NULL; + return "g"; case E_XFmode: /* "long double" or __float80 is "e". */ return "e"; diff --git a/gcc/config/i386/t-i386 b/gcc/config/i386/t-i386 index 4e2a0ef..ffdbbdf 100644 --- a/gcc/config/i386/t-i386 +++ b/gcc/config/i386/t-i386 @@ -62,7 +62,12 @@ i386-features.o: $(srcdir)/config/i386/i386-features.cc $(COMPILE) $< $(POSTCOMPILE) +# i386-builtin-types.inc is included into i386-builtins.h. +# Below are direct users of i386-builtins.h: i386.o: i386-builtin-types.inc +i386-builtins.o: i386-builtin-types.inc +i386-expand.o: i386-builtin-types.inc +i386-features.o: i386-builtin-types.inc i386-builtin-types.inc: s-i386-bt ; @true s-i386-bt: $(srcdir)/config/i386/i386-builtin-types.awk \ diff --git a/gcc/config/ia64/ia64.cc b/gcc/config/ia64/ia64.cc index d510573..995ff90 100644 --- a/gcc/config/ia64/ia64.cc +++ b/gcc/config/ia64/ia64.cc @@ -11225,6 +11225,9 @@ ia64_mangle_type (const_tree type) && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE) return NULL; + if (type == float128_type_node || type == float64x_type_node) + return NULL; + /* On HP-UX, "long double" is mangled as "e" so __float128 is mangled as "e". */ if (!TARGET_HPUX && TYPE_MODE (type) == TFmode) diff --git a/gcc/config/or1k/or1k.cc b/gcc/config/or1k/or1k.cc index da2f590..0ce7b23 100644 --- a/gcc/config/or1k/or1k.cc +++ b/gcc/config/or1k/or1k.cc @@ -2206,8 +2206,10 @@ or1k_output_mi_thunk (FILE *file, tree thunk_fndecl, #undef TARGET_LEGITIMATE_ADDRESS_P #define TARGET_LEGITIMATE_ADDRESS_P or1k_legitimate_address_p +#ifdef HAVE_AS_TLS #undef TARGET_HAVE_TLS #define TARGET_HAVE_TLS true +#endif #undef TARGET_HAVE_SPECULATION_SAFE_VALUE #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 0d61831..0a4c37e 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -5440,6 +5440,11 @@ riscv_file_start (void) if (! riscv_mrelax) fprintf (asm_out_file, "\t.option norelax\n"); + /* If the user specifies "-mcsr-check" on the command line then enable csr + check in the assembler. */ + if (riscv_mcsr_check) + fprintf (asm_out_file, "\t.option csr-check\n"); + if (riscv_emit_attribute_p) riscv_emit_attribute (); } @@ -6279,6 +6284,7 @@ riscv_excess_precision (enum excess_precision_type type) return (TARGET_ZFH ? FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16 : FLT_EVAL_METHOD_PROMOTE_TO_FLOAT); case EXCESS_PRECISION_TYPE_IMPLICIT: + case EXCESS_PRECISION_TYPE_FLOAT16: return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16; default: gcc_unreachable (); diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt index e3af561..8923a11 100644 --- a/gcc/config/riscv/riscv.opt +++ b/gcc/config/riscv/riscv.opt @@ -132,6 +132,12 @@ Target Bool Var(riscv_mrelax) Init(1) Take advantage of linker relaxations to reduce the number of instructions required to materialize symbol addresses. +mcsr-check +Target Bool Var(riscv_mcsr_check) Init(0) +Enable the CSR checking for the ISA-dependent CRS and the read-only CSR. +The ISA-dependent CSR are only valid when the specific ISA is set. The +read-only CSR can not be written by the CSR instructions. + Mask(64BIT) Mask(MUL) diff --git a/gcc/config/rs6000/rs6000-internal.h b/gcc/config/rs6000/rs6000-internal.h index b9e82c0..e75b8d5 100644 --- a/gcc/config/rs6000/rs6000-internal.h +++ b/gcc/config/rs6000/rs6000-internal.h @@ -182,6 +182,10 @@ extern tree rs6000_fold_builtin (tree fndecl ATTRIBUTE_UNUSED, tree *args ATTRIBUTE_UNUSED, bool ignore ATTRIBUTE_UNUSED); +extern void rs6000_print_patchable_function_entry (FILE *, + unsigned HOST_WIDE_INT, + bool); + extern bool rs6000_passes_float; extern bool rs6000_passes_long_double; extern bool rs6000_passes_vector; diff --git a/gcc/config/rs6000/rs6000-logue.cc b/gcc/config/rs6000/rs6000-logue.cc index a11d020..3621cb5 100644 --- a/gcc/config/rs6000/rs6000-logue.cc +++ b/gcc/config/rs6000/rs6000-logue.cc @@ -4009,11 +4009,43 @@ rs6000_output_function_prologue (FILE *file) fprintf (file, "\tadd 2,2,12\n"); } + unsigned short patch_area_size = crtl->patch_area_size; + unsigned short patch_area_entry = crtl->patch_area_entry; + /* Need to emit the patching area. */ + if (patch_area_size > 0) + { + cfun->machine->global_entry_emitted = true; + /* As ELFv2 ABI shows, the allowable bytes between the global + and local entry points are 0, 4, 8, 16, 32 and 64 when + there is a local entry point. Considering there are two + non-prefixed instructions for global entry point prologue + (8 bytes), the count for patchable nops before local entry + point would be 2, 6 and 14. It's possible to support those + other counts of nops by not making a local entry point, but + we don't have clear use cases for them, so leave them + unsupported for now. */ + if (patch_area_entry > 0) + { + if (patch_area_entry != 2 + && patch_area_entry != 6 + && patch_area_entry != 14) + error ("unsupported number of nops before function entry (%u)", + patch_area_entry); + rs6000_print_patchable_function_entry (file, patch_area_entry, + true); + patch_area_size -= patch_area_entry; + } + } + fputs ("\t.localentry\t", file); assemble_name (file, name); fputs (",.-", file); assemble_name (file, name); fputs ("\n", file); + /* Emit the nops after local entry. */ + if (patch_area_size > 0) + rs6000_print_patchable_function_entry (file, patch_area_size, + patch_area_entry == 0); } else if (rs6000_pcrel_p ()) diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc index bbe21ea..d2743f7 100644 --- a/gcc/config/rs6000/rs6000.cc +++ b/gcc/config/rs6000/rs6000.cc @@ -14930,8 +14930,14 @@ rs6000_print_patchable_function_entry (FILE *file, if (!(TARGET_64BIT && DEFAULT_ABI != ABI_ELFv2) && HAVE_GAS_SECTION_LINK_ORDER) flags |= SECTION_LINK_ORDER; - default_print_patchable_function_entry_1 (file, patch_area_size, record_p, - flags); + bool global_entry_needed_p = rs6000_global_entry_point_prologue_needed_p (); + /* For a function which needs global entry point, we will emit the + patchable area before and after local entry point under the control of + cfun->machine->global_entry_emitted, see the handling in function + rs6000_output_function_prologue. */ + if (!global_entry_needed_p || cfun->machine->global_entry_emitted) + default_print_patchable_function_entry_1 (file, patch_area_size, record_p, + flags); } enum rtx_code @@ -20270,13 +20276,12 @@ rs6000_mangle_type (const_tree type) if (type == bool_int_type_node) return "U6__booli"; if (type == bool_long_long_type_node) return "U6__boolx"; + if (type == float128_type_node || type == float64x_type_node) + return NULL; + if (SCALAR_FLOAT_TYPE_P (type) && FLOAT128_IBM_P (TYPE_MODE (type))) return "g"; - if (SCALAR_FLOAT_TYPE_P (type) - && FLOAT128_IEEE_P (TYPE_MODE (type)) - /* _Float128 should mangle as DF128_ (done in generic code) - rather than u9__ieee128 (used for __ieee128 and __float128). */ - && type != float128_type_node) + if (SCALAR_FLOAT_TYPE_P (type) && FLOAT128_IEEE_P (TYPE_MODE (type))) return "u9__ieee128"; if (type == vector_pair_type_node) diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index eb7b215..b4df22b 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -2435,6 +2435,10 @@ typedef struct GTY(()) machine_function bool lr_is_wrapped_separately; bool toc_is_wrapped_separately; bool mma_return_type_error; + /* Indicate global entry is emitted, only useful when the function requires + global entry. It helps to control the patchable area before and after + local entry. */ + bool global_entry_emitted; } machine_function; #endif diff --git a/gcc/config/rs6000/vxworks.h b/gcc/config/rs6000/vxworks.h index 6f11de6..b220a1a 100644 --- a/gcc/config/rs6000/vxworks.h +++ b/gcc/config/rs6000/vxworks.h @@ -265,9 +265,10 @@ along with GCC; see the file COPYING3. If not see #undef LINK_OS_EXTRA_SPEC64 #define LINK_OS_EXTRA_SPEC64 VXWORKS_LINK_SPEC -/* linux64.h enables this, not supported in vxWorks. */ -#undef TARGET_FLOAT128_ENABLE_TYPE -#define TARGET_FLOAT128_ENABLE_TYPE 0 +/* Leave TARGET_FLOAT128_ENABLE_TYPE alone here, possibly inherited from + a linux configuration file. This lets compilation tests pass and will + trigger visible link errors (hence remain harmless) if the support isn't + really there. */ #endif /* TARGET_VXWORKS7 */ diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc index 9861913..ae30947 100644 --- a/gcc/config/s390/s390.cc +++ b/gcc/config/s390/s390.cc @@ -7642,8 +7642,7 @@ s390_mangle_type (const_tree type) if (type == s390_builtin_types[BT_BV4SI]) return "U6__booli"; if (type == s390_builtin_types[BT_BV2DI]) return "U6__booll"; - if (TYPE_MAIN_VARIANT (type) == long_double_type_node - && TARGET_LONG_DOUBLE_128) + if (type == long_double_type_node && TARGET_LONG_DOUBLE_128) return "g"; /* For all other types, use normal C++ mangling. */ diff --git a/gcc/config/t-vxworks b/gcc/config/t-vxworks index 40c6cc4..dc97a4e 100644 --- a/gcc/config/t-vxworks +++ b/gcc/config/t-vxworks @@ -16,6 +16,10 @@ # along with GCC; see the file COPYING3. If not see # <http://www.gnu.org/licenses/>. +vxworks-driver.o: $(srcdir)/config/vxworks-driver.cc + $(COMPILE) $< + $(POSTCOMPILE) + vxworks.o: $(srcdir)/config/vxworks.cc $(COMPILE) $< $(POSTCOMPILE) diff --git a/gcc/config/vx-common.h b/gcc/config/vx-common.h index bc27684..bf5823a 100644 --- a/gcc/config/vx-common.h +++ b/gcc/config/vx-common.h @@ -74,7 +74,8 @@ along with GCC; see the file COPYING3. If not see /* ---------------------- Debug and unwind info formats ------------------ */ /* Dwarf2 unwind info is supported, unless overriden by a request for a target - specific format. + specific format. Always #define DWARF2_UNWIND_INFO to prevent defaults.h + from picking a possibly different value. Taking care of this here allows using DWARF2_UNWIND_INFO in #if conditions from the common config/vxworks.h files, included before the cpu @@ -84,8 +85,10 @@ along with GCC; see the file COPYING3. If not see #if point. Since <cpu>/vxworks.h. is typically included after config/vxworks.h, #if expressions in the latter can't rely on possible redefinitions in the former. */ -#if !ARM_UNWIND_INFO #undef DWARF2_UNWIND_INFO +#if ARM_UNWIND_INFO +#define DWARF2_UNWIND_INFO 0 +#else #define DWARF2_UNWIND_INFO 1 #endif diff --git a/gcc/config/vxworks-driver.cc b/gcc/config/vxworks-driver.cc new file mode 100644 index 0000000..da5f015 --- /dev/null +++ b/gcc/config/vxworks-driver.cc @@ -0,0 +1,93 @@ +/* Copyright (C) 2022 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "opts.h" + +/* Perform early driver flags initializations that can't be achieved + with specs. In particular, we need to explicitly request a static + link for rtps by default before lang_specific_driver gets control. */ + +void vxworks_driver_init (unsigned int *in_decoded_options_count, + struct cl_decoded_option **in_decoded_options) +{ + unsigned int i; + struct cl_decoded_option *decoded_options = *in_decoded_options; + + /* Arrange to add -static if we are going to link a rtp and there is no + trace of any explicit request for a specific kind of link. */ + bool wont_link = false; + bool mrtp = false; + bool link_kind_indication = false; + + /* The new argument list will be contained in this. */ + struct cl_decoded_option *new_decoded_options; + unsigned int num_options = *in_decoded_options_count; + + for (i = 1; i < num_options; i++) + { + if (decoded_options[i].errors & CL_ERR_MISSING_ARG) + continue; + + switch (decoded_options[i].opt_index) + { + case OPT_static: + case OPT_shared: + case OPT_Bdynamic: + case OPT_Bstatic: + case OPT_non_static: + link_kind_indication = true; + break; + + case OPT_c: + case OPT_r: + case OPT_S: + case OPT_E: + case OPT_M: + case OPT_MM: + case OPT_fsyntax_only: + wont_link = true; + break; + + case OPT_mrtp: + mrtp = true; + break; + + default: + break; + } + } + + if (!wont_link && mrtp && !link_kind_indication) + { + num_options++; + new_decoded_options = XNEWVEC(struct cl_decoded_option, num_options); + + for (i = 0; i < num_options - 1; i++) + new_decoded_options[i] = decoded_options[i]; + + generate_option(OPT_static, NULL, 1, CL_DRIVER, + &new_decoded_options[num_options - 1]); + + *in_decoded_options = new_decoded_options; + *in_decoded_options_count = num_options; + } +} diff --git a/gcc/config/vxworks.h b/gcc/config/vxworks.h index 6a5f2f8..84a9c93 100644 --- a/gcc/config/vxworks.h +++ b/gcc/config/vxworks.h @@ -19,10 +19,25 @@ You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ +/* ??? We use HAVE_INITFINI_ARRAY_SUPPORT in preprocessor guards in this + header, which is conveyed by auto-host.h despite being a target property. + #include auto-host.h here would trigger lots of conflicts so we rely on + compiler .c files doing this before target configuration headers. */ + /* Assert that we are targeting VxWorks. */ #undef TARGET_VXWORKS #define TARGET_VXWORKS 1 +/* ??? Even though assigned to a HOST driver hook, this function + operates for all vxworks targets regardless of the current host. + We will get warnings at build time if the macro happens to be + redefined one way or another for a host. */ +struct cl_decoded_option; +extern void vxworks_driver_init (unsigned int *, struct cl_decoded_option **); + +#define GCC_DRIVER_HOST_INITIALIZATION \ + vxworks_driver_init (&decoded_options_count, &decoded_options) + /* In kernel mode, VxWorks provides all the libraries itself, as well as the functionality of startup files, etc. In RTP mode, it behaves more like a traditional Unix, with more external files. Most of our specs @@ -115,7 +130,7 @@ along with GCC; see the file COPYING3. If not see -lc_internal after -lc -lgcc. - libc_internal also contains __init/__fini functions for - USE_INITFINI_ARRAY support. However, the system expects these in + INITFINI_ARRAY support. However, the system expects these in every shared lib as well, with slightly different names, and it is simpler for us to provide our own versions through vxcrtstuff. @@ -220,10 +235,9 @@ along with GCC; see the file COPYING3. If not see #endif /* Setup the crtstuff begin/end we might need for dwarf EH registration - and/or INITFINI_ARRAY support for shared libs. */ - -#if (HAVE_INITFINI_ARRAY_SUPPORT && defined(ENABLE_SHARED_LIBGCC)) \ - || (DWARF2_UNWIND_INFO && !defined(CONFIG_SJLJ_EXCEPTIONS)) + and/or INITFINI_ARRAY support. */ +#if (HAVE_INITFINI_ARRAY_SUPPORT \ + || (DWARF2_UNWIND_INFO && !defined(CONFIG_SJLJ_EXCEPTIONS))) #define VX_CRTBEGIN_SPEC "%{!shared:vx_crtbegin.o%s;:vx_crtbeginS.o%s}" #define VX_CRTEND_SPEC "%{!shared:vx_crtend.o%s;:vx_crtendS.o%s}" #else diff --git a/gcc/configure b/gcc/configure index 70a013e..ce4e185 100755 --- a/gcc/configure +++ b/gcc/configure @@ -29727,13 +29727,16 @@ else if $gcc_cv_as --compress-debug-sections -o conftest.o conftest.s 2>&1 | grep -i warning > /dev/null then gcc_cv_as_compress_debug=0 - # Since binutils 2.26, gas supports --compress-debug-sections=zlib, - # defaulting to the ELF gABI format. elif $gcc_cv_as --compress-debug-sections=zlib -o conftest.o conftest.s > /dev/null 2>&1 then gcc_cv_as_compress_debug=1 gcc_cv_as_compress_debug_option="--compress-debug-sections" gcc_cv_as_no_compress_debug_option="--nocompress-debug-sections" + # Since binutils 2.40, gas supports --compress-debug-sections=zstd. + if $gcc_cv_as --compress-debug-sections=zstd -o conftest.o conftest.s > /dev/null 2>&1 + then + gcc_cv_as_compress_debug=2 + fi else gcc_cv_as_compress_debug=0 fi @@ -30251,6 +30254,10 @@ $as_echo_n "checking linker for compressed debug sections... " >&6; } if $gcc_cv_ld --help 2>&1 | grep -- '--compress-debug-sections.*\<zlib-gabi\>' > /dev/null; then gcc_cv_ld_compress_debug=1 gcc_cv_ld_compress_debug_option="--compress-debug-sections" + # Detect zstd debug section compression support + if $gcc_cv_ld --help 2>&1 | grep -- '--compress-debug-sections.*\<zstd\>' > /dev/null; then + gcc_cv_ld_compress_debug=2 + fi else case "${target}" in *-*-solaris2*) diff --git a/gcc/configure.ac b/gcc/configure.ac index 96e10d7..b6bafa8 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -5732,13 +5732,16 @@ gcc_GAS_CHECK_FEATURE([compressed debug sections], if $gcc_cv_as --compress-debug-sections -o conftest.o conftest.s 2>&1 | grep -i warning > /dev/null then gcc_cv_as_compress_debug=0 - # Since binutils 2.26, gas supports --compress-debug-sections=zlib, - # defaulting to the ELF gABI format. elif $gcc_cv_as --compress-debug-sections=zlib -o conftest.o conftest.s > /dev/null 2>&1 then gcc_cv_as_compress_debug=1 gcc_cv_as_compress_debug_option="--compress-debug-sections" gcc_cv_as_no_compress_debug_option="--nocompress-debug-sections" + # Since binutils 2.40, gas supports --compress-debug-sections=zstd. + if $gcc_cv_as --compress-debug-sections=zstd -o conftest.o conftest.s > /dev/null 2>&1 + then + gcc_cv_as_compress_debug=2 + fi else gcc_cv_as_compress_debug=0 fi]) @@ -6127,6 +6130,10 @@ AC_MSG_CHECKING(linker for compressed debug sections) if $gcc_cv_ld --help 2>&1 | grep -- '--compress-debug-sections.*\<zlib-gabi\>' > /dev/null; then gcc_cv_ld_compress_debug=1 gcc_cv_ld_compress_debug_option="--compress-debug-sections" + # Detect zstd debug section compression support + if $gcc_cv_ld --help 2>&1 | grep -- '--compress-debug-sections.*\<zstd\>' > /dev/null; then + gcc_cv_ld_compress_debug=2 + fi else changequote(,)dnl case "${target}" in diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3f512c6..db6fea1 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,169 @@ +2022-10-03 Jakub Jelinek <jakub@redhat.com> + + * cp-tree.h (BCS_STMT_EXPR): New enumerator. + * name-lookup.h (enum scope_kind): Add sk_stmt_expr. + * name-lookup.cc (begin_scope): Handle sk_stmt_expr like sk_block. + * semantics.cc (begin_compound_stmt): For BCS_STMT_EXPR use + sk_stmt_expr. + * parser.cc (cp_parser_statement_expr): Use BCS_STMT_EXPR instead of + BCS_NORMAL. + * decl.cc (struct named_label_entry): Add in_stmt_expr. + (poplevel_named_label_1): Handle sk_stmt_expr. + (check_previous_goto_1): Diagnose entering of statement expression. + (check_goto): Likewise. + +2022-10-03 Patrick Palka <ppalka@redhat.com> + + * constraint.cc (diagnose_trait_expr): Use CPTK_IS_SAME instead + of CPTK_IS_SAME_AS. + * cp-trait.def (IS_SAME_AS): Rename to ... + (IS_SAME): ... this. + * pt.cc (alias_ctad_tweaks): Use CPTK_IS_SAME instead of + CPTK_IS_SAME_AS. + * semantics.cc (trait_expr_value): Likewise. + (finish_trait_expr): Likewise. + +2022-10-01 Patrick Palka <ppalka@redhat.com> + + * semantics.cc (trait_expr_value): Make cp_trait_kind switch + statement exhaustive. + (finish_trait_expr): Likewise. + (finish_trait_type): Likewise. + +2022-10-01 Jason Merrill <jason@redhat.com> + + * init.cc (build_vec_init): Clear from_array for CONSTRUCTOR + initializer. + +2022-10-01 Jason Merrill <jason@redhat.com> + + * cp-gimplify.cc (cp_genericize_init): Also convert the result of + split_nonconstant_init to void. + +2022-09-30 Patrick Palka <ppalka@redhat.com> + + * constraint.cc (diagnose_trait_expr): Likewise. + * cp-objcp-common.cc (names_builtin_p): Likewise. + * cp-tree.h (enum cp_trait_kind): Likewise. + * cxx-pretty-print.cc (pp_cxx_trait): Likewise. + * parser.cc (cp_keyword_starts_decl_specifier_p): Likewise. + (cp_parser_primary_expression): Likewise. + (cp_parser_trait): Likewise. + (cp_parser_simple_type_specifier): Likewise. + * cp-trait.def: New file. + +2022-09-30 Jason Merrill <jason@redhat.com> + + * cp-gimplify.cc (cp_fold_r) [TARGET_EXPR]: Collapse + TARGET_EXPR within TARGET_EXPR. + * constexpr.cc (cxx_eval_outermost_constant_expr): Avoid + adding redundant TARGET_EXPR. + * cp-tree.h (target_expr_needs_replace): VEC_INIT_EXPR doesn't. + +2022-09-29 Patrick Palka <ppalka@redhat.com> + + PR c++/102576 + * pt.cc (listify): Use lookup_qualified_name instead of + get_namespace_binding. + +2022-09-29 Jason Merrill <jason@redhat.com> + + * class.cc (check_methods): Call constraints_satisfied_p. + +2022-09-29 Jason Merrill <jason@redhat.com> + + * constexpr.cc (potential_constant_expression_1): Look into + DECL_INITIAL. Use location wrappers. + +2022-09-29 Jason Merrill <jason@redhat.com> + + PR c++/93046 + * call.cc (build_conditional_expr): For a?:c extension, treat + a reused class prvalue as an xvalue. + +2022-09-29 Jason Merrill <jason@redhat.com> + + * call.cc (build_conditional_expr): Set TARGET_EXPR_NO_ELIDE on the + outer TARGET_EXPR. + +2022-09-29 Patrick Palka <ppalka@redhat.com> + + * constraint.cc (diagnose_trait_expr): Handle CPTK_REMOVE_CV, + CPTK_REMOVE_REFERENCE and CPTK_REMOVE_CVREF. + * cp-objcp-common.cc (names_builtin_p): Likewise. + * cp-tree.h (enum cp_trait_kind): Add CPTK_REMOVE_CV, + CPTK_REMOVE_REFERENCE and CPTK_REMOVE_CVREF. + * cxx-pretty-print.cc (pp_cxx_trait): Handle CPTK_REMOVE_CV, + CPTK_REMOVE_REFERENCE and CPTK_REMOVE_CVREF. + * parser.cc (cp_keyword_starts_decl_specifier_p): Return true + for RID_REMOVE_CV, RID_REMOVE_REFERENCE and RID_REMOVE_CVREF. + (cp_parser_trait): Handle RID_REMOVE_CV, RID_REMOVE_REFERENCE + and RID_REMOVE_CVREF. + (cp_parser_simple_type_specifier): Likewise. + * semantics.cc (finish_trait_type): Likewise. + +2022-09-29 Patrick Palka <ppalka@redhat.com> + + * cp-objcp-common.cc (cp_common_init_ts): Replace + UNDERLYING_TYPE with TRAIT_TYPE. + * cp-tree.def (TRAIT_TYPE): Define. + (UNDERLYING_TYPE): Remove. + * cp-tree.h (TRAIT_TYPE_KIND_RAW): Define. + (TRAIT_TYPE_KIND): Define. + (TRAIT_TYPE_TYPE1): Define. + (TRAIT_TYPE_TYPE2): Define. + (WILDCARD_TYPE_P): Return true for TRAIT_TYPE. + (finish_trait_type): Declare. + * cxx-pretty-print.cc (cxx_pretty_printer::primary_expression): + Adjust after renaming pp_cxx_trait_expression. + (cxx_pretty_printer::simple_type_specifier) <case TRAIT_TYPE>: + New. + (cxx_pretty_printer::type_id): Replace UNDERLYING_TYPE with + TRAIT_TYPE. + (pp_cxx_trait_expression): Rename to ... + (pp_cxx_trait): ... this. Handle TRAIT_TYPE as well. Correct + pretty printing of the trailing arguments. + * cxx-pretty-print.h (pp_cxx_trait_expression): Rename to ... + (pp_cxx_trait_type): ... this. + * error.cc (dump_type) <case UNDERLYING_TYPE>: Remove. + <case TRAIT_TYPE>: New. + (dump_type_prefix): Replace UNDERLYING_WITH with TRAIT_TYPE. + (dump_type_suffix): Likewise. + * mangle.cc (write_type) <case UNDERLYING_TYPE>: Remove. + <case TRAIT_TYPE>: New. + * module.cc (trees_out::type_node) <case UNDERLYING_TYPE>: + Remove. + <case TRAIT_TYPE>: New. + (trees_in::tree_node): Likewise. + * parser.cc (cp_parser_primary_expression): Adjust after + renaming cp_parser_trait_expr. + (cp_parser_trait_expr): Rename to ... + (cp_parser_trait): ... this. Call finish_trait_type for traits + that yield a type. + (cp_parser_simple_type_specifier): Adjust after renaming + cp_parser_trait_expr. + * pt.cc (for_each_template_parm_r) <case UNDERLYING_TYPE>: + Remove. + <case TRAIT_TYPE>: New. + (tsubst): Likewise. + (unify): Replace UNDERLYING_TYPE with TRAIT_TYPE. + (dependent_type_p_r): Likewise. + * semantics.cc (finish_underlying_type): Don't return + UNDERLYING_TYPE anymore when processing_template_decl. + (finish_trait_type): Define. + * tree.cc (strip_typedefs) <case UNDERLYING_TYPE>: Remove. + <case TRAIT_TYPE>: New. + (cp_walk_subtrees): Likewise. + * typeck.cc (structural_comptypes): Likewise. + +2022-09-29 Nathan Sidwell <nathan@acm.org> + + PR c++/100616 + * module.cc (enum tree_tag): Add tt_nttp_var. + (trees_out::decl_node): Handle NTTP objects. + (trees_in::tree_node): Handle tt_nttp_var. + (depset::hash::add_binding_entry): Skip NTTP objects. + 2022-09-28 Eugene Rozenfeld <erozen@microsoft.com> * module.cc (write_location): Write discriminator. diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc index 3506b0f..bd04a1d 100644 --- a/gcc/cp/call.cc +++ b/gcc/cp/call.cc @@ -5402,6 +5402,11 @@ build_conditional_expr (const op_location_t &loc, arg1 = cp_stabilize_reference (arg1); arg2 = arg1 = prevent_lifetime_extension (arg1); } + else if (TREE_CODE (arg1) == TARGET_EXPR) + /* arg1 can't be a prvalue result of the conditional + expression, since it needs to be materialized for the + conversion to bool, so treat it as an xvalue in arg2. */ + arg2 = move (TARGET_EXPR_SLOT (arg1)); else arg2 = arg1 = cp_save_expr (arg1); } @@ -6009,7 +6014,13 @@ build_conditional_expr (const op_location_t &loc, but now we sometimes wrap them in NOP_EXPRs so the test would fail. */ if (CLASS_TYPE_P (TREE_TYPE (result))) - result = get_target_expr (result, complain); + { + result = get_target_expr (result, complain); + /* Tell gimplify_modify_expr_rhs not to strip this in + assignment context: we want both arms to initialize + the same temporary. */ + TARGET_EXPR_NO_ELIDE (result) = true; + } /* If this expression is an rvalue, but might be mistaken for an lvalue, we must add a NON_LVALUE_EXPR. */ result = rvalue (result); diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc index b84f422..aebcb53 100644 --- a/gcc/cp/class.cc +++ b/gcc/cp/class.cc @@ -4795,8 +4795,9 @@ check_methods (tree t) /* Check whether the eligible special member functions (P0848) are user-provided. add_method arranged that the CLASSTYPE_MEMBER_VEC only - has the eligible ones; TYPE_FIELDS also contains ineligible overloads, - which is why this needs to be separate from the loop above. */ + has the eligible ones, unless none are eligible; TYPE_FIELDS also contains + ineligible overloads, which is why this needs to be separate from the loop + above. */ if (tree dtor = CLASSTYPE_DESTRUCTOR (t)) { @@ -4819,6 +4820,10 @@ check_methods (tree t) { if (!user_provided_p (fn)) /* Might be trivial. */; + else if (TREE_CODE (fn) == TEMPLATE_DECL) + /* Templates are never special members. */; + else if (!constraints_satisfied_p (fn)) + /* Not eligible. */; else if (copy_fn_p (fn)) TYPE_HAS_COMPLEX_COPY_CTOR (t) = true; else if (move_fn_p (fn)) @@ -4829,6 +4834,10 @@ check_methods (tree t) { if (!user_provided_p (fn)) /* Might be trivial. */; + else if (TREE_CODE (fn) == TEMPLATE_DECL) + /* Templates are never special members. */; + else if (!constraints_satisfied_p (fn)) + /* Not eligible. */; else if (copy_fn_p (fn)) TYPE_HAS_COMPLEX_COPY_ASSIGN (t) = true; else if (move_fn_p (fn)) diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index 1063987..db7571d 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -8065,8 +8065,8 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant, if (TREE_CODE (t) == TARGET_EXPR && TARGET_EXPR_INITIAL (t) == r) return t; - else if (TREE_CODE (t) == CONSTRUCTOR) - ; + else if (TREE_CODE (t) == CONSTRUCTOR || TREE_CODE (t) == CALL_EXPR) + /* Don't add a TARGET_EXPR if our argument didn't have one. */; else if (TREE_CODE (t) == TARGET_EXPR && TARGET_EXPR_CLEANUP (t)) r = get_target_expr (r); else @@ -8892,7 +8892,10 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now, { tree from = TREE_OPERAND (t, 0); if (location_wrapper_p (t)) - return (RECUR (from, want_rval)); + { + iloc_sentinel ils = loc; + return (RECUR (from, want_rval)); + } if (INDIRECT_TYPE_P (TREE_TYPE (t))) { STRIP_ANY_LOCATION_WRAPPER (from); @@ -9348,7 +9351,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now, (tmp, /*constexpr_context_p=*/true, flags)) return false; } - return RECUR (tmp, want_rval); + return RECUR (DECL_INITIAL (tmp), want_rval); case TRY_FINALLY_EXPR: return (RECUR (TREE_OPERAND (t, 0), want_rval) diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index 266ec58..74898ca 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -3649,7 +3649,7 @@ diagnose_trait_expr (tree expr, tree args) case CPTK_IS_POLYMORPHIC: inform (loc, " %qT is not a polymorphic type", t1); break; - case CPTK_IS_SAME_AS: + case CPTK_IS_SAME: inform (loc, " %qT is not the same as %qT", t1, t2); break; case CPTK_IS_STD_LAYOUT: @@ -3711,10 +3711,11 @@ diagnose_trait_expr (tree expr, tree args) inform (loc, " %qT is not a reference that binds to a temporary " "object of type %qT (copy-initialization)", t1, t2); break; - case CPTK_BASES: - case CPTK_DIRECT_BASES: - case CPTK_UNDERLYING_TYPE: - /* We shouldn't see these non-expression traits. */ +#define DEFTRAIT_TYPE(CODE, NAME, ARITY) \ + case CPTK_##CODE: +#include "cp-trait.def" +#undef DEFTRAIT_TYPE + /* Type-yielding traits aren't expressions. */ gcc_unreachable (); /* We deliberately omit the default case so that when adding a new trait we'll get reminded (by way of a warning) to handle it here. */ diff --git a/gcc/cp/cp-gimplify.cc b/gcc/cp/cp-gimplify.cc index c05be83..cca3b9f 100644 --- a/gcc/cp/cp-gimplify.cc +++ b/gcc/cp/cp-gimplify.cc @@ -892,13 +892,9 @@ omp_cxx_notice_variable (struct cp_genericize_omp_taskreg *omp_ctx, tree decl) static void cp_genericize_init (tree *replace, tree from, tree to) { + tree init = NULL_TREE; if (TREE_CODE (from) == VEC_INIT_EXPR) - { - tree init = expand_vec_init_expr (to, from, tf_warning_or_error); - - /* Make cp_gimplify_init_expr call replace_decl. */ - *replace = fold_convert (void_type_node, init); - } + init = expand_vec_init_expr (to, from, tf_warning_or_error); else if (flag_exceptions && TREE_CODE (from) == CONSTRUCTOR && TREE_SIDE_EFFECTS (from) @@ -906,7 +902,16 @@ cp_genericize_init (tree *replace, tree from, tree to) { to = cp_stabilize_reference (to); replace_placeholders (from, to); - *replace = split_nonconstant_init (to, from); + init = split_nonconstant_init (to, from); + } + + if (init) + { + if (*replace == from) + /* Make cp_gimplify_init_expr call replace_decl on this + TARGET_EXPR_INITIAL. */ + init = fold_convert (void_type_node, init); + *replace = init; } } @@ -1084,9 +1089,9 @@ cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data_) } break; - /* These are only for genericize time; they're here rather than in - cp_genericize to avoid problems with the invisible reference - transition. */ + /* cp_genericize_{init,target}_expr are only for genericize time; they're + here rather than in cp_genericize to avoid problems with the invisible + reference transition. */ case INIT_EXPR: if (data->genericize) cp_genericize_init_expr (stmt_p); @@ -1095,6 +1100,16 @@ cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data_) case TARGET_EXPR: if (data->genericize) cp_genericize_target_expr (stmt_p); + + /* Folding might replace e.g. a COND_EXPR with a TARGET_EXPR; in + that case, use it in place of this one. */ + if (tree &init = TARGET_EXPR_INITIAL (stmt)) + { + cp_walk_tree (&init, cp_fold_r, data, NULL); + *walk_subtrees = 0; + if (TREE_CODE (init) == TARGET_EXPR) + *stmt_p = init; + } break; default: diff --git a/gcc/cp/cp-objcp-common.cc b/gcc/cp/cp-objcp-common.cc index 6497569..e4df30d 100644 --- a/gcc/cp/cp-objcp-common.cc +++ b/gcc/cp/cp-objcp-common.cc @@ -430,43 +430,10 @@ names_builtin_p (const char *name) case RID_BUILTIN_ASSOC_BARRIER: case RID_BUILTIN_BIT_CAST: case RID_OFFSETOF: - case RID_HAS_NOTHROW_ASSIGN: - case RID_HAS_NOTHROW_CONSTRUCTOR: - case RID_HAS_NOTHROW_COPY: - case RID_HAS_TRIVIAL_ASSIGN: - case RID_HAS_TRIVIAL_CONSTRUCTOR: - case RID_HAS_TRIVIAL_COPY: - case RID_HAS_TRIVIAL_DESTRUCTOR: - case RID_HAS_UNIQUE_OBJ_REPRESENTATIONS: - case RID_HAS_VIRTUAL_DESTRUCTOR: - case RID_IS_ABSTRACT: - case RID_IS_AGGREGATE: - case RID_IS_BASE_OF: - case RID_IS_CLASS: - case RID_IS_EMPTY: - case RID_IS_ENUM: - case RID_IS_FINAL: - case RID_IS_LAYOUT_COMPATIBLE: - case RID_IS_LITERAL_TYPE: - case RID_IS_POINTER_INTERCONVERTIBLE_BASE_OF: - case RID_IS_POD: - case RID_IS_POLYMORPHIC: - case RID_IS_SAME_AS: - case RID_IS_STD_LAYOUT: - case RID_IS_TRIVIAL: - case RID_IS_TRIVIALLY_ASSIGNABLE: - case RID_IS_TRIVIALLY_CONSTRUCTIBLE: - case RID_IS_TRIVIALLY_COPYABLE: - case RID_IS_UNION: - case RID_IS_ASSIGNABLE: - case RID_IS_CONSTRUCTIBLE: - case RID_IS_NOTHROW_ASSIGNABLE: - case RID_IS_NOTHROW_CONSTRUCTIBLE: - case RID_UNDERLYING_TYPE: - case RID_IS_CONVERTIBLE: - case RID_IS_NOTHROW_CONVERTIBLE: - case RID_REF_CONSTRUCTS_FROM_TEMPORARY: - case RID_REF_CONVERTS_FROM_TEMPORARY: +#define DEFTRAIT(TCC, CODE, NAME, ARITY) \ + case RID_##CODE: +#include "cp-trait.def" +#undef DEFTRAIT return true; default: break; @@ -518,7 +485,7 @@ cp_common_init_ts (void) MARK_TS_TYPE_NON_COMMON (DECLTYPE_TYPE); MARK_TS_TYPE_NON_COMMON (TYPENAME_TYPE); MARK_TS_TYPE_NON_COMMON (TYPEOF_TYPE); - MARK_TS_TYPE_NON_COMMON (UNDERLYING_TYPE); + MARK_TS_TYPE_NON_COMMON (TRAIT_TYPE); MARK_TS_TYPE_NON_COMMON (BOUND_TEMPLATE_TEMPLATE_PARM); MARK_TS_TYPE_NON_COMMON (TEMPLATE_TEMPLATE_PARM); MARK_TS_TYPE_NON_COMMON (TEMPLATE_TYPE_PARM); diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def new file mode 100644 index 0000000..823899a --- /dev/null +++ b/gcc/cp/cp-trait.def @@ -0,0 +1,106 @@ +/* This file contains the definitions for C++-specific built-in traits. + + Copyright The GNU Toolchain Authors. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + +/* Add a DEFTRAIT_EXPR (CODE, NAME, N) line to this file to define an + expression-yielding built-in trait that has internal code name CODE, is + spelled as NAME and takes N type arguments (where N is either 1, 2, or + the special value -1 which denotes that it takes at least one argument). + Such traits are represented as TRAIT_EXPR tree whose TRAIT_EXPR_KIND is + CPTK_CODE. Define the behavior of the trait in finish_trait_expr. */ + +/* Add a DEFTRAIT_TYPE (CODE, NAME, N) line to this file to define a + type-yielding built-in trait as described above. Such traits are + generally represented as a TRAIT_TYPE tree whose TRAIT_TYPE_KIND is + CPTK_CODE (exceptions are BASES and DIRECT_BASES below). Define the + behavior of the trait in finish_trait_type. */ + +#ifdef DEFTRAIT +#define DEFTRAIT_EXPR(CODE, NAME, ARITY) DEFTRAIT(tcc_expression, CODE, NAME, ARITY) +#define DEFTRAIT_TYPE(CODE, NAME, ARITY) DEFTRAIT(tcc_type, CODE, NAME, ARITY) +#define DEFTRAIT_EXPR_DEFAULTED +#define DEFTRAIT_TYPE_DEFAULTED +#endif + +#ifndef DEFTRAIT_EXPR +#define DEFTRAIT_EXPR(CODE, NAME, ARITY) +#define DEFTRAIT_EXPR_DEFAULTED +#endif + +#ifndef DEFTRAIT_TYPE +#define DEFTRAIT_TYPE(CODE, NAME, ARITY) +#define DEFTRAIT_TYPE_DEFAULTED +#endif + +DEFTRAIT_EXPR (HAS_NOTHROW_ASSIGN, "__has_nothrow_assign", 1) +DEFTRAIT_EXPR (HAS_NOTHROW_CONSTRUCTOR, "__has_nothrow_constructor", 1) +DEFTRAIT_EXPR (HAS_NOTHROW_COPY, "__has_nothrow_copy", 1) +DEFTRAIT_EXPR (HAS_TRIVIAL_ASSIGN, "__has_trivial_assign", 1) +DEFTRAIT_EXPR (HAS_TRIVIAL_CONSTRUCTOR, "__has_trivial_constructor", 1) +DEFTRAIT_EXPR (HAS_TRIVIAL_COPY, "__has_trivial_copy", 1) +DEFTRAIT_EXPR (HAS_TRIVIAL_DESTRUCTOR, "__has_trivial_destructor", 1) +DEFTRAIT_EXPR (HAS_UNIQUE_OBJ_REPRESENTATIONS, "__has_unique_object_representations", 1) +DEFTRAIT_EXPR (HAS_VIRTUAL_DESTRUCTOR, "__has_virtual_destructor", 1) +DEFTRAIT_EXPR (IS_ABSTRACT, "__is_abstract", 1) +DEFTRAIT_EXPR (IS_AGGREGATE, "__is_aggregate", 1) +DEFTRAIT_EXPR (IS_ASSIGNABLE, "__is_assignable", 2) +DEFTRAIT_EXPR (IS_BASE_OF, "__is_base_of", 2) +DEFTRAIT_EXPR (IS_CLASS, "__is_class", 1) +DEFTRAIT_EXPR (IS_CONSTRUCTIBLE, "__is_constructible", -1) +DEFTRAIT_EXPR (IS_CONVERTIBLE, "__is_convertible", 2) +DEFTRAIT_EXPR (IS_EMPTY, "__is_empty", 1) +DEFTRAIT_EXPR (IS_ENUM, "__is_enum", 1) +DEFTRAIT_EXPR (IS_FINAL, "__is_final", 1) +DEFTRAIT_EXPR (IS_LAYOUT_COMPATIBLE, "__is_layout_compatible", 2) +DEFTRAIT_EXPR (IS_LITERAL_TYPE, "__is_literal_type", 1) +DEFTRAIT_EXPR (IS_NOTHROW_ASSIGNABLE, "__is_nothrow_assignable", 2) +DEFTRAIT_EXPR (IS_NOTHROW_CONSTRUCTIBLE, "__is_nothrow_constructible", -1) +DEFTRAIT_EXPR (IS_NOTHROW_CONVERTIBLE, "__is_nothrow_convertible", 2) +DEFTRAIT_EXPR (IS_POINTER_INTERCONVERTIBLE_BASE_OF, "__is_pointer_interconvertible_base_of", 2) +DEFTRAIT_EXPR (IS_POD, "__is_pod", 1) +DEFTRAIT_EXPR (IS_POLYMORPHIC, "__is_polymorphic", 1) +DEFTRAIT_EXPR (IS_SAME, "__is_same", 2) +DEFTRAIT_EXPR (IS_STD_LAYOUT, "__is_standard_layout", 1) +DEFTRAIT_EXPR (IS_TRIVIAL, "__is_trivial", 1) +DEFTRAIT_EXPR (IS_TRIVIALLY_ASSIGNABLE, "__is_trivially_assignable", 2) +DEFTRAIT_EXPR (IS_TRIVIALLY_CONSTRUCTIBLE, "__is_trivially_constructible", -1) +DEFTRAIT_EXPR (IS_TRIVIALLY_COPYABLE, "__is_trivially_copyable", 1) +DEFTRAIT_EXPR (IS_UNION, "__is_union", 1) +DEFTRAIT_EXPR (REF_CONSTRUCTS_FROM_TEMPORARY, "__reference_constructs_from_temporary", 2) +DEFTRAIT_EXPR (REF_CONVERTS_FROM_TEMPORARY, "__reference_converts_from_temporary", 2) + +DEFTRAIT_TYPE (REMOVE_CV, "__remove_cv", 1) +DEFTRAIT_TYPE (REMOVE_REFERENCE, "__remove_reference", 1) +DEFTRAIT_TYPE (REMOVE_CVREF, "__remove_cvref", 1) +DEFTRAIT_TYPE (UNDERLYING_TYPE, "__underlying_type", 1) + +/* These traits yield a type pack, not a type, and are represented by + cp_parser_trait as a special BASES tree instead of a TRAIT_TYPE tree. */ +DEFTRAIT_TYPE (BASES, "__bases", 1) +DEFTRAIT_TYPE (DIRECT_BASES, "__direct_bases", 1) + +#ifdef DEFTRAIT_EXPR_DEFAULTED +#undef DEFTRAIT_EXPR +#undef DEFTRAIT_EXPR_DEFAULTED +#endif + +#ifdef DEFTRAIT_TYPE_DEFAULTED +#undef DEFTRAIT_TYPE +#undef DEFTRAIT_TYPE_DEFAULTED +#endif diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def index f9cbd33..f83b4c5 100644 --- a/gcc/cp/cp-tree.def +++ b/gcc/cp/cp-tree.def @@ -444,9 +444,12 @@ DEFTREECODE (BIT_CAST_EXPR, "bit_cast_expr", tcc_expression, 1) /** C++ extensions. */ -/* Represents a trait expression during template expansion. */ +/* Represents a templated trait that yields an expression. */ DEFTREECODE (TRAIT_EXPR, "trait_expr", tcc_exceptional, 0) +/* Represents a templated trait that yields a type. */ +DEFTREECODE (TRAIT_TYPE, "trait_type", tcc_type, 0) + /* A lambda expression. This is a C++0x extension. LAMBDA_EXPR_DEFAULT_CAPTURE_MODE is an enum for the default, which may be none. @@ -466,10 +469,6 @@ DEFTREECODE (LAMBDA_EXPR, "lambda_expr", tcc_exceptional, 0) DECLTYPE_FOR_LAMBDA_RETURN is set if we want lambda return deduction. */ DEFTREECODE (DECLTYPE_TYPE, "decltype_type", tcc_type, 0) -/* A type designated by `__underlying_type (type)'. - UNDERLYING_TYPE_TYPE is the type in question. */ -DEFTREECODE (UNDERLYING_TYPE, "underlying_type", tcc_type, 0) - /* A type designated by one of the bases type traits. BASES_TYPE is the type in question. */ DEFTREECODE (BASES, "bases", tcc_type, 0) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index d0f1b18..8cf9707 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1374,45 +1374,10 @@ struct GTY (()) tree_argument_pack_select { enum cp_trait_kind { - CPTK_BASES, - CPTK_DIRECT_BASES, - CPTK_HAS_NOTHROW_ASSIGN, - CPTK_HAS_NOTHROW_CONSTRUCTOR, - CPTK_HAS_NOTHROW_COPY, - CPTK_HAS_TRIVIAL_ASSIGN, - CPTK_HAS_TRIVIAL_CONSTRUCTOR, - CPTK_HAS_TRIVIAL_COPY, - CPTK_HAS_TRIVIAL_DESTRUCTOR, - CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS, - CPTK_HAS_VIRTUAL_DESTRUCTOR, - CPTK_IS_ABSTRACT, - CPTK_IS_AGGREGATE, - CPTK_IS_BASE_OF, - CPTK_IS_CLASS, - CPTK_IS_EMPTY, - CPTK_IS_ENUM, - CPTK_IS_FINAL, - CPTK_IS_LAYOUT_COMPATIBLE, - CPTK_IS_LITERAL_TYPE, - CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF, - CPTK_IS_POD, - CPTK_IS_POLYMORPHIC, - CPTK_IS_SAME_AS, - CPTK_IS_STD_LAYOUT, - CPTK_IS_TRIVIAL, - CPTK_IS_TRIVIALLY_ASSIGNABLE, - CPTK_IS_TRIVIALLY_CONSTRUCTIBLE, - CPTK_IS_TRIVIALLY_COPYABLE, - CPTK_IS_UNION, - CPTK_UNDERLYING_TYPE, - CPTK_IS_ASSIGNABLE, - CPTK_IS_CONSTRUCTIBLE, - CPTK_IS_NOTHROW_ASSIGNABLE, - CPTK_IS_NOTHROW_CONSTRUCTIBLE, - CPTK_IS_CONVERTIBLE, - CPTK_IS_NOTHROW_CONVERTIBLE, - CPTK_REF_CONSTRUCTS_FROM_TEMPORARY, - CPTK_REF_CONVERTS_FROM_TEMPORARY +#define DEFTRAIT(TCC, CODE, NAME, ARITY) \ + CPTK_##CODE, +#include "cp-trait.def" +#undef DEFTRAIT }; /* The types that we are processing. */ @@ -1437,6 +1402,22 @@ struct GTY (()) tree_trait_expr { enum cp_trait_kind kind; }; +/* An INTEGER_CST containing the kind of the trait type NODE. */ +#define TRAIT_TYPE_KIND_RAW(NODE) \ + TYPE_VALUES_RAW (TRAIT_TYPE_CHECK (NODE)) + +/* The kind of the trait type NODE. */ +#define TRAIT_TYPE_KIND(NODE) \ + ((enum cp_trait_kind) TREE_INT_CST_LOW (TRAIT_TYPE_KIND_RAW (NODE))) + +/* The first argument of the trait type NODE. */ +#define TRAIT_TYPE_TYPE1(NODE) \ + TYPE_MIN_VALUE_RAW (TRAIT_TYPE_CHECK (NODE)) + +/* The rest of the arguments of the trait type NODE. */ +#define TRAIT_TYPE_TYPE2(NODE) \ + TYPE_MAX_VALUE_RAW (TRAIT_TYPE_CHECK (NODE)) + /* Identifiers used for lambda types are almost anonymous. Use this spare flag to distinguish them (they also have the anonymous flag). */ #define IDENTIFIER_LAMBDA_P(NODE) \ @@ -1836,11 +1817,12 @@ union GTY((desc ("cp_tree_node_structure (&%h)"), }; -struct GTY(()) omp_declare_target_attr { +struct GTY(()) cp_omp_declare_target_attr { bool attr_syntax; + int device_type; }; -struct GTY(()) omp_begin_assumes_data { +struct GTY(()) cp_omp_begin_assumes_data { bool attr_syntax; }; @@ -1890,8 +1872,8 @@ struct GTY(()) saved_scope { cp_binding_level *bindings; hash_map<tree, tree> *GTY((skip)) x_local_specializations; - vec<omp_declare_target_attr, va_gc> *omp_declare_target_attribute; - vec<omp_begin_assumes_data, va_gc> *omp_begin_assumes; + vec<cp_omp_declare_target_attr, va_gc> *omp_declare_target_attribute; + vec<cp_omp_begin_assumes_data, va_gc> *omp_begin_assumes; struct saved_scope *prev; }; @@ -2226,6 +2208,7 @@ enum languages { lang_c, lang_cplusplus }; || TREE_CODE (T) == TYPEOF_TYPE \ || TREE_CODE (T) == BOUND_TEMPLATE_TEMPLATE_PARM \ || TREE_CODE (T) == DECLTYPE_TYPE \ + || TREE_CODE (T) == TRAIT_TYPE \ || TREE_CODE (T) == DEPENDENT_OPERATOR_TYPE) /* Nonzero if T is a class (or struct or union) type. Also nonzero @@ -5406,7 +5389,8 @@ target_expr_needs_replace (tree t) return false; while (TREE_CODE (init) == COMPOUND_EXPR) init = TREE_OPERAND (init, 1); - return TREE_CODE (init) != AGGR_INIT_EXPR; + return (TREE_CODE (init) != AGGR_INIT_EXPR + && TREE_CODE (init) != VEC_INIT_EXPR); } /* True if EXPR expresses direct-initialization of a TYPE. */ @@ -7616,7 +7600,8 @@ enum { BCS_NO_SCOPE = 1, BCS_TRY_BLOCK = 2, BCS_FN_BODY = 4, - BCS_TRANSACTION = 8 + BCS_TRANSACTION = 8, + BCS_STMT_EXPR = 16 }; extern tree begin_compound_stmt (unsigned int); @@ -7736,6 +7721,7 @@ extern tree finish_decltype_type (tree, bool, tsubst_flags_t); extern tree fold_builtin_is_corresponding_member (location_t, int, tree *); extern tree fold_builtin_is_pointer_inverconvertible_with_class (location_t, int, tree *); extern tree finish_trait_expr (location_t, enum cp_trait_kind, tree, tree); +extern tree finish_trait_type (enum cp_trait_kind, tree, tree); extern tree build_lambda_expr (void); extern tree build_lambda_object (tree); extern tree begin_lambda_type (tree); diff --git a/gcc/cp/cxx-pretty-print.cc b/gcc/cp/cxx-pretty-print.cc index bbd51bb..8ca1b8f 100644 --- a/gcc/cp/cxx-pretty-print.cc +++ b/gcc/cp/cxx-pretty-print.cc @@ -483,7 +483,7 @@ cxx_pretty_printer::primary_expression (tree t) break; case TRAIT_EXPR: - pp_cxx_trait_expression (this, t); + pp_cxx_trait (this, t); break; case VA_ARG_EXPR: @@ -1240,7 +1240,7 @@ cxx_pretty_printer::expression (tree t) break; case TRAIT_EXPR: - pp_cxx_trait_expression (this, t); + pp_cxx_trait (this, t); break; case ATOMIC_CONSTR: @@ -1385,6 +1385,10 @@ cxx_pretty_printer::simple_type_specifier (tree t) pp_cxx_ws_string (this, "std::nullptr_t"); break; + case TRAIT_TYPE: + pp_cxx_trait (this, t); + break; + default: c_pretty_printer::simple_type_specifier (t); break; @@ -1876,7 +1880,7 @@ cxx_pretty_printer::type_id (tree t) case TEMPLATE_PARM_INDEX: case TEMPLATE_DECL: case TYPEOF_TYPE: - case UNDERLYING_TYPE: + case TRAIT_TYPE: case DECLTYPE_TYPE: case NULLPTR_TYPE: case TEMPLATE_ID_EXPR: @@ -2594,137 +2598,49 @@ pp_cxx_binary_fold_expression (cxx_pretty_printer *pp, tree t) } void -pp_cxx_trait_expression (cxx_pretty_printer *pp, tree t) +pp_cxx_trait (cxx_pretty_printer *pp, tree t) { - cp_trait_kind kind = TRAIT_EXPR_KIND (t); + cp_trait_kind kind; + tree type1, type2; + if (TREE_CODE (t) == TRAIT_EXPR) + { + kind = TRAIT_EXPR_KIND (t); + type1 = TRAIT_EXPR_TYPE1 (t); + type2 = TRAIT_EXPR_TYPE2 (t); + } + else + { + kind = TRAIT_TYPE_KIND (t); + type1 = TRAIT_TYPE_TYPE1 (t); + type2 = TRAIT_TYPE_TYPE2 (t); + } switch (kind) { - case CPTK_HAS_NOTHROW_ASSIGN: - pp_cxx_ws_string (pp, "__has_nothrow_assign"); - break; - case CPTK_HAS_TRIVIAL_ASSIGN: - pp_cxx_ws_string (pp, "__has_trivial_assign"); - break; - case CPTK_HAS_NOTHROW_CONSTRUCTOR: - pp_cxx_ws_string (pp, "__has_nothrow_constructor"); - break; - case CPTK_HAS_TRIVIAL_CONSTRUCTOR: - pp_cxx_ws_string (pp, "__has_trivial_constructor"); - break; - case CPTK_HAS_NOTHROW_COPY: - pp_cxx_ws_string (pp, "__has_nothrow_copy"); - break; - case CPTK_HAS_TRIVIAL_COPY: - pp_cxx_ws_string (pp, "__has_trivial_copy"); - break; - case CPTK_HAS_TRIVIAL_DESTRUCTOR: - pp_cxx_ws_string (pp, "__has_trivial_destructor"); - break; - case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS: - pp_cxx_ws_string (pp, "__has_unique_object_representations"); - break; - case CPTK_HAS_VIRTUAL_DESTRUCTOR: - pp_cxx_ws_string (pp, "__has_virtual_destructor"); - break; - case CPTK_IS_ABSTRACT: - pp_cxx_ws_string (pp, "__is_abstract"); - break; - case CPTK_IS_AGGREGATE: - pp_cxx_ws_string (pp, "__is_aggregate"); - break; - case CPTK_IS_BASE_OF: - pp_cxx_ws_string (pp, "__is_base_of"); - break; - case CPTK_IS_CLASS: - pp_cxx_ws_string (pp, "__is_class"); - break; - case CPTK_IS_EMPTY: - pp_cxx_ws_string (pp, "__is_empty"); - break; - case CPTK_IS_ENUM: - pp_cxx_ws_string (pp, "__is_enum"); - break; - case CPTK_IS_FINAL: - pp_cxx_ws_string (pp, "__is_final"); - break; - case CPTK_IS_LAYOUT_COMPATIBLE: - pp_cxx_ws_string (pp, "__is_layout_compatible"); - break; - case CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF: - pp_cxx_ws_string (pp, "__is_pointer_interconvertible_base_of"); - break; - case CPTK_IS_POD: - pp_cxx_ws_string (pp, "__is_pod"); - break; - case CPTK_IS_POLYMORPHIC: - pp_cxx_ws_string (pp, "__is_polymorphic"); - break; - case CPTK_IS_SAME_AS: - pp_cxx_ws_string (pp, "__is_same"); +#define DEFTRAIT(TCC, CODE, NAME, ARITY) \ + case CPTK_##CODE: \ + pp_cxx_ws_string (pp, NAME); \ break; - case CPTK_IS_STD_LAYOUT: - pp_cxx_ws_string (pp, "__is_std_layout"); - break; - case CPTK_IS_TRIVIAL: - pp_cxx_ws_string (pp, "__is_trivial"); - break; - case CPTK_IS_TRIVIALLY_ASSIGNABLE: - pp_cxx_ws_string (pp, "__is_trivially_assignable"); - break; - case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE: - pp_cxx_ws_string (pp, "__is_trivially_constructible"); - break; - case CPTK_IS_TRIVIALLY_COPYABLE: - pp_cxx_ws_string (pp, "__is_trivially_copyable"); - break; - case CPTK_IS_UNION: - pp_cxx_ws_string (pp, "__is_union"); - break; - case CPTK_IS_LITERAL_TYPE: - pp_cxx_ws_string (pp, "__is_literal_type"); - break; - case CPTK_IS_ASSIGNABLE: - pp_cxx_ws_string (pp, "__is_assignable"); - break; - case CPTK_IS_CONSTRUCTIBLE: - pp_cxx_ws_string (pp, "__is_constructible"); - break; - case CPTK_IS_NOTHROW_ASSIGNABLE: - pp_cxx_ws_string (pp, "__is_nothrow_assignable"); - break; - case CPTK_IS_NOTHROW_CONSTRUCTIBLE: - pp_cxx_ws_string (pp, "__is_nothrow_constructible"); - break; - case CPTK_IS_CONVERTIBLE: - pp_cxx_ws_string (pp, "__is_convertible"); - break; - case CPTK_IS_NOTHROW_CONVERTIBLE: - pp_cxx_ws_string (pp, "__is_nothrow_convertible"); - break; - case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY: - pp_cxx_ws_string (pp, "__reference_constructs_from_temporary"); - break; - case CPTK_REF_CONVERTS_FROM_TEMPORARY: - pp_cxx_ws_string (pp, "__reference_converts_from_temporary"); - break; - - default: - gcc_unreachable (); +#include "cp-trait.def" +#undef DEFTRAIT } pp_cxx_left_paren (pp); - pp->type_id (TRAIT_EXPR_TYPE1 (t)); - - if (kind == CPTK_IS_BASE_OF - || kind == CPTK_IS_SAME_AS - || kind == CPTK_IS_LAYOUT_COMPATIBLE - || kind == CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF) + pp->type_id (type1); + if (type2) { - pp_cxx_separate_with (pp, ','); - pp->type_id (TRAIT_EXPR_TYPE2 (t)); + if (TREE_CODE (type2) != TREE_LIST) + { + pp_cxx_separate_with (pp, ','); + pp->type_id (type2); + } + else + for (tree arg = type2; arg; arg = TREE_CHAIN (arg)) + { + pp_cxx_separate_with (pp, ','); + pp->type_id (TREE_VALUE (arg)); + } } - pp_cxx_right_paren (pp); } diff --git a/gcc/cp/cxx-pretty-print.h b/gcc/cp/cxx-pretty-print.h index 593bd91..25a2c7c 100644 --- a/gcc/cp/cxx-pretty-print.h +++ b/gcc/cp/cxx-pretty-print.h @@ -90,7 +90,7 @@ void pp_cxx_colon_colon (cxx_pretty_printer *); void pp_cxx_separate_with (cxx_pretty_printer *, int); void pp_cxx_canonical_template_parameter (cxx_pretty_printer *, tree); -void pp_cxx_trait_expression (cxx_pretty_printer *, tree); +void pp_cxx_trait (cxx_pretty_printer *, tree); void pp_cxx_va_arg_expression (cxx_pretty_printer *, tree); void pp_cxx_offsetof_expression (cxx_pretty_printer *, tree); void pp_cxx_addressof_expression (cxx_pretty_printer *, tree); diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index fb85564..07148b9 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -223,6 +223,7 @@ struct GTY((for_user)) named_label_entry { bool in_transaction_scope; bool in_constexpr_if; bool in_consteval_if; + bool in_stmt_expr; }; #define named_labels cp_function_chain->x_named_labels @@ -538,6 +539,9 @@ poplevel_named_label_1 (named_label_entry **slot, cp_binding_level *bl) case sk_transaction: ent->in_transaction_scope = true; break; + case sk_stmt_expr: + ent->in_stmt_expr = true; + break; case sk_block: if (level_for_constexpr_if (bl->level_chain)) ent->in_constexpr_if = true; @@ -3487,7 +3491,7 @@ check_previous_goto_1 (tree decl, cp_binding_level* level, tree names, bool complained = false; int identified = 0; bool saw_eh = false, saw_omp = false, saw_tm = false, saw_cxif = false; - bool saw_ceif = false; + bool saw_ceif = false, saw_se = false; if (exited_omp) { @@ -3560,6 +3564,12 @@ check_previous_goto_1 (tree decl, cp_binding_level* level, tree names, saw_tm = true; break; + case sk_stmt_expr: + if (!saw_se) + inf = G_(" enters statement expression"); + saw_se = true; + break; + case sk_block: if (!saw_cxif && level_for_constexpr_if (b->level_chain)) { @@ -3650,12 +3660,13 @@ check_goto (tree decl) if (ent->in_try_scope || ent->in_catch_scope || ent->in_transaction_scope || ent->in_constexpr_if || ent->in_consteval_if - || ent->in_omp_scope || !vec_safe_is_empty (ent->bad_decls)) + || ent->in_omp_scope || ent->in_stmt_expr + || !vec_safe_is_empty (ent->bad_decls)) { diagnostic_t diag_kind = DK_PERMERROR; if (ent->in_try_scope || ent->in_catch_scope || ent->in_constexpr_if || ent->in_consteval_if || ent->in_transaction_scope - || ent->in_omp_scope) + || ent->in_omp_scope || ent->in_stmt_expr) diag_kind = DK_ERROR; complained = identify_goto (decl, DECL_SOURCE_LOCATION (decl), &input_location, diag_kind); @@ -3703,6 +3714,8 @@ check_goto (tree decl) inform (input_location, " enters %<constexpr if%> statement"); else if (ent->in_consteval_if) inform (input_location, " enters %<consteval if%> statement"); + else if (ent->in_stmt_expr) + inform (input_location, " enters statement expression"); } if (ent->in_omp_scope) diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc index 9f18466..e677926 100644 --- a/gcc/cp/decl2.cc +++ b/gcc/cp/decl2.cc @@ -1652,17 +1652,40 @@ cplus_decl_attributes (tree *decl, tree attributes, int flags) && DECL_CLASS_SCOPE_P (*decl)) error ("%q+D static data member inside of declare target directive", *decl); - else if (VAR_P (*decl) - && (processing_template_decl - || !omp_mappable_type (TREE_TYPE (*decl)))) - attributes = tree_cons (get_identifier ("omp declare target implicit"), - NULL_TREE, attributes); else { - attributes = tree_cons (get_identifier ("omp declare target"), - NULL_TREE, attributes); - attributes = tree_cons (get_identifier ("omp declare target block"), - NULL_TREE, attributes); + if (VAR_P (*decl) + && (processing_template_decl + || !omp_mappable_type (TREE_TYPE (*decl)))) + attributes + = tree_cons (get_identifier ("omp declare target implicit"), + NULL_TREE, attributes); + else + { + attributes = tree_cons (get_identifier ("omp declare target"), + NULL_TREE, attributes); + attributes + = tree_cons (get_identifier ("omp declare target block"), + NULL_TREE, attributes); + } + if (TREE_CODE (*decl) == FUNCTION_DECL) + { + cp_omp_declare_target_attr &last + = scope_chain->omp_declare_target_attribute->last (); + int device_type = MAX (last.device_type, 0); + if ((device_type & OMP_CLAUSE_DEVICE_TYPE_HOST) != 0 + && !lookup_attribute ("omp declare target host", + attributes)) + attributes + = tree_cons (get_identifier ("omp declare target host"), + NULL_TREE, attributes); + if ((device_type & OMP_CLAUSE_DEVICE_TYPE_NOHOST) != 0 + && !lookup_attribute ("omp declare target nohost", + attributes)) + attributes + = tree_cons (get_identifier ("omp declare target nohost"), + NULL_TREE, attributes); + } } } diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc index 53904e3..4514c8b 100644 --- a/gcc/cp/error.cc +++ b/gcc/cp/error.cc @@ -698,12 +698,8 @@ dump_type (cxx_pretty_printer *pp, tree t, int flags) pp_cxx_right_paren (pp); break; - case UNDERLYING_TYPE: - pp_cxx_ws_string (pp, "__underlying_type"); - pp_cxx_whitespace (pp); - pp_cxx_left_paren (pp); - dump_expr (pp, UNDERLYING_TYPE_TYPE (t), flags & ~TFF_EXPR_IN_PARENS); - pp_cxx_right_paren (pp); + case TRAIT_TYPE: + pp_cxx_trait (pp, t); break; case TYPE_PACK_EXPANSION: @@ -971,7 +967,7 @@ dump_type_prefix (cxx_pretty_printer *pp, tree t, int flags) case COMPLEX_TYPE: case VECTOR_TYPE: case TYPEOF_TYPE: - case UNDERLYING_TYPE: + case TRAIT_TYPE: case DECLTYPE_TYPE: case TYPE_PACK_EXPANSION: case FIXED_POINT_TYPE: @@ -1095,7 +1091,7 @@ dump_type_suffix (cxx_pretty_printer *pp, tree t, int flags) case COMPLEX_TYPE: case VECTOR_TYPE: case TYPEOF_TYPE: - case UNDERLYING_TYPE: + case TRAIT_TYPE: case DECLTYPE_TYPE: case TYPE_PACK_EXPANSION: case FIXED_POINT_TYPE: @@ -2956,7 +2952,7 @@ dump_expr (cxx_pretty_printer *pp, tree t, int flags) break; case TRAIT_EXPR: - pp_cxx_trait_expression (pp, t); + pp_cxx_trait (pp, t); break; case VA_ARG_EXPR: diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc index a85c303..bf46578 100644 --- a/gcc/cp/init.cc +++ b/gcc/cp/init.cc @@ -4394,6 +4394,10 @@ build_vec_init (tree base, tree maxindex, tree init, } } + /* from_array doesn't apply to initialization from CONSTRUCTOR. */ + if (init && TREE_CODE (init) == CONSTRUCTOR) + from_array = 0; + /* If we have a braced-init-list or string constant, make sure that the array is big enough for all the initializers. */ bool length_check = (init @@ -4493,7 +4497,7 @@ build_vec_init (tree base, tree maxindex, tree init, /* If initializing one array from another, initialize element by element. We rely upon the below calls to do the argument checking. Evaluate the initializer before entering the try block. */ - if (from_array && init && TREE_CODE (init) != CONSTRUCTOR) + if (from_array) { if (lvalue_kind (init) & clk_rvalueref) xvalue = true; diff --git a/gcc/cp/mangle.cc b/gcc/cp/mangle.cc index 1a45585..f051e76 100644 --- a/gcc/cp/mangle.cc +++ b/gcc/cp/mangle.cc @@ -2389,8 +2389,9 @@ write_type (tree type) sorry ("mangling %<typeof%>, use %<decltype%> instead"); break; - case UNDERLYING_TYPE: - sorry ("mangling %<__underlying_type%>"); + case TRAIT_TYPE: + error ("use of built-in trait %qT in function signature; " + "use library traits instead", type); break; case LANG_TYPE: diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index d965017..500ac06 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -2737,6 +2737,7 @@ enum tree_tag { tt_tinfo_var, /* Typeinfo object. */ tt_tinfo_typedef, /* Typeinfo typedef. */ tt_ptrmem_type, /* Pointer to member type. */ + tt_nttp_var, /* NTTP_OBJECT VAR_DECL. */ tt_parm, /* Function parameter or result. */ tt_enum_value, /* An enum value. */ @@ -8548,6 +8549,21 @@ trees_out::decl_node (tree decl, walk_kind ref) } return false; } + + if (DECL_NTTP_OBJECT_P (decl)) + { + /* A NTTP parm object. */ + if (streaming_p ()) + i (tt_nttp_var); + tree_node (tparm_object_argument (decl)); + tree_node (DECL_NAME (decl)); + int tag = insert (decl); + if (streaming_p ()) + dump (dumper::TREE) + && dump ("Wrote nttp object:%d %N", tag, DECL_NAME (decl)); + return false; + } + break; case TYPE_DECL: @@ -8910,7 +8926,6 @@ trees_out::type_node (tree type) case DECLTYPE_TYPE: case TYPEOF_TYPE: - case UNDERLYING_TYPE: case DEPENDENT_OPERATOR_TYPE: tree_node (TYPE_VALUES_RAW (type)); if (TREE_CODE (type) == DECLTYPE_TYPE) @@ -8920,6 +8935,12 @@ trees_out::type_node (tree type) tree_node_bools (type); break; + case TRAIT_TYPE: + tree_node (TRAIT_TYPE_KIND_RAW (type)); + tree_node (TRAIT_TYPE_TYPE1 (type)); + tree_node (TRAIT_TYPE_TYPE2 (type)); + break; + case TYPE_ARGUMENT_PACK: /* No additional data. */ break; @@ -9434,7 +9455,6 @@ trees_in::tree_node (bool is_use) case DECLTYPE_TYPE: case TYPEOF_TYPE: - case UNDERLYING_TYPE: case DEPENDENT_OPERATOR_TYPE: { tree expr = tree_node (); @@ -9449,6 +9469,22 @@ trees_in::tree_node (bool is_use) } break; + case TRAIT_TYPE: + { + tree kind = tree_node (); + tree type1 = tree_node (); + tree type2 = tree_node (); + if (!get_overrun ()) + { + res = cxx_make_type (TRAIT_TYPE); + TRAIT_TYPE_KIND_RAW (res) = kind; + TRAIT_TYPE_TYPE1 (res) = type1; + TRAIT_TYPE_TYPE2 (res) = type2; + SET_TYPE_STRUCTURAL_EQUALITY (res); + } + } + break; + case TYPE_ARGUMENT_PACK: if (!get_overrun ()) { @@ -9627,6 +9663,21 @@ trees_in::tree_node (bool is_use) } break; + case tt_nttp_var: + /* An NTTP object. */ + { + tree init = tree_node (); + tree name = tree_node (); + if (!get_overrun ()) + { + res = get_template_parm_object (init, name); + int tag = insert (res); + dump (dumper::TREE) + && dump ("Created nttp object:%d %N", tag, name); + } + } + break; + case tt_enum_value: /* An enum const value. */ { @@ -12760,6 +12811,10 @@ depset::hash::add_binding_entity (tree decl, WMB_Flags flags, void *data_) /* Ignore TINFO things. */ return false; + if (TREE_CODE (decl) == VAR_DECL && DECL_NTTP_OBJECT_P (decl)) + /* Ignore NTTP objects. */ + return false; + if (!(flags & WMB_Using) && CP_DECL_CONTEXT (decl) != data->ns) { /* A using that lost its wrapper or an unscoped enum diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc index 69d555d..d6757d1 100644 --- a/gcc/cp/name-lookup.cc +++ b/gcc/cp/name-lookup.cc @@ -4296,6 +4296,7 @@ begin_scope (scope_kind kind, tree entity) case sk_scoped_enum: case sk_transaction: case sk_omp: + case sk_stmt_expr: scope->keep = keep_next_level_flag; break; diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h index 999db33..7201ae8 100644 --- a/gcc/cp/name-lookup.h +++ b/gcc/cp/name-lookup.h @@ -200,6 +200,7 @@ enum scope_kind { init-statement. */ sk_cond, /* The scope of the variable declared in the condition of an if or switch statement. */ + sk_stmt_expr, /* GNU statement expression block. */ sk_function_parms, /* The scope containing function parameters. */ sk_class, /* The scope containing the members of a class. */ sk_scoped_enum, /* The scope containing the enumerators of a C++11 diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index d501178..7b41635 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -1146,13 +1146,18 @@ cp_keyword_starts_decl_specifier_p (enum rid keyword) case RID_TYPEOF: /* C++11 extensions. */ case RID_DECLTYPE: - case RID_UNDERLYING_TYPE: case RID_CONSTEXPR: /* C++20 extensions. */ case RID_CONSTINIT: case RID_CONSTEVAL: return true; +#define DEFTRAIT_TYPE(CODE, NAME, ARITY) \ + case RID_##CODE: +#include "cp-trait.def" +#undef DEFTRAIT_TYPE + return true; + default: if (keyword >= RID_FIRST_INT_N && keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS @@ -2783,7 +2788,7 @@ static void cp_parser_late_parsing_default_args (cp_parser *, tree); static tree cp_parser_sizeof_operand (cp_parser *, enum rid); -static cp_expr cp_parser_trait_expr +static cp_expr cp_parser_trait (cp_parser *, enum rid); static bool cp_parser_declares_only_class_p (cp_parser *); @@ -5267,7 +5272,7 @@ cp_parser_statement_expr (cp_parser *parser) /* Start the statement-expression. */ tree expr = begin_stmt_expr (); /* Parse the compound-statement. */ - cp_parser_compound_statement (parser, expr, BCS_NORMAL, false); + cp_parser_compound_statement (parser, expr, BCS_STMT_EXPR, false); /* Finish up. */ expr = finish_stmt_expr (expr, false); /* Consume the ')'. */ @@ -5892,43 +5897,11 @@ cp_parser_primary_expression (cp_parser *parser, case RID_OFFSETOF: return cp_parser_builtin_offsetof (parser); - case RID_HAS_NOTHROW_ASSIGN: - case RID_HAS_NOTHROW_CONSTRUCTOR: - case RID_HAS_NOTHROW_COPY: - case RID_HAS_TRIVIAL_ASSIGN: - case RID_HAS_TRIVIAL_CONSTRUCTOR: - case RID_HAS_TRIVIAL_COPY: - case RID_HAS_TRIVIAL_DESTRUCTOR: - case RID_HAS_UNIQUE_OBJ_REPRESENTATIONS: - case RID_HAS_VIRTUAL_DESTRUCTOR: - case RID_IS_ABSTRACT: - case RID_IS_AGGREGATE: - case RID_IS_BASE_OF: - case RID_IS_CLASS: - case RID_IS_EMPTY: - case RID_IS_ENUM: - case RID_IS_FINAL: - case RID_IS_LAYOUT_COMPATIBLE: - case RID_IS_LITERAL_TYPE: - case RID_IS_POINTER_INTERCONVERTIBLE_BASE_OF: - case RID_IS_POD: - case RID_IS_POLYMORPHIC: - case RID_IS_SAME_AS: - case RID_IS_STD_LAYOUT: - case RID_IS_TRIVIAL: - case RID_IS_TRIVIALLY_ASSIGNABLE: - case RID_IS_TRIVIALLY_CONSTRUCTIBLE: - case RID_IS_TRIVIALLY_COPYABLE: - case RID_IS_UNION: - case RID_IS_ASSIGNABLE: - case RID_IS_CONSTRUCTIBLE: - case RID_IS_NOTHROW_ASSIGNABLE: - case RID_IS_NOTHROW_CONSTRUCTIBLE: - case RID_IS_CONVERTIBLE: - case RID_IS_NOTHROW_CONVERTIBLE: - case RID_REF_CONSTRUCTS_FROM_TEMPORARY: - case RID_REF_CONVERTS_FROM_TEMPORARY: - return cp_parser_trait_expr (parser, token->keyword); +#define DEFTRAIT_EXPR(CODE, NAME, ARITY) \ + case RID_##CODE: +#include "cp-trait.def" +#undef DEFTRAIT_EXPR + return cp_parser_trait (parser, token->keyword); // C++ concepts case RID_REQUIRES: @@ -10882,152 +10855,28 @@ cp_parser_builtin_offsetof (cp_parser *parser) return expr; } -/* Parse a trait expression. - - Returns a representation of the expression, the underlying type - of the type at issue when KEYWORD is RID_UNDERLYING_TYPE. */ +/* Parse a builtin trait expression or type. */ static cp_expr -cp_parser_trait_expr (cp_parser* parser, enum rid keyword) +cp_parser_trait (cp_parser* parser, enum rid keyword) { cp_trait_kind kind; tree type1, type2 = NULL_TREE; bool binary = false; bool variadic = false; + bool type = false; switch (keyword) { - case RID_HAS_NOTHROW_ASSIGN: - kind = CPTK_HAS_NOTHROW_ASSIGN; - break; - case RID_HAS_NOTHROW_CONSTRUCTOR: - kind = CPTK_HAS_NOTHROW_CONSTRUCTOR; - break; - case RID_HAS_NOTHROW_COPY: - kind = CPTK_HAS_NOTHROW_COPY; - break; - case RID_HAS_TRIVIAL_ASSIGN: - kind = CPTK_HAS_TRIVIAL_ASSIGN; - break; - case RID_HAS_TRIVIAL_CONSTRUCTOR: - kind = CPTK_HAS_TRIVIAL_CONSTRUCTOR; - break; - case RID_HAS_TRIVIAL_COPY: - kind = CPTK_HAS_TRIVIAL_COPY; - break; - case RID_HAS_TRIVIAL_DESTRUCTOR: - kind = CPTK_HAS_TRIVIAL_DESTRUCTOR; - break; - case RID_HAS_UNIQUE_OBJ_REPRESENTATIONS: - kind = CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS; - break; - case RID_HAS_VIRTUAL_DESTRUCTOR: - kind = CPTK_HAS_VIRTUAL_DESTRUCTOR; - break; - case RID_IS_ABSTRACT: - kind = CPTK_IS_ABSTRACT; - break; - case RID_IS_AGGREGATE: - kind = CPTK_IS_AGGREGATE; - break; - case RID_IS_BASE_OF: - kind = CPTK_IS_BASE_OF; - binary = true; - break; - case RID_IS_CLASS: - kind = CPTK_IS_CLASS; - break; - case RID_IS_EMPTY: - kind = CPTK_IS_EMPTY; - break; - case RID_IS_ENUM: - kind = CPTK_IS_ENUM; - break; - case RID_IS_FINAL: - kind = CPTK_IS_FINAL; - break; - case RID_IS_LAYOUT_COMPATIBLE: - kind = CPTK_IS_LAYOUT_COMPATIBLE; - binary = true; - break; - case RID_IS_LITERAL_TYPE: - kind = CPTK_IS_LITERAL_TYPE; - break; - case RID_IS_POINTER_INTERCONVERTIBLE_BASE_OF: - kind = CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF; - binary = true; - break; - case RID_IS_POD: - kind = CPTK_IS_POD; - break; - case RID_IS_POLYMORPHIC: - kind = CPTK_IS_POLYMORPHIC; - break; - case RID_IS_SAME_AS: - kind = CPTK_IS_SAME_AS; - binary = true; - break; - case RID_IS_STD_LAYOUT: - kind = CPTK_IS_STD_LAYOUT; - break; - case RID_IS_TRIVIAL: - kind = CPTK_IS_TRIVIAL; - break; - case RID_IS_TRIVIALLY_ASSIGNABLE: - kind = CPTK_IS_TRIVIALLY_ASSIGNABLE; - binary = true; - break; - case RID_IS_TRIVIALLY_CONSTRUCTIBLE: - kind = CPTK_IS_TRIVIALLY_CONSTRUCTIBLE; - variadic = true; - break; - case RID_IS_TRIVIALLY_COPYABLE: - kind = CPTK_IS_TRIVIALLY_COPYABLE; - break; - case RID_IS_UNION: - kind = CPTK_IS_UNION; - break; - case RID_UNDERLYING_TYPE: - kind = CPTK_UNDERLYING_TYPE; - break; - case RID_BASES: - kind = CPTK_BASES; - break; - case RID_DIRECT_BASES: - kind = CPTK_DIRECT_BASES; - break; - case RID_IS_ASSIGNABLE: - kind = CPTK_IS_ASSIGNABLE; - binary = true; - break; - case RID_IS_CONSTRUCTIBLE: - kind = CPTK_IS_CONSTRUCTIBLE; - variadic = true; - break; - case RID_IS_NOTHROW_ASSIGNABLE: - kind = CPTK_IS_NOTHROW_ASSIGNABLE; - binary = true; - break; - case RID_IS_NOTHROW_CONSTRUCTIBLE: - kind = CPTK_IS_NOTHROW_CONSTRUCTIBLE; - variadic = true; - break; - case RID_IS_CONVERTIBLE: - kind = CPTK_IS_CONVERTIBLE; - binary = true; - break; - case RID_IS_NOTHROW_CONVERTIBLE: - kind = CPTK_IS_NOTHROW_CONVERTIBLE; - binary = true; - break; - case RID_REF_CONSTRUCTS_FROM_TEMPORARY: - kind = CPTK_REF_CONSTRUCTS_FROM_TEMPORARY; - binary = true; - break; - case RID_REF_CONVERTS_FROM_TEMPORARY: - kind = CPTK_REF_CONVERTS_FROM_TEMPORARY; - binary = true; +#define DEFTRAIT(TCC, CODE, NAME, ARITY) \ + case RID_##CODE: \ + kind = CPTK_##CODE; \ + binary = (ARITY == 2); \ + variadic = (ARITY == -1); \ + type = (TCC == tcc_type); \ break; +#include "cp-trait.def" +#undef DEFTRAIT default: gcc_unreachable (); } @@ -11092,14 +10941,15 @@ cp_parser_trait_expr (cp_parser* parser, enum rid keyword) the trait expr now or saving it for template instantiation. */ switch (kind) { - case CPTK_UNDERLYING_TYPE: - return cp_expr (finish_underlying_type (type1), trait_loc); case CPTK_BASES: return cp_expr (finish_bases (type1, false), trait_loc); case CPTK_DIRECT_BASES: return cp_expr (finish_bases (type1, true), trait_loc); default: - return finish_trait_expr (trait_loc, kind, type1, type2); + if (type) + return finish_trait_type (kind, type1, type2); + else + return finish_trait_expr (trait_loc, kind, type1, type2); } } @@ -19866,8 +19716,11 @@ cp_parser_simple_type_specifier (cp_parser* parser, return type; - case RID_UNDERLYING_TYPE: - type = cp_parser_trait_expr (parser, RID_UNDERLYING_TYPE); +#define DEFTRAIT_TYPE(CODE, NAME, ARITY) \ + case RID_##CODE: +#include "cp-trait.def" +#undef DEFTRAIT_TYPE + type = cp_parser_trait (parser, token->keyword); if (decl_specs) cp_parser_set_decl_spec_type (decl_specs, type, token, @@ -19875,14 +19728,6 @@ cp_parser_simple_type_specifier (cp_parser* parser, return type; - case RID_BASES: - case RID_DIRECT_BASES: - type = cp_parser_trait_expr (parser, token->keyword); - if (decl_specs) - cp_parser_set_decl_spec_type (decl_specs, type, - token, - /*type_definition_p=*/false); - return type; default: break; } @@ -40297,8 +40142,8 @@ cp_parser_omp_clause_device_type (cp_parser *parser, tree list, goto resync_fail; c = build_omp_clause (location, OMP_CLAUSE_DEVICE_TYPE); - /* check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE, "device_type", - location); */ + check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE, "device_type", + location); OMP_CLAUSE_DEVICE_TYPE_KIND (c) = kind; OMP_CLAUSE_CHAIN (c) = list; return c; @@ -40822,7 +40667,7 @@ cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask, break; case PRAGMA_OMP_CLAUSE_LINK: clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_LINK, clauses); - c_name = "to"; + c_name = "link"; break; case PRAGMA_OMP_CLAUSE_TO: if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)) != 0) @@ -46719,8 +46564,8 @@ cp_parser_omp_declare_target (cp_parser *parser, cp_token *pragma_tok) } else { - struct omp_declare_target_attr a - = { parser->lexer->in_omp_attribute_pragma }; + cp_omp_declare_target_attr a + = { parser->lexer->in_omp_attribute_pragma, -1 }; vec_safe_push (scope_chain->omp_declare_target_attribute, a); cp_parser_require_pragma_eol (parser, pragma_tok); return; @@ -46745,12 +46590,17 @@ cp_parser_omp_declare_target (cp_parser *parser, cp_token *pragma_tok) device_type); } if (device_type && only_device_type) - warning_at (OMP_CLAUSE_LOCATION (clauses), 0, - "directive with only %<device_type%> clauses ignored"); + error_at (OMP_CLAUSE_LOCATION (clauses), + "directive with only %<device_type%> clause"); } /* OpenMP 5.1 - #pragma omp begin assumes clauses[optseq] new-line */ + # pragma omp begin assumes clauses[optseq] new-line + + # pragma omp begin declare target clauses[optseq] new-line */ + +#define OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK \ + (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE) static void cp_parser_omp_begin (cp_parser *parser, cp_token *pragma_tok) @@ -46762,16 +46612,47 @@ cp_parser_omp_begin (cp_parser *parser, cp_token *pragma_tok) tree id = cp_lexer_peek_token (parser->lexer)->u.value; p = IDENTIFIER_POINTER (id); } - if (strcmp (p, "assumes") == 0) + if (strcmp (p, "declare") == 0) + { + cp_lexer_consume_token (parser->lexer); + p = ""; + if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)) + { + tree id = cp_lexer_peek_token (parser->lexer)->u.value; + p = IDENTIFIER_POINTER (id); + } + if (strcmp (p, "target") == 0) + { + cp_lexer_consume_token (parser->lexer); + tree clauses + = cp_parser_omp_all_clauses (parser, + OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK, + "#pragma omp begin declare target", + pragma_tok); + int device_type = 0; + for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c)) + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE) + device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c); + cp_omp_declare_target_attr a + = { in_omp_attribute_pragma, device_type }; + vec_safe_push (scope_chain->omp_declare_target_attribute, a); + } + else + { + cp_parser_error (parser, "expected %<target%>"); + cp_parser_skip_to_pragma_eol (parser, pragma_tok); + } + } + else if (strcmp (p, "assumes") == 0) { cp_lexer_consume_token (parser->lexer); cp_parser_omp_assumption_clauses (parser, pragma_tok, false); - struct omp_begin_assumes_data a = { in_omp_attribute_pragma }; + cp_omp_begin_assumes_data a = { in_omp_attribute_pragma }; vec_safe_push (scope_chain->omp_begin_assumes, a); } else { - cp_parser_error (parser, "expected %<assumes%>"); + cp_parser_error (parser, "expected %<declare target%> or %<assumes%>"); cp_parser_skip_to_pragma_eol (parser, pragma_tok); } } @@ -46813,21 +46694,28 @@ cp_parser_omp_end (cp_parser *parser, cp_token *pragma_tok) if (!vec_safe_length (scope_chain->omp_declare_target_attribute)) error_at (pragma_tok->location, "%<#pragma omp end declare target%> without corresponding " - "%<#pragma omp declare target%>"); + "%<#pragma omp declare target%> or " + "%<#pragma omp begin declare target%>"); else { - omp_declare_target_attr + cp_omp_declare_target_attr a = scope_chain->omp_declare_target_attribute->pop (); if (a.attr_syntax != in_omp_attribute_pragma) { if (a.attr_syntax) error_at (pragma_tok->location, - "%<declare target%> in attribute syntax terminated " - "with %<end declare target%> in pragma syntax"); + "%qs in attribute syntax terminated " + "with %qs in pragma syntax", + a.device_type >= 0 ? "begin declare target" + : "declare target", + "end declare target"); else error_at (pragma_tok->location, - "%<declare target%> in pragma syntax terminated " - "with %<end declare target%> in attribute syntax"); + "%qs in pragma syntax terminated " + "with %qs in attribute syntax", + a.device_type >= 0 ? "begin declare target" + : "declare target", + "end declare target"); } } } @@ -46837,22 +46725,24 @@ cp_parser_omp_end (cp_parser *parser, cp_token *pragma_tok) cp_parser_require_pragma_eol (parser, pragma_tok); if (!vec_safe_length (scope_chain->omp_begin_assumes)) error_at (pragma_tok->location, - "%<#pragma omp end assumes%> without corresponding " - "%<#pragma omp begin assumes%>"); + "%qs without corresponding %qs", + "#pragma omp end assumes", "#pragma omp begin assumes"); else { - omp_begin_assumes_data + cp_omp_begin_assumes_data a = scope_chain->omp_begin_assumes->pop (); if (a.attr_syntax != in_omp_attribute_pragma) { if (a.attr_syntax) error_at (pragma_tok->location, - "%<begin assumes%> in attribute syntax terminated " - "with %<end assumes%> in pragma syntax"); + "%qs in attribute syntax terminated " + "with %qs in pragma syntax", + "begin assumes", "end assumes"); else error_at (pragma_tok->location, - "%<begin assumes%> in pragma syntax terminated " - "with %<end assumes%> in attribute syntax"); + "%qs in pragma syntax terminated " + "with %qs in attribute syntax", + "begin assumes", "end assumes"); } } } diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index c7adaef..bce2a77 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -10617,7 +10617,6 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d) case TYPEOF_TYPE: case DECLTYPE_TYPE: - case UNDERLYING_TYPE: if (pfd->include_nondeduced_p && for_each_template_parm (TYPE_VALUES_RAW (t), fn, data, pfd->visited, @@ -10627,6 +10626,15 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d) *walk_subtrees = false; break; + case TRAIT_TYPE: + if (pfd->include_nondeduced_p) + { + WALK_SUBTREE (TRAIT_TYPE_TYPE1 (t)); + WALK_SUBTREE (TRAIT_TYPE_TYPE2 (t)); + } + *walk_subtrees = false; + break; + case FUNCTION_DECL: case VAR_DECL: if (DECL_LANG_SPECIFIC (t) && DECL_TEMPLATE_INFO (t)) @@ -16513,11 +16521,14 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) complain | tf_ignore_bad_quals); } - case UNDERLYING_TYPE: + case TRAIT_TYPE: { - tree type = tsubst (UNDERLYING_TYPE_TYPE (t), args, - complain, in_decl); - return finish_underlying_type (type); + tree type1 = tsubst (TRAIT_TYPE_TYPE1 (t), args, complain, in_decl); + tree type2 = tsubst (TRAIT_TYPE_TYPE2 (t), args, complain, in_decl); + type = finish_trait_type (TRAIT_TYPE_KIND (t), type1, type2); + return cp_build_qualified_type (type, + cp_type_quals (t) | cp_type_quals (type), + complain | tf_ignore_bad_quals); } case TYPE_ARGUMENT_PACK: @@ -24927,9 +24938,9 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict, case TYPEOF_TYPE: case DECLTYPE_TYPE: - case UNDERLYING_TYPE: + case TRAIT_TYPE: /* Cannot deduce anything from TYPEOF_TYPE, DECLTYPE_TYPE, - or UNDERLYING_TYPE nodes. */ + or TRAIT_TYPE nodes. */ return unify_success (explain_p); case ERROR_MARK: @@ -27504,12 +27515,12 @@ dependent_type_p_r (tree type) (INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (type))))) return true; - /* All TYPEOF_TYPEs, DECLTYPE_TYPEs, and UNDERLYING_TYPEs are + /* All TYPEOF_TYPEs, DECLTYPE_TYPEs, and TRAIT_TYPEs are dependent; if the argument of the `typeof' expression is not type-dependent, then it should already been have resolved. */ if (TREE_CODE (type) == TYPEOF_TYPE || TREE_CODE (type) == DECLTYPE_TYPE - || TREE_CODE (type) == UNDERLYING_TYPE) + || TREE_CODE (type) == TRAIT_TYPE) return true; /* A template argument pack is dependent if any of its packed @@ -29150,9 +29161,10 @@ finish_concept_definition (cp_expr id, tree init) static tree listify (tree arg) { - tree std_init_list = get_namespace_binding (std_node, init_list_identifier); + tree std_init_list = lookup_qualified_name (std_node, init_list_identifier); - if (!std_init_list || !DECL_CLASS_TEMPLATE_P (std_init_list)) + if (std_init_list == error_mark_node + || !DECL_CLASS_TEMPLATE_P (std_init_list)) { gcc_rich_location richloc (input_location); maybe_add_include_fixit (&richloc, "<initializer_list>", false); @@ -30017,7 +30029,7 @@ alias_ctad_tweaks (tree tmpl, tree uguides) /* FIXME this should mean they don't compare as equivalent. */ || dependent_alias_template_spec_p (atype, nt_opaque)) { - tree same = finish_trait_expr (loc, CPTK_IS_SAME_AS, atype, ret); + tree same = finish_trait_expr (loc, CPTK_IS_SAME, atype, ret); ci = append_constraint (ci, same); } diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index e8cd505..30cf2f9 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -1761,6 +1761,8 @@ begin_compound_stmt (unsigned int flags) sk = sk_try; else if (flags & BCS_TRANSACTION) sk = sk_transaction; + else if (flags & BCS_STMT_EXPR) + sk = sk_stmt_expr; r = do_pushlevel (sk); } @@ -3358,16 +3360,20 @@ finish_translation_unit (void) if (vec_safe_length (scope_chain->omp_declare_target_attribute)) { + cp_omp_declare_target_attr + a = scope_chain->omp_declare_target_attribute->pop (); if (!errorcount) - error ("%<#pragma omp declare target%> without corresponding " - "%<#pragma omp end declare target%>"); + error ("%qs without corresponding %qs", + a.device_type >= 0 ? "#pragma omp begin declare target" + : "#pragma omp declare target", + "#pragma omp end declare target"); vec_safe_truncate (scope_chain->omp_declare_target_attribute, 0); } if (vec_safe_length (scope_chain->omp_begin_assumes)) { if (!errorcount) - error ("%<#pragma omp begin assumes%> without corresponding " - "%<#pragma omp end assumes%>"); + error ("%qs without corresponding %qs", + "#pragma omp begin assumes", "#pragma omp end assumes"); vec_safe_truncate (scope_chain->omp_begin_assumes, 0); } } @@ -4397,17 +4403,6 @@ finish_typeof (tree expr) tree finish_underlying_type (tree type) { - tree underlying_type; - - if (processing_template_decl) - { - underlying_type = cxx_make_type (UNDERLYING_TYPE); - UNDERLYING_TYPE_TYPE (underlying_type) = type; - SET_TYPE_STRUCTURAL_EQUALITY (underlying_type); - - return underlying_type; - } - if (!complete_type_or_else (type, NULL_TREE)) return error_mark_node; @@ -4417,7 +4412,7 @@ finish_underlying_type (tree type) return error_mark_node; } - underlying_type = ENUM_UNDERLYING_TYPE (type); + tree underlying_type = ENUM_UNDERLYING_TYPE (type); /* Fixup necessary in this case because ENUM_UNDERLYING_TYPE includes TYPE_MIN_VALUE and TYPE_MAX_VALUE information. @@ -12018,7 +12013,7 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2) case CPTK_IS_POLYMORPHIC: return CLASS_TYPE_P (type1) && TYPE_POLYMORPHIC_P (type1); - case CPTK_IS_SAME_AS: + case CPTK_IS_SAME: return same_type_p (type1, type2); case CPTK_IS_STD_LAYOUT: @@ -12063,10 +12058,15 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2) case CPTK_REF_CONVERTS_FROM_TEMPORARY: return ref_xes_from_temporary (type1, type2, /*direct_init=*/false); - default: - gcc_unreachable (); - return false; +#define DEFTRAIT_TYPE(CODE, NAME, ARITY) \ + case CPTK_##CODE: +#include "cp-trait.def" +#undef DEFTRAIT_TYPE + /* Type-yielding traits are handled in finish_trait_type. */ + break; } + + gcc_unreachable (); } /* Returns true if TYPE meets the requirements for the specified KIND, @@ -12199,7 +12199,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2) case CPTK_IS_CLASS: case CPTK_IS_ENUM: case CPTK_IS_UNION: - case CPTK_IS_SAME_AS: + case CPTK_IS_SAME: break; case CPTK_IS_LAYOUT_COMPATIBLE: @@ -12215,7 +12215,11 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2) return error_mark_node; break; - default: +#define DEFTRAIT_TYPE(CODE, NAME, ARITY) \ + case CPTK_##CODE: +#include "cp-trait.def" +#undef DEFTRAIT_TYPE + /* Type-yielding traits are handled in finish_trait_type. */ gcc_unreachable (); } @@ -12224,6 +12228,58 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2) return maybe_wrap_with_location (val, loc); } +/* Process a trait type. */ + +tree +finish_trait_type (cp_trait_kind kind, tree type1, tree type2) +{ + if (type1 == error_mark_node + || type2 == error_mark_node) + return error_mark_node; + + if (processing_template_decl) + { + tree type = cxx_make_type (TRAIT_TYPE); + TRAIT_TYPE_TYPE1 (type) = type1; + TRAIT_TYPE_TYPE2 (type) = type2; + TRAIT_TYPE_KIND_RAW (type) = build_int_cstu (integer_type_node, kind); + /* These traits are intended to be used in the definition of the ::type + member of the corresponding standard library type trait and aren't + mangleable (and thus won't appear directly in template signatures), + so structural equality should suffice. */ + SET_TYPE_STRUCTURAL_EQUALITY (type); + return type; + } + + switch (kind) + { + case CPTK_UNDERLYING_TYPE: + return finish_underlying_type (type1); + case CPTK_REMOVE_CV: + return cv_unqualified (type1); + case CPTK_REMOVE_REFERENCE: + if (TYPE_REF_P (type1)) + type1 = TREE_TYPE (type1); + return type1; + case CPTK_REMOVE_CVREF: + if (TYPE_REF_P (type1)) + type1 = TREE_TYPE (type1); + return cv_unqualified (type1); + +#define DEFTRAIT_EXPR(CODE, NAME, ARITY) \ + case CPTK_##CODE: +#include "cp-trait.def" +#undef DEFTRAIT_EXPR + /* Expression-yielding traits are handled in finish_trait_expr. */ + case CPTK_BASES: + case CPTK_DIRECT_BASES: + /* BASES and DIRECT_BASES are handled in finish_bases. */ + break; + } + + gcc_unreachable (); +} + /* Do-nothing variants of functions to handle pragma FLOAT_CONST_DECIMAL64, which is ignored for C++. */ diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc index ea4dfc6..aa9c1b7 100644 --- a/gcc/cp/tree.cc +++ b/gcc/cp/tree.cc @@ -1776,10 +1776,17 @@ strip_typedefs (tree t, bool *remove_attributes /* = NULL */, DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t), tf_none)); break; - case UNDERLYING_TYPE: - type = strip_typedefs (UNDERLYING_TYPE_TYPE (t), - remove_attributes, flags); - result = finish_underlying_type (type); + case TRAIT_TYPE: + { + tree type1 = strip_typedefs (TRAIT_TYPE_TYPE1 (t), + remove_attributes, flags); + tree type2 = strip_typedefs (TRAIT_TYPE_TYPE2 (t), + remove_attributes, flags); + if (type1 == TRAIT_TYPE_TYPE1 (t) && type2 == TRAIT_TYPE_TYPE2 (t)) + result = NULL_TREE; + else + result = finish_trait_type (TRAIT_TYPE_KIND (t), type1, type2); + } break; case TYPE_PACK_EXPANSION: { @@ -5383,7 +5390,6 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func, case UNBOUND_CLASS_TEMPLATE: case TEMPLATE_PARM_INDEX: case TYPEOF_TYPE: - case UNDERLYING_TYPE: /* None of these have subtrees other than those already walked above. */ *walk_subtrees_p = 0; @@ -5472,6 +5478,12 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func, *walk_subtrees_p = 0; break; + case TRAIT_TYPE: + WALK_SUBTREE (TRAIT_TYPE_TYPE1 (*tp)); + WALK_SUBTREE (TRAIT_TYPE_TYPE2 (*tp)); + *walk_subtrees_p = 0; + break; + case DECLTYPE_TYPE: ++cp_unevaluated_operand; /* We can't use WALK_SUBTREE here because of the goto. */ diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc index 5f16c4d..cecf825 100644 --- a/gcc/cp/typeck.cc +++ b/gcc/cp/typeck.cc @@ -1621,8 +1621,11 @@ structural_comptypes (tree t1, tree t2, int strict) return false; break; - case UNDERLYING_TYPE: - if (!same_type_p (UNDERLYING_TYPE_TYPE (t1), UNDERLYING_TYPE_TYPE (t2))) + case TRAIT_TYPE: + if (TRAIT_TYPE_KIND (t1) != TRAIT_TYPE_KIND (t2)) + return false; + if (!same_type_p (TRAIT_TYPE_TYPE1 (t1), TRAIT_TYPE_TYPE1 (t2)) + || !cp_tree_equal (TRAIT_TYPE_TYPE2 (t1), TRAIT_TYPE_TYPE2 (t2))) return false; break; diff --git a/gcc/cppdefault.cc b/gcc/cppdefault.cc index 7888300..7d8f9a5 100644 --- a/gcc/cppdefault.cc +++ b/gcc/cppdefault.cc @@ -74,6 +74,9 @@ const struct default_include cpp_include_defaults[] #endif #ifdef FIXED_INCLUDE_DIR /* This is the dir for fixincludes. */ +#ifndef SYSROOT_HEADERS_SUFFIX_SPEC + { FIXED_INCLUDE_DIR, "GCC", 0, 0, 0, 2 }, +#endif { FIXED_INCLUDE_DIR, "GCC", 0, 0, 0, /* A multilib suffix needs adding if different multilibs use different headers. */ diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi index a0792fe..112f83d 100644 --- a/gcc/doc/install.texi +++ b/gcc/doc/install.texi @@ -3525,16 +3525,28 @@ information have to. @item @uref{#alpha-x-x,,alpha*-*-*} @item +@uref{#amdgcn-x-amdhsa,,amdgcn-*-amdhsa} +@item @uref{#amd64-x-solaris2,,amd64-*-solaris2*} @item +@uref{#arc-x-elf32,,arc-*-elf32} +@item +@uref{#arc-linux-uclibc,,arc-linux-uclibc} +@item @uref{#arm-x-eabi,,arm-*-eabi} @item @uref{#avr,,avr} @item @uref{#bfin,,Blackfin} @item +@uref{#cris,,cris} +@item @uref{#dos,,DOS} @item +@uref{#epiphany-x-elf,,epiphany-*-elf} +@item +@uref{#ft32-x-elf,,ft32-*-elf} +@item @uref{#x-x-freebsd,,*-*-freebsd*} @item @uref{#h8300-hms,,h8300-hms} @@ -3559,6 +3571,8 @@ information have to. @item @uref{#iq2000-x-elf,,iq2000-*-elf} @item +@uref{#loongarch,,loongarch} +@item @uref{#lm32-x-elf,,lm32-*-elf} @item @uref{#lm32-x-uclinux,,lm32-*-uclinux} @@ -3569,12 +3583,16 @@ information have to. @item @uref{#m68k-x-x,,m68k-*-*} @item -@uref{#m68k-uclinux,,m68k-uclinux} +@uref{#m68k-x-uclinux,,m68k-*-uclinux} @item @uref{#microblaze-x-elf,,microblaze-*-elf} @item @uref{#mips-x-x,,mips-*-*} @item +@uref{#moxie-x-elf,,moxie-*-elf} +@item +@uref{#msp430-x-elf,,msp430-*-elf} +@item @uref{#nds32le-x-elf,,nds32le-*-elf} @item @uref{#nds32be-x-elf,,nds32be-*-elf} @@ -3613,6 +3631,10 @@ information have to. @item @uref{#riscv64-x-linux,,riscv64-*-linux} @item +@uref{#rl78-x-elf,,rl78-*-elf} +@item +@uref{#rx-x-elf,,rx-*-elf} +@item @uref{#s390-x-linux,,s390-*-linux*} @item @uref{#s390x-x-linux,,s390x-*-linux*} @@ -3727,14 +3749,14 @@ This is a synonym for @samp{x86_64-*-solaris2*}. @heading amdgcn-*-amdhsa AMD GCN GPU target. -Instead of GNU Binutils, you will need to install LLVM 6, or later, and copy +Instead of GNU Binutils, you will need to install LLVM 13.0.1, or later, and copy @file{bin/llvm-mc} to @file{amdgcn-amdhsa/bin/as}, @file{bin/lld} to @file{amdgcn-amdhsa/bin/ld}, @file{bin/llvm-nm} to @file{amdgcn-amdhsa/bin/nm}, and @file{bin/llvm-ar} to both @file{bin/amdgcn-amdhsa-ar} and @file{bin/amdgcn-amdhsa-ranlib}. -Use Newlib (2019-01-16, or newer). +Use Newlib (3.2.0, or newer). To run the binaries, install the HSA Runtime from the @uref{https://rocm.github.io,,ROCm Platform}, and use @@ -4551,8 +4573,7 @@ Instead of GNU binutils, you will need to install Tell GCC where to find it: @option{--with-build-time-tools=[install-nvptx-tools]/nvptx-none/bin}. -You will need newlib 3.0 git revision -cd31fbb2aea25f94d7ecedc9db16dfc87ab0c316 or later. It can be +You will need newlib 3.1.0 or later. It can be automatically built together with GCC@. For this, add a symbolic link to nvptx-newlib's @file{newlib} directory to the directory containing the GCC sources. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index d39dd82..cc9754b 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -1188,6 +1188,7 @@ See RS/6000 and PowerPC Options. -mbig-endian -mlittle-endian @gol -mstack-protector-guard=@var{guard} -mstack-protector-guard-reg=@var{reg} @gol -mstack-protector-guard-offset=@var{offset}} +-mcsr-check -mno-csr-check @gol @emph{RL78 Options} @gccoptlist{-msim -mmul=none -mmul=g13 -mmul=g14 -mallregs @gol @@ -16846,9 +16847,13 @@ the area size or to remove it completely on a single function. If @code{N=0}, no pad location is recorded. The NOP instructions are inserted at---and maybe before, depending on -@var{M}---the function entry address, even before the prologue. +@var{M}---the function entry address, even before the prologue. On +PowerPC with the ELFv2 ABI, for a function with dual entry points, +the local entry point is this function entry address. -The maximum value of @var{N} and @var{M} is 65535. +The maximum value of @var{N} and @var{M} is 65535. On PowerPC with the +ELFv2 ABI, for a function with dual entry points, the supported values +for @var{M} are 0, 2, 6 and 14. @end table @@ -28559,6 +28564,11 @@ linker relaxations. Emit (do not emit) RISC-V attribute to record extra information into ELF objects. This feature requires at least binutils 2.32. +@item -mcsr-check +@itemx -mno-csr-check +@opindex mcsr-check +Enables or disables the CSR checking. + @item -malign-data=@var{type} @opindex malign-data Control how GCC aligns variables and constants of array, structure, or union diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index d46963f..bb42ee1 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -4950,9 +4950,10 @@ This pattern is not allowed to @code{FAIL}. @cindex @code{while_ult@var{m}@var{n}} instruction pattern @item @code{while_ult@var{m}@var{n}} Set operand 0 to a mask that is true while incrementing operand 1 -gives a value that is less than operand 2. Operand 0 has mode @var{n} -and operands 1 and 2 are scalar integers of mode @var{m}. -The operation is equivalent to: +gives a value that is less than operand 2, for a vector length up to operand 3. +Operand 0 has mode @var{n} and operands 1 and 2 are scalar integers of mode +@var{m}. Operand 3 should be omitted when @var{n} is a vector mode, and +a @code{CONST_INT} otherwise. The operation for vector modes is equivalent to: @smallexample operand0[0] = operand1 < operand2; @@ -4960,6 +4961,14 @@ for (i = 1; i < GET_MODE_NUNITS (@var{n}); i++) operand0[i] = operand0[i - 1] && (operand1 + i < operand2); @end smallexample +And for non-vector modes the operation is equivalent to: + +@smallexample +operand0[0] = operand1 < operand2; +for (i = 1; i < operand3; i++) + operand0[i] = operand0[i - 1] && (operand1 + i < operand2); +@end smallexample + @cindex @code{check_raw_ptrs@var{m}} instruction pattern @item @samp{check_raw_ptrs@var{m}} Check whether, given two pointers @var{a} and @var{b} and a length @var{len}, diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi index 52357cc..c81e2ff 100644 --- a/gcc/doc/sourcebuild.texi +++ b/gcc/doc/sourcebuild.texi @@ -2868,6 +2868,9 @@ Vector alignment is reachable for types of 32 bits or less. @item vector_alignment_reachable_for_64bit Vector alignment is reachable for types of 64 bits or less. +@item vma_equals_lma +Target generates executable with VMA equal to LMA for .data section. + @item wchar_t_char16_t_compatible Target supports @code{wchar_t} that is compatible with @code{char16_t}. diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index ff484b6..4f4f090 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -1035,7 +1035,7 @@ of the excess precision explicitly added. For @code{EXCESS_PRECISION_TYPE_FLOAT16}, and @code{EXCESS_PRECISION_TYPE_FAST}, the target should return the explicit excess precision that should be added depending on the -value set for @option{-fexcess-precision=@r{[}standard@r{|}fast@r{]}}. +value set for @option{-fexcess-precision=@r{[}standard@r{|}fast@r{|}16@r{]}}. Note that unpredictable explicit excess precision does not make sense, so a target should never return @code{FLT_EVAL_METHOD_UNPREDICTABLE} when @var{type} is @code{EXCESS_PRECISION_TYPE_STANDARD}, diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc index 2df7590..e81044b 100644 --- a/gcc/dwarf2out.cc +++ b/gcc/dwarf2out.cc @@ -24783,7 +24783,8 @@ add_call_src_coords_attributes (tree stmt, dw_die_ref die) if (RESERVED_LOCATION_P (BLOCK_SOURCE_LOCATION (stmt))) return; - expanded_location s = expand_location (BLOCK_SOURCE_LOCATION (stmt)); + location_t locus = BLOCK_SOURCE_LOCATION (stmt); + expanded_location s = expand_location (locus); if (dwarf_version >= 3 || !dwarf_strict) { @@ -24791,6 +24792,9 @@ add_call_src_coords_attributes (tree stmt, dw_die_ref die) add_AT_unsigned (die, DW_AT_call_line, s.line); if (debug_column_info && s.column) add_AT_unsigned (die, DW_AT_call_column, s.column); + unsigned discr = get_discriminator_from_loc (locus); + if (discr != 0) + add_AT_unsigned (die, DW_AT_GNU_discriminator, discr); } } diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index dcbfd54..0559fc3 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,22 @@ +2022-10-01 José Rui Faustino de Sousa <jrfsousa@gmail.com> + + PR fortran/100040 + PR fortran/100029 + * trans-expr.cc (gfc_conv_class_to_class): Add code to have + assumed-rank arrays recognized as full arrays and fix the type + of the array assignment. + (gfc_conv_procedure_call): Change order of code blocks such that + the free of ALLOCATABLE dummy arguments with INTENT(OUT) occurs + first. + +2022-09-30 Tobias Burnus <tobias@codesourcery.com> + + PR fortran/105318 + * openmp.cc (resolve_omp_clauses): Update is_device_ptr restrictions + for OpenMP 5.1 and map to has_device_addr where applicable; map + use_device_ptr to use_device_addr where applicable. + Silence integer-range warning for device(omp_{initial,invalid}_device). + 2022-09-27 Harald Anlauf <anlauf@gmx.de> PR fortran/107054 diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc index 457e983..ce719bd 100644 --- a/gcc/fortran/openmp.cc +++ b/gcc/fortran/openmp.cc @@ -6511,7 +6511,7 @@ static void resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses, gfc_namespace *ns, bool openacc = false) { - gfc_omp_namelist *n; + gfc_omp_namelist *n, *last; gfc_expr_list *el; int list; int ifc; @@ -7369,30 +7369,58 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses, } break; case OMP_LIST_IS_DEVICE_PTR: - for (n = omp_clauses->lists[list]; n != NULL; n = n->next) + last = NULL; + for (n = omp_clauses->lists[list]; n != NULL; ) { - if (!n->sym->attr.dummy) - gfc_error ("Non-dummy object %qs in %s clause at %L", - n->sym->name, name, &n->where); - if (n->sym->attr.allocatable - || (n->sym->ts.type == BT_CLASS - && CLASS_DATA (n->sym)->attr.allocatable)) - gfc_error ("ALLOCATABLE object %qs in %s clause at %L", - n->sym->name, name, &n->where); - if (n->sym->attr.pointer - || (n->sym->ts.type == BT_CLASS - && CLASS_DATA (n->sym)->attr.pointer)) - gfc_error ("POINTER object %qs in %s clause at %L", - n->sym->name, name, &n->where); - if (n->sym->attr.value) - gfc_error ("VALUE object %qs in %s clause at %L", - n->sym->name, name, &n->where); + if (n->sym->ts.type == BT_DERIVED + && n->sym->ts.u.derived->ts.is_iso_c + && code->op != EXEC_OMP_TARGET) + /* Non-TARGET (i.e. DISPATCH) requires a C_PTR. */ + gfc_error ("List item %qs in %s clause at %L must be of " + "TYPE(C_PTR)", n->sym->name, name, &n->where); + else if (n->sym->ts.type != BT_DERIVED + || !n->sym->ts.u.derived->ts.is_iso_c) + { + /* For TARGET, non-C_PTR are deprecated and handled as + has_device_addr. */ + gfc_omp_namelist *n2 = n; + n = n->next; + if (last) + last->next = n; + else + omp_clauses->lists[list] = n; + n2->next = omp_clauses->lists[OMP_LIST_HAS_DEVICE_ADDR]; + omp_clauses->lists[OMP_LIST_HAS_DEVICE_ADDR] = n2; + continue; + } + last = n; + n = n->next; } break; case OMP_LIST_HAS_DEVICE_ADDR: - case OMP_LIST_USE_DEVICE_PTR: case OMP_LIST_USE_DEVICE_ADDR: - /* FIXME: Handle OMP_LIST_USE_DEVICE_PTR. */ + break; + case OMP_LIST_USE_DEVICE_PTR: + /* Non-C_PTR are deprecated and handled as use_device_ADDR. */ + last = NULL; + for (n = omp_clauses->lists[list]; n != NULL; ) + { + gfc_omp_namelist *n2 = n; + if (n->sym->ts.type != BT_DERIVED + || !n->sym->ts.u.derived->ts.is_iso_c) + { + n = n->next; + if (last) + last->next = n; + else + omp_clauses->lists[list] = n; + n2->next = omp_clauses->lists[OMP_LIST_USE_DEVICE_ADDR]; + omp_clauses->lists[OMP_LIST_USE_DEVICE_ADDR] = n2; + continue; + } + last = n; + n = n->next; + } break; default: for (; n != NULL; n = n->next) @@ -7758,7 +7786,7 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses, &omp_clauses->num_teams_lower->where, &omp_clauses->num_teams_upper->where); if (omp_clauses->device) - resolve_nonnegative_int_expr (omp_clauses->device, "DEVICE"); + resolve_scalar_int_expr (omp_clauses->device, "DEVICE"); if (omp_clauses->filter) resolve_nonnegative_int_expr (omp_clauses->filter, "FILTER"); if (omp_clauses->hint) diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index 4f3ae82..1551a2e 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -1178,8 +1178,10 @@ gfc_conv_class_to_class (gfc_se *parmse, gfc_expr *e, gfc_typespec class_ts, return; /* Test for FULL_ARRAY. */ - if (e->rank == 0 && gfc_expr_attr (e).codimension - && gfc_expr_attr (e).dimension) + if (e->rank == 0 + && ((gfc_expr_attr (e).codimension && gfc_expr_attr (e).dimension) + || (class_ts.u.derived->components->as + && class_ts.u.derived->components->as->type == AS_ASSUMED_RANK))) full_array = true; else gfc_is_class_array_ref (e, &full_array); @@ -1227,8 +1229,12 @@ gfc_conv_class_to_class (gfc_se *parmse, gfc_expr *e, gfc_typespec class_ts, && e->rank != class_ts.u.derived->components->as->rank) { if (e->rank == 0) - gfc_add_modify (&parmse->post, gfc_class_data_get (parmse->expr), - gfc_conv_descriptor_data_get (ctree)); + { + tmp = gfc_class_data_get (parmse->expr); + gfc_add_modify (&parmse->post, tmp, + fold_convert (TREE_TYPE (tmp), + gfc_conv_descriptor_data_get (ctree))); + } else class_array_data_assign (&parmse->post, parmse->expr, ctree, true); } @@ -6560,23 +6566,6 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, base_object = build_fold_indirect_ref_loc (input_location, parmse.expr); - /* A class array element needs converting back to be a - class object, if the formal argument is a class object. */ - if (fsym && fsym->ts.type == BT_CLASS - && e->ts.type == BT_CLASS - && ((CLASS_DATA (fsym)->as - && CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK) - || CLASS_DATA (e)->attr.dimension)) - gfc_conv_class_to_class (&parmse, e, fsym->ts, false, - fsym->attr.intent != INTENT_IN - && (CLASS_DATA (fsym)->attr.class_pointer - || CLASS_DATA (fsym)->attr.allocatable), - fsym->attr.optional - && e->expr_type == EXPR_VARIABLE - && e->symtree->n.sym->attr.optional, - CLASS_DATA (fsym)->attr.class_pointer - || CLASS_DATA (fsym)->attr.allocatable); - /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is allocated on entry, it must be deallocated. */ if (fsym && fsym->attr.intent == INTENT_OUT @@ -6637,6 +6626,23 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, gfc_add_expr_to_block (&se->pre, tmp); } + /* A class array element needs converting back to be a + class object, if the formal argument is a class object. */ + if (fsym && fsym->ts.type == BT_CLASS + && e->ts.type == BT_CLASS + && ((CLASS_DATA (fsym)->as + && CLASS_DATA (fsym)->as->type == AS_ASSUMED_RANK) + || CLASS_DATA (e)->attr.dimension)) + gfc_conv_class_to_class (&parmse, e, fsym->ts, false, + fsym->attr.intent != INTENT_IN + && (CLASS_DATA (fsym)->attr.class_pointer + || CLASS_DATA (fsym)->attr.allocatable), + fsym->attr.optional + && e->expr_type == EXPR_VARIABLE + && e->symtree->n.sym->attr.optional, + CLASS_DATA (fsym)->attr.class_pointer + || CLASS_DATA (fsym)->attr.allocatable); + if (fsym && (fsym->ts.type == BT_DERIVED || fsym->ts.type == BT_ASSUMED) && e->ts.type == BT_CLASS @@ -835,6 +835,14 @@ proper position among the other output files. */ #define LINK_COMPRESS_DEBUG_SPEC \ " %{gz|gz=zlib:" LD_COMPRESS_DEBUG_OPTION "=zlib}" \ " %{gz=none:" LD_COMPRESS_DEBUG_OPTION "=none}" \ + " %{gz*:%e-gz=zstd is not supported in this configuration} " \ + " %{gz=zlib-gnu:}" /* Ignore silently zlib-gnu option value. */ +#elif HAVE_LD_COMPRESS_DEBUG == 2 +/* ELF gABI style and ZSTD. */ +#define LINK_COMPRESS_DEBUG_SPEC \ + " %{gz|gz=zlib:" LD_COMPRESS_DEBUG_OPTION "=zlib}" \ + " %{gz=none:" LD_COMPRESS_DEBUG_OPTION "=none}" \ + " %{gz=zstd:" LD_COMPRESS_DEBUG_OPTION "=zstd}" \ " %{gz=zlib-gnu:}" /* Ignore silently zlib-gnu option value. */ #else #error Unknown value for HAVE_LD_COMPRESS_DEBUG. @@ -890,6 +898,13 @@ proper position among the other output files. */ " %{gz|gz=zlib:" AS_COMPRESS_DEBUG_OPTION "=zlib}" \ " %{gz=none:" AS_COMPRESS_DEBUG_OPTION "=none}" \ " %{gz=zlib-gnu:}" /* Ignore silently zlib-gnu option value. */ +#elif HAVE_AS_COMPRESS_DEBUG == 2 +/* ELF gABI style and ZSTD. */ +#define ASM_COMPRESS_DEBUG_SPEC \ + " %{gz|gz=zlib:" AS_COMPRESS_DEBUG_OPTION "=zlib}" \ + " %{gz=none:" AS_COMPRESS_DEBUG_OPTION "=none}" \ + " %{gz=zstd:" AS_COMPRESS_DEBUG_OPTION "=zstd}" \ + " %{gz=zlib-gnu:}" /* Ignore silently zlib-gnu option value. */ #else #error Unknown value for HAVE_AS_COMPRESS_DEBUG. #endif @@ -6400,6 +6415,18 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) if (*sysroot_hdrs_suffix_spec) info.append = concat (info.append, dir_separator_str, multilib_dir, NULL); + else if (multiarch_dir) + { + /* For multiarch, search include-fixed/<multiarch-dir> + before include-fixed. */ + info.append = concat (info.append, dir_separator_str, + multiarch_dir, NULL); + info.append_len = strlen (info.append); + for_each_path (&include_prefixes, false, info.append_len, + spec_path, &info); + + info.append = "include-fixed"; + } info.append_len = strlen (info.append); for_each_path (&include_prefixes, false, info.append_len, spec_path, &info); diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc index 40b2f2f..b37d03c 100644 --- a/gcc/gimple-range-gori.cc +++ b/gcc/gimple-range-gori.cc @@ -603,8 +603,10 @@ gori_compute::compute_operand_range_switch (vrange &r, gswitch *s, bool gori_compute::compute_operand_range (vrange &r, gimple *stmt, const vrange &lhs, tree name, - fur_source &src) + fur_source &src, value_relation *rel) { + value_relation vrel; + value_relation *vrel_ptr = rel; // If the lhs doesn't tell us anything, neither will unwinding further. if (lhs.varying_p ()) return false; @@ -625,11 +627,23 @@ gori_compute::compute_operand_range (vrange &r, gimple *stmt, tree op1 = gimple_range_ssa_p (handler.operand1 ()); tree op2 = gimple_range_ssa_p (handler.operand2 ()); + // If there is a relation, use it instead of any passed in. This will allow + // multiple relations to be processed in compound logicals. + if (op1 && op2) + { + relation_kind k = handler.op1_op2_relation (lhs); + if (k != VREL_VARYING) + { + vrel.set_relation (k, op1, op2); + vrel_ptr = &vrel; + } + } + // Handle end of lookup first. if (op1 == name) - return compute_operand1_range (r, handler, lhs, name, src); + return compute_operand1_range (r, handler, lhs, name, src, vrel_ptr); if (op2 == name) - return compute_operand2_range (r, handler, lhs, name, src); + return compute_operand2_range (r, handler, lhs, name, src, vrel_ptr); // NAME is not in this stmt, but one of the names in it ought to be // derived from it. @@ -672,11 +686,12 @@ gori_compute::compute_operand_range (vrange &r, gimple *stmt, } // Follow the appropriate operands now. else if (op1_in_chain && op2_in_chain) - res = compute_operand1_and_operand2_range (r, handler, lhs, name, src); + res = compute_operand1_and_operand2_range (r, handler, lhs, name, src, + vrel_ptr); else if (op1_in_chain) - res = compute_operand1_range (r, handler, lhs, name, src); + res = compute_operand1_range (r, handler, lhs, name, src, vrel_ptr); else if (op2_in_chain) - res = compute_operand2_range (r, handler, lhs, name, src); + res = compute_operand2_range (r, handler, lhs, name, src, vrel_ptr); else gcc_unreachable (); @@ -919,6 +934,115 @@ gori_compute::compute_logical_operands (vrange &true_range, vrange &false_range, src.get_operand (false_range, name); } + +// This routine will try to refine the ranges of OP1 and OP2 given a relation +// K between them. In order to perform this refinement, one of the operands +// must be in the definition chain of the other. The use is refined using +// op1/op2_range on the statement, and the defintion is then recalculated +// using the relation. + +bool +gori_compute::refine_using_relation (tree op1, vrange &op1_range, + tree op2, vrange &op2_range, + fur_source &src, relation_kind k) +{ + gcc_checking_assert (TREE_CODE (op1) == SSA_NAME); + gcc_checking_assert (TREE_CODE (op2) == SSA_NAME); + gcc_checking_assert (k != VREL_VARYING && k != VREL_UNDEFINED); + + bool change = false; + bool op1_def_p = in_chain_p (op2, op1); + if (!op1_def_p) + if (!in_chain_p (op1, op2)) + return false; + + tree def_op = op1_def_p ? op1 : op2; + tree use_op = op1_def_p ? op2 : op1; + + if (!op1_def_p) + k = relation_swap (k); + + // op1_def is true if we want to look up op1, otherwise we want op2. + // if neither is the case, we returned in the above check. + + gimple *def_stmt = SSA_NAME_DEF_STMT (def_op); + gimple_range_op_handler op_handler (def_stmt); + if (!op_handler) + return false; + tree def_op1 = op_handler.operand1 (); + tree def_op2 = op_handler.operand2 (); + // if the def isn't binary, the relation will not be useful. + if (!def_op2) + return false; + + // Determine if op2 is directly referenced as an operand. + if (def_op1 == use_op) + { + // def_stmt has op1 in the 1st operand position. + Value_Range other_op (TREE_TYPE (def_op2)); + src.get_operand (other_op, def_op2); + + // Using op1_range as the LHS, and relation REL, evaluate op2. + tree type = TREE_TYPE (def_op1); + Value_Range new_result (type); + if (!op_handler.op1_range (new_result, type, + op1_def_p ? op1_range : op2_range, + other_op, k)) + return false; + if (op1_def_p) + { + change |= op2_range.intersect (new_result); + // Recalculate op2. + if (op_handler.fold_range (new_result, type, op2_range, other_op)) + { + change |= op1_range.intersect (new_result); + } + } + else + { + change |= op1_range.intersect (new_result); + // Recalculate op1. + if (op_handler.fold_range (new_result, type, op1_range, other_op)) + { + change |= op2_range.intersect (new_result); + } + } + } + else if (def_op2 == use_op) + { + // def_stmt has op1 in the 1st operand position. + Value_Range other_op (TREE_TYPE (def_op1)); + src.get_operand (other_op, def_op1); + + // Using op1_range as the LHS, and relation REL, evaluate op2. + tree type = TREE_TYPE (def_op2); + Value_Range new_result (type); + if (!op_handler.op2_range (new_result, type, + op1_def_p ? op1_range : op2_range, + other_op, k)) + return false; + if (op1_def_p) + { + change |= op2_range.intersect (new_result); + // Recalculate op1. + if (op_handler.fold_range (new_result, type, other_op, op2_range)) + { + change |= op1_range.intersect (new_result); + } + } + else + { + change |= op1_range.intersect (new_result); + // Recalculate op2. + if (op_handler.fold_range (new_result, type, other_op, op1_range)) + { + change |= op2_range.intersect (new_result); + } + } + } + return change; +} + // Calculate a range for NAME from the operand 1 position of STMT // assuming the result of the statement is LHS. Return the range in // R, or false if no range could be calculated. @@ -927,11 +1051,12 @@ bool gori_compute::compute_operand1_range (vrange &r, gimple_range_op_handler &handler, const vrange &lhs, tree name, - fur_source &src) + fur_source &src, value_relation *rel) { gimple *stmt = handler.stmt (); tree op1 = handler.operand1 (); tree op2 = handler.operand2 (); + tree lhs_name = gimple_get_lhs (stmt); Value_Range op1_range (TREE_TYPE (op1)); Value_Range tmp (TREE_TYPE (op1)); @@ -944,7 +1069,21 @@ gori_compute::compute_operand1_range (vrange &r, if (op2) { src.get_operand (op2_range, op2); - if (!handler.calc_op1 (tmp, lhs, op2_range)) + relation_kind k = VREL_VARYING; + if (rel) + { + if (lhs_name == rel->op1 () && op1 == rel->op2 ()) + k = rel->kind (); + else if (lhs_name == rel->op2 () && op1 == rel->op1 ()) + k = relation_swap (rel->kind ()); + else if (op1 == rel->op1 () && op2 == rel->op2 ()) + refine_using_relation (op1, op1_range, op2, op2_range, src, + rel->kind ()); + else if (op1 == rel->op2 () && op2 == rel->op1 ()) + refine_using_relation (op1, op1_range, op2, op2_range, src, + relation_swap (rel->kind ())); + } + if (!handler.calc_op1 (tmp, lhs, op2_range, k)) return false; } else @@ -952,7 +1091,7 @@ gori_compute::compute_operand1_range (vrange &r, // We pass op1_range to the unary operation. Nomally it's a // hidden range_for_type parameter, but sometimes having the // actual range can result in better information. - if (!handler.calc_op1 (tmp, lhs, op1_range)) + if (!handler.calc_op1 (tmp, lhs, op1_range, VREL_VARYING)) return false; } @@ -998,7 +1137,7 @@ gori_compute::compute_operand1_range (vrange &r, gcc_checking_assert (src_stmt); // Then feed this range back as the LHS of the defining statement. - return compute_operand_range (r, src_stmt, op1_range, name, src); + return compute_operand_range (r, src_stmt, op1_range, name, src, rel); } @@ -1010,11 +1149,12 @@ bool gori_compute::compute_operand2_range (vrange &r, gimple_range_op_handler &handler, const vrange &lhs, tree name, - fur_source &src) + fur_source &src, value_relation *rel) { gimple *stmt = handler.stmt (); tree op1 = handler.operand1 (); tree op2 = handler.operand2 (); + tree lhs_name = gimple_get_lhs (stmt); Value_Range op1_range (TREE_TYPE (op1)); Value_Range op2_range (TREE_TYPE (op2)); @@ -1022,9 +1162,24 @@ gori_compute::compute_operand2_range (vrange &r, src.get_operand (op1_range, op1); src.get_operand (op2_range, op2); + relation_kind k = VREL_VARYING; + if (rel) + { + if (lhs_name == rel->op1 () && op2 == rel->op2 ()) + k = rel->kind (); + else if (lhs_name == rel->op2 () && op2 == rel->op1 ()) + k = relation_swap (rel->kind ()); + else if (op1 == rel->op1 () && op2 == rel->op2 ()) + refine_using_relation (op1, op1_range, op2, op2_range, src, + rel->kind ()); + else if (op1 == rel->op2 () && op2 == rel->op1 ()) + refine_using_relation (op1, op1_range, op2, op2_range, src, + relation_swap (rel->kind ())); + } + // Intersect with range for op2 based on lhs and op1. - if (!handler.calc_op2 (tmp, lhs, op1_range)) + if (!handler.calc_op2 (tmp, lhs, op1_range, k)) return false; unsigned idx; @@ -1070,7 +1225,7 @@ gori_compute::compute_operand2_range (vrange &r, // gcc_checking_assert (!is_import_p (op2, find.bb)); // Then feed this range back as the LHS of the defining statement. - return compute_operand_range (r, src_stmt, op2_range, name, src); + return compute_operand_range (r, src_stmt, op2_range, name, src, rel); } // Calculate a range for NAME from both operand positions of S @@ -1083,17 +1238,18 @@ gori_compute::compute_operand1_and_operand2_range (vrange &r, &handler, const vrange &lhs, tree name, - fur_source &src) + fur_source &src, + value_relation *rel) { Value_Range op_range (TREE_TYPE (name)); // Calculate a good a range for op2. Since op1 == op2, this will // have already included whatever the actual range of name is. - if (!compute_operand2_range (op_range, handler, lhs, name, src)) + if (!compute_operand2_range (op_range, handler, lhs, name, src, rel)) return false; // Now get the range thru op1. - if (!compute_operand1_range (r, handler, lhs, name, src)) + if (!compute_operand1_range (r, handler, lhs, name, src, rel)) return false; // Both operands have to be simultaneously true, so perform an intersection. diff --git a/gcc/gimple-range-gori.h b/gcc/gimple-range-gori.h index 0c776ef..c7a3216 100644 --- a/gcc/gimple-range-gori.h +++ b/gcc/gimple-range-gori.h @@ -153,6 +153,8 @@ private: // // The remaining routines are internal use only. +class value_relation; + class gori_compute : public gori_map { public: @@ -164,20 +166,27 @@ public: bool has_edge_range_p (tree name, edge e); void dump (FILE *f); private: + bool refine_using_relation (tree op1, vrange &op1_range, + tree op2, vrange &op2_range, + fur_source &src, relation_kind k); bool may_recompute_p (tree name, edge e); bool may_recompute_p (tree name, basic_block bb = NULL); bool compute_operand_range (vrange &r, gimple *stmt, const vrange &lhs, - tree name, class fur_source &src); + tree name, class fur_source &src, + value_relation *rel = NULL); bool compute_operand_range_switch (vrange &r, gswitch *s, const vrange &lhs, tree name, fur_source &src); bool compute_operand1_range (vrange &r, gimple_range_op_handler &handler, - const vrange &lhs, tree name, fur_source &src); + const vrange &lhs, tree name, fur_source &src, + value_relation *rel = NULL); bool compute_operand2_range (vrange &r, gimple_range_op_handler &handler, - const vrange &lhs, tree name, fur_source &src); + const vrange &lhs, tree name, fur_source &src, + value_relation *rel = NULL); bool compute_operand1_and_operand2_range (vrange &r, gimple_range_op_handler &handler, const vrange &lhs, tree name, - fur_source &src); + fur_source &src, + value_relation *rel = NULL); void compute_logical_operands (vrange &true_range, vrange &false_range, gimple_range_op_handler &handler, const irange &lhs, tree name, fur_source &src, diff --git a/gcc/gimple-range-op.cc b/gcc/gimple-range-op.cc index 3f5e585..5b71d1c 100644 --- a/gcc/gimple-range-op.cc +++ b/gcc/gimple-range-op.cc @@ -202,7 +202,7 @@ gimple_range_op_handler::calc_op1 (vrange &r, const vrange &lhs_range) bool gimple_range_op_handler::calc_op1 (vrange &r, const vrange &lhs_range, - const vrange &op2_range) + const vrange &op2_range, relation_kind k) { // Give up on empty ranges. if (lhs_range.undefined_p ()) @@ -225,9 +225,9 @@ gimple_range_op_handler::calc_op1 (vrange &r, const vrange &lhs_range, op2_type = TREE_TYPE (operand1 ()); Value_Range trange (op2_type); trange.set_varying (op2_type); - return op1_range (r, type, lhs_range, trange); + return op1_range (r, type, lhs_range, trange, k); } - return op1_range (r, type, lhs_range, op2_range); + return op1_range (r, type, lhs_range, op2_range, k); } // Calculate what we can determine of the range of this statement's @@ -237,7 +237,7 @@ gimple_range_op_handler::calc_op1 (vrange &r, const vrange &lhs_range, bool gimple_range_op_handler::calc_op2 (vrange &r, const vrange &lhs_range, - const vrange &op1_range) + const vrange &op1_range, relation_kind k) { // Give up on empty ranges. if (lhs_range.undefined_p ()) @@ -250,9 +250,9 @@ gimple_range_op_handler::calc_op2 (vrange &r, const vrange &lhs_range, tree op1_type = TREE_TYPE (operand1 ()); Value_Range trange (op1_type); trange.set_varying (op1_type); - return op2_range (r, type, lhs_range, trange); + return op2_range (r, type, lhs_range, trange, k); } - return op2_range (r, type, lhs_range, op1_range); + return op2_range (r, type, lhs_range, op1_range, k); } // -------------------------------------------------------------------- @@ -387,8 +387,8 @@ cfn_toupper_tolower::fold_range (irange &r, tree type, const irange &lh, return true; } -// Implement range operator for CFN_BUILT_IN_FFS and CFN_BUILT_IN_POPCOUNT. -class cfn_popcount : public range_operator +// Implement range operator for CFN_BUILT_IN_FFS. +class cfn_ffs : public range_operator { public: using range_operator::fold_range; @@ -397,14 +397,6 @@ public: { if (lh.undefined_p ()) return false; - // Calculating the popcount of a singleton is trivial. - if (lh.singleton_p ()) - { - wide_int nz = lh.get_nonzero_bits (); - wide_int pop = wi::shwi (wi::popcount (nz), TYPE_PRECISION (type)); - r.set (type, pop, pop); - return true; - } // __builtin_ffs* and __builtin_popcount* return [0, prec]. int prec = TYPE_PRECISION (lh.type ()); // If arg is non-zero, then ffs or popcount are non-zero. @@ -420,6 +412,26 @@ public: r.set (build_int_cst (type, mini), build_int_cst (type, maxi)); return true; } +} op_cfn_ffs; + +// Implement range operator for CFN_BUILT_IN_POPCOUNT. +class cfn_popcount : public cfn_ffs +{ +public: + using range_operator::fold_range; + virtual bool fold_range (irange &r, tree type, const irange &lh, + const irange &rh, relation_kind rel) const + { + // Calculating the popcount of a singleton is trivial. + if (lh.singleton_p ()) + { + wide_int nz = lh.get_nonzero_bits (); + wide_int pop = wi::shwi (wi::popcount (nz), TYPE_PRECISION (type)); + r.set (type, pop, pop); + return true; + } + return cfn_ffs::fold_range (r, type, lh, rh, rel); + } } op_cfn_popcount; // Implement range operator for CFN_BUILT_IN_CLZ @@ -734,6 +746,11 @@ gimple_range_op_handler::maybe_builtin_call () break; CASE_CFN_FFS: + m_op1 = gimple_call_arg (call, 0); + m_int = &op_cfn_ffs; + m_valid = true; + break; + CASE_CFN_POPCOUNT: m_op1 = gimple_call_arg (call, 0); m_int = &op_cfn_popcount; diff --git a/gcc/gimple-range-op.h b/gcc/gimple-range-op.h index 6876419..3a555f2 100644 --- a/gcc/gimple-range-op.h +++ b/gcc/gimple-range-op.h @@ -35,8 +35,10 @@ public: tree operand1 () const { gcc_checking_assert (m_valid); return m_op1; } tree operand2 () const { gcc_checking_assert (m_valid); return m_op2; } bool calc_op1 (vrange &r, const vrange &lhs_range); - bool calc_op1 (vrange &r, const vrange &lhs_range, const vrange &op2_range); - bool calc_op2 (vrange &r, const vrange &lhs_range, const vrange &op1_range); + bool calc_op1 (vrange &r, const vrange &lhs_range, const vrange &op2_range, + relation_kind k = VREL_VARYING); + bool calc_op2 (vrange &r, const vrange &lhs_range, const vrange &op1_range, + relation_kind k = VREL_VARYING); private: void maybe_builtin_call (); gimple *m_stmt; diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc index 4d032c6..9e0e342 100644 --- a/gcc/gimplify.cc +++ b/gcc/gimplify.cc @@ -9245,6 +9245,7 @@ omp_group_base (omp_mapping_group *grp, unsigned int *chained, case GOMP_MAP_RELEASE: case GOMP_MAP_DELETE: case GOMP_MAP_FORCE_ALLOC: + case GOMP_MAP_IF_PRESENT: if (node == grp->grp_end) return node; @@ -9323,7 +9324,6 @@ omp_group_base (omp_mapping_group *grp, unsigned int *chained, case GOMP_MAP_FORCE_DEVICEPTR: case GOMP_MAP_DEVICE_RESIDENT: case GOMP_MAP_LINK: - case GOMP_MAP_IF_PRESENT: case GOMP_MAP_FIRSTPRIVATE: case GOMP_MAP_FIRSTPRIVATE_INT: case GOMP_MAP_USE_DEVICE_PTR: @@ -9861,6 +9861,134 @@ omp_lastprivate_for_combined_outer_constructs (struct gimplify_omp_ctx *octx, omp_notice_variable (octx, decl, true); } +/* If we have mappings INNER and OUTER, where INNER is a component access and + OUTER is a mapping of the whole containing struct, check that the mappings + are compatible. We'll be deleting the inner mapping, so we need to make + sure the outer mapping does (at least) the same transfers to/from the device + as the inner mapping. */ + +bool +omp_check_mapping_compatibility (location_t loc, + omp_mapping_group *outer, + omp_mapping_group *inner) +{ + tree first_outer = *outer->grp_start, first_inner = *inner->grp_start; + + gcc_assert (OMP_CLAUSE_CODE (first_outer) == OMP_CLAUSE_MAP); + gcc_assert (OMP_CLAUSE_CODE (first_inner) == OMP_CLAUSE_MAP); + + enum gomp_map_kind outer_kind = OMP_CLAUSE_MAP_KIND (first_outer); + enum gomp_map_kind inner_kind = OMP_CLAUSE_MAP_KIND (first_inner); + + if (outer_kind == inner_kind) + return true; + + switch (outer_kind) + { + case GOMP_MAP_ALWAYS_TO: + if (inner_kind == GOMP_MAP_FORCE_PRESENT + || inner_kind == GOMP_MAP_ALLOC + || inner_kind == GOMP_MAP_TO) + return true; + break; + + case GOMP_MAP_ALWAYS_FROM: + if (inner_kind == GOMP_MAP_FORCE_PRESENT + || inner_kind == GOMP_MAP_ALLOC + || inner_kind == GOMP_MAP_FROM) + return true; + break; + + case GOMP_MAP_TO: + case GOMP_MAP_FROM: + if (inner_kind == GOMP_MAP_FORCE_PRESENT + || inner_kind == GOMP_MAP_ALLOC) + return true; + break; + + case GOMP_MAP_ALWAYS_TOFROM: + case GOMP_MAP_TOFROM: + if (inner_kind == GOMP_MAP_FORCE_PRESENT + || inner_kind == GOMP_MAP_ALLOC + || inner_kind == GOMP_MAP_TO + || inner_kind == GOMP_MAP_FROM + || inner_kind == GOMP_MAP_TOFROM) + return true; + break; + + default: + ; + } + + error_at (loc, "data movement for component %qE is not compatible with " + "movement for struct %qE", OMP_CLAUSE_DECL (first_inner), + OMP_CLAUSE_DECL (first_outer)); + + return false; +} + +/* Similar to omp_resolve_clause_dependencies, but for OpenACC. The only + clause dependencies we handle for now are struct element mappings and + whole-struct mappings on the same directive, and duplicate clause + detection. */ + +void +oacc_resolve_clause_dependencies (vec<omp_mapping_group> *groups, + hash_map<tree_operand_hash, + omp_mapping_group *> *grpmap) +{ + int i; + omp_mapping_group *grp; + hash_set<tree_operand_hash> *seen_components = NULL; + hash_set<tree_operand_hash> *shown_error = NULL; + + FOR_EACH_VEC_ELT (*groups, i, grp) + { + tree grp_end = grp->grp_end; + tree decl = OMP_CLAUSE_DECL (grp_end); + + gcc_assert (OMP_CLAUSE_CODE (grp_end) == OMP_CLAUSE_MAP); + + if (DECL_P (grp_end)) + continue; + + tree c = OMP_CLAUSE_DECL (*grp->grp_start); + while (TREE_CODE (c) == ARRAY_REF) + c = TREE_OPERAND (c, 0); + if (TREE_CODE (c) != COMPONENT_REF) + continue; + if (!seen_components) + seen_components = new hash_set<tree_operand_hash> (); + if (!shown_error) + shown_error = new hash_set<tree_operand_hash> (); + if (seen_components->contains (c) + && !shown_error->contains (c)) + { + error_at (OMP_CLAUSE_LOCATION (grp_end), + "%qE appears more than once in map clauses", + OMP_CLAUSE_DECL (grp_end)); + shown_error->add (c); + } + else + seen_components->add (c); + + omp_mapping_group *struct_group; + if (omp_mapped_by_containing_struct (grpmap, decl, &struct_group) + && *grp->grp_start == grp_end) + { + omp_check_mapping_compatibility (OMP_CLAUSE_LOCATION (grp_end), + struct_group, grp); + /* Remove the whole of this mapping -- redundant. */ + grp->deleted = true; + } + } + + if (seen_components) + delete seen_components; + if (shown_error) + delete shown_error; +} + /* Link node NEWNODE so it is pointed to by chain INSERT_AT. NEWNODE's chain is linked to the previous node pointed to by INSERT_AT. */ @@ -10238,37 +10366,6 @@ omp_accumulate_sibling_list (enum omp_region_type region_type, break; if (scp) continue; - if ((region_type & ORT_ACC) != 0) - { - /* This duplicate checking code is currently only enabled for - OpenACC. */ - tree d1 = OMP_CLAUSE_DECL (*sc); - tree d2 = OMP_CLAUSE_DECL (grp_end); - while (TREE_CODE (d1) == ARRAY_REF) - d1 = TREE_OPERAND (d1, 0); - while (TREE_CODE (d2) == ARRAY_REF) - d2 = TREE_OPERAND (d2, 0); - if (TREE_CODE (d1) == INDIRECT_REF) - d1 = TREE_OPERAND (d1, 0); - if (TREE_CODE (d2) == INDIRECT_REF) - d2 = TREE_OPERAND (d2, 0); - while (TREE_CODE (d1) == COMPONENT_REF) - if (TREE_CODE (d2) == COMPONENT_REF - && TREE_OPERAND (d1, 1) == TREE_OPERAND (d2, 1)) - { - d1 = TREE_OPERAND (d1, 0); - d2 = TREE_OPERAND (d2, 0); - } - else - break; - if (d1 == d2) - { - error_at (OMP_CLAUSE_LOCATION (grp_end), - "%qE appears more than once in map clauses", - OMP_CLAUSE_DECL (grp_end)); - return NULL; - } - } if (maybe_lt (coffset, offset) || (known_eq (coffset, offset) && maybe_lt (cbitpos, bitpos))) @@ -10400,6 +10497,11 @@ omp_build_struct_sibling_lists (enum tree_code code, if (DECL_P (decl)) continue; + /* Skip groups we marked for deletion in + oacc_resolve_clause_dependencies. */ + if (grp->deleted) + continue; + if (OMP_CLAUSE_CHAIN (*grp_start_p) && OMP_CLAUSE_CHAIN (*grp_start_p) != grp_end) { @@ -10436,14 +10538,14 @@ omp_build_struct_sibling_lists (enum tree_code code, if (TREE_CODE (decl) != COMPONENT_REF) continue; - /* If we're mapping the whole struct in another node, skip creation of - sibling lists. */ + /* If we're mapping the whole struct in another node, skip adding this + node to a sibling list. */ omp_mapping_group *wholestruct; - if (!(region_type & ORT_ACC) - && omp_mapped_by_containing_struct (*grpmap, OMP_CLAUSE_DECL (c), - &wholestruct)) + if (omp_mapped_by_containing_struct (*grpmap, OMP_CLAUSE_DECL (c), + &wholestruct)) { - if (*grp_start_p == grp_end) + if (!(region_type & ORT_ACC) + && *grp_start_p == grp_end) /* Remove the whole of this mapping -- redundant. */ grp->deleted = true; @@ -10632,6 +10734,7 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, hash_map<tree_operand_hash, omp_mapping_group *> *grpmap; grpmap = omp_index_mapping_groups (groups); + oacc_resolve_clause_dependencies (groups, grpmap); omp_build_struct_sibling_lists (code, region_type, groups, &grpmap, list_p); diff --git a/gcc/internal-fn.cc b/gcc/internal-fn.cc index 651d99e..c306240 100644 --- a/gcc/internal-fn.cc +++ b/gcc/internal-fn.cc @@ -3664,7 +3664,7 @@ expand_direct_optab_fn (internal_fn fn, gcall *stmt, direct_optab optab, static void expand_while_optab_fn (internal_fn, gcall *stmt, convert_optab optab) { - expand_operand ops[3]; + expand_operand ops[4]; tree rhs_type[2]; tree lhs = gimple_call_lhs (stmt); @@ -3680,10 +3680,24 @@ expand_while_optab_fn (internal_fn, gcall *stmt, convert_optab optab) create_input_operand (&ops[i + 1], rhs_rtx, TYPE_MODE (rhs_type[i])); } + int opcnt; + if (!VECTOR_MODE_P (TYPE_MODE (lhs_type))) + { + /* When the mask is an integer mode the exact vector length may not + be clear to the backend, so we pass it in operand[3]. + Use the vector in arg2 for the most reliable intended size. */ + tree type = TREE_TYPE (gimple_call_arg (stmt, 2)); + create_integer_operand (&ops[3], TYPE_VECTOR_SUBPARTS (type)); + opcnt = 4; + } + else + /* The mask has a vector type so the length operand is unnecessary. */ + opcnt = 3; + insn_code icode = convert_optab_handler (optab, TYPE_MODE (rhs_type[0]), TYPE_MODE (lhs_type)); - expand_insn (icode, 3, ops); + expand_insn (icode, opcnt, ops); if (!rtx_equal_p (lhs_rtx, ops[0].value)) emit_move_insn (lhs_rtx, ops[0].value); } diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc index ca5b9f3..724c945 100644 --- a/gcc/ipa-prop.cc +++ b/gcc/ipa-prop.cc @@ -126,8 +126,8 @@ struct ipa_vr_ggc_hash_traits : public ggc_cache_remove <value_range *> static bool equal (const value_range *a, const value_range *b) { - return (*a == *b - && types_compatible_p (a->type (), b->type ())); + return (types_compatible_p (a->type (), b->type ()) + && *a == *b); } static const bool empty_zero_p = true; static void diff --git a/gcc/po/ChangeLog b/gcc/po/ChangeLog index 55d13c7..9499a3d 100644 --- a/gcc/po/ChangeLog +++ b/gcc/po/ChangeLog @@ -1,3 +1,7 @@ +2022-10-03 Joseph Myers <joseph@codesourcery.com> + + * sv.po: Update. + 2022-09-22 Joseph Myers <joseph@codesourcery.com> * fr.po: Update. diff --git a/gcc/po/sv.po b/gcc/po/sv.po index d15c134..2b871e0 100644 --- a/gcc/po/sv.po +++ b/gcc/po/sv.po @@ -29,7 +29,7 @@ msgstr "" "Project-Id-Version: gcc 12.2.0\n" "Report-Msgid-Bugs-To: https://gcc.gnu.org/bugs/\n" "POT-Creation-Date: 2022-08-17 22:17+0000\n" -"PO-Revision-Date: 2022-08-26 22:47+0200\n" +"PO-Revision-Date: 2022-10-02 11:19+0200\n" "Last-Translator: Göran Uddeborg <goeran@uddeborg.se>\n" "Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n" "Language: sv\n" @@ -20975,7 +20975,7 @@ msgstr "argument till Offsetof implicerar indirektion till ett inbäddat fält" #: go/gofrontend/expressions.cc:10587 go/gofrontend/expressions.cc:12740 #: go/gofrontend/expressions.cc:12757 go/gofrontend/expressions.cc:12773 msgid "not enough arguments" -msgstr "inte tillräckligt med argument" +msgstr "för få argument" #: go/gofrontend/expressions.cc:8439 go/gofrontend/expressions.cc:8475 #: go/gofrontend/expressions.cc:10270 go/gofrontend/expressions.cc:10388 @@ -21168,7 +21168,7 @@ msgstr "avbildningsindex förväntades på högersidan" #: go/gofrontend/statements.cc:3198 go/gofrontend/statements.cc:3228 msgid "not enough arguments to return" -msgstr "inte tillräckligt med argument att returnera" +msgstr "för få argument att returnera" #: go/gofrontend/statements.cc:3206 msgid "return with value in function with no return type" @@ -29655,6 +29655,7 @@ msgstr "statisk kedja med funktion som inte använder en" msgid "%<__builtin_unreachable%> or %<__builtin_trap%> call with arguments" msgstr "%<__builtin_unreachable%> eller %<__builtin_trap%> anropad med argument" +# Misspelling reported as https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107121 #: tree-cfg.cc:3478 #, gcc-internal-format msgid "%<DEFFERED_INIT%> calls should have same constant size for the first argument and LHS" @@ -30551,7 +30552,7 @@ msgstr "längden beräknad här" #: tree-ssa-strlen.cc:4253 #, gcc-internal-format msgid "%qD of a string of length %wu or more and an array of size %wu evaluates to nonzero" -msgstr "%qD av strängar med längden %wu eller mer och en vektor av storlek %wu evalueras till nollskilt" +msgstr "%qD av en sträng med längden %wu eller mer och en vektor av storlek %wu evalueras till nollskilt" #: tree-ssa-strlen.cc:4255 #, gcc-internal-format @@ -32710,7 +32711,7 @@ msgstr "begärd minnesjustering %qE överskrider maximum %u" #: c-family/c-common.cc:5679 #, gcc-internal-format msgid "not enough variable arguments to fit a sentinel" -msgstr "inte tillräckligt med variabla argument för att få plats med en vaktpost" +msgstr "för få variabla argument för att få plats med en vaktpost" #: c-family/c-common.cc:5693 #, gcc-internal-format @@ -45221,7 +45222,7 @@ msgstr "iterationsdeklaration eller initiering förväntades" #: c/c-parser.cc:19440 #, gcc-internal-format msgid "not enough perfectly nested loops" -msgstr "inte tillräckligt med perfekt nästade slingor" +msgstr "för få perfekt nästade slingor" #: c/c-parser.cc:19488 cp/parser.cc:42786 #, gcc-internal-format @@ -48940,7 +48941,7 @@ msgstr "(en pekare på medlem kan bara skapas med %<&%E%>)" #: cp/class.cc:8694 cp/class.cc:8736 #, gcc-internal-format msgid "not enough type information" -msgstr "inte tillräcklig typinformation" +msgstr "för lite typinformation" #: cp/class.cc:8714 #, gcc-internal-format @@ -58202,7 +58203,7 @@ msgstr "iterationsvariabel %qD skall inte vara reduction" #: cp/parser.cc:42723 #, gcc-internal-format msgid "not enough for loops to collapse" -msgstr "inte tillräckligt med for-slingor att kollapsa" +msgstr "för få for-slingor att kollapsa" #: cp/parser.cc:45065 #, gcc-internal-format @@ -63455,7 +63456,7 @@ msgstr "%qs-argumentet till inbyggd %qs vid %L har en ogiltig permutation av dim #: fortran/check.cc:4841 #, gcc-internal-format, gfc-internal-format msgid "Without padding, there are not enough elements in the intrinsic RESHAPE source at %L to match the shape" -msgstr "Utan utfyllnad finns det inte tillräckligt med element i inbyggda RESHAPE-källan vid %L för att stämma med formen" +msgstr "Utan utfyllnad finns det för få element i inbyggda RESHAPE-källan vid %L för att stämma med formen" #: fortran/check.cc:4858 fortran/check.cc:4877 #, gcc-internal-format @@ -64498,7 +64499,7 @@ msgstr "Typparameterspecifikationslistan vid %C får inte innehålla både ASSUM #: fortran/decl.cc:3833 #, gcc-internal-format, gfc-internal-format msgid "The type parameter spec list at %C does not contain enough parameter expressions" -msgstr "Typparameterspecifikationslistan vid %C innehåller inte tillräckligt med parameteruttryck" +msgstr "Typparameterspecifikationslistan vid %C innehåller för få parameteruttryck" #: fortran/decl.cc:3857 #, gcc-internal-format @@ -64853,7 +64854,7 @@ msgstr "BIND(C)-sats vid %C" #: fortran/decl.cc:6268 #, gcc-internal-format, gfc-internal-format msgid "CLASS entity at %C cannot have the PARAMETER attribute" -msgstr "CLASS-enheten vid %C får inte ha attributet PARAMETER" +msgstr "CLASS-entiteten vid %C får inte ha attributet PARAMETER" #: fortran/decl.cc:6300 #, gcc-internal-format, gfc-internal-format @@ -65139,7 +65140,7 @@ msgstr "ENTRY-sats vid %L med BIND(C) är otillåten i en elementär procedur" #: fortran/decl.cc:8060 #, gcc-internal-format, gfc-internal-format msgid "Alternate return dummy argument cannot appear in a SUBROUTINE with the BIND(C) attribute at %L" -msgstr "Alternativt returattrappgument får inte förekomma i en SUBROUTINE med attributet BIND(C) vid %L" +msgstr "Alternativt returattrappargument får inte förekomma i en SUBROUTINE med attributet BIND(C) vid %L" #: fortran/decl.cc:8123 fortran/decl.cc:8130 #, gcc-internal-format, gfc-internal-format @@ -70507,6 +70508,7 @@ msgstr "Den implicit deklarerade subrutinen %s används i !$OMP DECLARE REDUCTIO msgid "ORDERED clause parameter is less than COLLAPSE at %L" msgstr "ORDERED-klausulparameter är mindre än COLLAPSE vid %L" +# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107122 #: fortran/openmp.cc:6294 #, gcc-internal-format, gfc-internal-format msgid "ORDER clause must not be used together ORDERED at %L" @@ -70940,7 +70942,7 @@ msgstr "En skalär inbyggd variabel förväntades vid %L i atomär jämförelse" #: fortran/openmp.cc:7885 #, gcc-internal-format, gfc-internal-format msgid "Expected scalar intrinsic expression at %L in atomic comparison" -msgstr "Ett skalärt inbyggt uttryck förväntades vid %L vid i atomär jämförelse" +msgstr "Ett skalärt inbyggt uttryck förväntades vid %L i atomär jämförelse" #: fortran/openmp.cc:7893 #, gcc-internal-format, gfc-internal-format @@ -71110,7 +71112,7 @@ msgstr "kollapsade %s-slingor är inte perfekt nästade vid %L" #: fortran/openmp.cc:8640 fortran/openmp.cc:8648 #, gcc-internal-format, gfc-internal-format msgid "not enough DO loops for collapsed %s at %L" -msgstr "inte tillräckligt med DO-slingor för kollapsad %s vid %L" +msgstr "för få DO-slingor för kollapsad %s vid %L" #: fortran/openmp.cc:8853 fortran/openmp.cc:8866 #, gcc-internal-format, gfc-internal-format @@ -71145,7 +71147,7 @@ msgstr "%s !$ACC LOOP-slingor är inte perfekt nästade vid %L" #: fortran/openmp.cc:8935 fortran/openmp.cc:8944 #, gcc-internal-format, gfc-internal-format msgid "not enough DO loops for %s !$ACC LOOP at %L" -msgstr "inte tillräckligt med DO-slingor för %s !$ACC LOOP vid %L" +msgstr "för få DO-slingor för %s !$ACC LOOP vid %L" #: fortran/openmp.cc:8960 #, gcc-internal-format, gfc-internal-format @@ -72610,7 +72612,7 @@ msgstr "Gränssnittet stämmer inte för procedurpekarkomponenten %qs i postkons #: fortran/resolve.cc:1484 #, gcc-internal-format msgid "Bad array spec of component %qs referenced in structure constructor at %L" -msgstr "Felaktig vektorcspecifikation av kompnenten %qs refererad i postkonstruerare vid %L" +msgstr "Felaktig vektorspecifikation av komponenten %qs refererad i postkonstruerare vid %L" #: fortran/resolve.cc:1497 #, gcc-internal-format @@ -75897,7 +75899,7 @@ msgstr "ej konstant initieringsuttryck vid %L" #: fortran/trans-decl.cc:761 #, gcc-internal-format msgid "Array %qs at %L is larger than limit set by %<-fmax-stack-var-size=%>, moved from stack to static storage. This makes the procedure unsafe when called recursively, or concurrently from multiple threads. Consider increasing the %<-fmax-stack-var-size=%> limit (or use %<-frecursive%>, which implies unlimited %<-fmax-stack-var-size%>) - or change the code to use an ALLOCATABLE array. If the variable is never accessed concurrently, this warning can be ignored, and the variable could also be declared with the SAVE attribute." -msgstr "Vektorn %qs vid %L är större än gränsen satt med %<-fmax-stack-var-size=%>, flyttad från stacken till statisk lagring. Detta gör proceduren osäker när den anropas rekursivt, eller samtidigt från flera trådar. Överväg att öka gränsen %<-fmax-stack-var-size=%> (eller anvånd %<-frecursive%>, som implicerad obegränsad %<-fmax-stack-var-size=%> – eller ändra koden till att använda en ALLOCATABLE vektor. Om variabeln aldrig används av flera samtidigt kan denna varning ignoreras och variabeln skulle också kunna deklareras med attributet SAVE." +msgstr "Vektorn %qs vid %L är större än gränsen satt med %<-fmax-stack-var-size=%>, flyttad från stacken till statisk lagring. Detta gör proceduren osäker när den anropas rekursivt, eller samtidigt från flera trådar. Överväg att öka gränsen %<-fmax-stack-var-size=%> (eller använd %<-frecursive%>, som implicerad obegränsad %<-fmax-stack-var-size=%> – eller ändra koden till att använda en ALLOCATABLE vektor. Om variabeln aldrig används av flera samtidigt kan denna varning ignoreras och variabeln skulle också kunna deklareras med attributet SAVE." #: fortran/trans-decl.cc:1790 #, gcc-internal-format diff --git a/gcc/range-op.cc b/gcc/range-op.cc index fc930f4..4f647ab 100644 --- a/gcc/range-op.cc +++ b/gcc/range-op.cc @@ -1305,22 +1305,125 @@ operator_plus::wi_fold (irange &r, tree type, value_range_with_overflow (r, type, new_lb, new_ub, ov_lb, ov_ub); } +// Given addition or subtraction, determine the possible NORMAL ranges and +// OVERFLOW ranges given an OFFSET range. ADD_P is true for addition. +// Return the relation that exists between the LHS and OP1 in order for the +// NORMAL range to apply. +// a return value of VREL_VARYING means no ranges were applicable. + +static relation_kind +plus_minus_ranges (irange &r_ov, irange &r_normal, const irange &offset, + bool add_p) +{ + relation_kind kind = VREL_VARYING; + // For now, only deal with constant adds. This could be extended to ranges + // when someone is so motivated. + if (!offset.singleton_p () || offset.zero_p ()) + return kind; + + // Always work with a positive offset. ie a+ -2 -> a-2 and a- -2 > a+2 + wide_int off = offset.lower_bound (); + if (wi::neg_p (off, SIGNED)) + { + add_p = !add_p; + off = wi::neg (off); + } + + wi::overflow_type ov; + tree type = offset.type (); + unsigned prec = TYPE_PRECISION (type); + wide_int ub; + wide_int lb; + // calculate the normal range and relation for the operation. + if (add_p) + { + // [ 0 , INF - OFF] + lb = wi::zero (prec); + ub = wi::sub (wi::to_wide (vrp_val_max (type)), off, UNSIGNED, &ov); + kind = VREL_GT; + } + else + { + // [ OFF, INF ] + lb = off; + ub = wi::to_wide (vrp_val_max (type)); + kind = VREL_LT; + } + int_range<2> normal_range (type, lb, ub); + int_range<2> ov_range (type, lb, ub, VR_ANTI_RANGE); + + r_ov = ov_range; + r_normal = normal_range; + return kind; +} + +// Once op1 has been calculated by operator_plus or operator_minus, check +// to see if the relation passed causes any part of the calculation to +// be not possible. ie +// a_2 = b_3 + 1 with a_2 < b_3 can refine the range of b_3 to [INF, INF] +// and that further refines a_2 to [0, 0]. +// R is the value of op1, OP2 is the offset being added/subtracted, REL is the +// relation between LHS relatoin OP1 and ADD_P is true for PLUS, false for +// MINUS. IF any adjustment can be made, R will reflect it. + +static void +adjust_op1_for_overflow (irange &r, const irange &op2, relation_kind rel, + bool add_p) +{ + if (r.undefined_p ()) + return; + tree type = r.type (); + // Check for unsigned overflow and calculate the overflow part. + signop s = TYPE_SIGN (type); + if (!TYPE_OVERFLOW_WRAPS (type) || s == SIGNED) + return; + + // Only work with <, <=, >, >= relations. + if (!relation_lt_le_gt_ge_p (rel)) + return; + + // Get the ranges for this offset. + int_range_max normal, overflow; + relation_kind k = plus_minus_ranges (overflow, normal, op2, add_p); + + // VREL_VARYING means there are no adjustments. + if (k == VREL_VARYING) + return; + + // If the relations match use the normal range, otherwise use overflow range. + if (relation_intersect (k, rel) == k) + r.intersect (normal); + else + r.intersect (overflow); + return; +} + bool operator_plus::op1_range (irange &r, tree type, const irange &lhs, const irange &op2, - relation_kind rel ATTRIBUTE_UNUSED) const + relation_kind rel) const { - return range_op_handler (MINUS_EXPR, type).fold_range (r, type, lhs, op2); + if (lhs.undefined_p ()) + return false; + // Start with the default operation. + range_op_handler minus (MINUS_EXPR, type); + if (!minus) + return false; + bool res = minus.fold_range (r, type, lhs, op2); + // Check for a relation refinement. + if (res) + adjust_op1_for_overflow (r, op2, rel, true /* PLUS_EXPR */); + return res; } bool operator_plus::op2_range (irange &r, tree type, const irange &lhs, const irange &op1, - relation_kind rel ATTRIBUTE_UNUSED) const + relation_kind rel) const { - return range_op_handler (MINUS_EXPR, type).fold_range (r, type, lhs, op1); + return op1_range (r, type, lhs, op1, rel); } @@ -1472,7 +1575,17 @@ operator_minus::op1_range (irange &r, tree type, const irange &op2, relation_kind rel ATTRIBUTE_UNUSED) const { - return range_op_handler (PLUS_EXPR, type).fold_range (r, type, lhs, op2); + if (lhs.undefined_p ()) + return false; + // Start with the default operation. + range_op_handler minus (PLUS_EXPR, type); + if (!minus) + return false; + bool res = minus.fold_range (r, type, lhs, op2); + if (res) + adjust_op1_for_overflow (r, op2, rel, false /* PLUS_EXPR */); + return res; + } bool @@ -1481,6 +1594,8 @@ operator_minus::op2_range (irange &r, tree type, const irange &op1, relation_kind rel ATTRIBUTE_UNUSED) const { + if (lhs.undefined_p ()) + return false; return fold_range (r, type, op1, lhs); } @@ -1650,6 +1765,8 @@ operator_mult::op1_range (irange &r, tree type, relation_kind rel ATTRIBUTE_UNUSED) const { tree offset; + if (lhs.undefined_p ()) + return false; // We can't solve 0 = OP1 * N by dividing by N with a wrapping type. // For example: For 0 = OP1 * 2, OP1 could be 0, or MAXINT, whereas @@ -1902,6 +2019,8 @@ operator_exact_divide::op1_range (irange &r, tree type, const irange &op2, relation_kind rel ATTRIBUTE_UNUSED) const { + if (lhs.undefined_p ()) + return false; tree offset; // [2, 4] = op1 / [3,3] since its exact divide, no need to worry about // remainders in the endpoints, so op1 = [2,4] * [3,3] = [6,12]. @@ -2111,6 +2230,8 @@ operator_lshift::op1_range (irange &r, const irange &op2, relation_kind rel ATTRIBUTE_UNUSED) const { + if (lhs.undefined_p ()) + return false; tree shift_amount; if (!lhs.contains_p (build_zero_cst (type))) @@ -2183,6 +2304,8 @@ operator_rshift::op1_range (irange &r, relation_kind rel ATTRIBUTE_UNUSED) const { tree shift; + if (lhs.undefined_p ()) + return false; if (op2.singleton_p (&shift)) { // Ignore nonsensical shifts. @@ -2401,6 +2524,8 @@ operator_cast::op1_range (irange &r, tree type, const irange &op2, relation_kind rel ATTRIBUTE_UNUSED) const { + if (lhs.undefined_p ()) + return false; tree lhs_type = lhs.type (); gcc_checking_assert (types_compatible_p (op2.type(), type)); @@ -2936,6 +3061,8 @@ operator_bitwise_and::op1_range (irange &r, tree type, const irange &op2, relation_kind rel ATTRIBUTE_UNUSED) const { + if (lhs.undefined_p ()) + return false; if (types_compatible_p (type, boolean_type_node)) return op_logical_and.op1_range (r, type, lhs, op2); @@ -3121,6 +3248,8 @@ operator_bitwise_or::op1_range (irange &r, tree type, const irange &op2, relation_kind rel ATTRIBUTE_UNUSED) const { + if (lhs.undefined_p ()) + return false; // If this is really a logical wi_fold, call that. if (types_compatible_p (type, boolean_type_node)) return op_logical_or.op1_range (r, type, lhs, op2); @@ -3370,6 +3499,8 @@ operator_trunc_mod::op1_range (irange &r, tree type, const irange &, relation_kind rel ATTRIBUTE_UNUSED) const { + if (lhs.undefined_p ()) + return false; // PR 91029. signop sign = TYPE_SIGN (type); unsigned prec = TYPE_PRECISION (type); @@ -3394,6 +3525,8 @@ operator_trunc_mod::op2_range (irange &r, tree type, const irange &, relation_kind rel ATTRIBUTE_UNUSED) const { + if (lhs.undefined_p ()) + return false; // PR 91029. signop sign = TYPE_SIGN (type); unsigned prec = TYPE_PRECISION (type); @@ -3522,6 +3655,8 @@ operator_bitwise_not::op1_range (irange &r, tree type, const irange &op2, relation_kind rel ATTRIBUTE_UNUSED) const { + if (lhs.undefined_p ()) + return false; if (types_compatible_p (type, boolean_type_node)) return op_logical_not.op1_range (r, type, lhs, op2); @@ -4008,6 +4143,8 @@ pointer_or_operator::op1_range (irange &r, tree type, const irange &op2 ATTRIBUTE_UNUSED, relation_kind rel ATTRIBUTE_UNUSED) const { + if (lhs.undefined_p ()) + return false; if (lhs.zero_p ()) { tree zero = build_zero_cst (type); @@ -4239,6 +4376,9 @@ range_op_handler::op1_range (vrange &r, tree type, relation_kind rel) const { gcc_checking_assert (m_valid); + + if (lhs.undefined_p ()) + return false; if (m_int) return m_int->op1_range (as_a <irange> (r), type, as_a <irange> (lhs), @@ -4260,6 +4400,8 @@ range_op_handler::op2_range (vrange &r, tree type, relation_kind rel) const { gcc_checking_assert (m_valid); + if (lhs.undefined_p ()) + return false; if (m_int) return m_int->op2_range (as_a <irange> (r), type, as_a <irange> (lhs), diff --git a/gcc/target.def b/gcc/target.def index 0e4147e..650e416 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -6167,7 +6167,7 @@ of the excess precision explicitly added. For\n\ @code{EXCESS_PRECISION_TYPE_FLOAT16}, and\n\ @code{EXCESS_PRECISION_TYPE_FAST}, the target should return the\n\ explicit excess precision that should be added depending on the\n\ -value set for @option{-fexcess-precision=@r{[}standard@r{|}fast@r{]}}.\n\ +value set for @option{-fexcess-precision=@r{[}standard@r{|}fast@r{|}16@r{]}}.\n\ Note that unpredictable explicit excess precision does not make sense,\n\ so a target should never return @code{FLT_EVAL_METHOD_UNPREDICTABLE}\n\ when @var{type} is @code{EXCESS_PRECISION_TYPE_STANDARD},\n\ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9007c43..0c6e5d4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,236 @@ +2022-10-03 Torbjörn SVENSSON <torbjorn.svensson@foss.st.com> + Yvan ROUX <yvan.roux@foss.st.com> + + * gcc.target/arm/cmse/cmse-15.c: Align with -Os improvements. + +2022-10-03 Jakub Jelinek <jakub@redhat.com> + + * g++.dg/ext/stmtexpr24.C: New test. + +2022-10-03 Andrew MacLeod <amacleod@redhat.com> + + * gcc.dg/pr107109.c: New. + +2022-10-03 Christophe Lyon <christophe.lyon@arm.com> + + * gcc.target/arm/mve/intrinsics/vrev64q_m_s16-clobber.c: New test. + +2022-10-03 Joseph Myers <joseph@codesourcery.com> + + * gcc.dg/c11-float-7.c, gcc.dg/c2x-float-12.c: New tests. + +2022-10-03 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> + + PR fortran/107062 + * gfortran.dg/ieee/fma_1.f90: Fix test. + * gfortran.dg/ieee/modes_1.f90: Fix test. + +2022-10-01 José Rui Faustino de Sousa <jrfsousa@gmail.com> + + PR fortran/100029 + PR fortran/100040 + * gfortran.dg/PR100029.f90: New test. + * gfortran.dg/PR100040.f90: New test. + +2022-09-30 Jeff Law <jeffreyalaw@gmail.com> + + * gcc.dg/infinite-loop.c: New test. + +2022-09-30 Jakub Jelinek <jakub@redhat.com> + + PR c++/107080 + * g++.target/arm/pr107080.C: New test. + +2022-09-30 Lewis Hyatt <lhyatt@gmail.com> + + PR preprocessor/69543 + * c-c++-common/pr69543-3.c: Remove xfail. + * c-c++-common/pr69543-4.c: Likewise. + * gcc.dg/cpp/pragma-diagnostic-2.c: Adjust test for new behavior. + * c-c++-common/pragma-diag-16.c: New test. + +2022-09-30 Jakub Jelinek <jakub@redhat.com> + + PR c++/107080 + * g++.target/aarch64/pr107080.C: New test. + +2022-09-30 Jakub Jelinek <jakub@redhat.com> + + PR c++/107080 + * g++.dg/cpp23/ext-floating11.C: New test. + +2022-09-30 Torbjörn SVENSSON <torbjorn.svensson@foss.st.com> + Yvan ROUX <yvan.roux@foss.st.com> + + * lib/target-supports.exp (check_effective_target_vma_equals_lma): New. + * c-c++-common/torture/attr-noinit-1.c: Requre VMA == LMA to run. + * c-c++-common/torture/attr-noinit-2.c: Likewise. + * c-c++-common/torture/attr-noinit-3.c: Likewise. + * c-c++-common/torture/attr-persistent-1.c: Likewise. + * c-c++-common/torture/attr-persistent-3.c: Likewise. + +2022-09-30 Torbjörn SVENSSON <torbjorn.svensson@foss.st.com> + + * lib/gcc-defs.exp: Do not prefix linker script with "-Wl,". + +2022-09-30 Torbjörn SVENSSON <torbjorn.svensson@foss.st.com> + Yvan ROUX <yvan.roux@foss.st.com> + + * g++.dg/modules/ben-1.map: Replace the colon with dash. + * g++.dg/modules/ben-1_a.C: Likewise + +2022-09-30 Kewen Lin <linkw@linux.ibm.com> + + PR target/99888 + PR target/105649 + * gcc.target/powerpc/pr99888-1.c: New test. + * gcc.target/powerpc/pr99888-2.c: New test. + * gcc.target/powerpc/pr99888-3.c: New test. + * gcc.target/powerpc/pr99888-4.c: New test. + * gcc.target/powerpc/pr99888-5.c: New test. + * gcc.target/powerpc/pr99888-6.c: New test. + * c-c++-common/patchable_function_entry-default.c: Adjust for + powerpc_elfv2 to avoid compilation error. + +2022-09-30 Kewen Lin <linkw@linux.ibm.com> + + PR testsuite/106516 + * gcc.dg/pr104992.c: Adjust with vect_int_mod. + * lib/target-supports.exp (check_effective_target_vect_int_mod): New + effective target. + +2022-09-30 Christophe Lyon <christophe.lyon@arm.com> + + * gcc.target/arm/mve/mve_load_memory_modes.c: Update expected + registers. + * gcc.target/arm/mve/mve_store_memory_modes.c: Likewise. + +2022-09-30 Tobias Burnus <tobias@codesourcery.com> + + PR fortran/105318 + * gfortran.dg/gomp/is_device_ptr-1.f90: Remove dg-error. + * gfortran.dg/gomp/is_device_ptr-2.f90: Likewise. + * gfortran.dg/gomp/is_device_ptr-3.f90: Update tree-scan-dump. + +2022-09-29 Joseph Myers <joseph@codesourcery.com> + + * gcc.dg/c2x-attr-noreturn-1.c, gcc.dg/c2x-attr-noreturn-2.c, + gcc.dg/c2x-attr-noreturn-3.c: New tests. + * gcc.dg/c2x-has-c-attribute-2.c: Also test __has_c_attribute for + noreturn attribute. + +2022-09-29 Andrew MacLeod <amacleod@redhat.com> + + * gcc.dg/tree-ssa/pr79095.c: Test evrp pass rather than vrp1. + +2022-09-29 Andrew MacLeod <amacleod@redhat.com> + + PR tree-optimization/102892 + * gcc.dg/pr102892-1.c: Remove undefined behaviour. + +2022-09-29 Patrick Palka <ppalka@redhat.com> + + PR c++/102576 + * g++.dg/modules/pr102576_a.H: New test. + * g++.dg/modules/pr102576_b.C: New test. + +2022-09-29 Jason Merrill <jason@redhat.com> + + * g++.dg/cpp2a/cond-triv3.C: New test. + +2022-09-29 Jason Merrill <jason@redhat.com> + + * g++.dg/cpp1y/constexpr-local4.C: Expect error sooner. + * g++.dg/cpp2a/consteval24.C: Likewise. + * g++.dg/cpp2a/consteval7.C: Likewise. + * g++.dg/cpp2a/inline-asm3.C: Likewise. + +2022-09-29 Jason Merrill <jason@redhat.com> + + PR c++/93046 + * g++.dg/ext/cond4.C: Add runtime test. + +2022-09-29 Jason Merrill <jason@redhat.com> + + * g++.dg/tree-ssa/cond-temp1.C: New test. + +2022-09-29 Julian Brown <julian@codesourcery.com> + + PR middle-end/107028 + * c-c++-common/goacc/struct-component-kind-1.c: New test. + * g++.dg/goacc/pr107028-1.C: New test. + * g++.dg/goacc/pr107028-2.C: New test. + * gfortran.dg/goacc/mapping-tests-5.f90: New test. + +2022-09-29 Patrick Palka <ppalka@redhat.com> + + * g++.dg/ext/has-builtin-1.C: Test existence of __remove_cv, + __remove_reference and __remove_cvref. + * g++.dg/ext/remove_cv.C: New test. + * g++.dg/ext/remove_reference.C: New test. + * g++.dg/ext/remove_cvref.C: New test. + +2022-09-29 Patrick Palka <ppalka@redhat.com> + + * g++.dg/cpp0x/alias-decl-59.C: Adjust expected error message. + * g++.dg/ext/underlying_type7.C: Likewise. + * g++.dg/ext/underlying_type13.C: New test. + * g++.dg/ext/underlying_type14.C: New test. + +2022-09-29 Nathan Sidwell <nathan@acm.org> + + PR c++/100616 + * g++.dg/modules/100616_a.H: New. + * g++.dg/modules/100616_b.C: New. + * g++.dg/modules/100616_c.C: New. + * g++.dg/modules/100616_d.C: New. + +2022-09-29 Jose E. Marchesi <jose.marchesi@oracle.com> + + PR middle-end/25521 + * lib/target-supports.exp (check_effective_target_elf): Define. + * gcc.dg/pr25521.c: New test. + +2022-09-29 Richard Sandiford <richard.sandiford@arm.com> + + * gcc.target/aarch64/cpunative/info_8: Add all dependencies of sve. + * gcc.target/aarch64/cpunative/info_9: Likewise svesm4. + * gcc.target/aarch64/cpunative/info_15: Likewise. + * gcc.target/aarch64/cpunative/info_16: Likewise sve2. + * gcc.target/aarch64/cpunative/info_17: Likewise. + * gcc.target/aarch64/cpunative/native_cpu_2.c: Expect just +nofp + rather than +nofp+nosimd. + * gcc.target/aarch64/cpunative/native_cpu_10.c: Likewise. + * gcc.target/aarch64/target_attr_15.c: Likewise. + +2022-09-29 Richard Sandiford <richard.sandiford@arm.com> + + * gcc.target/aarch64/cpunative/native_cpu_0.c: Expect +crypto + to come after +crc. + * gcc.target/aarch64/cpunative/native_cpu_13.c: Likewise. + * gcc.target/aarch64/cpunative/native_cpu_16.c: Likewise. + * gcc.target/aarch64/cpunative/native_cpu_17.c: Likewise. + * gcc.target/aarch64/cpunative/native_cpu_6.c: Likewise. + * gcc.target/aarch64/cpunative/native_cpu_7.c: Likewise. + * gcc.target/aarch64/options_set_2.c: Likewise. + * gcc.target/aarch64/options_set_3.c: Likewise. + * gcc.target/aarch64/options_set_4.c: Likewise. + +2022-09-29 Richard Sandiford <richard.sandiford@arm.com> + + * gcc.target/aarch64/options_set_6.c: Expect +crypto+nosha2 to + disable crypto but keep aes. + * gcc.target/aarch64/pragma_cpp_predefs_4.c: New test. + +2022-09-29 Richard Biener <rguenther@suse.de> + + PR tree-optimization/105646 + * g++.dg/uninit-pr105646.C: New testcase. + +2022-09-29 liuhongt <hongtao.liu@intel.com> + + * gcc.target/i386/pr107055.c: New test. + 2022-09-28 Eugene Rozenfeld <erozen@microsoft.com> * c-c++-common/ubsan/pr85213.c: Pass -gno-statement-frontiers. diff --git a/gcc/testsuite/c-c++-common/goacc/struct-component-kind-1.c b/gcc/testsuite/c-c++-common/goacc/struct-component-kind-1.c new file mode 100644 index 0000000..8d2f5ea --- /dev/null +++ b/gcc/testsuite/c-c++-common/goacc/struct-component-kind-1.c @@ -0,0 +1,72 @@ +/* { dg-do compile } */ + +#include <stdlib.h> + +#define N 20 + +struct s { + int base[N]; +}; + +int main (void) +{ + struct s v; + +#pragma acc parallel copy(v, v.base[0:N]) +{ } + +#pragma acc parallel copyin(v, v.base[0:N]) +{ } + +#pragma acc parallel copyout(v, v.base[0:N]) +{ } + +#pragma acc parallel copy(v) copyin(v.base[0:N]) +{ } + +#pragma acc parallel copy(v) copyout(v.base[0:N]) +{ } + +#pragma acc parallel copy(v) present(v.base[0:N]) +{ } + +#pragma acc parallel copyin(v) present(v.base[0:N]) +{ } + +#pragma acc parallel copyout(v) present(v.base[0:N]) +{ } + +#pragma acc enter data copyin(v, v.base[0:N]) +#pragma acc update device(v, v.base[0:N]) +#pragma acc exit data delete(v, v.base[0:N]) + +#pragma acc parallel copyin(v) copy(v.base[0:N]) +/* { dg-error "data movement for component 'v\\.(s::)?base\\\[0\\\]' is not compatible with movement for struct 'v'" "" { target *-*-* } .-1 } */ +{ } + +#pragma acc parallel copyout(v) copy(v.base[0:N]) +/* { dg-error "data movement for component 'v\\.(s::)?base\\\[0\\\]' is not compatible with movement for struct 'v'" "" { target *-*-* } .-1 } */ +{ } + +#pragma acc parallel present(v) copy(v.base[0:N]) +/* { dg-error "data movement for component 'v\\.(s::)?base\\\[0\\\]' is not compatible with movement for struct 'v'" "" { target *-*-* } .-1 } */ +{ } + +#pragma acc parallel present(v) copyin(v.base[0:N]) +/* { dg-error "data movement for component 'v\\.(s::)?base\\\[0\\\]' is not compatible with movement for struct 'v'" "" { target *-*-* } .-1 } */ +{ } + +#pragma acc parallel present(v) copyout(v.base[0:N]) +/* { dg-error "data movement for component 'v\\.(s::)?base\\\[0\\\]' is not compatible with movement for struct 'v'" "" { target *-*-* } .-1 } */ +{ } + +#pragma acc parallel present(v) no_create(v.base[0:N]) +/* { dg-error "data movement for component 'v\\.(s::)?base\\\[0\\\]' is not compatible with movement for struct 'v'" "" { target *-*-* } .-1 } */ +{ } + +#pragma acc parallel no_create(v) present(v.base[0:N]) +/* { dg-error "data movement for component 'v\\.(s::)?base\\\[0\\\]' is not compatible with movement for struct 'v'" "" { target *-*-* } .-1 } */ +{ } + + return 0; +} diff --git a/gcc/testsuite/c-c++-common/gomp/begin-declare-target-1.c b/gcc/testsuite/c-c++-common/gomp/begin-declare-target-1.c new file mode 100644 index 0000000..fd8caba --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/begin-declare-target-1.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-fopenmp" } */ + +extern int a; +#pragma omp begin declare target device_type (host) +int b; +#pragma omp begin declare target device_type (any) +char d; +#pragma omp end declare target +#pragma omp end declare target +#pragma omp begin declare target +long c; +#pragma omp end declare target +#pragma omp declare target +int foo (void) { return 0; } +#pragma omp begin declare target device_type (any) +int bar (void) { return 0; } +#pragma omp end declare target +#pragma omp end declare target +#pragma omp begin declare target device_type (any) +int baz (void) { return 0; } +#pragma omp declare target +int qux (void) { return 0; } +#pragma omp end declare target +#pragma omp end declare target diff --git a/gcc/testsuite/c-c++-common/gomp/begin-declare-target-2.c b/gcc/testsuite/c-c++-common/gomp/begin-declare-target-2.c new file mode 100644 index 0000000..2bc72cf --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/begin-declare-target-2.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-fopenmp" } */ + +extern int a; +#pragma omp begin declare target +#pragma omp declare target to (a) +#pragma omp end declare target +int b; +#pragma omp begin declare target to (b) /* { dg-error "'to' is not valid for '#pragma omp begin declare target'" } */ +#pragma omp end declare target +int c; +#pragma omp begin declare target link (c) /* { dg-error "'link' is not valid for '#pragma omp begin declare target'" } */ +#pragma omp end declare target +int m; +#pragma omp begin declare target device_type (host) device_type (any) /* { dg-error "too many 'device_type' clauses" } */ +#pragma omp end declare target +#pragma omp begin declare target +#pragma omp end declare target to (p) /* { dg-error "expected end of line before .to." } */ diff --git a/gcc/testsuite/c-c++-common/gomp/begin-declare-target-3.c b/gcc/testsuite/c-c++-common/gomp/begin-declare-target-3.c new file mode 100644 index 0000000..ac4d4d9 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/begin-declare-target-3.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-fopenmp" } */ + +#pragma omp begin declare target +int a[] = { 1, 2, 3 }; +extern int b[]; /* { dg-error "'b' in declare target directive does not have mappable type" } */ +extern int c[]; /* { dg-error "'c' in declare target directive does not have mappable type" } */ +extern int d[]; /* { dg-error "'d' in declare target directive does not have mappable type" } */ +int d[3]; +#pragma omp end declare target +int c[3]; +#pragma omp begin declare target device_type (host) +int e[] = { 1, 2, 3 }; +extern int f[]; /* { dg-error "'f' in declare target directive does not have mappable type" } */ +extern int g[]; /* { dg-error "'g' in declare target directive does not have mappable type" } */ +extern int h[]; /* { dg-error "'h' in declare target directive does not have mappable type" } */ +int h[3]; +#pragma omp end declare target +int g[3]; diff --git a/gcc/testsuite/c-c++-common/gomp/begin-declare-target-4.c b/gcc/testsuite/c-c++-common/gomp/begin-declare-target-4.c new file mode 100644 index 0000000..d275f73 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/begin-declare-target-4.c @@ -0,0 +1,2 @@ +#pragma omp begin declare target +void foo (void); /* { dg-error "'#pragma omp begin declare target' without corresponding '#pragma omp end declare target'" } */ diff --git a/gcc/testsuite/c-c++-common/gomp/declare-target-4.c b/gcc/testsuite/c-c++-common/gomp/declare-target-4.c index 887a815..a6bd128 100644 --- a/gcc/testsuite/c-c++-common/gomp/declare-target-4.c +++ b/gcc/testsuite/c-c++-common/gomp/declare-target-4.c @@ -1,8 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-fopenmp" } */ -#pragma omp declare target device_type (any) /* { dg-warning "directive with only 'device_type' clauses ignored" } */ - void f1 (void) {} void f2 (void); #pragma omp declare target to (f1) device_type (any) to (f2) @@ -38,7 +36,3 @@ void f13 (void) {} void f14 (void) {} #pragma omp declare target device_type (nohost) to (f14) #pragma omp declare target device_type (any) to (f14) -void f15 (void) {} -#pragma omp declare target device_type (host) to (f15) device_type (nohost) -void f16 (void) {} -#pragma omp declare target device_type (any) to (f15) device_type (any) diff --git a/gcc/testsuite/c-c++-common/gomp/declare-target-6.c b/gcc/testsuite/c-c++-common/gomp/declare-target-6.c index 586eb50..ba323e2 100644 --- a/gcc/testsuite/c-c++-common/gomp/declare-target-6.c +++ b/gcc/testsuite/c-c++-common/gomp/declare-target-6.c @@ -1,2 +1,2 @@ -#pragma omp end declare target /* { dg-error "'#pragma omp end declare target' without corresponding '#pragma omp declare target'" } */ +#pragma omp end declare target /* { dg-error "'#pragma omp end declare target' without corresponding '#pragma omp declare target' or '#pragma omp begin declare target'" } */ void foo (void); diff --git a/gcc/testsuite/c-c++-common/gomp/declare-target-7.c b/gcc/testsuite/c-c++-common/gomp/declare-target-7.c new file mode 100644 index 0000000..747000a --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/declare-target-7.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-options "-fopenmp" } */ + +#pragma omp declare target device_type (any) /* { dg-error "directive with only 'device_type' clause" } */ + +void f1 (void) {} +#pragma omp declare target device_type (host) to (f1) device_type (nohost) /* { dg-error "too many 'device_type' clauses" } */ +#pragma omp declare target device_type (any) to (f1) device_type (any) /* { dg-error "too many 'device_type' clauses" } */ diff --git a/gcc/testsuite/c-c++-common/patchable_function_entry-default.c b/gcc/testsuite/c-c++-common/patchable_function_entry-default.c index 7036f7b..a501efc 100644 --- a/gcc/testsuite/c-c++-common/patchable_function_entry-default.c +++ b/gcc/testsuite/c-c++-common/patchable_function_entry-default.c @@ -1,6 +1,9 @@ /* { dg-do compile { target { ! { nvptx*-*-* visium-*-* } } } } */ /* { dg-options "-O2 -fpatchable-function-entry=3,1" } */ /* { dg-additional-options "-fno-pie" { target sparc*-*-* } } */ +/* See PR99888, one single preceding nop isn't allowed on powerpc_elfv2, + so overriding with two preceding nops to make it pass there. */ +/* { dg-additional-options "-fpatchable-function-entry=3,2" { target powerpc_elfv2 } } */ /* { dg-final { scan-assembler-times "nop|NOP|SWYM" 3 { target { ! { alpha*-*-* } } } } } */ /* { dg-final { scan-assembler-times "bis" 3 { target alpha*-*-* } } } */ diff --git a/gcc/testsuite/c-c++-common/pr69543-3.c b/gcc/testsuite/c-c++-common/pr69543-3.c index fcf750c..6d4224f 100644 --- a/gcc/testsuite/c-c++-common/pr69543-3.c +++ b/gcc/testsuite/c-c++-common/pr69543-3.c @@ -3,15 +3,11 @@ /* Verify disabling a warning, where the _Pragma is in regular code, but the affected code is within a macro. */ -/* TODO: XFAIL: both C and C++ erroneously fail to suppress the warning - The warning is reported at the macro definition location, rather than - the macro expansion location. */ - -#define WARNABLE_CODE *++yyvsp = yylval; /* { dg-bogus "used uninitialized" "" { xfail *-*-* } } */ +#define WARNABLE_CODE *++yyvsp = yylval; /* { dg-bogus "used uninitialized" } */ void test (char yylval) { - char *yyvsp; /* { dg-bogus "declared here" "" { xfail *-*-* } } */ + char *yyvsp; /* { dg-bogus "declared here" } */ _Pragma ("GCC diagnostic push") _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") diff --git a/gcc/testsuite/c-c++-common/pr69543-4.c b/gcc/testsuite/c-c++-common/pr69543-4.c index cd71e7e..3db2eeb 100644 --- a/gcc/testsuite/c-c++-common/pr69543-4.c +++ b/gcc/testsuite/c-c++-common/pr69543-4.c @@ -3,10 +3,6 @@ /* Verify disabling a warning, where both the _Pragma and the affected code are within (different) macros. */ -/* TODO: XFAIL: both C and C++ erroneously fail to suppress the warning - The warning is reported at the macro definition location, rather than - the macro expansion location. */ - # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ @@ -14,11 +10,11 @@ # define YY_IGNORE_MAYBE_UNINITIALIZED_END \ _Pragma ("GCC diagnostic pop") -#define WARNABLE_CODE *++yyvsp = yylval; /* { dg-bogus "used uninitialized" "" { xfail *-*-* } } */ +#define WARNABLE_CODE *++yyvsp = yylval; /* { dg-bogus "used uninitialized" } */ void test (char yylval) { - char *yyvsp; /* { dg-bogus "declared here" "" { xfail *-*-* } } */ + char *yyvsp; /* { dg-bogus "declared here" } */ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN WARNABLE_CODE YY_IGNORE_MAYBE_UNINITIALIZED_END diff --git a/gcc/testsuite/c-c++-common/pr91669.c b/gcc/testsuite/c-c++-common/pr91669.c new file mode 100644 index 0000000..1070751e --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr91669.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-Wreturn-type" } */ + +/* The location of the right brace within the macro expansion can be an adhoc + location, because the frontend attached custom data to it. In order for the + diagnostic pragma to correctly understand that the diagnostic pop occurs + after the function and not before, linemap_location_before_p needs to handle + adhoc locations within a macro map, which was broken until fixed by r10-325. + Verify that we get it right, both when the brace is a macro token and when it + is part of the macro expansion. */ + +#define ENDFUNC1 \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wreturn-type\"") \ + } /* { dg-bogus {-Wreturn-type} } */ \ + _Pragma("GCC diagnostic pop") + +int f1 () { +ENDFUNC1 /* { dg-bogus {in expansion of macro 'ENDFUNC1' } } */ + +#define ENDFUNC2(term) \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wreturn-type\"") \ + term /* { dg-bogus {in definition of macro 'ENDFUNC2'} } */ \ + _Pragma("GCC diagnostic pop") + +int f2 () { +ENDFUNC2(}) /* { dg-bogus {-Wreturn-type} } */ diff --git a/gcc/testsuite/c-c++-common/pragma-diag-16.c b/gcc/testsuite/c-c++-common/pragma-diag-16.c new file mode 100644 index 0000000..8cacd87 --- /dev/null +++ b/gcc/testsuite/c-c++-common/pragma-diag-16.c @@ -0,0 +1,63 @@ +/* Make sure that the 3 types of warnings generated from tree-ssa-uninit.cc have + proper virtual locations and so can be controlled by pragmas when they appear + in macros. */ + +/* { dg-do compile } */ +/* { dg-options "-Wuninitialized -Wmaybe-uninitialized" } */ + +/* 1. Check maybe_warn_read_write_only(). */ +#define DEREF1(p) (*p) /* { dg-warning {may be used uninitialized} } */ +__attribute__ ((access (write_only, 1))) +int f1 (int* x) /* { dg-note {accessing argument 1} } */ +{ + return DEREF1 (x); /* { dg-note {in expansion of macro 'DEREF1'} } */ +} + +#define DEREF2(p) (*p) /* { dg-bogus {may be used uninitialized} } */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +__attribute__ ((access (write_only, 1))) +int f2 (int* x) /* { dg-bogus {accessing argument 1} } */ +{ + return DEREF2 (x); /* { dg-bogus {in expansion of macro 'DEREF1'} } */ +} +#pragma GCC diagnostic pop + +/* 2. Check warn_uninit(). */ +int g; +#define SET3(a, b) ((a) = (b)) /* { dg-warning {'x' is used uninitialized} } */ +void f3 () +{ + int x; /* { dg-note {'x' was declared here} } */ + SET3 (g, x); /* { dg-note {in expansion of macro 'SET3'} } */ +} + +#define SET4(a, b) ((a) = (b)) /* { dg-bogus {'x' is used uninitialized} } */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wuninitialized" +void f4 () +{ + int x; /* { dg-bogus {'x' was declared here} } */ + SET4 (g, x); /* { dg-bogus {in expansion of macro 'SET3'} } */ +} +#pragma GCC diagnostic pop + +/* 3. Check maybe_warn_operand(). */ +#define CALL5(func, arg) ((func) (arg)) /* { dg-warning {'c' may be used uninitialized} } */ +void f5a (const char *); /* { dg-note {by argument 1} } */ +void f5b () +{ + char c; /* { dg-note {'c' declared here} } */ + CALL5 (f5a, &c); /* { dg-note {in expansion of macro 'CALL5'} } */ +} + +#define CALL6(func, arg) ((func) (arg)) /* { dg-bogus {'c' may be used uninitialized} } */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +void f6a (const char *); /* { dg-bogus {by argument 1} } */ +void f6b () +{ + char c; /* { dg-bogus {'c' declared here} } */ + CALL6 (f6a, &c); /* { dg-bogus {in expansion of macro 'CALL6'} } */ +} +#pragma GCC diagnostic pop diff --git a/gcc/testsuite/c-c++-common/torture/attr-noinit-1.c b/gcc/testsuite/c-c++-common/torture/attr-noinit-1.c index 877e764..f84eba0 100644 --- a/gcc/testsuite/c-c++-common/torture/attr-noinit-1.c +++ b/gcc/testsuite/c-c++-common/torture/attr-noinit-1.c @@ -1,4 +1,5 @@ -/* { dg-do run } */ +/* { dg-do link } */ +/* { dg-do run { target { vma_equals_lma } } } */ /* { dg-require-effective-target noinit } */ /* { dg-skip-if "data LMA != VMA" { msp430-*-* } { "-mlarge" } } */ /* { dg-options "-save-temps" } */ diff --git a/gcc/testsuite/c-c++-common/torture/attr-noinit-2.c b/gcc/testsuite/c-c++-common/torture/attr-noinit-2.c index befa2a0..4528b9e 100644 --- a/gcc/testsuite/c-c++-common/torture/attr-noinit-2.c +++ b/gcc/testsuite/c-c++-common/torture/attr-noinit-2.c @@ -1,4 +1,5 @@ -/* { dg-do run } */ +/* { dg-do link } */ +/* { dg-do run { target { vma_equals_lma } } } */ /* { dg-require-effective-target noinit } */ /* { dg-options "-fdata-sections -save-temps" } */ /* { dg-skip-if "data LMA != VMA" { msp430-*-* } { "-mlarge" } } */ diff --git a/gcc/testsuite/c-c++-common/torture/attr-noinit-3.c b/gcc/testsuite/c-c++-common/torture/attr-noinit-3.c index 519e88a..2f17456 100644 --- a/gcc/testsuite/c-c++-common/torture/attr-noinit-3.c +++ b/gcc/testsuite/c-c++-common/torture/attr-noinit-3.c @@ -1,4 +1,5 @@ -/* { dg-do run } */ +/* { dg-do link } */ +/* { dg-do run { target { vma_equals_lma } } } */ /* { dg-require-effective-target noinit } */ /* { dg-options "-flto -save-temps" } */ /* { dg-skip-if "data LMA != VMA" { msp430-*-* } { "-mlarge" } } */ diff --git a/gcc/testsuite/c-c++-common/torture/attr-persistent-1.c b/gcc/testsuite/c-c++-common/torture/attr-persistent-1.c index 72dc3c2..b11a515 100644 --- a/gcc/testsuite/c-c++-common/torture/attr-persistent-1.c +++ b/gcc/testsuite/c-c++-common/torture/attr-persistent-1.c @@ -1,4 +1,5 @@ -/* { dg-do run } */ +/* { dg-do link } */ +/* { dg-do run { target { vma_equals_lma } } } */ /* { dg-require-effective-target persistent } */ /* { dg-skip-if "data LMA != VMA" { msp430-*-* } { "-mlarge" } } */ /* { dg-options "-save-temps" } */ diff --git a/gcc/testsuite/c-c++-common/torture/attr-persistent-3.c b/gcc/testsuite/c-c++-common/torture/attr-persistent-3.c index 3e4fd28..068a72a 100644 --- a/gcc/testsuite/c-c++-common/torture/attr-persistent-3.c +++ b/gcc/testsuite/c-c++-common/torture/attr-persistent-3.c @@ -1,4 +1,5 @@ -/* { dg-do run } */ +/* { dg-do link } */ +/* { dg-do run { target { vma_equals_lma } } } */ /* { dg-require-effective-target persistent } */ /* { dg-options "-flto -save-temps" } */ /* { dg-skip-if "data LMA != VMA" { msp430-*-* } { "-mlarge" } } */ diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-59.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-59.C index 1f5e94f..5094657 100644 --- a/gcc/testsuite/g++.dg/cpp0x/alias-decl-59.C +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-59.C @@ -5,7 +5,7 @@ template<typename> struct A {}; template<typename T> -using B = A<__underlying_type(T) [[gnu::aligned(4)]]>; // { dg-warning "ignoring attributes on template argument" } +using B = A<__underlying_type(T) [[gnu::aligned(4)]]>; // { dg-warning "ignoring attributes applied to dependent type" } template<typename T> -using B = A<__underlying_type(T) [[gnu::packed]]>; // { dg-warning "ignoring attributes on template argument" } +using B = A<__underlying_type(T) [[gnu::packed]]>; // { dg-warning "ignoring attributes applied to dependent type" } diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-local4.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-local4.C index bef6248..647b5dc 100644 --- a/gcc/testsuite/g++.dg/cpp1y/constexpr-local4.C +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-local4.C @@ -10,8 +10,8 @@ const A a = 42; constexpr int f() { - const int j = a.i; // { dg-message "'a'" } + const int j = a.i; // { dg-error "'a'" } return j; } -static_assert (f() == 42,""); // { dg-error "non-constant" } +static_assert (f() == 42,""); // { dg-error "" } diff --git a/gcc/testsuite/g++.dg/cpp23/ext-floating11.C b/gcc/testsuite/g++.dg/cpp23/ext-floating11.C new file mode 100644 index 0000000..2a52c94 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/ext-floating11.C @@ -0,0 +1,79 @@ +// P1467R9 - Extended floating-point types and standard names. +// { dg-do compile { target c++23 } } +// { dg-options "" } + +#include "ext-floating.h" + +#ifdef __STRICT_ANSI__ +#undef __SIZEOF_FLOAT128__ +#endif + +extern "C" void abort (); + +using namespace std; + +template <typename T, typename U> +int +foo (T x, U y) noexcept +{ + return 3; +} + +int +main () +{ + if (foo (0.0f, 0.0f) != 3) + abort (); + if (foo (0.0, 0.0) != 3) + abort (); + if (foo (0.0L, 0.0L) != 3) + abort (); +#ifdef __STDCPP_FLOAT16_T__ + if (foo (0.0f16, 0.0f16) != 3) + abort (); + if (foo (0.0f, 0.0f16) != 3) + abort (); +#endif +#ifdef __STDCPP_FLOAT32_T__ + if (foo (0.0f32, 0.0f32) != 3) + abort (); + if (foo (0.0f, 0.0f32) != 3) + abort (); +#endif +#ifdef __STDCPP_FLOAT64_T__ + if (foo (0.0f64, 0.0f64) != 3) + abort (); + if (foo (0.0, 0.0f64) != 3) + abort (); +#endif +#ifdef __STDCPP_FLOAT128_T__ + if (foo (0.0f128, 0.0f128) != 3) + abort (); + if (foo (0.0L, 0.0f128) != 3) + abort (); +#endif +#ifdef __STDCPP_BFLOAT16_T__ + if (foo (0.0bf16, 0.0bf16) != 3) + abort (); + if (foo (0.0f, 0.0bf16) != 3) + abort (); +#endif +#ifdef __FLT32X_MANT_DIG__ + if (foo (0.0f32x, 0.0f32x) != 3) + abort (); + if (foo (0.0, 0.0f32x) != 3) + abort (); +#endif +#ifdef __FLT64X_MANT_DIG__ + if (foo (0.0f64x, 0.0f64x) != 3) + abort (); + if (foo (0.0L, 0.0f64x) != 3) + abort (); +#endif +#ifdef __FLT128X_MANT_DIG__ + if (foo (0.0f128x, 0.0f128x) != 3) + abort (); + if (foo (0.0L, 0.0f128x) != 3) + abort (); +#endif +} diff --git a/gcc/testsuite/g++.dg/cpp2a/cond-triv3.C b/gcc/testsuite/g++.dg/cpp2a/cond-triv3.C new file mode 100644 index 0000000..d0711cf --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/cond-triv3.C @@ -0,0 +1,44 @@ +// { dg-do compile { target c++20 } } + +template<class T> +struct X +{ + T first{}; + + X& operator=(const X&) = delete; + X& operator=(const X&) requires requires (T& t) { t = t; } { return *this; } +}; + +// C++20 std::pair<const int, int>: +using cxx20_pair = X<const int>; +static_assert( __is_trivially_constructible(cxx20_pair, const cxx20_pair&), "" ); +static_assert( !__is_assignable(cxx20_pair&, const cxx20_pair&), "" ); +static_assert( __is_trivially_copyable(cxx20_pair), "" ); + +template<bool, typename, typename F> struct conditional { using type = F; }; +template<typename T, typename F> struct conditional<true, T, F> { using type = T; }; + +struct base +{ + base() = default; + ~base() = default; + base(const base&) = default; + base& operator=(const base&) = delete; +}; + +struct nope; + +template<class T> +struct Y : base +{ + T first{}; + + Y& operator=(typename conditional<__is_assignable(T&, const T&), const Y&, const nope&>::type) + { return *this; } +}; + +// C++17 std::pair<const int, int>: +using cxx17_pair = Y<const int>; +static_assert( __is_trivially_constructible(cxx17_pair, const cxx17_pair&), "" ); +static_assert( ! __is_assignable(cxx17_pair&, const cxx17_pair&), "" ); +static_assert( __is_trivially_copyable(cxx17_pair), "???" ); diff --git a/gcc/testsuite/g++.dg/cpp2a/consteval24.C b/gcc/testsuite/g++.dg/cpp2a/consteval24.C index 6d0c63c..6d7034c 100644 --- a/gcc/testsuite/g++.dg/cpp2a/consteval24.C +++ b/gcc/testsuite/g++.dg/cpp2a/consteval24.C @@ -27,4 +27,4 @@ bar () return fn1 () + fn2 () + (s.*fn3) () + (s.*fn4) () + fn5 () + (s.*fn6) () + (s.*fn7) (); } -auto a = bar (); +auto a = bar (); // { dg-error "bar" } diff --git a/gcc/testsuite/g++.dg/cpp2a/consteval7.C b/gcc/testsuite/g++.dg/cpp2a/consteval7.C index 23f3d25..74996d3 100644 --- a/gcc/testsuite/g++.dg/cpp2a/consteval7.C +++ b/gcc/testsuite/g++.dg/cpp2a/consteval7.C @@ -10,4 +10,4 @@ consteval int qux () { S s = baz (); return s.b + s.c (); } consteval int quux () { constexpr S s = baz (); return s.b + s.c (); } // { dg-error "immediate evaluation returns address of immediate function 'consteval int foo\\(\\)'" } constexpr auto d = baz (); // { dg-error "immediate evaluation returns address of immediate function 'consteval int foo\\(\\)'" } constexpr auto e = qux (); -constexpr auto f = quux (); +constexpr auto f = quux (); // { dg-error "quux" } diff --git a/gcc/testsuite/g++.dg/cpp2a/inline-asm3.C b/gcc/testsuite/g++.dg/cpp2a/inline-asm3.C index a7476b1..a6f612e 100644 --- a/gcc/testsuite/g++.dg/cpp2a/inline-asm3.C +++ b/gcc/testsuite/g++.dg/cpp2a/inline-asm3.C @@ -9,4 +9,4 @@ foo () return i; } -constexpr int i = foo (); +constexpr int i = foo (); // { dg-error "foo" } diff --git a/gcc/testsuite/g++.dg/ext/cond4.C b/gcc/testsuite/g++.dg/ext/cond4.C index d2853f4..8699330 100644 --- a/gcc/testsuite/g++.dg/ext/cond4.C +++ b/gcc/testsuite/g++.dg/ext/cond4.C @@ -1,10 +1,14 @@ // PR c++/93046 -// { dg-do compile } +// { dg-do run } // { dg-options "" } +int c; + struct S { - S (int); - operator bool (); + int i; + S (int i) : i(i) { ++c; } + S (const S &s): i(s.i) { ++c; } + operator bool () { return i; } }; S @@ -12,3 +16,10 @@ foo () { return S (1) ? : S (2); } + +int main() +{ + S s = foo(); + if (s.i != 1 || c != 2) + __builtin_abort (); +} diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C index 17dabf6..f343e15 100644 --- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C +++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C @@ -137,3 +137,12 @@ #if !__has_builtin (__is_nothrow_convertible) # error "__has_builtin (__is_nothrow_convertible) failed" #endif +#if !__has_builtin (__remove_cv) +# error "__has_builtin (__remove_cv) failed" +#endif +#if !__has_builtin (__remove_reference) +# error "__has_builtin (__remove_reference) failed" +#endif +#if !__has_builtin (__remove_cvref) +# error "__has_builtin (__remove_cvref) failed" +#endif diff --git a/gcc/testsuite/g++.dg/ext/remove_cv.C b/gcc/testsuite/g++.dg/ext/remove_cv.C new file mode 100644 index 0000000..cff7050 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/remove_cv.C @@ -0,0 +1,32 @@ +// { dg-do compile { target c++11 } } + +#define SA(X) static_assert((X),#X) + +SA(__is_same(__remove_cv(void), void)); +SA(__is_same(__remove_cv(int*), int*)); + +SA(__is_same(__remove_cv(int&), int&)); +SA(__is_same(__remove_cv(const int&), const int&)); +SA(__is_same(__remove_cv(volatile int&), volatile int&)); +SA(__is_same(__remove_cv(const volatile int&), const volatile int&)); + +SA(__is_same(__remove_cv(int&&), int&&)); +SA(__is_same(__remove_cv(const int&&), const int&&)); +SA(__is_same(__remove_cv(volatile int&&), volatile int&&)); +SA(__is_same(__remove_cv(const volatile int&&), const volatile int&&)); + +SA(__is_same(__remove_cv(int[3]), int[3])); +SA(__is_same(__remove_cv(const int[3]), int[3])); +SA(__is_same(__remove_cv(volatile int[3]), int[3])); +SA(__is_same(__remove_cv(const volatile int[3]), int[3])); + +SA(__is_same(__remove_cv(int(int)), int(int))); +SA(__is_same(__remove_cv(int(*const)(int)), int(*)(int))); +SA(__is_same(__remove_cv(int(*volatile)(int)), int(*)(int))); +SA(__is_same(__remove_cv(int(*const volatile)(int)), int(*)(int))); + +template<class T> using const_non_volatile_t = const __remove_cv(T); +SA(__is_same(const_non_volatile_t<int>, const int)); +SA(__is_same(const_non_volatile_t<volatile int>, const int)); +SA(__is_same(const_non_volatile_t<int&>, int&)); +SA(__is_same(const_non_volatile_t<const int&>, const int&)); diff --git a/gcc/testsuite/g++.dg/ext/remove_cvref.C b/gcc/testsuite/g++.dg/ext/remove_cvref.C new file mode 100644 index 0000000..109d54f --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/remove_cvref.C @@ -0,0 +1,32 @@ +// { dg-do compile { target c++11 } } + +#define SA(X) static_assert((X),#X) + +SA(__is_same(__remove_cvref(void), void)); +SA(__is_same(__remove_cvref(int*), int*)); + +SA(__is_same(__remove_cvref(int&), int)); +SA(__is_same(__remove_cvref(const int&), int)); +SA(__is_same(__remove_cvref(volatile int&), int)); +SA(__is_same(__remove_cvref(const volatile int&), int)); + +SA(__is_same(__remove_cvref(int&&), int)); +SA(__is_same(__remove_cvref(const int&&), int)); +SA(__is_same(__remove_cvref(volatile int&&), int)); +SA(__is_same(__remove_cvref(const volatile int&&), int)); + +SA(__is_same(__remove_cvref(int[3]), int[3])); +SA(__is_same(__remove_cvref(const int[3]), int[3])); +SA(__is_same(__remove_cvref(volatile int[3]), int[3])); +SA(__is_same(__remove_cvref(const volatile int[3]), int[3])); + +SA(__is_same(__remove_cvref(int(int)), int(int))); +SA(__is_same(__remove_cvref(int(*const)(int)), int(*)(int))); +SA(__is_same(__remove_cvref(int(*volatile)(int)), int(*)(int))); +SA(__is_same(__remove_cvref(int(*const volatile)(int)), int(*)(int))); + +template<class T> using const_non_volatile_non_ref_t = const __remove_cvref(T); +SA(__is_same(const_non_volatile_non_ref_t<int>, const int)); +SA(__is_same(const_non_volatile_non_ref_t<volatile int&>, const int)); +SA(__is_same(const_non_volatile_non_ref_t<int&>, const int)); +SA(__is_same(const_non_volatile_non_ref_t<const int&>, const int)); diff --git a/gcc/testsuite/g++.dg/ext/remove_reference.C b/gcc/testsuite/g++.dg/ext/remove_reference.C new file mode 100644 index 0000000..1a2580b --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/remove_reference.C @@ -0,0 +1,32 @@ +// { dg-do compile { target c++11 } } + +#define SA(X) static_assert((X),#X) + +SA(__is_same(__remove_reference(void), void)); +SA(__is_same(__remove_reference(int*), int*)); + +SA(__is_same(__remove_reference(int&), int)); +SA(__is_same(__remove_reference(const int&), const int)); +SA(__is_same(__remove_reference(volatile int&), volatile int)); +SA(__is_same(__remove_reference(const volatile int&), const volatile int)); + +SA(__is_same(__remove_reference(int&&), int)); +SA(__is_same(__remove_reference(const int&&), const int)); +SA(__is_same(__remove_reference(volatile int&&), volatile int)); +SA(__is_same(__remove_reference(const volatile int&&), const volatile int)); + +SA(__is_same(__remove_reference(int[3]), int[3])); +SA(__is_same(__remove_reference(const int[3]), const int[3])); +SA(__is_same(__remove_reference(volatile int[3]), volatile int[3])); +SA(__is_same(__remove_reference(const volatile int[3]), const volatile int[3])); + +SA(__is_same(__remove_reference(int(int)), int(int))); +SA(__is_same(__remove_reference(int(*const)(int)), int(*const)(int))); +SA(__is_same(__remove_reference(int(*volatile)(int)), int(*volatile)(int))); +SA(__is_same(__remove_reference(int(*const volatile)(int)), int(*const volatile)(int))); + +template<class T> using const_non_ref_t = const __remove_reference(T); +SA(__is_same(const_non_ref_t<int>, const int)); +SA(__is_same(const_non_ref_t<volatile int&>, const volatile int)); +SA(__is_same(const_non_ref_t<int&>, const int)); +SA(__is_same(const_non_ref_t<const int&>, const int)); diff --git a/gcc/testsuite/g++.dg/ext/stmtexpr24.C b/gcc/testsuite/g++.dg/ext/stmtexpr24.C new file mode 100644 index 0000000..907d027 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/stmtexpr24.C @@ -0,0 +1,27 @@ +// { dg-do compile } +// { dg-options "" } + +void +foo (int x) +{ + bool a = false; + if (x == 1) + goto l1; // { dg-message "from here" } + a = ({ l0:; if (x == 0) goto l0; true; }); + a = ({ if (x == 0) throw 1; true; }); + a = ({ l1:; true; }); // { dg-error "jump to label 'l1'" } + // { dg-message "enters statement expression" "" { target *-*-* } .-1 } + a = ({ l2:; true; }); // { dg-error "jump to label 'l2'" } + switch (x) + { + case 2: + a = ({ case 3:; true; }); // { dg-error "jump to case label" } + // { dg-message "enters statement expression" "" { target *-*-* } .-1 } + a = ({ default:; true; }); // { dg-error "jump to case label" } + // { dg-message "enters statement expression" "" { target *-*-* } .-1 } + break; + } + if (x == 4) + goto l2; // { dg-message "from here" } + // { dg-message "enters statement expression" "" { target *-*-* } .-1 } +} diff --git a/gcc/testsuite/g++.dg/ext/underlying_type13.C b/gcc/testsuite/g++.dg/ext/underlying_type13.C new file mode 100644 index 0000000..c53da11 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/underlying_type13.C @@ -0,0 +1,7 @@ +// Verify when substituting __underlying_type its cv-quals are carried over. +// { dg-do compile { target c++11 } } + +template<class T> using const_underlying_type_t = const __underlying_type(T); +enum A { a }; +using type = const_underlying_type_t<A>; +using type = const __underlying_type(A); diff --git a/gcc/testsuite/g++.dg/ext/underlying_type14.C b/gcc/testsuite/g++.dg/ext/underlying_type14.C new file mode 100644 index 0000000..91840b2 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/underlying_type14.C @@ -0,0 +1,8 @@ +// Verify pretty-printing when nesting a builtin trait. + +template<class T> void f(__underlying_type(__underlying_type(T))); // { dg-error "" } +// { dg-message "__underlying_type\\(__underlying_type\\(T\\)\\)\\)" "" { target *-*-* } .-1 } + +int main() { + f<int>(0); // { dg-error "no match" } +} diff --git a/gcc/testsuite/g++.dg/ext/underlying_type7.C b/gcc/testsuite/g++.dg/ext/underlying_type7.C index 2d6ec51..137a0f0 100644 --- a/gcc/testsuite/g++.dg/ext/underlying_type7.C +++ b/gcc/testsuite/g++.dg/ext/underlying_type7.C @@ -9,7 +9,7 @@ enum class E6 : long { c = __LONG_MAX__ }; template<typename T> void - test(T, __underlying_type(T)) // { dg-message "sorry, unimplemented: mangling" } + test(T, __underlying_type(T)) // { dg-error "built-in trait '__underlying_type\\(T\\)'" } { } int main() diff --git a/gcc/testsuite/g++.dg/goacc/pr107028-1.C b/gcc/testsuite/g++.dg/goacc/pr107028-1.C new file mode 100644 index 0000000..93b8743 --- /dev/null +++ b/gcc/testsuite/g++.dg/goacc/pr107028-1.C @@ -0,0 +1,14 @@ +// { dg-do compile } +// { dg-additional-options "-fdump-tree-gimple" } + +class data_container { + public: + int data; +}; + +void test2() { + data_container a; +#pragma acc data copyin(a, a.data) +// { dg-final { scan-tree-dump {map\(to:a \[len: [0-9]+\]\)} "gimple" } } +{ } +} diff --git a/gcc/testsuite/g++.dg/goacc/pr107028-2.C b/gcc/testsuite/g++.dg/goacc/pr107028-2.C new file mode 100644 index 0000000..cf741bd --- /dev/null +++ b/gcc/testsuite/g++.dg/goacc/pr107028-2.C @@ -0,0 +1,27 @@ +// { dg-do compile } +// { dg-additional-options "-fdump-tree-gimple" } + +#include <cstdlib> + +typedef float real_t; + +struct foo { + real_t *data; +}; + +#define n 1024 + +int test3() { + real_t *a = (real_t *)malloc(n * sizeof(real_t)); + struct foo b; + b.data = (real_t *)malloc(n * sizeof(real_t)); + + #pragma acc data copyin(a[0:n], b, b.data[0:n]) +// { dg-final { scan-tree-dump {map\(to:\*_[0-9]+ \[len: [0-9]+\]\) map\(attach:b.data \[bias: 0\]\) map\(to:b \[len: [0-9]+\]\) map\(to:\*a \[len: [0-9]+\]\)} "gimple" } } + { } + + free (b.data); + free (a); + + return 0; +} diff --git a/gcc/testsuite/g++.dg/gomp/attrs-18.C b/gcc/testsuite/g++.dg/gomp/attrs-18.C new file mode 100644 index 0000000..6858f3f --- /dev/null +++ b/gcc/testsuite/g++.dg/gomp/attrs-18.C @@ -0,0 +1,41 @@ +// { dg-do compile { target c++11 } } + +#pragma omp begin declare target +#pragma omp begin declare target device_type (any) +[[omp::directive (begin declare target, device_type (host))]]; +int a; +[[omp::directive (end declare target)]]; +#pragma omp end declare target +#pragma omp end declare target +[[omp::directive (begin declare target device_type (nohost))]]; +int b; +#pragma omp end declare target // { dg-error "'begin declare target' in attribute syntax terminated with 'end declare target' in pragma syntax" } +#pragma omp begin declare target +int c; +[[omp::directive (end declare target)]];// { dg-error "'begin declare target' in pragma syntax terminated with 'end declare target' in attribute syntax" } +#pragma omp begin declare target device_type (host) +[[omp::directive (begin declare target)]]; +int d; +#pragma omp end declare target // { dg-error "'begin declare target' in attribute syntax terminated with 'end declare target' in pragma syntax" } +#pragma omp begin declare target +int e; +[[omp::directive (end declare target)]];// { dg-error "'begin declare target' in pragma syntax terminated with 'end declare target' in attribute syntax" } +#pragma omp end declare target +[[omp::directive (begin declare target device_type (any))]]; +[[omp::directive (begin declare target)]]; +int f; +#pragma omp end declare target // { dg-error "'begin declare target' in attribute syntax terminated with 'end declare target' in pragma syntax" } +#pragma omp begin declare target +int g; +[[omp::directive (end declare target)]];// { dg-error "'begin declare target' in pragma syntax terminated with 'end declare target' in attribute syntax" } +[[omp::directive (end declare target)]]; +[[omp::directive (begin declare target)]]; +#pragma omp begin declare target +int h; +#pragma omp end declare target +#pragma omp end declare target // { dg-error "'begin declare target' in attribute syntax terminated with 'end declare target' in pragma syntax" } +#pragma omp begin declare target +[[omp::directive (begin declare target)]]; +int i; +[[omp::directive (end declare target)]]; +[[omp::directive (end declare target)]];// { dg-error "'begin declare target' in pragma syntax terminated with 'end declare target' in attribute syntax" } diff --git a/gcc/testsuite/g++.dg/gomp/attrs-9.C b/gcc/testsuite/g++.dg/gomp/attrs-9.C index fa02299..cf7cef4 100644 --- a/gcc/testsuite/g++.dg/gomp/attrs-9.C +++ b/gcc/testsuite/g++.dg/gomp/attrs-9.C @@ -14,6 +14,21 @@ int b, c, e; int d; [[omp::directive (end declare target)]]; [[omp::directive (end declare target)]]; +[[omp::directive (begin declare target, device_type (any))]]; +[[omp::directive (begin declare target)]]; +int f; +[[omp::directive (end declare target)]]; +[[omp::directive (end declare target)]]; +[[omp::directive (begin declare target device_type (host))]]; +[[omp::directive (declare target)]]; +int g; +[[omp::directive (end declare target)]]; +[[omp::directive (end declare target)]]; +[[omp::directive (declare target)]]; +[[omp::directive (begin declare target, device_type (nohost))]]; +int h; +[[omp::directive (end declare target)]]; +[[omp::directive (end declare target)]]; [[omp::directive (nothing)]]; [[omp::directive (begin assumes no_openmp no_openmp_routines no_parallelism absent (atomic, barrier, cancel, cancellation point) diff --git a/gcc/testsuite/g++.dg/modules/100616_a.H b/gcc/testsuite/g++.dg/modules/100616_a.H new file mode 100644 index 0000000..9bc42bc --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/100616_a.H @@ -0,0 +1,5 @@ +// { dg-additional-options {-std=c++20 -fmodule-header} } +// { dg-module-cmi {} } + +template<auto> struct C { }; +struct A { }; diff --git a/gcc/testsuite/g++.dg/modules/100616_b.C b/gcc/testsuite/g++.dg/modules/100616_b.C new file mode 100644 index 0000000..416fd52 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/100616_b.C @@ -0,0 +1,7 @@ +// { dg-additional-options {-std=c++20 -fmodules-ts} } + +export module pr100616_b; +// { dg-module-cmi pr100616_b } + +import "100616_a.H"; +export C<A{}> c1; diff --git a/gcc/testsuite/g++.dg/modules/100616_c.C b/gcc/testsuite/g++.dg/modules/100616_c.C new file mode 100644 index 0000000..5c79f5e --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/100616_c.C @@ -0,0 +1,7 @@ +// { dg-additional-options {-std=c++20 -fmodules-ts} } + +export module pr100616_c; +// { dg-module-cmi pr100616_c } + +import "100616_a.H"; +export C<A{}> c2; diff --git a/gcc/testsuite/g++.dg/modules/100616_d.C b/gcc/testsuite/g++.dg/modules/100616_d.C new file mode 100644 index 0000000..d9515db --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/100616_d.C @@ -0,0 +1,10 @@ +// { dg-additional-options {-std=c++20 -fmodules-ts} } + +import "100616_a.H"; +import pr100616_b; +import pr100616_c; + +C<A{}> c0; +using type = decltype(c0); +using type = decltype(c1); +using type = decltype(c2); // bogus error: types of c1 and c2 don't match diff --git a/gcc/testsuite/g++.dg/modules/ben-1.map b/gcc/testsuite/g++.dg/modules/ben-1.map index 182183a..ad84c11 100644 --- a/gcc/testsuite/g++.dg/modules/ben-1.map +++ b/gcc/testsuite/g++.dg/modules/ben-1.map @@ -1,3 +1,3 @@ $root . -module:import partitions/module:import.mod +module:import partitions/module-import.mod module module.mod diff --git a/gcc/testsuite/g++.dg/modules/ben-1_a.C b/gcc/testsuite/g++.dg/modules/ben-1_a.C index 7e9b566..f1562eb 100644 --- a/gcc/testsuite/g++.dg/modules/ben-1_a.C +++ b/gcc/testsuite/g++.dg/modules/ben-1_a.C @@ -2,7 +2,7 @@ // { dg-additional-files ben-1.map } export module module:import; -// { dg-module-cmi =partitions/module:import.mod } +// { dg-module-cmi =partitions/module-import.mod } export int b() { return 0; diff --git a/gcc/testsuite/g++.dg/modules/pr102576_a.H b/gcc/testsuite/g++.dg/modules/pr102576_a.H new file mode 100644 index 0000000..87ba9b5 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/pr102576_a.H @@ -0,0 +1,5 @@ +// PR c++/102576 +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +#include <initializer_list> diff --git a/gcc/testsuite/g++.dg/modules/pr102576_b.C b/gcc/testsuite/g++.dg/modules/pr102576_b.C new file mode 100644 index 0000000..10251ed --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/pr102576_b.C @@ -0,0 +1,9 @@ +// PR c++/102576 +// { dg-additional-options -fmodules-ts } + +import "pr102576_a.H"; + +int main() { + for (int i : {1, 2, 3}) + ; +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/cond-temp1.C b/gcc/testsuite/g++.dg/tree-ssa/cond-temp1.C new file mode 100644 index 0000000..b156358 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/cond-temp1.C @@ -0,0 +1,16 @@ +// Test that the ?: only creates one temporary. +// { dg-additional-options "-fdump-tree-gimple" } +// { dg-final { scan-tree-dump-times "struct A" 2 "gimple" } } + +struct A +{ + int i; + A(int); +}; + +bool b; +int main() +{ + A a = 1; + a = b ? A(2) : A(3); +} diff --git a/gcc/testsuite/g++.target/aarch64/pr107080.C b/gcc/testsuite/g++.target/aarch64/pr107080.C new file mode 100644 index 0000000..28212c0 --- /dev/null +++ b/gcc/testsuite/g++.target/aarch64/pr107080.C @@ -0,0 +1,19 @@ +// PR c++/107080 +// { dg-do compile } +// { dg-options "" } + +template <typename T, typename T1> +int +foo (T x, T1 y) +{ + return 3; +} + +int +main () +{ + return (foo (0.0f16, 0.0f16) + foo (0.0f16, (__fp16) 0.0)) != 6; +} + +// { dg-final { scan-assembler "_Z3fooIDF16_DF16_EiT_T0_" } } +// { dg-final { scan-assembler "_Z3fooIDF16_DhEiT_T0_" } } diff --git a/gcc/testsuite/g++.target/arm/pr107080.C b/gcc/testsuite/g++.target/arm/pr107080.C new file mode 100644 index 0000000..89a5746 --- /dev/null +++ b/gcc/testsuite/g++.target/arm/pr107080.C @@ -0,0 +1,19 @@ +// PR c++/107080 +// { dg-do compile } +// { dg-options "-mfp16-format=ieee" } + +template <typename T, typename T1> +int +foo (T x, T1 y) +{ + return 3; +} + +int +main () +{ + return (foo (0.0f16, 0.0f16) + foo (0.0f16, (__fp16) 0.0)) != 6; +} + +// { dg-final { scan-assembler "_Z3fooIDF16_DF16_EiT_T0_" } } +// { dg-final { scan-assembler "_Z3fooIDF16_DhEiT_T0_" } } diff --git a/gcc/testsuite/gcc.dg/c11-float-7.c b/gcc/testsuite/gcc.dg/c11-float-7.c new file mode 100644 index 0000000..a8a7ef5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c11-float-7.c @@ -0,0 +1,24 @@ +/* Test C11 definition of LDBL_EPSILON. Based on + gcc.target/powerpc/rs6000-ldouble-2.c. */ +/* { dg-do run } */ +/* { dg-options "-std=c11 -pedantic-errors" } */ + +#include <float.h> + +extern void abort (void); +extern void exit (int); + +int +main (void) +{ + volatile long double ee = 1.0; + long double eps = ee; + while (ee + 1.0 != 1.0) + { + eps = ee; + ee = eps / 2; + } + if (eps != LDBL_EPSILON) + abort (); + exit (0); +} diff --git a/gcc/testsuite/gcc.dg/c2x-attr-noreturn-1.c b/gcc/testsuite/gcc.dg/c2x-attr-noreturn-1.c new file mode 100644 index 0000000..d903c09 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c2x-attr-noreturn-1.c @@ -0,0 +1,56 @@ +/* Test C2x noreturn attribute: valid uses. */ +/* { dg-do compile } */ +/* { dg-options "-std=c2x -pedantic-errors" } */ + +[[noreturn]] void exit (int); + +[[__noreturn__]] int f1 (void); + +[[_Noreturn]] void f2 (void); + +[[___Noreturn__]] static void f3 (void) { exit (0); } + +/* Returning from a noreturn function is undefined at runtime, not a + constraint violation, but recommended practice is to diagnose if + such a return appears possible. */ + +[[noreturn]] int +f4 (void) +{ + return 1; /* { dg-warning "has a 'return' statement" } */ + /* { dg-warning "does return" "second warning" { target *-*-* } .-1 } */ +} + +[[__noreturn__]] void +f5 (void) +{ + return; /* { dg-warning "has a 'return' statement" } */ + /* { dg-warning "does return" "second warning" { target *-*-* } .-1 } */ +} + +[[_Noreturn]] void +f6 (void) +{ +} /* { dg-warning "does return" } */ + +[[___Noreturn__]] void +f7 (int a) +{ + if (a) + exit (0); +} /* { dg-warning "does return" } */ + +/* Declarations need not all have the attribute (buf if the first does not, + there is undefined behavior). */ + +void f2 (void); + +/* Duplicate attribute, and use with _Noreturn, is OK. */ +[[noreturn]] [[noreturn]] [[noreturn, __noreturn__]] void _Noreturn f9 (void); + +/* The attribute does not affect type compatibility. */ + +void (*fp) (void) = f5; + +/* Unlike the function specifier, the attribute may be used on main. */ +[[noreturn]] int main (); diff --git a/gcc/testsuite/gcc.dg/c2x-attr-noreturn-2.c b/gcc/testsuite/gcc.dg/c2x-attr-noreturn-2.c new file mode 100644 index 0000000..331da4a --- /dev/null +++ b/gcc/testsuite/gcc.dg/c2x-attr-noreturn-2.c @@ -0,0 +1,72 @@ +/* Test C2x noreturn attribute: invalid contexts. */ +/* { dg-do compile } */ +/* { dg-options "-std=c2x -pedantic-errors" } */ + +[[noreturn]]; /* { dg-error "ignored" } */ + +int [[noreturn]] var; /* { dg-error "ignored" } */ + +int array_with_dep_type[2] [[noreturn]]; /* { dg-error "ignored" } */ + +void fn_with_dep_type () [[noreturn]]; /* { dg-error "ignored" } */ + +int z = sizeof (int [[__noreturn__]]); /* { dg-error "ignored" } */ + +[[noreturn]] int x1; /* { dg-error "can only be applied to functions" } */ +int x2 [[__noreturn__]]; /* { dg-error "can only be applied to functions" } */ + +[[_Noreturn]] void (*fp) (); /* { dg-error "can only be applied to functions" } */ + +void +f (void) +{ + int a; + [[_Noreturn]]; /* { dg-error "ignored" } */ + [[___Noreturn__]] a = 1; /* { dg-error "ignored" } */ +} + +int +g ([[noreturn]] int x, int y) /* { dg-error "can only be applied to functions" } */ +{ + [[noreturn]] typedef float F; /* { dg-error "can only be applied to functions" } */ + [[noreturn]] int a; /* { dg-error "can only be applied to functions" } */ + int b [[__noreturn__]]; /* { dg-error "can only be applied to functions" } */ + int c [[noreturn]]; /* { dg-error "can only be applied to functions" } */ + [[__noreturn__]] label1: ; /* { dg-error "can only be applied to functions" } */ + c = y; + [[noreturn]] label2: ; /* { dg-error "can only be applied to functions" } */ + return y; +} + +struct [[_Noreturn]] s { double d; }; /* { dg-error "can only be applied to functions" } */ + +struct s2 +{ + [[___Noreturn__]] int a; /* { dg-error "can only be applied to functions" } */ + int b [[noreturn]]; /* { dg-error "can only be applied to functions" } */ +} x; + +enum e { E1 [[noreturn]] }; /* { dg-error "can only be applied to functions" } */ + +union [[_Noreturn]] u { int x; }; /* { dg-error "can only be applied to functions" } */ + +enum [[noreturn]] eu { E2 }; /* { dg-error "can only be applied to functions" } */ + +void fx ([[noreturn]] int p); /* { dg-error "can only be applied" } */ + +union u2 +{ + [[noreturn]] int a; /* { dg-error "can only be applied to functions" } */ + int b [[noreturn]]; /* { dg-error "can only be applied to functions" } */ +} y; + +void +g2 (int x) +{ + switch (x) + { + [[noreturn]] case 1: ; /* { dg-error "can only be applied to functions" } */ + [[__noreturn__]] case 2: ; /* { dg-error "can only be applied to functions" } */ + [[noreturn]] default: ; /* { dg-error "can only be applied to functions" } */ + } +} diff --git a/gcc/testsuite/gcc.dg/c2x-attr-noreturn-3.c b/gcc/testsuite/gcc.dg/c2x-attr-noreturn-3.c new file mode 100644 index 0000000..aaf21e2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c2x-attr-noreturn-3.c @@ -0,0 +1,11 @@ +/* Test C2x noreturn attribute: invalid syntax. */ +/* { dg-do compile } */ +/* { dg-options "-std=c2x -pedantic-errors" } */ + +[[noreturn()]] void a(); /* { dg-error "does not take any arguments" } */ + +[[__noreturn__(0)]] void b(); /* { dg-error "does not take any arguments|expected" } */ + +[[_Noreturn("", 123)]] void c(); /* { dg-error "does not take any arguments|expected" } */ + +[[___Noreturn__("")]] void d(); /* { dg-error "does not take any arguments|expected" } */ diff --git a/gcc/testsuite/gcc.dg/c2x-float-12.c b/gcc/testsuite/gcc.dg/c2x-float-12.c new file mode 100644 index 0000000..40900bd --- /dev/null +++ b/gcc/testsuite/gcc.dg/c2x-float-12.c @@ -0,0 +1,19 @@ +/* Test C2x definition of LDBL_EPSILON. */ +/* { dg-do run } */ +/* { dg-options "-std=c2x -pedantic-errors" } */ + +#include <float.h> + +extern void abort (void); +extern void exit (int); + +int +main (void) +{ + volatile long double x = 1.0L; + for (int i = 0; i < LDBL_MANT_DIG - 1; i++) + x /= 2; + if (x != LDBL_EPSILON) + abort (); + exit (0); +} diff --git a/gcc/testsuite/gcc.dg/c2x-has-c-attribute-2.c b/gcc/testsuite/gcc.dg/c2x-has-c-attribute-2.c index 6a379e9..3c34ab6 100644 --- a/gcc/testsuite/gcc.dg/c2x-has-c-attribute-2.c +++ b/gcc/testsuite/gcc.dg/c2x-has-c-attribute-2.c @@ -34,6 +34,22 @@ #error "bad result for __fallthrough__" #endif +#if __has_c_attribute (noreturn) != 202202L +#error "bad result for noreturn" +#endif + +#if __has_c_attribute (__noreturn__) != 202202L +#error "bad result for __noreturn__" +#endif + +#if __has_c_attribute (_Noreturn) != 202202L +#error "bad result for _Noreturn" +#endif + +#if __has_c_attribute (___Noreturn__) != 202202L +#error "bad result for ___Noreturn__" +#endif + /* Macros in the attribute name are expanded. */ #define foo deprecated #if __has_c_attribute (foo) != 201904L diff --git a/gcc/testsuite/gcc.dg/cpp/pragma-diagnostic-2.c b/gcc/testsuite/gcc.dg/cpp/pragma-diagnostic-2.c index 38fc77c..89d2975 100644 --- a/gcc/testsuite/gcc.dg/cpp/pragma-diagnostic-2.c +++ b/gcc/testsuite/gcc.dg/cpp/pragma-diagnostic-2.c @@ -7,18 +7,17 @@ void f (unsigned); #define CODE_WITH_WARNING \ int a; /* { dg-message "was declared here" } */ \ - f (a) /* { dg-warning "used uninitialized" } */ + f (a) /* { dg-error "used uninitialized" } */ #pragma GCC diagnostic ignored "-Wuninitialized" void g (void) { + /* No warning expected here since the #pragma is in effect. */ CODE_WITH_WARNING; } -#pragma GCC diagnostic push - #pragma GCC diagnostic error "-Wuninitialized" void @@ -26,3 +25,5 @@ h (void) { CODE_WITH_WARNING; /* { dg-message "in expansion of macro 'CODE_WITH_WARNING'" } */ } + +/* { dg-regexp {.*some warnings being treated as errors} } */ diff --git a/gcc/testsuite/gcc.dg/infinite-loop.c b/gcc/testsuite/gcc.dg/infinite-loop.c new file mode 100644 index 0000000..25037a2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/infinite-loop.c @@ -0,0 +1,26 @@ +/* { dg-do link } */ +/* { dg-options "-O2" } */ +void link_error (void); + +void __attribute__ ((noinline,noipa)) +foo(int a) +{ + int b = 0; + + while (1) + { + if (!a) + break; + b = 1; + } + + if (b != 0) + link_error (); +} + +int +main() +{ + foo (0); +} + diff --git a/gcc/testsuite/gcc.dg/pr102892-1.c b/gcc/testsuite/gcc.dg/pr102892-1.c index f08b2b8..faca3f2 100644 --- a/gcc/testsuite/gcc.dg/pr102892-1.c +++ b/gcc/testsuite/gcc.dg/pr102892-1.c @@ -12,7 +12,7 @@ int main () { long c = 0; - for (long a; a < 1; ++a) + for (long a = 0; a < 1; ++a) for (; c <= 1; c++) { bar(); if (1 == b[c][0]) diff --git a/gcc/testsuite/gcc.dg/pr104992.c b/gcc/testsuite/gcc.dg/pr104992.c index 217c89a..82f8c75 100644 --- a/gcc/testsuite/gcc.dg/pr104992.c +++ b/gcc/testsuite/gcc.dg/pr104992.c @@ -54,4 +54,5 @@ __attribute__((noipa)) unsigned waldo (unsigned x, unsigned y, unsigned z) { return x / y * z == x; } -/* { dg-final {scan-tree-dump-times " % " 9 "optimized" } } */ +/* { dg-final { scan-tree-dump-times " % " 9 "optimized" { target { ! vect_int_mod } } } } */ +/* { dg-final { scan-tree-dump-times " % " 6 "optimized" { target vect_int_mod } } } */ diff --git a/gcc/testsuite/gcc.dg/pr107109.c b/gcc/testsuite/gcc.dg/pr107109.c new file mode 100644 index 0000000..e3036f6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr107109.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ + +int printf(const char *, ...); +int a, b; +void c() { + int d, e; + L: + a = (b && a) ^ 2756578370; + d = ~a + (e ^ d) ^ 2756578370; + if (!d) + printf("%d", a); + d = a / e; + goto L; +} +int main() { + if (a) + c(); + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/pr25521.c b/gcc/testsuite/gcc.dg/pr25521.c new file mode 100644 index 0000000..74fe2ae --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr25521.c @@ -0,0 +1,10 @@ +/* PR middle-end/25521 - place `const volatile' objects in read-only + sections. + + { dg-require-effective-target elf } + { dg-do compile } */ + +const volatile int foo = 30; + + +/* { dg-final { scan-assembler "\\.rodata" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr107130.c b/gcc/testsuite/gcc.dg/tree-ssa/pr107130.c new file mode 100644 index 0000000..11fb816 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr107130.c @@ -0,0 +1,19 @@ +// { dg-do compile } +// { dg-options "-Os -fno-tree-ccp -fno-tree-forwprop -fno-tree-fre -fdump-tree-vrp1" } + +static inline int +foo (int i) +{ + return __builtin_ffsl (i); +} + +int +main (void) +{ + int x = foo (41); + if (x != 1) + __builtin_abort (); + return 0; +} + +// { dg-final { scan-tree-dump-not "builtin_abort" "vrp1" } } diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr79095.c b/gcc/testsuite/gcc.dg/tree-ssa/pr79095.c index f635fca..b175187 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr79095.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr79095.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fno-ipa-icf -fdump-tree-vrp1" } */ +/* { dg-options "-O2 -fno-ipa-icf -fdump-tree-evrp" } */ extern void arf (unsigned x, unsigned y); extern void baz (unsigned x, unsigned y); @@ -429,8 +429,8 @@ f4nro (unsigned a, unsigned b) } /* All calls to baz should still reference a & b as arguments. */ -/* { dg-final { scan-tree-dump-times "baz \\(a_\[0-9\]+\\(D\\), b_\[0-9\]+\\)" 32 "vrp1"} } */ +/* { dg-final { scan-tree-dump-times "baz \\(a_\[0-9\]+\\(D\\), b_\[0-9\]+\\)" 32 "evrp"} } */ /* All calls to arf should have constant arguments. */ -/* { dg-final { scan-tree-dump-times "arf \\(\[0-9\]+, \[0-9\]+\\)" 32 "vrp1"} } */ +/* { dg-final { scan-tree-dump-times "arf \\(\[0-9\]+, \[0-9\]+\\)" 32 "evrp"} } */ diff --git a/gcc/testsuite/gcc.target/aarch64/cpunative/info_15 b/gcc/testsuite/gcc.target/aarch64/cpunative/info_15 index bc64539..6b425ea 100644 --- a/gcc/testsuite/gcc.target/aarch64/cpunative/info_15 +++ b/gcc/testsuite/gcc.target/aarch64/cpunative/info_15 @@ -1,6 +1,6 @@ processor : 0 BogoMIPS : 100.00 -Features : Lorem ipsum dolor sit ametd rebum expetendis per at Dolor lucilius referrentur ei mei virtute eruditi eum ne Iisque verter svesm4 asimd fp +Features : Lorem ipsum dolor sit ametd rebum expetendis per at Dolor lucilius referrentur ei mei virtute eruditi eum ne Iisque verter svesm4 asimd fp sve sve2 fphp asimdhp sm3 sm4 CPU implementer : 0x41 CPU architecture: 8 CPU variant : 0x0 diff --git a/gcc/testsuite/gcc.target/aarch64/cpunative/info_16 b/gcc/testsuite/gcc.target/aarch64/cpunative/info_16 index 2c04ff1..26f01c4 100644 --- a/gcc/testsuite/gcc.target/aarch64/cpunative/info_16 +++ b/gcc/testsuite/gcc.target/aarch64/cpunative/info_16 @@ -1,6 +1,6 @@ processor : 0 BogoMIPS : 100.00 -Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 asimddp sve sve2 +Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 asimddp sve sve2 fphp asimdhp CPU implementer : 0xfe CPU architecture: 8 CPU variant : 0x0 diff --git a/gcc/testsuite/gcc.target/aarch64/cpunative/info_17 b/gcc/testsuite/gcc.target/aarch64/cpunative/info_17 index 2c04ff1..26f01c4 100644 --- a/gcc/testsuite/gcc.target/aarch64/cpunative/info_17 +++ b/gcc/testsuite/gcc.target/aarch64/cpunative/info_17 @@ -1,6 +1,6 @@ processor : 0 BogoMIPS : 100.00 -Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 asimddp sve sve2 +Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 asimddp sve sve2 fphp asimdhp CPU implementer : 0xfe CPU architecture: 8 CPU variant : 0x0 diff --git a/gcc/testsuite/gcc.target/aarch64/cpunative/info_8 b/gcc/testsuite/gcc.target/aarch64/cpunative/info_8 index d6d9d03..76da16c 100644 --- a/gcc/testsuite/gcc.target/aarch64/cpunative/info_8 +++ b/gcc/testsuite/gcc.target/aarch64/cpunative/info_8 @@ -1,6 +1,6 @@ processor : 0 BogoMIPS : 100.00 -Features : asimd sve fp +Features : asimd sve fp fphp asimdhp CPU implementer : 0x41 CPU architecture: 8 CPU variant : 0x0 diff --git a/gcc/testsuite/gcc.target/aarch64/cpunative/info_9 b/gcc/testsuite/gcc.target/aarch64/cpunative/info_9 index c9aa4a9..14703dd 100644 --- a/gcc/testsuite/gcc.target/aarch64/cpunative/info_9 +++ b/gcc/testsuite/gcc.target/aarch64/cpunative/info_9 @@ -1,6 +1,6 @@ processor : 0 BogoMIPS : 100.00 -Features : asimd fp svesm4 +Features : asimd fp svesm4 sve sve2 fphp asimdhp sm3 sm4 CPU implementer : 0x41 CPU architecture: 8 CPU variant : 0x0 diff --git a/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_0.c b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_0.c index f155f51..8499f87 100644 --- a/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_0.c +++ b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_0.c @@ -7,6 +7,6 @@ int main() return 0; } -/* { dg-final { scan-assembler {\.arch armv8-a\+crypto\+crc\+dotprod} } } */ +/* { dg-final { scan-assembler {\.arch armv8-a\+crc\+dotprod\+crypto} } } */ /* Test a normal looking procinfo. */ diff --git a/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_10.c b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_10.c index 6a75396..ddb06b8 100644 --- a/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_10.c +++ b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_10.c @@ -7,6 +7,6 @@ int main() return 0; } -/* { dg-final { scan-assembler {\.arch armv8-a\+nofp\+nosimd} } } */ +/* { dg-final { scan-assembler {\.arch armv8-a\+nofp} } } */ /* Test one with no entry in feature list. */ diff --git a/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_13.c b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_13.c index b7b3a8e..5516690 100644 --- a/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_13.c +++ b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_13.c @@ -7,6 +7,6 @@ int main() return 0; } -/* { dg-final { scan-assembler {\.arch armv8-a\+crypto\+crc\+dotprod} } } */ +/* { dg-final { scan-assembler {\.arch armv8-a\+crc\+dotprod\+crypto} } } */ /* Test one with mixed order of feature bits. */ diff --git a/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_16.c b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_16.c index a424e7c..2f963bb 100644 --- a/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_16.c +++ b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_16.c @@ -7,6 +7,6 @@ int main() return 0; } -/* { dg-final { scan-assembler {\.arch armv8-a\+crypto\+crc\+dotprod\+sve2} } } */ +/* { dg-final { scan-assembler {\.arch armv8-a\+crc\+dotprod\+crypto\+sve2} } } */ /* Test a normal looking procinfo. */ diff --git a/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_17.c b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_17.c index c269c5f..c68a697 100644 --- a/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_17.c +++ b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_17.c @@ -7,6 +7,6 @@ int main() return 0; } -/* { dg-final { scan-assembler {\.arch armv8-a\+crypto\+crc\+dotprod\+sve2} } } */ +/* { dg-final { scan-assembler {\.arch armv8-a\+crc\+dotprod\+crypto\+sve2} } } */ /* Test a normal looking procinfo. */ diff --git a/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_2.c b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_2.c index aad71f4..edbdb56 100644 --- a/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_2.c +++ b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_2.c @@ -7,6 +7,6 @@ int main() return 0; } -/* { dg-final { scan-assembler {\.arch armv8-a\+nofp\+nosimd} } } */ +/* { dg-final { scan-assembler {\.arch armv8-a\+nofp} } } */ /* Test one where asimd is provided byt no fp. */ diff --git a/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_6.c b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_6.c index da72052..7608e88 100644 --- a/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_6.c +++ b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_6.c @@ -7,7 +7,7 @@ int main() return 0; } -/* { dg-final { scan-assembler {\.arch armv8-a\+crypto\+fp16} } } */ +/* { dg-final { scan-assembler {\.arch armv8-a\+fp16\+crypto} } } */ /* Test one where the feature bits for crypto and fp16 are given in same order as declared in options file. */ diff --git a/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_7.c b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_7.c index 96ad4c1..72b14b4 100644 --- a/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_7.c +++ b/gcc/testsuite/gcc.target/aarch64/cpunative/native_cpu_7.c @@ -7,7 +7,7 @@ int main() return 0; } -/* { dg-final { scan-assembler {\.arch armv8-a\+crypto\+fp16} } } */ +/* { dg-final { scan-assembler {\.arch armv8-a\+fp16\+crypto} } } */ /* Test one where the crypto and fp16 options are specified in different order from what is in the options file. */ diff --git a/gcc/testsuite/gcc.target/aarch64/options_set_2.c b/gcc/testsuite/gcc.target/aarch64/options_set_2.c index 3476feb..f82cb5f 100644 --- a/gcc/testsuite/gcc.target/aarch64/options_set_2.c +++ b/gcc/testsuite/gcc.target/aarch64/options_set_2.c @@ -6,6 +6,6 @@ int main () return 0; } -/* { dg-final { scan-assembler-times {\.arch armv8\.2\-a\+crypto\+crc} 1 } } */ +/* { dg-final { scan-assembler-times {\.arch armv8\.2\-a\+crc\+crypto} 1 } } */ /* Check to see if crc and crypto are maintained if crypto specified. */ diff --git a/gcc/testsuite/gcc.target/aarch64/options_set_3.c b/gcc/testsuite/gcc.target/aarch64/options_set_3.c index 4558339..7d350cf 100644 --- a/gcc/testsuite/gcc.target/aarch64/options_set_3.c +++ b/gcc/testsuite/gcc.target/aarch64/options_set_3.c @@ -6,6 +6,6 @@ int main () return 0; } -/* { dg-final { scan-assembler-times {\.arch armv8\.2\-a\+crypto\+crc} 1 } } */ +/* { dg-final { scan-assembler-times {\.arch armv8\.2\-a\+crc\+crypto} 1 } } */ /* Check if smallest set is maintained when outputting. */ diff --git a/gcc/testsuite/gcc.target/aarch64/options_set_4.c b/gcc/testsuite/gcc.target/aarch64/options_set_4.c index 15514bf..5370e02 100644 --- a/gcc/testsuite/gcc.target/aarch64/options_set_4.c +++ b/gcc/testsuite/gcc.target/aarch64/options_set_4.c @@ -6,7 +6,7 @@ int main () return 0; } -/* { dg-final { scan-assembler-times {\.arch armv8\.2\-a\+crypto\+crc} 1 } } */ +/* { dg-final { scan-assembler-times {\.arch armv8\.2\-a\+crc\+crypto} 1 } } */ /* Check if individual bits that make up a grouping is specified that only the - grouping is kept. */
\ No newline at end of file + grouping is kept. */ diff --git a/gcc/testsuite/gcc.target/aarch64/options_set_6.c b/gcc/testsuite/gcc.target/aarch64/options_set_6.c index 90a0559..2a1d7fe 100644 --- a/gcc/testsuite/gcc.target/aarch64/options_set_6.c +++ b/gcc/testsuite/gcc.target/aarch64/options_set_6.c @@ -6,7 +6,6 @@ int main () return 0; } -/* { dg-final { scan-assembler-times {\.arch armv8\.2\-a\+crypto\+crc} 1 } } */ +/* { dg-final { scan-assembler-times {\.arch armv8\.2\-a\+crc\+aes} 1 } } */ -/* Group as a whole was requested to be turned on, crypto itself is a bit and so - just turning off one feature can't turn it off. */ +/* +crypto turns on +aes and +sha2, but +nosha2 disables +crypto. */ diff --git a/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_4.c b/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_4.c new file mode 100644 index 0000000..0e6461f --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_4.c @@ -0,0 +1,47 @@ +#pragma GCC target "+nothing+dotprod" +#ifndef __ARM_FEATURE_FMA +#error Foo +#endif + +#pragma GCC target "+nothing+aes" +#ifndef __ARM_FEATURE_FMA +#error Foo +#endif + +#pragma GCC target "+nothing+sha2" +#ifndef __ARM_FEATURE_FMA +#error Foo +#endif + +#pragma GCC target "+nothing+sha3" +#ifndef __ARM_FEATURE_FMA +#error Foo +#endif + +#pragma GCC target "+nothing+sm4" +#ifndef __ARM_FEATURE_FMA +#error Foo +#endif + +#pragma GCC target "+crypto+noaes" +#ifdef __ARM_FEATURE_CRYPTO +#error Foo +#endif + +#pragma GCC target "+crypto+nosha2" +#ifdef __ARM_FEATURE_CRYPTO +#error Foo +#endif + +#pragma GCC target "+nothing+sve2-sha3" +#ifndef __ARM_FEATURE_SHA2 +#error Foo +#endif + +#pragma GCC target "+sve2-sha3+nosha2" +#ifdef __ARM_FEATURE_SHA3 +#error Foo +#endif +#ifdef __ARM_FEATURE_SVE2_SHA3 +#error Foo +#endif diff --git a/gcc/testsuite/gcc.target/aarch64/target_attr_15.c b/gcc/testsuite/gcc.target/aarch64/target_attr_15.c index 108b372..069a001 100644 --- a/gcc/testsuite/gcc.target/aarch64/target_attr_15.c +++ b/gcc/testsuite/gcc.target/aarch64/target_attr_15.c @@ -10,4 +10,4 @@ foo (int a) return a + 1; } -/* { dg-final { scan-assembler-times "\\.arch armv8-a\\+nofp\\+nosimd\n" 1 } } */ +/* { dg-final { scan-assembler-times "\\.arch armv8-a\\+nofp\n" 1 } } */ diff --git a/gcc/testsuite/gcc.target/arm/cmse/cmse-15.c b/gcc/testsuite/gcc.target/arm/cmse/cmse-15.c index b0fefe5..5188f1d 100644 --- a/gcc/testsuite/gcc.target/arm/cmse/cmse-15.c +++ b/gcc/testsuite/gcc.target/arm/cmse/cmse-15.c @@ -144,6 +144,8 @@ int secure2 (s_bar_ptr s_bar_p) ** bx r[0-3] ** | ** blx r[0-3] +** | +** b secure1 ** ) ** ... */ diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrev64q_m_s16-clobber.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrev64q_m_s16-clobber.c new file mode 100644 index 0000000..6464c96 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrev64q_m_s16-clobber.c @@ -0,0 +1,17 @@ +/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */ +/* { dg-add-options arm_v8_1m_mve_fp } */ +/* { dg-additional-options "-O2" } */ + +#include "arm_mve.h" + +int16x8_t +foo (int16x8_t a, mve_pred16_t p) +{ + return vrev64q_m_s16 (a, a, p); +} + +float16x8_t +foo2 (float16x8_t a, mve_pred16_t p) +{ + return vrev64q_m_f16 (a, a, p); +} diff --git a/gcc/testsuite/gcc.target/arm/mve/mve_load_memory_modes.c b/gcc/testsuite/gcc.target/arm/mve/mve_load_memory_modes.c index e35eb11..816980d1 100644 --- a/gcc/testsuite/gcc.target/arm/mve/mve_load_memory_modes.c +++ b/gcc/testsuite/gcc.target/arm/mve/mve_load_memory_modes.c @@ -7,7 +7,7 @@ /* **off_load8_0: ** ... -** vldrb.8 q0, \[r0, #16\] +** vldrb.8 q[0-7], \[r0, #16\] ** ... */ int8x16_t off_load8_0 (int8_t * a) @@ -18,7 +18,7 @@ int8x16_t off_load8_0 (int8_t * a) /* **off_load8_1: ** ... -** vldrb.u16 q0, \[r0, #1\] +** vldrb.u16 q[0-7], \[r0, #1\] ** ... */ uint16x8_t off_load8_1 (uint8_t * a) @@ -29,7 +29,7 @@ uint16x8_t off_load8_1 (uint8_t * a) /* **off_load8_2: ** ... -** vldrb.s32 q0, \[r0, #127\] +** vldrb.s32 q[0-7], \[r0, #127\] ** ... */ int32x4_t off_load8_2 (int8_t * a) @@ -40,7 +40,7 @@ int32x4_t off_load8_2 (int8_t * a) /* **off_load8_3: ** ... -** vldrb.8 q0, \[r0, #-127\] +** vldrb.8 q[0-7], \[r0, #-127\] ** ... */ uint8x16_t off_load8_3 (uint8_t * a) @@ -51,7 +51,7 @@ uint8x16_t off_load8_3 (uint8_t * a) /* **not_off_load8_0: ** ... -** vldrb.8 q0, \[r[0-9]+\] +** vldrb.8 q[0-7], \[r[0-7]+\] ** ... */ int8x16_t not_off_load8_0 (int8_t * a) @@ -62,7 +62,7 @@ int8x16_t not_off_load8_0 (int8_t * a) /* **off_loadfp16_0: ** ... -** vldrh.16 q0, \[r0, #-244\] +** vldrh.16 q[0-7], \[r0, #-244\] ** ... */ float16x8_t off_loadfp16_0 (float16_t *a) @@ -73,7 +73,7 @@ float16x8_t off_loadfp16_0 (float16_t *a) /* **off_load16_0: ** ... -** vldrh.16 q0, \[r0, #-2\] +** vldrh.16 q[0-7], \[r0, #-2\] ** ... */ uint16x8_t off_load16_0 (uint16_t * a) @@ -84,7 +84,7 @@ uint16x8_t off_load16_0 (uint16_t * a) /* **off_load16_1: ** ... -** vldrh.u32 q0, \[r0, #254\] +** vldrh.u32 q[0-7], \[r0, #254\] ** ... */ uint32x4_t off_load16_1 (uint16_t * a) @@ -95,7 +95,7 @@ uint32x4_t off_load16_1 (uint16_t * a) /* **not_off_load16_0: ** ... -** vldrh.16 q0, \[r[0-9]+\] +** vldrh.16 q[0-7], \[r[0-7]+\] ** ... */ int16x8_t not_off_load16_0 (int8_t * a) @@ -106,7 +106,7 @@ int16x8_t not_off_load16_0 (int8_t * a) /* **not_off_load16_1: ** ... -** vldrh.u32 q0, \[r[0-9]+\] +** vldrh.u32 q[0-7], \[r[0-7]+\] ** ... */ uint32x4_t not_off_load16_1 (uint16_t * a) @@ -117,7 +117,7 @@ uint32x4_t not_off_load16_1 (uint16_t * a) /* **off_loadfp32_0: ** ... -** vldrw.32 q0, \[r0, #24\] +** vldrw.32 q[0-7], \[r0, #24\] ** ... */ float32x4_t off_loadfp32_0 (float32_t *a) @@ -128,7 +128,7 @@ float32x4_t off_loadfp32_0 (float32_t *a) /* **off_load32_0: ** ... -** vldrw.32 q0, \[r0, #4\] +** vldrw.32 q[0-7], \[r0, #4\] ** ... */ uint32x4_t off_load32_0 (uint32_t * a) @@ -139,7 +139,7 @@ uint32x4_t off_load32_0 (uint32_t * a) /* **off_load32_1: ** ... -** vldrw.32 q0, \[r0, #-508\] +** vldrw.32 q[0-7], \[r0, #-508\] ** ... */ int32x4_t off_load32_1 (int32_t * a) @@ -149,7 +149,7 @@ int32x4_t off_load32_1 (int32_t * a) /* **pre_load8_0: ** ... -** vldrb.8 q[0-9]+, \[r0, #16\]! +** vldrb.8 q[0-7], \[r0, #16\]! ** ... */ int8_t* pre_load8_0 (int8_t * a, int8x16_t *v) @@ -162,7 +162,7 @@ int8_t* pre_load8_0 (int8_t * a, int8x16_t *v) /* **pre_load8_1: ** ... -** vldrb.u16 q[0-9]+, \[r0, #4\]! +** vldrb.u16 q[0-7], \[r0, #4\]! ** ... */ uint8_t* pre_load8_1 (uint8_t * a, uint16x8_t *v) @@ -175,7 +175,7 @@ uint8_t* pre_load8_1 (uint8_t * a, uint16x8_t *v) /* **pre_loadfp16_0: ** ... -** vldrh.16 q[0-9]+, \[r0, #128\]! +** vldrh.16 q[0-7], \[r0, #128\]! ** ... */ float16_t* pre_loadfp16_0 (float16_t *a, float16x8_t *v) @@ -188,7 +188,7 @@ float16_t* pre_loadfp16_0 (float16_t *a, float16x8_t *v) /* **pre_load16_0: ** ... -** vldrh.16 q[0-9]+, \[r0, #-254\]! +** vldrh.16 q[0-7], \[r0, #-254\]! ** ... */ int16_t* pre_load16_0 (int16_t * a, int16x8_t *v) @@ -201,7 +201,7 @@ int16_t* pre_load16_0 (int16_t * a, int16x8_t *v) /* **pre_load16_1: ** ... -** vldrh.s32 q[0-9]+, \[r0, #52\]! +** vldrh.s32 q[0-7], \[r0, #52\]! ** ... */ int16_t* pre_load16_1 (int16_t * a, int32x4_t *v) @@ -214,7 +214,7 @@ int16_t* pre_load16_1 (int16_t * a, int32x4_t *v) /* **pre_loadfp32_0: ** ... -** vldrw.32 q[0-9]+, \[r0, #-72\]! +** vldrw.32 q[0-7], \[r0, #-72\]! ** ... */ float32_t* pre_loadfp32_0 (float32_t *a, float32x4_t *v) @@ -228,7 +228,7 @@ float32_t* pre_loadfp32_0 (float32_t *a, float32x4_t *v) /* **pre_load32_0: ** ... -** vldrw.32 q[0-9]+, \[r0, #-4\]! +** vldrw.32 q[0-7], \[r0, #-4\]! ** ... */ uint32_t* pre_load32_0 (uint32_t * a, uint32x4_t *v) @@ -242,7 +242,7 @@ uint32_t* pre_load32_0 (uint32_t * a, uint32x4_t *v) /* **post_load8_0: ** ... -** vldrb.8 q[0-9]+, \[r0\], #26 +** vldrb.8 q[0-7], \[r0\], #26 ** ... */ uint8_t* post_load8_0 (uint8_t * a, uint8x16_t *v) @@ -255,7 +255,7 @@ uint8_t* post_load8_0 (uint8_t * a, uint8x16_t *v) /* **post_load8_1: ** ... -** vldrb.s16 q[0-9]+, \[r0\], #-1 +** vldrb.s16 q[0-7], \[r0\], #-1 ** ... */ int8_t* post_load8_1 (int8_t * a, int16x8_t *v) @@ -268,7 +268,7 @@ int8_t* post_load8_1 (int8_t * a, int16x8_t *v) /* **post_load8_2: ** ... -** vldrb.8 q[0-9]+, \[r0\], #26 +** vldrb.8 q[0-7], \[r0\], #26 ** ... */ uint8_t* post_load8_2 (uint8_t * a, uint8x16_t *v) @@ -281,7 +281,7 @@ uint8_t* post_load8_2 (uint8_t * a, uint8x16_t *v) /* **post_load8_3: ** ... -** vldrb.s16 q[0-9]+, \[r0\], #-1 +** vldrb.s16 q[0-7], \[r0\], #-1 ** ... */ int8_t* post_load8_3 (int8_t * a, int16x8_t *v) @@ -294,7 +294,7 @@ int8_t* post_load8_3 (int8_t * a, int16x8_t *v) /* **post_loadfp16_0: ** ... -** vldrh.16 q[0-9]+, \[r0\], #-24 +** vldrh.16 q[0-7], \[r0\], #-24 ** ... */ float16_t* post_loadfp16_0 (float16_t *a, float16x8_t *v) @@ -307,7 +307,7 @@ float16_t* post_loadfp16_0 (float16_t *a, float16x8_t *v) /* **post_load16_0: ** ... -** vldrh.16 q[0-9]+, \[r0\], #-126 +** vldrh.16 q[0-7], \[r0\], #-126 ** ... */ uint16_t* post_load16_0 (uint16_t * a, uint16x8_t *v) @@ -320,7 +320,7 @@ uint16_t* post_load16_0 (uint16_t * a, uint16x8_t *v) /* **post_load16_1: ** ... -** vldrh.u32 q[0-9]+, \[r0\], #16 +** vldrh.u32 q[0-7], \[r0\], #16 ** ... */ uint16_t* post_load16_1 (uint16_t * a, uint32x4_t *v) @@ -333,7 +333,7 @@ uint16_t* post_load16_1 (uint16_t * a, uint32x4_t *v) /* **post_loadfp32_0: ** ... -** vldrw.32 q[0-9]+, \[r0\], #4 +** vldrw.32 q[0-7], \[r0\], #4 ** ... */ float32_t* post_loadfp32_0 (float32_t *a, float32x4_t *v) @@ -346,7 +346,7 @@ float32_t* post_loadfp32_0 (float32_t *a, float32x4_t *v) /* **post_load32_0: ** ... -** vldrw.32 q[0-9]+, \[r0\], #-16 +** vldrw.32 q[0-7], \[r0\], #-16 ** ... */ int32_t* post_load32_0 (int32_t * a, int32x4_t *v) diff --git a/gcc/testsuite/gcc.target/arm/mve/mve_store_memory_modes.c b/gcc/testsuite/gcc.target/arm/mve/mve_store_memory_modes.c index 632f5b4..11df114 100644 --- a/gcc/testsuite/gcc.target/arm/mve/mve_store_memory_modes.c +++ b/gcc/testsuite/gcc.target/arm/mve/mve_store_memory_modes.c @@ -7,7 +7,7 @@ /* **off_store8_0: ** ... -** vstrb.8 q0, \[r0, #16\] +** vstrb.8 q[0-7], \[r0, #16\] ** ... */ uint8_t *off_store8_0 (uint8_t * a, uint8x16_t v) @@ -19,7 +19,7 @@ uint8_t *off_store8_0 (uint8_t * a, uint8x16_t v) /* **off_store8_1: ** ... -** vstrb.16 q0, \[r0, #-1\] +** vstrb.16 q[0-7], \[r0, #-1\] ** ... */ int8_t *off_store8_1 (int8_t * a, int16x8_t v) @@ -31,7 +31,7 @@ int8_t *off_store8_1 (int8_t * a, int16x8_t v) /* **off_store8_2: ** ... -** vstrb.32 q0, \[r0, #-127\] +** vstrb.32 q[0-7], \[r0, #-127\] ** ... */ uint8_t *off_store8_2 (uint8_t * a, uint32x4_t v) @@ -43,7 +43,7 @@ uint8_t *off_store8_2 (uint8_t * a, uint32x4_t v) /* **off_store8_3: ** ... -** vstrb.8 q0, \[r0, #127\] +** vstrb.8 q[0-7], \[r0, #127\] ** ... */ int8_t *off_store8_3 (int8_t * a, int8x16_t v) @@ -55,7 +55,7 @@ int8_t *off_store8_3 (int8_t * a, int8x16_t v) /* **not_off_store8_0: ** ... -** vstrb.8 q0, \[r[0-9]+\] +** vstrb.8 q[0-7], \[r[0-7]+\] ** ... */ uint8_t *not_off_store8_0 (uint8_t * a, uint8x16_t v) @@ -67,7 +67,7 @@ uint8_t *not_off_store8_0 (uint8_t * a, uint8x16_t v) /* **off_storefp16_0: ** ... -** vstrh.16 q0, \[r0, #250\] +** vstrh.16 q[0-7], \[r0, #250\] ** ... */ float16_t *off_storefp16_0 (float16_t *a, float16x8_t v) @@ -79,7 +79,7 @@ float16_t *off_storefp16_0 (float16_t *a, float16x8_t v) /* **off_store16_0: ** ... -** vstrh.16 q0, \[r0, #4\] +** vstrh.16 q[0-7], \[r0, #4\] ** ... */ int16_t *off_store16_0 (int16_t * a, int16x8_t v) @@ -91,7 +91,7 @@ int16_t *off_store16_0 (int16_t * a, int16x8_t v) /* **off_store16_1: ** ... -** vstrh.32 q0, \[r0, #-254\] +** vstrh.32 q[0-7], \[r0, #-254\] ** ... */ int16_t *off_store16_1 (int16_t * a, int32x4_t v) @@ -103,7 +103,7 @@ int16_t *off_store16_1 (int16_t * a, int32x4_t v) /* **not_off_store16_0: ** ... -** vstrh.16 q0, \[r[0-9]+\] +** vstrh.16 q[0-7], \[r[0-7]+\] ** ... */ uint8_t *not_off_store16_0 (uint8_t * a, uint16x8_t v) @@ -115,7 +115,7 @@ uint8_t *not_off_store16_0 (uint8_t * a, uint16x8_t v) /* **not_off_store16_1: ** ... -** vstrh.32 q0, \[r[0-9]+\] +** vstrh.32 q[0-7], \[r[0-7]+\] ** ... */ int16_t *not_off_store16_1 (int16_t * a, int32x4_t v) @@ -127,7 +127,7 @@ int16_t *not_off_store16_1 (int16_t * a, int32x4_t v) /* **off_storefp32_0: ** ... -** vstrw.32 q0, \[r0, #-412\] +** vstrw.32 q[0-7], \[r0, #-412\] ** ... */ float32_t *off_storefp32_0 (float32_t *a, float32x4_t v) @@ -139,7 +139,7 @@ float32_t *off_storefp32_0 (float32_t *a, float32x4_t v) /* **off_store32_0: ** ... -** vstrw.32 q0, \[r0, #-4\] +** vstrw.32 q[0-7], \[r0, #-4\] ** ... */ int32_t *off_store32_0 (int32_t * a, int32x4_t v) @@ -151,7 +151,7 @@ int32_t *off_store32_0 (int32_t * a, int32x4_t v) /* **off_store32_1: ** ... -** vstrw.32 q0, \[r0, #508\] +** vstrw.32 q[0-7], \[r0, #508\] ** ... */ uint32_t *off_store32_1 (uint32_t * a, uint32x4_t v) @@ -163,7 +163,7 @@ uint32_t *off_store32_1 (uint32_t * a, uint32x4_t v) /* **pre_store8_0: ** ... -** vstrb.8 q[0-9]+, \[r0, #-16\]! +** vstrb.8 q[0-7], \[r0, #-16\]! ** ... */ uint8_t* pre_store8_0 (uint8_t * a, uint8x16_t v) @@ -176,7 +176,7 @@ uint8_t* pre_store8_0 (uint8_t * a, uint8x16_t v) /* **pre_store8_1: ** ... -** vstrb.16 q[0-9]+, \[r0, #4\]! +** vstrb.16 q[0-7], \[r0, #4\]! ** ... */ int8_t* pre_store8_1 (int8_t * a, int16x8_t v) @@ -189,7 +189,7 @@ int8_t* pre_store8_1 (int8_t * a, int16x8_t v) /* **pre_storefp16_0: ** ... -** vstrh.16 q0, \[r0, #8\]! +** vstrh.16 q[0-7], \[r0, #8\]! ** ... */ float16_t *pre_storefp16_0 (float16_t *a, float16x8_t v) @@ -202,7 +202,7 @@ float16_t *pre_storefp16_0 (float16_t *a, float16x8_t v) /* **pre_store16_0: ** ... -** vstrh.16 q[0-9]+, \[r0, #254\]! +** vstrh.16 q[0-7], \[r0, #254\]! ** ... */ uint16_t* pre_store16_0 (uint16_t * a, uint16x8_t v) @@ -215,7 +215,7 @@ uint16_t* pre_store16_0 (uint16_t * a, uint16x8_t v) /* **pre_store16_1: ** ... -** vstrh.32 q[0-9]+, \[r0, #-52\]! +** vstrh.32 q[0-7], \[r0, #-52\]! ** ... */ int16_t* pre_store16_1 (int16_t * a, int32x4_t v) @@ -228,7 +228,7 @@ int16_t* pre_store16_1 (int16_t * a, int32x4_t v) /* **pre_storefp32_0: ** ... -** vstrw.32 q0, \[r0, #-4\]! +** vstrw.32 q[0-7], \[r0, #-4\]! ** ... */ float32_t *pre_storefp32_0 (float32_t *a, float32x4_t v) @@ -241,7 +241,7 @@ float32_t *pre_storefp32_0 (float32_t *a, float32x4_t v) /* **pre_store32_0: ** ... -** vstrw.32 q[0-9]+, \[r0, #4\]! +** vstrw.32 q[0-7], \[r0, #4\]! ** ... */ int32_t* pre_store32_0 (int32_t * a, int32x4_t v) @@ -255,7 +255,7 @@ int32_t* pre_store32_0 (int32_t * a, int32x4_t v) /* **post_store8_0: ** ... -** vstrb.8 q[0-9]+, \[r0\], #-26 +** vstrb.8 q[0-7], \[r0\], #-26 ** ... */ int8_t* post_store8_0 (int8_t * a, int8x16_t v) @@ -268,7 +268,7 @@ int8_t* post_store8_0 (int8_t * a, int8x16_t v) /* **post_store8_1: ** ... -** vstrb.16 q[0-9]+, \[r0\], #1 +** vstrb.16 q[0-7], \[r0\], #1 ** ... */ uint8_t* post_store8_1 (uint8_t * a, uint16x8_t v) @@ -281,7 +281,7 @@ uint8_t* post_store8_1 (uint8_t * a, uint16x8_t v) /* **post_store8_2: ** ... -** vstrb.8 q[0-9]+, \[r0\], #-26 +** vstrb.8 q[0-7], \[r0\], #-26 ** ... */ int8_t* post_store8_2 (int8_t * a, int8x16_t v) @@ -294,7 +294,7 @@ int8_t* post_store8_2 (int8_t * a, int8x16_t v) /* **post_store8_3: ** ... -** vstrb.16 q[0-9]+, \[r0\], #7 +** vstrb.16 q[0-7], \[r0\], #7 ** ... */ uint8_t* post_store8_3 (uint8_t * a, uint16x8_t v) @@ -307,7 +307,7 @@ uint8_t* post_store8_3 (uint8_t * a, uint16x8_t v) /* **post_storefp16_0: ** ... -** vstrh.16 q[0-9]+, \[r0\], #-16 +** vstrh.16 q[0-7], \[r0\], #-16 ** ... */ float16_t *post_storefp16_0 (float16_t *a, float16x8_t v) @@ -320,7 +320,7 @@ float16_t *post_storefp16_0 (float16_t *a, float16x8_t v) /* **post_store16_0: ** ... -** vstrh.16 q[0-9]+, \[r0\], #126 +** vstrh.16 q[0-7], \[r0\], #126 ** ... */ int16_t* post_store16_0 (int16_t * a, int16x8_t v) @@ -333,7 +333,7 @@ int16_t* post_store16_0 (int16_t * a, int16x8_t v) /* **post_store16_1: ** ... -** vstrh.32 q[0-9]+, \[r0\], #-16 +** vstrh.32 q[0-7], \[r0\], #-16 ** ... */ uint16_t* post_store16_1 (uint16_t * a, uint32x4_t v) @@ -346,7 +346,7 @@ uint16_t* post_store16_1 (uint16_t * a, uint32x4_t v) /* **post_storefp32_0: ** ... -** vstrw.32 q[0-9]+, \[r0\], #-16 +** vstrw.32 q[0-7], \[r0\], #-16 ** ... */ float32_t* post_storefp32_0 (float32_t * a, float32x4_t v) @@ -359,7 +359,7 @@ float32_t* post_storefp32_0 (float32_t * a, float32x4_t v) /* **post_store32_0: ** ... -** vstrw.32 q[0-9]+, \[r0\], #16 +** vstrw.32 q[0-7], \[r0\], #16 ** ... */ int32_t* post_store32_0 (int32_t * a, int32x4_t v) diff --git a/gcc/testsuite/gcc.target/powerpc/pr99888-1.c b/gcc/testsuite/gcc.target/powerpc/pr99888-1.c new file mode 100644 index 0000000..9370b4e --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr99888-1.c @@ -0,0 +1,43 @@ +/* Verify no errors for different nops after local entry on ELFv2. */ + +extern int a; + +__attribute__ ((noipa, patchable_function_entry (1, 0))) +int test1 (int b) { + return a + b; +} + +__attribute__ ((noipa, patchable_function_entry (2, 0))) +int test2 (int b) { + return a + b; +} + +__attribute__ ((noipa, patchable_function_entry (3, 0))) +int test3 (int b) { + return a + b; +} + +__attribute__ ((noipa, patchable_function_entry (4, 0))) +int test4 (int b) { + return a + b; +} + +__attribute__ ((noipa, patchable_function_entry (5, 0))) +int test5 (int b) { + return a + b; +} + +__attribute__ ((noipa, patchable_function_entry (6, 0))) +int test6 (int b) { + return a + b; +} + +__attribute__ ((noipa, patchable_function_entry (7, 0))) +int test7 (int b) { + return a + b; +} + +__attribute__ ((noipa, patchable_function_entry (8, 0))) +int test8 (int b) { + return a + b; +} diff --git a/gcc/testsuite/gcc.target/powerpc/pr99888-2.c b/gcc/testsuite/gcc.target/powerpc/pr99888-2.c new file mode 100644 index 0000000..4506171 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr99888-2.c @@ -0,0 +1,43 @@ +/* Verify no errors for 2, 6 and 14 nops before local entry on ELFv2. */ + +extern int a; + +__attribute__ ((noipa, patchable_function_entry (2, 2))) +int test1 (int b) { + return a + b; +} + +__attribute__ ((noipa, patchable_function_entry (4, 2))) +int test2 (int b) { + return a + b; +} + +__attribute__ ((noipa, patchable_function_entry (6, 6))) +int test3 (int b) { + return a + b; +} + +__attribute__ ((noipa, patchable_function_entry (8, 6))) +int test4 (int b) { + return a + b; +} + +__attribute__ ((noipa, patchable_function_entry (16, 6))) +int test5 (int b) { + return a + b; +} + +__attribute__ ((noipa, patchable_function_entry (14, 14))) +int test6 (int b) { + return a + b; +} + +__attribute__ ((noipa, patchable_function_entry (28, 14))) +int test7 (int b) { + return a + b; +} + +__attribute__ ((noipa, patchable_function_entry (64, 14))) +int test8 (int b) { + return a + b; +} diff --git a/gcc/testsuite/gcc.target/powerpc/pr99888-3.c b/gcc/testsuite/gcc.target/powerpc/pr99888-3.c new file mode 100644 index 0000000..4531ae3 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr99888-3.c @@ -0,0 +1,11 @@ +/* { dg-options "-fpatchable-function-entry=1" } */ + +/* Verify no errors on ELFv2, using command line option instead of + function attribute. */ + +extern int a; + +int test (int b) { + return a + b; +} + diff --git a/gcc/testsuite/gcc.target/powerpc/pr99888-4.c b/gcc/testsuite/gcc.target/powerpc/pr99888-4.c new file mode 100644 index 0000000..00a8d4d --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr99888-4.c @@ -0,0 +1,13 @@ +/* { dg-require-effective-target powerpc_elfv2 } */ +/* There is no global entry point prologue with pcrel. */ +/* { dg-options "-mno-pcrel -fpatchable-function-entry=1,1" } */ + +/* Verify one error emitted for unexpected 1 nop before local + entry. */ + +extern int a; + +int test (int b) { + return a + b; +} +/* { dg-error "unsupported number of nops before function entry \\(1\\)" "" { target *-*-* } .-1 } */ diff --git a/gcc/testsuite/gcc.target/powerpc/pr99888-5.c b/gcc/testsuite/gcc.target/powerpc/pr99888-5.c new file mode 100644 index 0000000..39d3b44 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr99888-5.c @@ -0,0 +1,13 @@ +/* { dg-require-effective-target powerpc_elfv2 } */ +/* There is no global entry point prologue with pcrel. */ +/* { dg-options "-mno-pcrel -fpatchable-function-entry=7,3" } */ + +/* Verify one error emitted for unexpected 3 nops before local + entry. */ + +extern int a; + +int test (int b) { + return a + b; +} +/* { dg-error "unsupported number of nops before function entry \\(3\\)" "" { target *-*-* } .-1 } */ diff --git a/gcc/testsuite/gcc.target/powerpc/pr99888-6.c b/gcc/testsuite/gcc.target/powerpc/pr99888-6.c new file mode 100644 index 0000000..c6c18dc --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr99888-6.c @@ -0,0 +1,14 @@ +/* { dg-require-effective-target powerpc_elfv2 } */ +/* There is no global entry point prologue with pcrel. */ +/* { dg-options "-mno-pcrel" } */ + +/* Verify one error emitted for unexpected 4 nops before local + entry. */ + +extern int a; + +__attribute__ ((patchable_function_entry (20, 4))) +int test (int b) { + return a + b; +} +/* { dg-error "unsupported number of nops before function entry \\(4\\)" "" { target *-*-* } .-1 } */ diff --git a/gcc/testsuite/gfortran.dg/PR100029.f90 b/gcc/testsuite/gfortran.dg/PR100029.f90 new file mode 100644 index 0000000..fd7e4c4 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/PR100029.f90 @@ -0,0 +1,22 @@ +! { dg-do run } +! +! Test the fix for PR100029 +! + +program foo_p + implicit none + + type :: foo_t + end type foo_t + + class(foo_t), allocatable :: pout + + call foo_s(pout) + +contains + + subroutine foo_s(that) + class(foo_t), allocatable, intent(out) :: that(..) + end subroutine foo_s + +end program foo_p diff --git a/gcc/testsuite/gfortran.dg/PR100040.f90 b/gcc/testsuite/gfortran.dg/PR100040.f90 new file mode 100644 index 0000000..0a135ff --- /dev/null +++ b/gcc/testsuite/gfortran.dg/PR100040.f90 @@ -0,0 +1,36 @@ +! { dg-do run } +! +! Test the fix for PR100040 +! + +program foo_p + implicit none + + integer, parameter :: n = 11 + + type :: foo_t + integer :: i + end type foo_t + + type(foo_t), parameter :: a = foo_t(n) + + class(foo_t), allocatable :: pout + + call foo_s(pout) + if(.not.allocated(pout)) stop 1 + if(pout%i/=n) stop 2 + +contains + + subroutine foo_s(that) + class(foo_t), allocatable, intent(out) :: that(..) + + select rank(that) + rank(0) + that = a + rank default + stop 3 + end select + end subroutine foo_s + +end program foo_p diff --git a/gcc/testsuite/gfortran.dg/goacc/mapping-tests-5.f90 b/gcc/testsuite/gfortran.dg/goacc/mapping-tests-5.f90 new file mode 100644 index 0000000..8df8c58 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/goacc/mapping-tests-5.f90 @@ -0,0 +1,15 @@ +subroutine foo + type one + integer, dimension(10) :: i, j + end type + type two + type(one) A, B + end type + + type(two) x + + !$acc enter data copyin(x%A%i(5), x%A%i(4), x%A) +! { dg-error ".x.a.i. appears more than once in map clauses" "" { target *-*-* } .-1 } + !$acc enter data copyin(x%A, x%A%i(5), x%A%i(4)) +! { dg-error ".x.a.i. appears more than once in map clauses" "" { target *-*-* } .-1 } +end diff --git a/gcc/testsuite/gfortran.dg/gomp/is_device_ptr-1.f90 b/gcc/testsuite/gfortran.dg/gomp/is_device_ptr-1.f90 index 0eeca0e..1d3a0d8 100644 --- a/gcc/testsuite/gfortran.dg/gomp/is_device_ptr-1.f90 +++ b/gcc/testsuite/gfortran.dg/gomp/is_device_ptr-1.f90 @@ -7,16 +7,16 @@ subroutine test(b,c,d) integer, target :: a(5) - !$omp target is_device_ptr(a) ! { dg-error "Non-dummy object .a. in IS_DEVICE_PTR clause" } + !$omp target is_device_ptr(a) ! Valid since OpenMP 5.1 !$omp end target - !$omp target is_device_ptr(b) ! { dg-error "VALUE object .b. in IS_DEVICE_PTR clause" } + !$omp target is_device_ptr(b) ! Valid since OpenMP 5.1 !$omp end target - !$omp target is_device_ptr(c) ! { dg-error "POINTER object .c. in IS_DEVICE_PTR clause" } + !$omp target is_device_ptr(c) ! Valid since OpenMP 5.1 !$omp end target - !$omp target is_device_ptr(d) ! { dg-error "ALLOCATABLE object .d. in IS_DEVICE_PTR clause" } + !$omp target is_device_ptr(d) ! Valid since OpenMP 5.1 !$omp end target !$omp target data map(a) use_device_addr(a) ! Should be okay diff --git a/gcc/testsuite/gfortran.dg/gomp/is_device_ptr-2.f90 b/gcc/testsuite/gfortran.dg/gomp/is_device_ptr-2.f90 index 7adc6f6..0762e57 100644 --- a/gcc/testsuite/gfortran.dg/gomp/is_device_ptr-2.f90 +++ b/gcc/testsuite/gfortran.dg/gomp/is_device_ptr-2.f90 @@ -8,7 +8,7 @@ subroutine abc(cc) !$omp target enter data map(to: cc, dd) !$omp target data use_device_addr(cc) use_device_ptr(dd) - !$omp target is_device_ptr(cc, dd) ! { dg-error "Non-dummy object 'dd' in IS_DEVICE_PTR clause at" } + !$omp target is_device_ptr(cc, dd) ! Valid since OpenMP 5.1 if (cc /= 131 .or. dd /= 484) stop 1 cc = 44 dd = 45 diff --git a/gcc/testsuite/gfortran.dg/gomp/is_device_ptr-3.f90 b/gcc/testsuite/gfortran.dg/gomp/is_device_ptr-3.f90 index c3de772..7b5b27b 100644 --- a/gcc/testsuite/gfortran.dg/gomp/is_device_ptr-3.f90 +++ b/gcc/testsuite/gfortran.dg/gomp/is_device_ptr-3.f90 @@ -23,5 +23,6 @@ contains end program main -! { dg-final { scan-tree-dump "is_device_ptr\\(a\\)" "gimple" } } +! { dg-final { scan-tree-dump "has_device_addr\\(a\\)" "gimple" } } +! { dg-final { scan-tree-dump-not "has_device_addr\\(b\\)" "gimple" } } ! { dg-final { scan-tree-dump-not "is_device_ptr\\(b\\)" "gimple" } } diff --git a/gcc/testsuite/gfortran.dg/ieee/fma_1.f90 b/gcc/testsuite/gfortran.dg/ieee/fma_1.f90 index 3463642..320c73a 100644 --- a/gcc/testsuite/gfortran.dg/ieee/fma_1.f90 +++ b/gcc/testsuite/gfortran.dg/ieee/fma_1.f90 @@ -38,7 +38,6 @@ print *, sx1 * sx2 + sx3 print *, ieee_fma(sx1, sx2, sx3) if (ieee_fma(sx1, sx2, sx3) /= real(3, kind(sx1)) / 2) stop 4 - !if (ieee_fma(sx1, sx2, sx3) == sx1 * sx2 + sx3) stop 5 ! Double @@ -57,7 +56,6 @@ print *, dx1 * dx2 + dx3 print *, ieee_fma(dx1, dx2, dx3) if (ieee_fma(dx1, dx2, dx3) /= real(3, kind(dx1)) / 2) stop 4 - !if (ieee_fma(dx1, dx2, dx3) == dx1 * dx2 + dx3) stop 5 ! Large kind 1 @@ -76,7 +74,6 @@ print *, lx1 * lx2 + lx3 print *, ieee_fma(lx1, lx2, lx3) if (ieee_fma(lx1, lx2, lx3) /= real(3, kind(lx1)) / 2) stop 4 - if (ieee_fma(lx1, lx2, lx3) == lx1 * lx2 + lx3) stop 5 ! Large kind 2 @@ -95,6 +92,5 @@ print *, wx1 * wx2 + wx3 print *, ieee_fma(wx1, wx2, wx3) if (ieee_fma(wx1, wx2, wx3) /= real(3, kind(wx1)) / 2) stop 4 - if (ieee_fma(wx1, wx2, wx3) == wx1 * wx2 + wx3) stop 5 end diff --git a/gcc/testsuite/gfortran.dg/ieee/modes_1.f90 b/gcc/testsuite/gfortran.dg/ieee/modes_1.f90 index b6ab288..205c47f 100644 --- a/gcc/testsuite/gfortran.dg/ieee/modes_1.f90 +++ b/gcc/testsuite/gfortran.dg/ieee/modes_1.f90 @@ -81,15 +81,15 @@ program foo ! Check again if (ieee_support_underflow_control()) then call ieee_get_underflow_mode(f) - if (.not. f) stop 3 + if (.not. f) stop 4 endif if (ieee_support_rounding(ieee_down)) then call ieee_get_rounding_mode(rmode) - if (rmode /= ieee_down) stop 4 + if (rmode /= ieee_down) stop 5 endif if (ieee_support_halting(ieee_overflow)) then call ieee_get_halting_mode(ieee_overflow, f) - if (f) stop 5 + if (f) stop 6 endif end program foo diff --git a/gcc/testsuite/lib/gcc-defs.exp b/gcc/testsuite/lib/gcc-defs.exp index 42ef1d8..2102ed6 100644 --- a/gcc/testsuite/lib/gcc-defs.exp +++ b/gcc/testsuite/lib/gcc-defs.exp @@ -332,7 +332,7 @@ proc gcc_adjust_linker_flags_list { args } { continue } elseif { $skip != "" } then { set skip "" - } elseif { $opt == "-Xlinker" } then { + } elseif { $opt == "-Xlinker" || $opt == "-T" } then { set skip $opt } elseif { ![string match "-*" $opt] \ && [file isfile $opt] } { diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 703aba4..7c9dd45 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -370,6 +370,55 @@ proc check_weak_override_available { } { return [check_weak_available] } +# Return 1 if VMA is equal to LMA for the .data section, 0 +# otherwise. Cache the result. + +proc check_effective_target_vma_equals_lma { } { + global tool + + return [check_cached_effective_target vma_equals_lma { + set src vma_equals_lma[pid].c + set exe vma_equals_lma[pid].exe + verbose "check_effective_target_vma_equals_lma compiling testfile $src" 2 + set f [open $src "w"] + puts $f "#ifdef __cplusplus\nextern \"C\"\n#endif\n" + puts $f "int foo = 42; void main() {}" + close $f + set lines [${tool}_target_compile $src $exe executable ""] + file delete $src + + if [string match "" $lines] then { + # No error messages + + set objdump_name [find_binutils_prog objdump] + set output [remote_exec host "$objdump_name" "--section-headers --section=.data $exe"] + set output [lindex $output 1] + + remote_file build delete $exe + + # Example output of objdump: + #vma_equals_lma9059.exe: file format elf32-littlearm + # + #Sections: + #Idx Name Size VMA LMA File off Algn + # 6 .data 00000558 20000000 08002658 00020000 2**3 + # CONTENTS, ALLOC, LOAD, DATA + + # Capture LMA and VMA columns for .data section + if ![ regexp {\d*\d+\s+\.data\s+\d+\s+(\d+)\s+(\d+)} $output dummy vma lma ] { + verbose "Could not parse objdump output" 2 + return 0 + } else { + return [string equal $vma $lma] + } + } else { + remote_file build delete $exe + verbose "Could not determine if VMA is equal to LMA. Assuming not equal." 2 + return 0 + } + }] +} + # The "noinit" attribute is only supported by some targets. # This proc returns 1 if it's supported, 0 if it's not. @@ -477,6 +526,16 @@ proc check_effective_target_alias { } { } } +# Returns 1 if the target uses the ELF object format, 0 otherwise. + +proc check_effective_target_elf { } { + if { [gcc_target_object_format] == "elf" } { + return 1; + } else { + return 0; + } +} + # Returns 1 if the target toolchain supports ifunc, 0 otherwise. proc check_ifunc_available { } { @@ -8253,6 +8312,14 @@ proc check_effective_target_vect_long_mult { } { return $answer } +# Return 1 if the target supports vector int modulus, 0 otherwise. + +proc check_effective_target_vect_int_mod { } { + return [check_cached_effective_target_indexed vect_int_mod { + expr { [istarget powerpc*-*-*] + && [check_effective_target_has_arch_pwr10] }}] +} + # Return 1 if the target supports vector even/odd elements extraction, 0 otherwise. proc check_effective_target_vect_extract_even_odd { } { diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc index ade66c5..09fa7b6 100644 --- a/gcc/tree-cfg.cc +++ b/gcc/tree-cfg.cc @@ -3510,7 +3510,7 @@ verify_gimple_call (gcall *stmt) if (is_constant_size_arg0 && is_constant_size_lhs) if (maybe_ne (size_from_arg0, size_from_lhs)) { - error ("%<DEFFERED_INIT%> calls should have same " + error ("%<DEFERRED_INIT%> calls should have same " "constant size for the first argument and LHS"); return true; } diff --git a/gcc/tree-data-ref.cc b/gcc/tree-data-ref.cc index 91bfb619d..978c3f0 100644 --- a/gcc/tree-data-ref.cc +++ b/gcc/tree-data-ref.cc @@ -2979,10 +2979,10 @@ dr_may_alias_p (const struct data_reference *a, const struct data_reference *b, && operand_equal_p (DR_OFFSET (a), DR_OFFSET (b)) && poly_int_tree_p (tree_size_a) && poly_int_tree_p (tree_size_b) - && !ranges_maybe_overlap_p (wi::to_widest (DR_INIT (a)), - wi::to_widest (tree_size_a), - wi::to_widest (DR_INIT (b)), - wi::to_widest (tree_size_b))) + && !ranges_maybe_overlap_p (wi::to_poly_widest (DR_INIT (a)), + wi::to_poly_widest (tree_size_a), + wi::to_poly_widest (DR_INIT (b)), + wi::to_poly_widest (tree_size_b))) { gcc_assert (integer_zerop (DR_STEP (a)) && integer_zerop (DR_STEP (b))); diff --git a/gcc/tree-ssa-dom.cc b/gcc/tree-ssa-dom.cc index 84bef79..e6b8dac 100644 --- a/gcc/tree-ssa-dom.cc +++ b/gcc/tree-ssa-dom.cc @@ -393,7 +393,8 @@ edge_info::record_simple_equiv (tree lhs, tree rhs) simple_equivalences.safe_push (equiv_pair (lhs, rhs)); } -/* Free the edge_info data attached to E, if it exists. */ +/* Free the edge_info data attached to E, if it exists and + clear e->aux. */ void free_dom_edge_info (edge e) @@ -402,6 +403,7 @@ free_dom_edge_info (edge e) if (edge_info) delete edge_info; + e->aux = NULL; } /* Free all EDGE_INFO structures associated with edges in the CFG. @@ -420,11 +422,76 @@ free_all_edge_infos (void) FOR_EACH_BB_FN (bb, cfun) { FOR_EACH_EDGE (e, ei, bb->preds) - { - free_dom_edge_info (e); - e->aux = NULL; + free_dom_edge_info (e); + } +} + +/* Return TRUE if BB has precisely two preds, one of which + is a backedge from a forwarder block where the forwarder + block is a direct successor of BB. Being a forwarder + block, it has no side effects other than transfer of + control. Otherwise return FALSE. */ + +static bool +single_block_loop_p (basic_block bb) +{ + /* Two preds. */ + if (EDGE_COUNT (bb->preds) != 2) + return false; + + /* One and only one of the edges must be marked with + EDGE_DFS_BACK. */ + basic_block pred = NULL; + unsigned int count = 0; + if (EDGE_PRED (bb, 0)->flags & EDGE_DFS_BACK) + { + pred = EDGE_PRED (bb, 0)->src; + count++; + } + if (EDGE_PRED (bb, 1)->flags & EDGE_DFS_BACK) + { + pred = EDGE_PRED (bb, 1)->src; + count++; + } + + if (count != 1) + return false; + + /* Now examine PRED. It should have a single predecessor which + is BB and a single successor that is also BB. */ + if (EDGE_COUNT (pred->preds) != 1 + || EDGE_COUNT (pred->succs) != 1 + || EDGE_PRED (pred, 0)->src != bb + || EDGE_SUCC (pred, 0)->dest != bb) + return false; + + /* This looks good from a CFG standpoint. Now look at the guts + of PRED. Basically we want to verify there are no PHI nodes + and no real statements. */ + if (! gimple_seq_empty_p (phi_nodes (pred))) + return false; + + gimple_stmt_iterator gsi; + for (gsi = gsi_last_bb (pred); !gsi_end_p (gsi); gsi_prev (&gsi)) + { + gimple *stmt = gsi_stmt (gsi); + + switch (gimple_code (stmt)) + { + case GIMPLE_LABEL: + if (DECL_NONLOCAL (gimple_label_label (as_a <glabel *> (stmt)))) + return false; + break; + + case GIMPLE_DEBUG: + break; + + default: + return false; } } + + return true; } /* We have finished optimizing BB, record any information implied by @@ -436,6 +503,13 @@ record_edge_info (basic_block bb) gimple_stmt_iterator gsi = gsi_last_bb (bb); class edge_info *edge_info; + /* Free all the outgoing edge info data associated with + BB's outgoing edges. */ + edge e; + edge_iterator ei; + FOR_EACH_EDGE (e, ei, bb->succs) + free_dom_edge_info (e); + if (! gsi_end_p (gsi)) { gimple *stmt = gsi_stmt (gsi); @@ -451,8 +525,6 @@ record_edge_info (basic_block bb) int i; int n_labels = gimple_switch_num_labels (switch_stmt); tree *info = XCNEWVEC (tree, last_basic_block_for_fn (cfun)); - edge e; - edge_iterator ei; for (i = 0; i < n_labels; i++) { @@ -584,6 +656,62 @@ record_edge_info (basic_block bb) if (can_infer_simple_equiv && TREE_CODE (inverted) == EQ_EXPR) edge_info->record_simple_equiv (op0, op1); } + + /* If this block is a single block loop, then we may be able to + record some equivalences on the loop's exit edge. */ + if (single_block_loop_p (bb)) + { + /* We know it's a single block loop. Now look at the loop + exit condition. What we're looking for is whether or not + the exit condition is loop invariant which we can detect + by checking if all the SSA_NAMEs referenced are defined + outside the loop. */ + if ((TREE_CODE (op0) != SSA_NAME + || gimple_bb (SSA_NAME_DEF_STMT (op0)) != bb) + && (TREE_CODE (op1) != SSA_NAME + || gimple_bb (SSA_NAME_DEF_STMT (op1)) != bb)) + { + /* At this point we know the exit condition is loop + invariant. The only way to get out of the loop is + if never traverses the backedge to begin with. This + implies that any PHI nodes create equivalances we can + attach to the loop exit edge. */ + int alternative + = (EDGE_PRED (bb, 0)->flags & EDGE_DFS_BACK) ? 1 : 0; + + gphi_iterator gsi; + for (gsi = gsi_start_phis (bb); + !gsi_end_p (gsi); + gsi_next (&gsi)) + { + /* Now get the EDGE_INFO class so we can append + it to our list. We want the successor edge + where the destination is not the source of + an incoming edge. */ + gphi *phi = gsi.phi (); + tree src = PHI_ARG_DEF (phi, alternative); + tree dst = PHI_RESULT (phi); + + /* If the other alternative is the same as the result, + then this is a degenerate and can be ignored. */ + if (dst == PHI_ARG_DEF (phi, !alternative)) + continue; + + if (EDGE_SUCC (bb, 0)->dest + != EDGE_PRED (bb, !alternative)->src) + edge_info = (class edge_info *)EDGE_SUCC (bb, 0)->aux; + else + edge_info = (class edge_info *)EDGE_SUCC (bb, 1)->aux; + + /* Note that since this processing is done independently + of other edge equivalency processing, we may not + have an EDGE_INFO structure set up yet. */ + if (edge_info == NULL) + edge_info = new class edge_info (false_edge); + edge_info->record_simple_equiv (dst, src); + } + } + } } } } diff --git a/gcc/tree-ssa-dse.cc b/gcc/tree-ssa-dse.cc index 2411ac7..c14e5e4 100644 --- a/gcc/tree-ssa-dse.cc +++ b/gcc/tree-ssa-dse.cc @@ -170,7 +170,7 @@ initialize_ao_ref_for_dse (gimple *stmt, ao_ref *write, bool may_def_ok = false) { ao_ref_init_from_ptr_and_size (write, gimple_call_arg (stmt, 0), - TYPE_SIZE_UNIT (TREE_TYPE (gimple_call_arg (stmt, 2)))); + TYPE_SIZE_UNIT (TREE_TYPE (gimple_call_arg (stmt, 3)))); return true; } break; diff --git a/gcc/tree-ssa-uninit.cc b/gcc/tree-ssa-uninit.cc index bde2399..bf2e505 100644 --- a/gcc/tree-ssa-uninit.cc +++ b/gcc/tree-ssa-uninit.cc @@ -274,9 +274,6 @@ warn_uninit (opt_code opt, tree t, tree var, gimple *context, else if (var_name_str) location = gimple_location (var_def_stmt); - location = linemap_resolve_location (line_table, location, - LRK_SPELLING_LOCATION, NULL); - auto_diagnostic_group d; gcc_assert (opt == OPT_Wuninitialized || opt == OPT_Wmaybe_uninitialized); if (var) @@ -424,10 +421,7 @@ maybe_warn_read_write_only (tree fndecl, gimple *stmt, tree arg, tree ptr) && access->mode != access_write_only) continue; - location_t stmtloc - = linemap_resolve_location (line_table, gimple_location (stmt), - LRK_SPELLING_LOCATION, NULL); - + location_t stmtloc = gimple_location (stmt); if (!warning_at (stmtloc, OPT_Wmaybe_uninitialized, "%qE may be used uninitialized", ptr)) break; @@ -722,9 +716,7 @@ maybe_warn_operand (ao_ref &ref, gimple *stmt, tree lhs, tree rhs, bool warned = false; /* We didn't find any may-defs so on all paths either reached function entry or a killing clobber. */ - location_t location - = linemap_resolve_location (line_table, gimple_location (stmt), - LRK_SPELLING_LOCATION, NULL); + location_t location = gimple_location (stmt); if (wlims.always_executed) { if (warning_at (location, OPT_Wuninitialized, diff --git a/gcc/value-range-storage.cc b/gcc/value-range-storage.cc index de7575e..6e05462 100644 --- a/gcc/value-range-storage.cc +++ b/gcc/value-range-storage.cc @@ -150,11 +150,7 @@ irange_storage_slot::set_irange (const irange &r) { gcc_checking_assert (fits_p (r)); - // Avoid calling unsupported get_nonzero_bits on legacy. - if (r.legacy_mode_p ()) - m_ints[0] = -1; - else - m_ints[0] = r.get_nonzero_bits (); + m_ints[0] = r.get_nonzero_bits (); unsigned pairs = r.num_pairs (); for (unsigned i = 0; i < pairs; ++i) diff --git a/gcc/value-range.cc b/gcc/value-range.cc index 6154d73..afb26a4 100644 --- a/gcc/value-range.cc +++ b/gcc/value-range.cc @@ -940,7 +940,7 @@ irange::irange_set (tree min, tree max) m_base[1] = max; m_num_ranges = 1; m_kind = VR_RANGE; - m_nonzero_mask = NULL; + m_nonzero_mask = wi::shwi (-1, TYPE_PRECISION (TREE_TYPE (min))); normalize_kind (); if (flag_checking) @@ -1014,7 +1014,7 @@ irange::irange_set_anti_range (tree min, tree max) } m_kind = VR_RANGE; - m_nonzero_mask = NULL; + m_nonzero_mask = wi::shwi (-1, TYPE_PRECISION (TREE_TYPE (min))); normalize_kind (); if (flag_checking) @@ -1071,7 +1071,7 @@ irange::set (tree min, tree max, value_range_kind kind) m_base[0] = min; m_base[1] = max; m_num_ranges = 1; - m_nonzero_mask = NULL; + m_nonzero_mask = wi::shwi (-1, TYPE_PRECISION (TREE_TYPE (min))); return; } @@ -1121,7 +1121,7 @@ irange::set (tree min, tree max, value_range_kind kind) m_base[0] = min; m_base[1] = max; m_num_ranges = 1; - m_nonzero_mask = NULL; + m_nonzero_mask = wi::shwi (-1, TYPE_PRECISION (TREE_TYPE (min))); normalize_kind (); if (flag_checking) verify_range (); @@ -1136,14 +1136,11 @@ irange::verify_range () if (m_kind == VR_UNDEFINED) { gcc_checking_assert (m_num_ranges == 0); - gcc_checking_assert (!m_nonzero_mask); return; } - if (m_nonzero_mask) - gcc_checking_assert (wi::to_wide (m_nonzero_mask) != -1); if (m_kind == VR_VARYING) { - gcc_checking_assert (!m_nonzero_mask); + gcc_checking_assert (m_nonzero_mask == -1); gcc_checking_assert (m_num_ranges == 1); gcc_checking_assert (varying_compatible_p ()); return; @@ -1233,15 +1230,12 @@ irange::legacy_equal_p (const irange &other) const if (m_kind == VR_UNDEFINED) return true; if (m_kind == VR_VARYING) - { - return (range_compatible_p (type (), other.type ()) - && vrp_operand_equal_p (m_nonzero_mask, other.m_nonzero_mask)); - } + return range_compatible_p (type (), other.type ()); return (vrp_operand_equal_p (tree_lower_bound (0), other.tree_lower_bound (0)) && vrp_operand_equal_p (tree_upper_bound (0), other.tree_upper_bound (0)) - && vrp_operand_equal_p (m_nonzero_mask, other.m_nonzero_mask)); + && get_nonzero_bits () == other.get_nonzero_bits ()); } bool @@ -1263,6 +1257,9 @@ irange::operator== (const irange &other) const if (m_num_ranges != other.m_num_ranges) return false; + if (m_num_ranges == 0) + return true; + for (unsigned i = 0; i < m_num_ranges; ++i) { tree lb = tree_lower_bound (i); @@ -1273,7 +1270,7 @@ irange::operator== (const irange &other) const || !operand_equal_p (ub, ub_other, 0)) return false; } - return vrp_operand_equal_p (m_nonzero_mask, other.m_nonzero_mask); + return get_nonzero_bits () == other.get_nonzero_bits (); } /* Return TRUE if this is a symbolic range. */ @@ -1416,10 +1413,11 @@ irange::contains_p (tree cst) const gcc_checking_assert (TREE_CODE (cst) == INTEGER_CST); - if (m_nonzero_mask) + // See if we can exclude CST based on the nonzero bits. + if (m_nonzero_mask != -1) { wide_int cstw = wi::to_wide (cst); - if (cstw != 0 && wi::bit_and (wi::to_wide (m_nonzero_mask), cstw) == 0) + if (cstw != 0 && wi::bit_and (m_nonzero_mask, cstw) == 0) return false; } @@ -1878,9 +1876,6 @@ irange::legacy_intersect (irange *vr0, const irange *vr1) intersect_ranges (&vr0kind, &vr0min, &vr0max, vr1->kind (), vr1->min (), vr1->max ()); - // Pessimize nonzero masks, as we don't support them. - m_nonzero_mask = NULL; - /* Make sure to canonicalize the result though as the inversion of a VR_RANGE can still be a VR_RANGE. */ if (vr0kind == VR_UNDEFINED) @@ -2202,9 +2197,6 @@ irange::legacy_union (irange *vr0, const irange *vr1) union_ranges (&vr0kind, &vr0min, &vr0max, vr1->kind (), vr1->min (), vr1->max ()); - // Pessimize nonzero masks, as we don't support them. - m_nonzero_mask = NULL; - if (vr0kind == VR_UNDEFINED) vr0->set_undefined (); else if (vr0kind == VR_VARYING) @@ -2310,8 +2302,6 @@ irange::legacy_verbose_intersect (const irange *other) // Perform an efficient union with R when both ranges have only a single pair. // Excluded are VARYING and UNDEFINED ranges. -// -// NOTE: It is the caller's responsibility to set the nonzero mask. bool irange::irange_single_pair_union (const irange &r) @@ -2325,7 +2315,7 @@ irange::irange_single_pair_union (const irange &r) { // If current upper bound is new upper bound, we're done. if (wi::le_p (wi::to_wide (r.m_base[1]), wi::to_wide (m_base[1]), sign)) - return false; + return union_nonzero_bits (r); // Otherwise R has the new upper bound. // Check for overlap/touching ranges, or single target range. if (m_max_ranges == 1 @@ -2338,8 +2328,7 @@ irange::irange_single_pair_union (const irange &r) m_base[3] = r.m_base[1]; m_num_ranges = 2; } - if (varying_compatible_p ()) - m_kind = VR_VARYING; + union_nonzero_bits (r); return true; } @@ -2353,11 +2342,7 @@ irange::irange_single_pair_union (const irange &r) // Check for overlapping ranges, or target limited to a single range. else if (m_max_ranges == 1 || wi::to_widest (r.m_base[1]) + 1 >= wi::to_widest (lb)) - { - // This has the new upper bound, just check for varying. - if (varying_compatible_p ()) - m_kind = VR_VARYING; - } + ; else { // Left with 2 pairs. @@ -2366,8 +2351,7 @@ irange::irange_single_pair_union (const irange &r) m_base[3] = m_base[1]; m_base[1] = r.m_base[1]; } - if (varying_compatible_p ()) - m_kind = VR_VARYING; + union_nonzero_bits (r); return true; } @@ -2398,27 +2382,13 @@ irange::irange_union (const irange &r) return true; } - // Save the nonzero mask in case the set operations below clobber it. - bool ret_nz = union_nonzero_bits (r); - tree saved_nz = m_nonzero_mask; - - // The union_nonzero_bits may have turned things into a varying. - if (varying_p ()) - return true; - // Special case one range union one range. if (m_num_ranges == 1 && r.m_num_ranges == 1) - { - bool ret = irange_single_pair_union (r); - set_nonzero_bits (saved_nz); - if (flag_checking) - verify_range (); - return ret || ret_nz; - } + return irange_single_pair_union (r); // If this ranges fully contains R, then we need do nothing. if (irange_contains_p (r)) - return ret_nz; + return union_nonzero_bits (r); // Do not worry about merging and such by reserving twice as many // pairs as needed, and then simply sort the 2 ranges into this @@ -2506,11 +2476,7 @@ irange::irange_union (const irange &r) m_num_ranges = i / 2; m_kind = VR_RANGE; - m_nonzero_mask = saved_nz; - normalize_kind (); - - if (flag_checking) - verify_range (); + union_nonzero_bits (r); return true; } @@ -2576,21 +2542,11 @@ irange::irange_intersect (const irange &r) set_undefined (); return true; } - - // Save the nonzero mask in case the set operations below clobber it. - bool ret_nz = intersect_nonzero_bits (r); - tree saved_nz = m_nonzero_mask; - if (r.varying_p ()) - return ret_nz; - + return false; if (varying_p ()) { operator= (r); - if (saved_nz) - set_nonzero_bits (saved_nz); - if (flag_checking) - verify_range (); return true; } @@ -2600,13 +2556,13 @@ irange::irange_intersect (const irange &r) if (undefined_p ()) return true; - set_nonzero_bits (saved_nz); - return res || saved_nz; + res |= intersect_nonzero_bits (r); + return res; } // If R fully contains this, then intersection will change nothing. if (r.irange_contains_p (*this)) - return ret_nz; + return intersect_nonzero_bits (r); signop sign = TYPE_SIGN (TREE_TYPE(m_base[0])); unsigned bld_pair = 0; @@ -2675,15 +2631,14 @@ irange::irange_intersect (const irange &r) // At the exit of this loop, it is one of 2 things: // ran out of r1, or r2, but either means we are done. m_num_ranges = bld_pair; + if (m_num_ranges == 0) + { + set_undefined (); + return true; + } m_kind = VR_RANGE; - if (!undefined_p ()) - m_nonzero_mask = saved_nz; - normalize_kind (); - - if (flag_checking) - verify_range (); - + intersect_nonzero_bits (r); return true; } @@ -2749,10 +2704,15 @@ irange::intersect (const wide_int& lb, const wide_int& ub) } m_num_ranges = bld_index; + if (m_num_ranges == 0) + { + set_undefined (); + return true; + } m_kind = VR_RANGE; - normalize_kind (); - + // No need to call normalize_kind(), as the caller will do this + // while intersecting the nonzero mask. if (flag_checking) verify_range (); return true; @@ -2801,7 +2761,6 @@ irange::invert () } gcc_checking_assert (!undefined_p () && !varying_p ()); - m_nonzero_mask = NULL; // We always need one more set of bounds to represent an inverse, so // if we're at the limit, we can't properly represent things. @@ -2822,6 +2781,7 @@ irange::invert () signop sign = TYPE_SIGN (ttype); wide_int type_min = wi::min_value (prec, sign); wide_int type_max = wi::max_value (prec, sign); + m_nonzero_mask = wi::shwi (-1, prec); if (m_num_ranges == m_max_ranges && lower_bound () != type_min && upper_bound () != type_max) @@ -2896,119 +2856,140 @@ irange::invert () verify_range (); } -void -irange::set_nonzero_bits (tree mask) +// Return the nonzero bits inherent in the range. + +wide_int +irange::get_nonzero_bits_from_range () const { - gcc_checking_assert (!undefined_p ()); + // For legacy symbolics. + if (!constant_p ()) + return wi::shwi (-1, TYPE_PRECISION (type ())); - if (!mask) + wide_int min = lower_bound (); + wide_int max = upper_bound (); + wide_int xorv = min ^ max; + if (xorv != 0) { - if (m_nonzero_mask) - { - m_nonzero_mask = NULL; - // Clearing the mask may have turned a range into VARYING. - normalize_kind (); - } - return; + unsigned prec = TYPE_PRECISION (type ()); + xorv = wi::mask (prec - wi::clz (xorv), false, prec); } - m_nonzero_mask = mask; - // Setting the mask may have turned a VARYING into a range. - if (m_kind == VR_VARYING) - m_kind = VR_RANGE; - - if (flag_checking) - verify_range (); + return min | xorv; } -void -irange::set_nonzero_bits (const wide_int_ref &bits) +// If the the nonzero mask can be trivially converted to a range, do +// so and return TRUE. + +bool +irange::set_range_from_nonzero_bits () { gcc_checking_assert (!undefined_p ()); + unsigned popcount = wi::popcount (m_nonzero_mask); - if (bits == -1) - { - set_nonzero_bits (NULL); - return; - } // If we have only one bit set in the mask, we can figure out the // range immediately. - if (wi::popcount (bits) == 1) + if (popcount == 1) { + // Make sure we don't pessimize the range. + if (!contains_p (wide_int_to_tree (type (), m_nonzero_mask))) + return false; + bool has_zero = contains_p (build_zero_cst (type ())); + wide_int bits = m_nonzero_mask; set (type (), bits, bits); + m_nonzero_mask = bits; if (has_zero) { int_range<2> zero; zero.set_zero (type ()); union_ (zero); } + return true; } - set_nonzero_bits (wide_int_to_tree (type (), bits)); + return false; } -wide_int -irange::get_nonzero_bits () const +void +irange::set_nonzero_bits (const wide_int_ref &bits) { gcc_checking_assert (!undefined_p ()); + unsigned prec = TYPE_PRECISION (type ()); + gcc_checking_assert (prec == bits.get_precision ()); - // In case anyone in the legacy world queries us. - if (!constant_p ()) - { - if (m_nonzero_mask) - return wi::to_wide (m_nonzero_mask); - return wi::shwi (-1, TYPE_PRECISION (type ())); - } + // Drop VARYINGs with a nonzero mask to a plain range. + if (m_kind == VR_VARYING && bits != -1) + m_kind = VR_RANGE; - // Calculate the nonzero bits inherent in the range. - wide_int min = lower_bound (); - wide_int max = upper_bound (); - wide_int xorv = min ^ max; - if (xorv != 0) - { - unsigned prec = TYPE_PRECISION (type ()); - xorv = wi::mask (prec - wi::clz (xorv), false, prec); - } - wide_int mask = min | xorv; + m_nonzero_mask = wide_int::from (bits, prec, TYPE_SIGN (type ())); + if (set_range_from_nonzero_bits ()) + return; - // Return the nonzero bits augmented by the range. - if (m_nonzero_mask) - return mask & wi::to_wide (m_nonzero_mask); + normalize_kind (); + if (flag_checking) + verify_range (); +} - return mask; +// Return the nonzero bitmask. This will return the nonzero bits plus +// the nonzero bits inherent in the range. + +wide_int +irange::get_nonzero_bits () const +{ + gcc_checking_assert (!undefined_p ()); + // The nonzero mask inherent in the range is calculated on-demand. + // For example, [0,255] does not have a 0xff nonzero mask by default + // (unless manually set). This saves us considerable time, because + // setting it at creation incurs a large penalty for irange::set. + // At the time of writing there was a 5% slowdown in VRP if we kept + // the mask precisely up to date at all times. Instead, we default + // to -1 and set it when explicitly requested. However, this + // function will always return the correct mask. + return m_nonzero_mask & get_nonzero_bits_from_range (); } -// Intersect the nonzero bits in R into THIS. +// Intersect the nonzero bits in R into THIS and normalize the range. +// Return TRUE if the intersection changed anything. bool irange::intersect_nonzero_bits (const irange &r) { gcc_checking_assert (!undefined_p () && !r.undefined_p ()); - if (m_nonzero_mask || r.m_nonzero_mask) + bool changed = false; + if (m_nonzero_mask != r.m_nonzero_mask) { - wide_int nz = wi::bit_and (get_nonzero_bits (), - r.get_nonzero_bits ()); - set_nonzero_bits (nz); - return true; + m_nonzero_mask = get_nonzero_bits () & r.get_nonzero_bits (); + if (set_range_from_nonzero_bits ()) + return true; + changed = true; } - return false; + normalize_kind (); + if (flag_checking) + verify_range (); + return changed; } -// Union the nonzero bits in R into THIS. +// Union the nonzero bits in R into THIS and normalize the range. +// Return TRUE if the union changed anything. bool irange::union_nonzero_bits (const irange &r) { gcc_checking_assert (!undefined_p () && !r.undefined_p ()); - if (m_nonzero_mask || r.m_nonzero_mask) + bool changed = false; + if (m_nonzero_mask != r.m_nonzero_mask) { - wide_int nz = wi::bit_or (get_nonzero_bits (), - r.get_nonzero_bits ()); - set_nonzero_bits (nz); - return true; + m_nonzero_mask = get_nonzero_bits () | r.get_nonzero_bits (); + // No need to call set_range_from_nonzero_bits, because we'll + // never narrow the range. Besides, it would cause endless + // recursion because of the union_ in + // set_range_from_nonzero_bits. + changed = true; } - return false; + normalize_kind (); + if (flag_checking) + verify_range (); + return changed; } void @@ -3597,13 +3578,6 @@ range_tests_nonzero_bits () r0.union_ (r1); ASSERT_TRUE (r0.get_nonzero_bits () == 0xff); - // Union where the mask of nonzero bits is implicit from the range. - r0.set_varying (integer_type_node); - r0.set_nonzero_bits (0xf00); - r1.set_zero (integer_type_node); // nonzero mask is implicitly 0 - r0.union_ (r1); - ASSERT_TRUE (r0.get_nonzero_bits () == 0xf00); - // Intersect of nonzero bits. r0.set (INT (0), INT (255)); r0.set_nonzero_bits (0xfe); @@ -3628,6 +3602,11 @@ range_tests_nonzero_bits () r1.set_nonzero_bits (0xff); r0.union_ (r1); ASSERT_TRUE (r0.varying_p ()); + + // Test that setting a nonzero bit of 1 does not pessimize the range. + r0.set_zero (integer_type_node); + r0.set_nonzero_bits (1); + ASSERT_TRUE (r0.zero_p ()); } // Build an frange from string endpoints. diff --git a/gcc/value-range.h b/gcc/value-range.h index 556e31a..d166362 100644 --- a/gcc/value-range.h +++ b/gcc/value-range.h @@ -207,14 +207,15 @@ private: void irange_set_1bit_anti_range (tree, tree); bool varying_compatible_p () const; - void set_nonzero_bits (tree mask); bool intersect_nonzero_bits (const irange &r); bool union_nonzero_bits (const irange &r); + wide_int get_nonzero_bits_from_range () const; + bool set_range_from_nonzero_bits (); bool intersect (const wide_int& lb, const wide_int& ub); unsigned char m_num_ranges; unsigned char m_max_ranges; - tree m_nonzero_mask; + wide_int m_nonzero_mask; tree *m_base; }; @@ -682,10 +683,11 @@ irange::varying_compatible_p () const if (INTEGRAL_TYPE_P (t)) return (wi::to_wide (l) == wi::min_value (prec, sign) && wi::to_wide (u) == wi::max_value (prec, sign) - && !m_nonzero_mask); + && m_nonzero_mask == -1); if (POINTER_TYPE_P (t)) return (wi::to_wide (l) == 0 - && wi::to_wide (u) == wi::max_value (prec, sign)); + && wi::to_wide (u) == wi::max_value (prec, sign) + && m_nonzero_mask == -1); return true; } @@ -752,8 +754,6 @@ gt_ggc_mx (irange *x) gt_ggc_mx (x->m_base[i * 2]); gt_ggc_mx (x->m_base[i * 2 + 1]); } - if (x->m_nonzero_mask) - gt_ggc_mx (x->m_nonzero_mask); } inline void @@ -764,8 +764,6 @@ gt_pch_nx (irange *x) gt_pch_nx (x->m_base[i * 2]); gt_pch_nx (x->m_base[i * 2 + 1]); } - if (x->m_nonzero_mask) - gt_pch_nx (x->m_nonzero_mask); } inline void @@ -776,8 +774,6 @@ gt_pch_nx (irange *x, gt_pointer_operator op, void *cookie) op (&x->m_base[i * 2], NULL, cookie); op (&x->m_base[i * 2 + 1], NULL, cookie); } - if (x->m_nonzero_mask) - op (&x->m_nonzero_mask, NULL, cookie); } template<unsigned N> @@ -872,7 +868,6 @@ irange::set_undefined () { m_kind = VR_UNDEFINED; m_num_ranges = 0; - m_nonzero_mask = NULL; } inline void @@ -880,7 +875,11 @@ irange::set_varying (tree type) { m_kind = VR_VARYING; m_num_ranges = 1; - m_nonzero_mask = NULL; + + if (type == error_mark_node) + m_nonzero_mask = wi::shwi (-1, 1); + else + m_nonzero_mask = wi::shwi (-1, TYPE_PRECISION (type)); if (INTEGRAL_TYPE_P (type)) { @@ -1002,8 +1001,6 @@ irange::normalize_kind () m_kind = VR_VARYING; else if (m_kind == VR_ANTI_RANGE) set_undefined (); - else - gcc_unreachable (); } } diff --git a/gcc/value-relation.cc b/gcc/value-relation.cc index 7fc22d3..e6f5ef4 100644 --- a/gcc/value-relation.cc +++ b/gcc/value-relation.cc @@ -635,61 +635,6 @@ equiv_oracle::dump (FILE *f) const // -------------------------------------------------------------------------- - -// The value-relation class is used to encapsulate the represention of an -// individual relation between 2 ssa-names, and to facilitate operating on -// the relation. - -class value_relation -{ -public: - value_relation (); - value_relation (relation_kind kind, tree n1, tree n2); - void set_relation (relation_kind kind, tree n1, tree n2); - - inline relation_kind kind () const { return related; } - inline tree op1 () const { return name1; } - inline tree op2 () const { return name2; } - - bool union_ (value_relation &p); - bool intersect (value_relation &p); - void negate (); - bool apply_transitive (const value_relation &rel); - - void dump (FILE *f) const; -private: - relation_kind related; - tree name1, name2; -}; - -// Set relation R between ssa_name N1 and N2. - -inline void -value_relation::set_relation (relation_kind r, tree n1, tree n2) -{ - related = r; - name1 = n1; - name2 = n2; -} - -// Default constructor. - -inline -value_relation::value_relation () -{ - related = VREL_VARYING; - name1 = NULL_TREE; - name2 = NULL_TREE; -} - -// Constructor for relation R between SSA version N1 nd N2. - -inline -value_relation::value_relation (relation_kind kind, tree n1, tree n2) -{ - set_relation (kind, n1, n2); -} - // Negate the current relation. void diff --git a/gcc/value-relation.h b/gcc/value-relation.h index 64884a8..e1347ea 100644 --- a/gcc/value-relation.h +++ b/gcc/value-relation.h @@ -78,6 +78,8 @@ relation_kind relation_union (relation_kind r1, relation_kind r2); relation_kind relation_intersect (relation_kind r1, relation_kind r2); relation_kind relation_negate (relation_kind r); relation_kind relation_swap (relation_kind r); +inline bool relation_lt_le_gt_ge_p (relation_kind r) + { return (r >= VREL_LT && r <= VREL_GE); } void print_relation (FILE *f, relation_kind rel); class relation_oracle @@ -256,4 +258,61 @@ private: bitmap_obstack m_bitmaps; struct obstack m_chain_obstack; }; + +// The value-relation class is used to encapsulate the represention of an +// individual relation between 2 ssa-names, and to facilitate operating on +// the relation. + +class value_relation +{ +public: + value_relation (); + value_relation (relation_kind kind, tree n1, tree n2); + void set_relation (relation_kind kind, tree n1, tree n2); + + inline relation_kind kind () const { return related; } + inline tree op1 () const { return name1; } + inline tree op2 () const { return name2; } + + bool union_ (value_relation &p); + bool intersect (value_relation &p); + void negate (); + bool apply_transitive (const value_relation &rel); + + void dump (FILE *f) const; +private: + relation_kind related; + tree name1, name2; +}; + +// Set relation R between ssa_name N1 and N2. + +inline void +value_relation::set_relation (relation_kind r, tree n1, tree n2) +{ + gcc_checking_assert (TREE_CODE (n1) == SSA_NAME + && TREE_CODE (n2) == SSA_NAME); + related = r; + name1 = n1; + name2 = n2; +} + +// Default constructor. + +inline +value_relation::value_relation () +{ + related = VREL_VARYING; + name1 = NULL_TREE; + name2 = NULL_TREE; +} + +// Constructor for relation R between SSA version N1 nd N2. + +inline +value_relation::value_relation (relation_kind kind, tree n1, tree n2) +{ + set_relation (kind, n1, n2); +} + #endif /* GCC_VALUE_RELATION_H */ diff --git a/gcc/varasm.cc b/gcc/varasm.cc index b0c4d6a..423f3f9 100644 --- a/gcc/varasm.cc +++ b/gcc/varasm.cc @@ -6967,7 +6967,6 @@ default_select_section (tree decl, int reloc, { if (! ((flag_pic && reloc) || !TREE_READONLY (decl) - || TREE_SIDE_EFFECTS (decl) || !TREE_CONSTANT (decl))) return readonly_data_section; } @@ -7001,7 +7000,6 @@ categorize_decl_for_section (const_tree decl, int reloc) if (bss_initializer_p (decl)) ret = SECCAT_BSS; else if (! TREE_READONLY (decl) - || TREE_SIDE_EFFECTS (decl) || (DECL_INITIAL (decl) && ! TREE_CONSTANT (DECL_INITIAL (decl)))) { @@ -7042,7 +7040,6 @@ categorize_decl_for_section (const_tree decl, int reloc) else if (TREE_CODE (decl) == CONSTRUCTOR) { if ((reloc & targetm.asm_out.reloc_rw_mask ()) - || TREE_SIDE_EFFECTS (decl) || ! TREE_CONSTANT (decl)) ret = SECCAT_DATA; else |