aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2021-08-26 11:23:40 +0200
committerMartin Liska <mliska@suse.cz>2021-08-26 11:23:40 +0200
commite88d1c83cdd1d349dc34f402e92363ba9393ee46 (patch)
tree777a21dcb14b6ea3fcac49a569d0dd3a5d30e857
parent7572f9cd10edd3bc1889a8f513dbf77b7f4e470d (diff)
parente370a2482d41fd382055695b9a0a638ce75e1038 (diff)
downloadgcc-e88d1c83cdd1d349dc34f402e92363ba9393ee46.zip
gcc-e88d1c83cdd1d349dc34f402e92363ba9393ee46.tar.gz
gcc-e88d1c83cdd1d349dc34f402e92363ba9393ee46.tar.bz2
Merge branch 'master' into devel/sphinx
-rw-r--r--contrib/ChangeLog6
-rwxr-xr-xcontrib/mklog.py23
-rw-r--r--gcc/ChangeLog342
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/analyzer/ChangeLog6
-rw-r--r--gcc/analyzer/engine.cc14
-rw-r--r--gcc/c-family/ChangeLog7
-rw-r--r--gcc/c-family/c-opts.c13
-rw-r--r--gcc/cgraph.h5
-rw-r--r--gcc/cgraphclones.c11
-rw-r--r--gcc/config.gcc2
-rw-r--r--gcc/config/i386/avx512dqintrin.h4
-rw-r--r--gcc/config/i386/i386.c36
-rw-r--r--gcc/config/nvptx/nvptx-c.c47
-rw-r--r--gcc/config/nvptx/nvptx-protos.h1
-rw-r--r--gcc/config/nvptx/nvptx.h12
-rw-r--r--gcc/config/nvptx/t-nvptx4
-rw-r--r--gcc/config/rs6000/aix.h4
-rw-r--r--gcc/config/rs6000/aix71.h4
-rw-r--r--gcc/config/rs6000/aix72.h3
-rw-r--r--gcc/config/rs6000/aix73.h2
-rw-r--r--gcc/config/rs6000/altivec.md158
-rw-r--r--gcc/config/rs6000/rs6000-builtin-new.def891
-rw-r--r--gcc/config/rs6000/rs6000-call.c148
-rw-r--r--gcc/config/rs6000/rs6000.h82
-rw-r--r--gcc/config/rs6000/vsx.md26
-rw-r--r--gcc/coretypes.h1
-rw-r--r--gcc/cp/ChangeLog12
-rw-r--r--gcc/cp/cp-objcp-common.c9
-rw-r--r--gcc/cp/init.c5
-rw-r--r--gcc/d/ChangeLog7
-rw-r--r--gcc/d/d-lang.cc19
-rw-r--r--gcc/diagnostic.c11
-rw-r--r--gcc/diagnostic.h19
-rw-r--r--gcc/doc/extend.texi20
-rw-r--r--gcc/doc/invoke.texi4
-rw-r--r--gcc/fortran/ChangeLog13
-rw-r--r--gcc/fortran/cpp.c6
-rw-r--r--gcc/fortran/trans-decl.c20
-rw-r--r--gcc/gimple-range-cache.cc40
-rw-r--r--gcc/gimple-range.cc45
-rw-r--r--gcc/gimple-ssa-warn-access.cc20
-rw-r--r--gcc/input.c100
-rw-r--r--gcc/input.h10
-rw-r--r--gcc/ipa-modref-tree.c44
-rw-r--r--gcc/ipa-modref-tree.h247
-rw-r--r--gcc/ipa-modref.c80
-rw-r--r--gcc/multiple_target.c16
-rw-r--r--gcc/params.opt4
-rw-r--r--gcc/pointer-query.cc105
-rw-r--r--gcc/simplify-rtx.c4
-rw-r--r--gcc/testsuite/ChangeLog155
-rw-r--r--gcc/testsuite/c-c++-common/dfp/convert-bfp-11.c20
-rw-r--r--gcc/testsuite/g++.dg/pr100574.C4
-rw-r--r--gcc/testsuite/g++.dg/warn/Warray-bounds-26.C27
-rw-r--r--gcc/testsuite/g++.dg/warn/Wreturn-5.C15
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-88.c134
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overread.c32
-rw-r--r--gcc/testsuite/gcc.dg/diagnostic-input-charset-1.c17
-rw-r--r--gcc/testsuite/gcc.dg/diagnostic-input-utf8-bom.c14
-rw-r--r--gcc/testsuite/gcc.dg/ipa/modref-1.c8
-rw-r--r--gcc/testsuite/gcc.dg/pr20126.c6
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/evrp1.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/evrp2.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/evrp3.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/evrp4.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/evrp6.c3
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/modref-4.c8
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/modref-8.c25
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr64130.c3
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr101145.c187
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr101145.inc65
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr101145_1.c13
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr101145_2.c13
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr101145_3.c13
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr101145inf.c25
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr101145inf.inc28
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr101145inf_1.c23
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr102046.c19
-rw-r--r--gcc/testsuite/gcc.dg/warn-strnlen-no-nul.c39
-rw-r--r--gcc/testsuite/gcc.target/i386/avx2-shiftqihi-constant-1.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-pr101471.c18
-rw-r--r--gcc/testsuite/gcc.target/i386/mvc5.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/mvc7.c8
-rw-r--r--gcc/testsuite/gcc.target/i386/pr101716.c11
-rw-r--r--gcc/testsuite/gcc.target/i386/pr95778-1.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/pr95778-2.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/sse2-shiftqihi-constant-1.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr70117.c24
-rw-r--r--gcc/testsuite/gcc.target/powerpc/unpack-vectorize-1.c18
-rw-r--r--gcc/testsuite/gcc.target/powerpc/unpack-vectorize-1.h14
-rw-r--r--gcc/testsuite/gcc.target/powerpc/unpack-vectorize-2.c12
-rw-r--r--gcc/testsuite/gcc.target/powerpc/unpack-vectorize-2.h7
-rw-r--r--gcc/testsuite/gcc.target/powerpc/unpack-vectorize-3.c11
-rw-r--r--gcc/testsuite/gcc.target/powerpc/unpack-vectorize-3.h7
-rw-r--r--gcc/testsuite/gcc.target/powerpc/unpack-vectorize-run-1.c24
-rw-r--r--gcc/testsuite/gcc.target/powerpc/unpack-vectorize-run-2.c16
-rw-r--r--gcc/testsuite/gcc.target/powerpc/unpack-vectorize-run-3.c16
-rw-r--r--gcc/testsuite/gcc.target/powerpc/unpack-vectorize.h42
-rw-r--r--gcc/testsuite/gfortran.dg/pr98411.f904
-rw-r--r--gcc/testsuite/lib/target-supports.exp128
-rw-r--r--gcc/tree-ssa-loop-niter.c157
-rw-r--r--gcc/tree-vect-slp.c4
-rw-r--r--libcpp/ChangeLog17
-rw-r--r--libcpp/charset.c109
-rw-r--r--libcpp/files.c56
-rw-r--r--libcpp/include/cpplib.h18
-rw-r--r--libgcc/ChangeLog6
-rw-r--r--libgcc/config/i386/cygming-crtend.c6
-rw-r--r--libstdc++-v3/ChangeLog65
-rw-r--r--libstdc++-v3/doc/html/manual/status.html4
-rw-r--r--libstdc++-v3/doc/xml/manual/status_cxx2020.xml3
-rw-r--r--libstdc++-v3/include/bits/stl_uninitialized.h100
-rw-r--r--libstdc++-v3/include/ext/rope5
-rw-r--r--libstdc++-v3/include/std/type_traits25
-rw-r--r--libstdc++-v3/include/std/valarray20
-rw-r--r--libstdc++-v3/include/std/version4
-rw-r--r--libstdc++-v3/testsuite/17_intro/names.cc12
-rw-r--r--libstdc++-v3/testsuite/20_util/is_layout_compatible/is_corresponding_member.cc19
-rw-r--r--libstdc++-v3/testsuite/20_util/is_layout_compatible/value.cc56
-rw-r--r--libstdc++-v3/testsuite/20_util/is_layout_compatible/version.cc10
-rw-r--r--libstdc++-v3/testsuite/20_util/is_pointer_interconvertible/with_class.cc29
-rw-r--r--libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy/1.cc2
-rw-r--r--libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy/102064.cc52
-rw-r--r--libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy_n/102064.cc48
-rw-r--r--libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill/102064.cc51
-rw-r--r--libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill_n/102064.cc51
-rw-r--r--libstdc++-v3/testsuite/23_containers/span/layout_compat.cc19
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/cons/89164.cc14
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/cons/89164_c++17.cc49
130 files changed, 4321 insertions, 684 deletions
diff --git a/contrib/ChangeLog b/contrib/ChangeLog
index d4aa96f..d496dc6 100644
--- a/contrib/ChangeLog
+++ b/contrib/ChangeLog
@@ -1,3 +1,9 @@
+2021-08-24 Andrew Pinski <apinski@marvell.com>
+
+ PR other/82704
+ * download_prerequisites: Fix issues with --md5 and
+ --sha512 options.
+
2021-08-18 Martin Liska <mliska@suse.cz>
* gcc-git-customization.sh: Wrap $@ in quotes.
diff --git a/contrib/mklog.py b/contrib/mklog.py
index d362be5..cd5ef0b 100755
--- a/contrib/mklog.py
+++ b/contrib/mklog.py
@@ -148,6 +148,13 @@ def append_changelog_line(out, relative_path, text):
return out
+def get_rel_path_if_prefixed(path, folder):
+ if path.startswith(folder):
+ return path[len(folder):].lstrip('/')
+ else:
+ return path
+
+
def generate_changelog(data, no_functions=False, fill_pr_titles=False,
additional_prs=None):
changelogs = {}
@@ -228,7 +235,7 @@ def generate_changelog(data, no_functions=False, fill_pr_titles=False,
for file in sorted(files, key=sort_changelog_files):
assert file.path.startswith(changelog)
in_tests = 'testsuite' in changelog or 'testsuite' in file.path
- relative_path = file.path[len(changelog):].lstrip('/')
+ relative_path = get_rel_path_if_prefixed(file.path, changelog)
functions = []
if file.is_added_file:
msg = 'New test.' if in_tests else 'New file.'
@@ -236,13 +243,17 @@ def generate_changelog(data, no_functions=False, fill_pr_titles=False,
elif file.is_removed_file:
out = append_changelog_line(out, relative_path, 'Removed.')
elif hasattr(file, 'is_rename') and file.is_rename:
- out = append_changelog_line(out, relative_path, 'Moved to...')
- new_path = file.target_file[2:]
# A file can be theoretically moved to a location that
# belongs to a different ChangeLog. Let user fix it.
- if new_path.startswith(changelog):
- new_path = new_path[len(changelog):].lstrip('/')
- out += '\t* %s: ...here.\n' % (new_path)
+ #
+ # Since unidiff 0.7.0, path.file == path.target_file[2:],
+ # it used to be path.source_file[2:]
+ relative_path = get_rel_path_if_prefixed(file.source_file[2:],
+ changelog)
+ out = append_changelog_line(out, relative_path, 'Moved to...')
+ new_path = get_rel_path_if_prefixed(file.target_file[2:],
+ changelog)
+ out += f'\t* {new_path}: ...here.\n'
elif os.path.basename(file.path) in generated_files:
out += '\t* %s: Regenerate.\n' % (relative_path)
append_changelog_line(out, relative_path, 'Regenerate.')
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0183764..fe8242b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,345 @@
+2021-08-25 Martin Sebor <msebor@redhat.com>
+
+ * gimple-range-cache.cc (ssa_global_cache::dump): Avoid printing
+ range table header alone.
+ * gimple-range.cc (gimple_ranger::export_global_ranges): Same.
+
+2021-08-25 Jan Hubicka <hubicka@ucw.cz>
+
+ * doc/invoke.texi: Document --param modref-max-adjustments.
+ * ipa-modref-tree.c (test_insert_search_collapse): Update.
+ (test_merge): Update.
+ * ipa-modref-tree.h (struct modref_access_node): Add adjustments;
+ (modref_access_node::operator==): Fix handling of access ranges.
+ (modref_access_node::contains): Constify parameter; handle also
+ mismatched parm offsets.
+ (modref_access_node::update): New function.
+ (modref_access_node::merge): New function.
+ (unspecified_modref_access_node): Update constructor.
+ (modref_ref_node::insert_access): Add record_adjustments parameter;
+ handle merging.
+ (modref_ref_node::try_merge_with): New private function.
+ (modref_tree::insert): New record_adjustments parameter.
+ (modref_tree::merge): New record_adjustments parameter.
+ (modref_tree::copy_from): Update.
+ * ipa-modref.c (dump_access): Dump adjustments field.
+ (get_access): Update constructor.
+ (record_access): Update call of insert.
+ (record_access_lto): Update call of insert.
+ (merge_call_side_effects): Add record_adjustments parameter.
+ (get_access_for_fnspec): Update.
+ (process_fnspec): Update.
+ (analyze_call): Update.
+ (analyze_function): Update.
+ (read_modref_records): Update.
+ (ipa_merge_modref_summary_after_inlining): Update.
+ (propagate_unknown_call): Update.
+ (modref_propagate_in_scc): Update.
+ * params.opt (param-max-modref-adjustments=): New.
+
+2021-08-25 Michael Meissner <meissner@linux.ibm.com>
+
+ * config/rs6000/vsx.md (UNSPEC_XXSPLTIDP): Rename from
+ UNSPEC_XXSPLTID.
+ (xxspltiw_v4si): Use vecperm type attribute.
+ (xxspltiw_v4si_inst): Use vecperm type attribute.
+ (xxspltiw_v4sf_inst): Likewise.
+ (xxspltidp_v2df): Use vecperm type attribute. Use
+ UNSPEC_XXSPLTIDP instead of UNSPEC_XXSPLTID.
+ (xxspltidp_v2df_inst): Likewise.
+ (xxsplti32dx_v4si): Use vecperm type attribute.
+ (xxsplti32dx_v4si_inst): Likewise.
+ (xxsplti32dx_v4sf_inst): Likewise.
+ (xxblend_<mode>): Likewise.
+ (xxpermx): Likewise.
+ (xxpermx_inst): Likewise.
+ (xxeval): Likewise.
+
+2021-08-25 Lewis Hyatt <lhyatt@gmail.com>
+
+ PR other/93067
+ * coretypes.h (typedef diagnostic_input_charset_callback): Declare.
+ * diagnostic.c (diagnostic_initialize_input_context): New function.
+ * diagnostic.h (diagnostic_initialize_input_context): Declare.
+ * input.c (default_charset_callback): New function.
+ (file_cache::initialize_input_context): New function.
+ (file_cache_slot::create): Added ability to convert the input
+ according to the input context.
+ (file_cache::file_cache): Initialize the new input context.
+ (class file_cache_slot): Added new m_alloc_offset member.
+ (file_cache_slot::file_cache_slot): Initialize the new member.
+ (file_cache_slot::~file_cache_slot): Handle potentially offset buffer.
+ (file_cache_slot::maybe_grow): Likewise.
+ (file_cache_slot::needs_read_p): Handle NULL fp, which is now possible.
+ (file_cache_slot::get_next_line): Likewise.
+ * input.h (class file_cache): Added input context member.
+
+2021-08-25 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/102046
+ * tree-vect-slp.c (vect_build_slp_tree_2): Conservatively
+ update ->any_pattern when swapping operands.
+
+2021-08-25 Hongyu Wang <hongyu.wang@intel.com>
+
+ PR target/101716
+ * config/i386/i386.c (ix86_live_on_entry): Adjust comment.
+ (ix86_decompose_address): Remove retval check for ASHIFT,
+ allow non-canonical zero extend if AND mask covers ASHIFT
+ count.
+ (ix86_legitimate_address_p): Adjust condition for decompose.
+ (ix86_rtx_costs): Adjust cost for lea with non-canonical
+ zero-extend.
+ Co-Authored by: Uros Bizjak <ubizjak@gmail.com>
+
+2021-08-25 Jiufu Guo <guojiufu@linux.ibm.com>
+
+ PR tree-optimization/101145
+ * tree-ssa-loop-niter.c (number_of_iterations_until_wrap):
+ New function.
+ (number_of_iterations_lt): Invoke above function.
+ (adjust_cond_for_loop_until_wrap):
+ Merge to number_of_iterations_until_wrap.
+ (number_of_iterations_cond): Update invokes for
+ adjust_cond_for_loop_until_wrap and number_of_iterations_lt.
+
+2021-08-25 konglin1 <lingling.kong@intel.com>
+
+ PR target/101471
+ * config/i386/avx512dqintrin.h (_mm512_fpclass_ps_mask): Fix
+ macro define in O0.
+ (_mm512_mask_fpclass_ps_mask): Ditto.
+
+2021-08-25 Kewen Lin <linkw@linux.ibm.com>
+
+ * config/rs6000/altivec.md (vec_unpacku_hi_v16qi): Remove.
+ (vec_unpacku_hi_v8hi): Likewise.
+ (vec_unpacku_lo_v16qi): Likewise.
+ (vec_unpacku_lo_v8hi): Likewise.
+ (vec_unpacku_hi_<VP_small_lc>): New define_expand.
+ (vec_unpacku_lo_<VP_small_lc>): Likewise.
+
+2021-08-24 David Edelsohn <dje.gcc@gmail.com>
+
+ * config/rs6000/aix.h (SYSTEM_IMPLICIT_EXTERN_C): Delete.
+ * config/rs6000/aix71.h (SYSTEM_IMPLICIT_EXTERN_C): Define.
+ * config/rs6000/aix72.h (SYSTEM_IMPLICIT_EXTERN_C): Define.
+ * config/rs6000/aix73.h (TARGET_AIX_VERSION): Increase to 73.
+
+2021-08-24 Roger Sayle <roger@nextmovesoftware.com>
+
+ PR middle-end/102031
+ * simplify-rtx.c (simplify_truncation): When comparing precisions
+ use "subreg_prec" variable, not "subreg_mode".
+
+2021-08-24 Bill Schmidt <wschmidt@linux.ibm.com>
+
+ * config/rs6000/rs6000-builtin-new.def: Add power10 and power10-64
+ stanzas.
+
+2021-08-24 Bill Schmidt <wschmidt@linux.ibm.com>
+
+ * config/rs6000/rs6000-call.c (rs6000_init_builtins): Initialize
+ various pointer type nodes.
+ * config/rs6000/rs6000.h (rs6000_builtin_type_index): Add enum
+ values for various pointer types.
+ (ptr_V16QI_type_node): New macro.
+ (ptr_V1TI_type_node): New macro.
+ (ptr_V2DI_type_node): New macro.
+ (ptr_V2DF_type_node): New macro.
+ (ptr_V4SI_type_node): New macro.
+ (ptr_V4SF_type_node): New macro.
+ (ptr_V8HI_type_node): New macro.
+ (ptr_unsigned_V16QI_type_node): New macro.
+ (ptr_unsigned_V1TI_type_node): New macro.
+ (ptr_unsigned_V8HI_type_node): New macro.
+ (ptr_unsigned_V4SI_type_node): New macro.
+ (ptr_unsigned_V2DI_type_node): New macro.
+ (ptr_bool_V16QI_type_node): New macro.
+ (ptr_bool_V8HI_type_node): New macro.
+ (ptr_bool_V4SI_type_node): New macro.
+ (ptr_bool_V2DI_type_node): New macro.
+ (ptr_bool_V1TI_type_node): New macro.
+ (ptr_pixel_type_node): New macro.
+ (ptr_intQI_type_node): New macro.
+ (ptr_uintQI_type_node): New macro.
+ (ptr_intHI_type_node): New macro.
+ (ptr_uintHI_type_node): New macro.
+ (ptr_intSI_type_node): New macro.
+ (ptr_uintSI_type_node): New macro.
+ (ptr_intDI_type_node): New macro.
+ (ptr_uintDI_type_node): New macro.
+ (ptr_intTI_type_node): New macro.
+ (ptr_uintTI_type_node): New macro.
+ (ptr_long_integer_type_node): New macro.
+ (ptr_long_unsigned_type_node): New macro.
+ (ptr_float_type_node): New macro.
+ (ptr_double_type_node): New macro.
+ (ptr_long_double_type_node): New macro.
+ (ptr_dfloat64_type_node): New macro.
+ (ptr_dfloat128_type_node): New macro.
+ (ptr_ieee128_type_node): New macro.
+ (ptr_ibm128_type_node): New macro.
+ (ptr_vector_pair_type_node): New macro.
+ (ptr_vector_quad_type_node): New macro.
+ (ptr_long_long_integer_type_node): New macro.
+ (ptr_long_long_unsigned_type_node): New macro.
+
+2021-08-24 Bill Schmidt <wschmidt@linux.ibm.com>
+
+ * config/rs6000/rs6000-builtin-new.def: Add power9-vector, power9,
+ and power9-64 stanzas.
+
+2021-08-24 Roger Sayle <roger@nextmovesoftware.com>
+ Tom de Vries <tdevries@suse.de>
+
+ * config.gcc (nvptx-*-*): Define {c,c++}_target_objs.
+ * config/nvptx/nvptx-protos.h (nvptx_cpu_cpp_builtins): Prototype.
+ * config/nvptx/nvptx.h (TARGET_CPU_CPP_BUILTINS): Implement with
+ a call to the new nvptx_cpu_cpp_builtins function in nvptx-c.c.
+ * config/nvptx/t-nvptx (nvptx-c.o): New rule.
+ * config/nvptx/nvptx-c.c: New source file.
+ (nvptx_cpu_cpp_builtins): Move implementation here.
+
+2021-08-24 Martin Sebor <msebor@redhat.com>
+
+ PR middle-end/101600
+ PR middle-end/101977
+ * gimple-ssa-warn-access.cc (maybe_warn_for_bound): Tighten up
+ the phrasing of a warning.
+ (check_access): Use the remaining size after subtracting any offset
+ rather than the whole object size.
+ * pointer-query.cc (access_ref::get_ref): Clear BASE0 flag if it's
+ clear for any nonnull PHI argument.
+ (compute_objsize): Clear argument.
+
+2021-08-24 Bill Schmidt <wschmidt@linux.ibm.com>
+
+ * config/rs6000/rs6000-builtin-new.def: Add power8-vector stanza.
+
+2021-08-24 Bill Schmidt <wschmidt@linux.ibm.com>
+
+ * config/rs6000/rs6000-builtin-new.def: Add power7 and power7-64
+ stanzas.
+
+2021-08-24 Andrew MacLeod <amacleod@redhat.com>
+
+ * value-relation.cc (rr_transitive_table): New.
+ (relation_transitive): New.
+ (value_relation::swap): Remove.
+ (value_relation::apply_transitive): New.
+ (relation_oracle::relation_oracle): Allocate a new tmp bitmap.
+ (relation_oracle::register_relation): Call register_transitives.
+ (relation_oracle::register_transitives): New.
+ * value-relation.h (relation_oracle): Add new temporary bitmap and
+ methods.
+
+2021-08-24 H.J. Lu <hjl.tools@gmail.com>
+
+ PR target/102021
+ * config/i386/i386-expand.c (ix86_expand_vector_move): Broadcast
+ from integer to a pseudo vector register.
+
+2021-08-24 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/100089
+ * tree-vectorizer.h (vect_slp_bb): Rename to ...
+ (vect_slp_if_converted_bb): ... this and get the original
+ loop as new argument.
+ * tree-vectorizer.c (try_vectorize_loop_1): Revert previous fix,
+ pass original loop to vect_slp_if_converted_bb.
+ * tree-vect-slp.c (vect_bb_vectorization_profitable_p):
+ If orig_loop was passed scan the not vectorized stmts
+ for COND_EXPRs and force not profitable if found.
+ (vect_slp_region): Pass down all SLP instances to costing
+ if orig_loop was specified.
+ (vect_slp_bbs): Pass through orig_loop.
+ (vect_slp_bb): Rename to ...
+ (vect_slp_if_converted_bb): ... this and get the original
+ loop as new argument.
+ (vect_slp_function): Adjust.
+
+2021-08-24 Richard Earnshaw <rearnsha@arm.com>
+
+ PR target/102035
+ * config/arm/arm.md (attribute arch): Add fix_vlldm.
+ (arch_enabled): Use it.
+ * config/arm/vfp.md (lazy_store_multiple_insn): Add alternative to
+ use when erratum mitigation is needed.
+
+2021-08-24 Richard Earnshaw <rearnsha@arm.com>
+
+ PR target/102035
+ * config/arm/arm.opt (mfix-cmse-cve-2021-35465): New option.
+ * doc/invoke.texi (Arm Options): Document it.
+ * config/arm/arm-cpus.in (quirk_vlldm): New feature bit.
+ (ALL_QUIRKS): Add quirk_vlldm.
+ (cortex-m33): Add quirk_vlldm.
+ (cortex-m35p, cortex-m55): Likewise.
+ * config/arm/arm.c (arm_option_override): Enable fix_vlldm if
+ targetting an affected CPU and not explicitly controlled on
+ the command line.
+
+2021-08-24 Richard Earnshaw <rearnsha@arm.com>
+
+ * config/arm/vfp.md (lazy_store_multiple_insn): Rewrite as valid RTL.
+ (lazy_load_multiple_insn): Likewise.
+
+2021-08-24 liuhongt <hongtao.liu@intel.com>
+
+ PR target/101989
+ * config/i386/sse.md (<avx512>_vternlog<mode><sd_maskz_name>):
+ Enable avx512 embedded broadcast.
+ (*<avx512>_vternlog<mode>_all): Ditto.
+ (<avx512>_vternlog<mode>_mask): Ditto.
+
+2021-08-24 liuhongt <hongtao.liu@intel.com>
+
+ PR target/101989
+ * config/i386/i386.c (ix86_rtx_costs): Define cost for
+ UNSPEC_VTERNLOG.
+ * config/i386/i386.h (STRIP_UNARY): New macro.
+ * config/i386/predicates.md (reg_or_notreg_operand): New
+ predicate.
+ * config/i386/sse.md (*<avx512>_vternlog<mode>_all): New define_insn.
+ (*<avx512>_vternlog<mode>_1): New pre_reload
+ define_insn_and_split.
+ (*<avx512>_vternlog<mode>_2): Ditto.
+ (*<avx512>_vternlog<mode>_3): Ditto.
+ (any_logic1,any_logic2): New code iterator.
+ (logic_op): New code attribute.
+ (ternlogsuffix): Extend to VNxDF and VNxSF.
+
+2021-08-24 Richard Biener <rguenther@suse.de>
+
+ * doc/invoke.texi (vect-inner-loop-cost-factor): Adjust.
+ * params.opt (--param vect-inner-loop-cost-factor): Adjust
+ maximum value.
+ * tree-vect-loop.c (vect_analyze_loop_form): Initialize
+ inner_loop_cost_factor to the minimum of the estimated number
+ of iterations of the inner loop and vect-inner-loop-cost-factor.
+
+2021-08-24 Roger Sayle <roger@nextmovesoftware.com>
+ Richard Biener <rguenther@suse.de>
+
+ * config/i386/i386-features.c (compute_convert_gain): Provide
+ more accurate values for CONST_INT, when optimizing for size.
+ * config/i386/i386.c (COSTS_N_BYTES): Move definition from here...
+ * config/i386/i386.h (COSTS_N_BYTES): to here.
+
+2021-08-24 Roger Sayle <roger@nextmovesoftware.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/102029
+ * match.pd (shift transformations): Add an additional check for
+ !POINTER_TYPE_P in the recently added left shift transformation.
+
+2021-08-24 liuhongt <hongtao.liu@intel.com>
+
+ PR tree-optimization/100089
+ * tree-vectorizer.c (try_vectorize_loop_1): Disable slp in
+ loop vectorizer when cost model is very-cheap.
+
2021-08-23 Bill Schmidt <wschmidt@linux.ibm.com>
* config/rs6000/rs6000-gen-builtins.c (parse_bif_entry): Don't call
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 83a5291..98be008 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20210824
+20210826
diff --git a/gcc/analyzer/ChangeLog b/gcc/analyzer/ChangeLog
index 211f34c..c7e8ba92 100644
--- a/gcc/analyzer/ChangeLog
+++ b/gcc/analyzer/ChangeLog
@@ -1,3 +1,9 @@
+2021-08-25 Ankur Saini <arsenic@sourceware.org>
+
+ PR analyzer/101980
+ * engine.cc (exploded_graph::maybe_create_dynamic_call): Don't create
+ calls if max recursion limit is reached.
+
2021-08-23 David Malcolm <dmalcolm@redhat.com>
* analyzer.h (struct rejected_constraint): Convert to...
diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index 4ee9279..9c604d1 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -3059,6 +3059,20 @@ exploded_graph::maybe_create_dynamic_call (const gcall *call,
new_point.push_to_call_stack (sn_exit,
next_point.get_supernode());
+
+ /* Impose a maximum recursion depth and don't analyze paths
+ that exceed it further.
+ This is something of a blunt workaround, but it only
+ applies to recursion (and mutual recursion), not to
+ general call stacks. */
+ if (new_point.get_call_string ().calc_recursion_depth ()
+ > param_analyzer_max_recursion_depth)
+ {
+ if (logger)
+ logger->log ("rejecting call edge: recursion limit exceeded");
+ return false;
+ }
+
next_state.push_call (*this, node, call, uncertainty);
if (next_state.m_valid)
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 873d7ab..5e3ac92 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,10 @@
+2021-08-25 Lewis Hyatt <lhyatt@gmail.com>
+
+ PR other/93067
+ * c-opts.c (c_common_input_charset_cb): New function.
+ (c_common_post_options): Call new function
+ diagnostic_initialize_input_context().
+
2021-08-20 Tobias Burnus <tobias@codesourcery.com>
* c-format.c (gcc_gfc_length_specs): Add 'll' and 'w'.
diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c
index 373af0c..fdde082 100644
--- a/gcc/c-family/c-opts.c
+++ b/gcc/c-family/c-opts.c
@@ -188,6 +188,14 @@ c_common_diagnostics_set_defaults (diagnostic_context *context)
context->opt_permissive = OPT_fpermissive;
}
+/* Input charset configuration for diagnostics. */
+static const char *
+c_common_input_charset_cb (const char * /*filename*/)
+{
+ const char *cs = cpp_opts->input_charset;
+ return cpp_input_conversion_is_trivial (cs) ? nullptr : cs;
+}
+
/* Whether options from all C-family languages should be accepted
quietly. */
static bool accept_all_c_family_options = false;
@@ -1136,6 +1144,11 @@ c_common_post_options (const char **pfilename)
cpp_post_options (parse_in);
init_global_opts_from_cpp (&global_options, cpp_get_options (parse_in));
+ /* Let diagnostics infrastructure know how to convert input files the same
+ way libcpp will do it, namely using the configured input charset and
+ skipping a UTF-8 BOM if present. */
+ diagnostic_initialize_input_context (global_dc,
+ c_common_input_charset_cb, true);
input_location = UNKNOWN_LOCATION;
*pfilename = this_input_filename
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index d54a258..4cdb373 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -1006,13 +1006,16 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : public symtab_node
that will promote value of the attribute DECL_FUNCTION_SPECIFIC_TARGET
of the declaration.
+ If VERSION_DECL is set true, use clone_function_name_numbered for the
+ function clone. Otherwise, use clone_function_name.
+
Return the new version's cgraph node. */
cgraph_node *create_version_clone_with_body
(vec<cgraph_edge *> redirect_callers,
vec<ipa_replace_map *, va_gc> *tree_map,
ipa_param_adjustments *param_adjustments,
bitmap bbs_to_copy, basic_block new_entry_block, const char *clone_name,
- tree target_attributes = NULL_TREE);
+ tree target_attributes = NULL_TREE, bool version_decl = true);
/* Insert a new cgraph_function_version_info node into cgraph_fnver_htab
corresponding to cgraph_node. */
diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c
index b16e681..ae91dcc 100644
--- a/gcc/cgraphclones.c
+++ b/gcc/cgraphclones.c
@@ -987,6 +987,9 @@ cgraph_node::create_version_clone (tree new_decl,
that will promote value of the attribute DECL_FUNCTION_SPECIFIC_TARGET
of the declaration.
+ If VERSION_DECL is set true, use clone_function_name_numbered for the
+ function clone. Otherwise, use clone_function_name.
+
Return the new version's cgraph node. */
cgraph_node *
@@ -995,7 +998,7 @@ cgraph_node::create_version_clone_with_body
vec<ipa_replace_map *, va_gc> *tree_map,
ipa_param_adjustments *param_adjustments,
bitmap bbs_to_copy, basic_block new_entry_block, const char *suffix,
- tree target_attributes)
+ tree target_attributes, bool version_decl)
{
tree old_decl = decl;
cgraph_node *new_version_node = NULL;
@@ -1016,8 +1019,10 @@ cgraph_node::create_version_clone_with_body
new_decl = copy_node (old_decl);
/* Generate a new name for the new version. */
- DECL_NAME (new_decl) = clone_function_name_numbered (old_decl, suffix);
- SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl));
+ tree fnname = (version_decl ? clone_function_name_numbered (old_decl, suffix)
+ : clone_function_name (old_decl, suffix));
+ DECL_NAME (new_decl) = fnname;
+ SET_DECL_ASSEMBLER_NAME (new_decl, fnname);
SET_DECL_RTL (new_decl, NULL);
DECL_VIRTUAL_P (new_decl) = 0;
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 94199d7..0ff5cac 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -468,6 +468,8 @@ nios2-*-*)
;;
nvptx-*-*)
cpu_type=nvptx
+ c_target_objs="nvptx-c.o"
+ cxx_target_objs="nvptx-c.o"
;;
or1k*-*-*)
cpu_type=or1k
diff --git a/gcc/config/i386/avx512dqintrin.h b/gcc/config/i386/avx512dqintrin.h
index 51c0b12..9794f5d 100644
--- a/gcc/config/i386/avx512dqintrin.h
+++ b/gcc/config/i386/avx512dqintrin.h
@@ -2814,7 +2814,7 @@ _mm512_fpclass_ps_mask (__m512 __A, const int __imm)
#define _mm512_mask_fpclass_ps_mask(u, x, c) \
((__mmask16) __builtin_ia32_fpclassps512_mask ((__v16sf) (__m512) (x),\
- (int) (c),(__mmask8)(u)))
+ (int) (c),(__mmask16)(u)))
#define _mm512_fpclass_pd_mask(X, C) \
((__mmask8) __builtin_ia32_fpclasspd512_mask ((__v8df) (__m512d) (X), \
@@ -2822,7 +2822,7 @@ _mm512_fpclass_ps_mask (__m512 __A, const int __imm)
#define _mm512_fpclass_ps_mask(x, c) \
((__mmask16) __builtin_ia32_fpclassps512_mask ((__v16sf) (__m512) (x),\
- (int) (c),(__mmask8)-1))
+ (int) (c),(__mmask16)-1))
#define _mm_reduce_sd(A, B, C) \
((__m128d) __builtin_ia32_reducesd_mask ((__v2df)(__m128d)(A), \
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index ebec866..ddbbbce 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -10018,8 +10018,7 @@ ix86_live_on_entry (bitmap regs)
/* Extract the parts of an RTL expression that is a valid memory address
for an instruction. Return 0 if the structure of the address is
- grossly off. Return -1 if the address contains ASHIFT, so it is not
- strictly valid, but still used for computing length of lea instruction. */
+ grossly off. */
int
ix86_decompose_address (rtx addr, struct ix86_address *out)
@@ -10029,7 +10028,6 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
HOST_WIDE_INT scale = 1;
rtx scale_rtx = NULL_RTX;
rtx tmp;
- int retval = 1;
addr_space_t seg = ADDR_SPACE_GENERIC;
/* Allow zero-extended SImode addresses,
@@ -10053,6 +10051,27 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
if (CONST_INT_P (addr))
return 0;
}
+ else if (GET_CODE (addr) == AND)
+ {
+ /* For ASHIFT inside AND, combine will not generate
+ canonical zero-extend. Merge mask for AND and shift_count
+ to check if it is canonical zero-extend. */
+ tmp = XEXP (addr, 0);
+ rtx mask = XEXP (addr, 1);
+ if (tmp && GET_CODE(tmp) == ASHIFT)
+ {
+ rtx shift_val = XEXP (tmp, 1);
+ if (CONST_INT_P (mask) && CONST_INT_P (shift_val)
+ && (((unsigned HOST_WIDE_INT) INTVAL(mask)
+ | ((HOST_WIDE_INT_1U << INTVAL(shift_val)) - 1))
+ == 0xffffffff))
+ {
+ addr = lowpart_subreg (SImode, XEXP (addr, 0),
+ DImode);
+ }
+ }
+
+ }
}
/* Allow SImode subregs of DImode addresses,
@@ -10179,7 +10198,6 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
if ((unsigned HOST_WIDE_INT) scale > 3)
return 0;
scale = 1 << scale;
- retval = -1;
}
else
disp = addr; /* displacement */
@@ -10252,7 +10270,7 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
out->scale = scale;
out->seg = seg;
- return retval;
+ return 1;
}
/* Return cost of the memory address x.
@@ -10765,7 +10783,7 @@ ix86_legitimate_address_p (machine_mode, rtx addr, bool strict)
HOST_WIDE_INT scale;
addr_space_t seg;
- if (ix86_decompose_address (addr, &parts) <= 0)
+ if (ix86_decompose_address (addr, &parts) == 0)
/* Decomposition failed. */
return false;
@@ -20419,6 +20437,12 @@ ix86_rtx_costs (rtx x, machine_mode mode, int outer_code_i, int opno,
<< (GET_MODE (XEXP (x, 1)) != DImode)));
return true;
}
+ else if (code == AND
+ && address_no_seg_operand (x, mode))
+ {
+ *total = cost->lea;
+ return true;
+ }
/* FALLTHRU */
case NEG:
diff --git a/gcc/config/nvptx/nvptx-c.c b/gcc/config/nvptx/nvptx-c.c
new file mode 100644
index 0000000..72594a82e
--- /dev/null
+++ b/gcc/config/nvptx/nvptx-c.c
@@ -0,0 +1,47 @@
+/* Subroutines for the C front end on the NVPTX architecture.
+ * Copyright (C) 2021 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/>. */
+
+#define IN_TARGET_CODE 1
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "target.h"
+#include "c-family/c-common.h"
+#include "memmodel.h"
+#include "tm_p.h"
+#include "c-family/c-pragma.h"
+
+/* Function to tell the preprocessor about the defines for the target. */
+void
+nvptx_cpu_cpp_builtins (void)
+{
+ cpp_assert (parse_in, "machine=nvptx");
+ cpp_assert (parse_in, "cpu=nvptx");
+ cpp_define (parse_in, "__nvptx__");
+ if (TARGET_SOFT_STACK)
+ cpp_define (parse_in, "__nvptx_softstack__");
+ if (TARGET_UNIFORM_SIMT)
+ cpp_define (parse_in,"__nvptx_unisimt__");
+ if (TARGET_SM35)
+ cpp_define (parse_in, "__PTX_SM__=350");
+ else
+ cpp_define (parse_in,"__PTX_SM__=300");
+}
+
diff --git a/gcc/config/nvptx/nvptx-protos.h b/gcc/config/nvptx/nvptx-protos.h
index b7e6ae2..b29ddc9 100644
--- a/gcc/config/nvptx/nvptx-protos.h
+++ b/gcc/config/nvptx/nvptx-protos.h
@@ -40,6 +40,7 @@ extern void nvptx_output_aligned_decl (FILE *file, const char *name,
extern void nvptx_function_end (FILE *);
extern void nvptx_output_skip (FILE *, unsigned HOST_WIDE_INT);
extern void nvptx_output_ascii (FILE *, const char *, unsigned HOST_WIDE_INT);
+extern void nvptx_cpu_cpp_builtins (void);
extern void nvptx_register_pragmas (void);
extern unsigned int nvptx_data_alignment (const_tree, unsigned int);
diff --git a/gcc/config/nvptx/nvptx.h b/gcc/config/nvptx/nvptx.h
index fdaacdd..d367174 100644
--- a/gcc/config/nvptx/nvptx.h
+++ b/gcc/config/nvptx/nvptx.h
@@ -34,17 +34,7 @@
nvptx-as. */
#define ASM_SPEC "%{misa=*:-m %*; :-m sm_35}"
-#define TARGET_CPU_CPP_BUILTINS() \
- do \
- { \
- builtin_assert ("machine=nvptx"); \
- builtin_assert ("cpu=nvptx"); \
- builtin_define ("__nvptx__"); \
- if (TARGET_SOFT_STACK) \
- builtin_define ("__nvptx_softstack__"); \
- if (TARGET_UNIFORM_SIMT) \
- builtin_define ("__nvptx_unisimt__"); \
- } while (0)
+#define TARGET_CPU_CPP_BUILTINS() nvptx_cpu_cpp_builtins ()
/* Avoid the default in ../../gcc.c, which adds "-pthread", which is not
supported for nvptx. */
diff --git a/gcc/config/nvptx/t-nvptx b/gcc/config/nvptx/t-nvptx
index 6c1010d..d33bacd 100644
--- a/gcc/config/nvptx/t-nvptx
+++ b/gcc/config/nvptx/t-nvptx
@@ -1,3 +1,7 @@
+nvptx-c.o: $(srcdir)/config/nvptx/nvptx-c.c
+ $(COMPILE) $<
+ $(POSTCOMPILE)
+
CFLAGS-mkoffload.o += $(DRIVER_DEFINES) \
-DGCC_INSTALL_NAME=\"$(GCC_INSTALL_NAME)\"
mkoffload.o: $(srcdir)/config/nvptx/mkoffload.c
diff --git a/gcc/config/rs6000/aix.h b/gcc/config/rs6000/aix.h
index 662785c..0f4d8cb 100644
--- a/gcc/config/rs6000/aix.h
+++ b/gcc/config/rs6000/aix.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
/* Definitions of target machine for GNU compiler,
for IBM RS/6000 POWER running AIX.
Copyright (C) 2000-2021 Free Software Foundation, Inc.
@@ -23,9 +24,6 @@
#undef TARGET_AIX
#define TARGET_AIX 1
-/* System headers are not C++-aware. */
-#define SYSTEM_IMPLICIT_EXTERN_C 1
-
/* Linux64.h wants to redefine TARGET_AIX based on -m64, but it can't be used
in the #if conditional in options-default.h, so provide another macro. */
#undef TARGET_AIX_OS
diff --git a/gcc/config/rs6000/aix71.h b/gcc/config/rs6000/aix71.h
index 38cfa9e..1bc1560 100644
--- a/gcc/config/rs6000/aix71.h
+++ b/gcc/config/rs6000/aix71.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
/* Definitions of target machine for GNU compiler,
for IBM RS/6000 POWER running AIX V7.1.
Copyright (C) 2002-2021 Free Software Foundation, Inc.
@@ -268,6 +269,9 @@ extern long long int atoll(const char *);
#define SET_CMODEL(opt) do {} while (0)
#endif
+/* System headers are not C++-aware. */
+#define SYSTEM_IMPLICIT_EXTERN_C 1
+
/* This target defines SUPPORTS_WEAK and TARGET_ASM_NAMED_SECTION,
but does not have crtbegin/end. */
diff --git a/gcc/config/rs6000/aix72.h b/gcc/config/rs6000/aix72.h
index a497a7d..cca64f1 100644
--- a/gcc/config/rs6000/aix72.h
+++ b/gcc/config/rs6000/aix72.h
@@ -270,6 +270,9 @@ extern long long int atoll(const char *);
#define SET_CMODEL(opt) do {} while (0)
#endif
+/* System headers are not C++-aware. */
+#define SYSTEM_IMPLICIT_EXTERN_C 1
+
/* This target defines SUPPORTS_WEAK and TARGET_ASM_NAMED_SECTION,
but does not have crtbegin/end. */
diff --git a/gcc/config/rs6000/aix73.h b/gcc/config/rs6000/aix73.h
index c707c7e..f0ca1a5 100644
--- a/gcc/config/rs6000/aix73.h
+++ b/gcc/config/rs6000/aix73.h
@@ -274,7 +274,7 @@ extern long long int atoll(const char *);
/* This target defines SUPPORTS_WEAK and TARGET_ASM_NAMED_SECTION,
but does not have crtbegin/end. */
-#define TARGET_AIX_VERSION 72
+#define TARGET_AIX_VERSION 73
/* AIX 7.2 supports DWARF3+ debugging. */
#define DWARF2_DEBUGGING_INFO 1
diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md
index 2c73dde..93d23715 100644
--- a/gcc/config/rs6000/altivec.md
+++ b/gcc/config/rs6000/altivec.md
@@ -134,10 +134,8 @@
UNSPEC_VMULWLUH
UNSPEC_VMULWHSH
UNSPEC_VMULWLSH
- UNSPEC_VUPKHUB
- UNSPEC_VUPKHUH
- UNSPEC_VUPKLUB
- UNSPEC_VUPKLUH
+ UNSPEC_VUPKHU
+ UNSPEC_VUPKLU
UNSPEC_VPERMSI
UNSPEC_VPERMHI
UNSPEC_INTERHI
@@ -3688,143 +3686,45 @@
[(set_attr "type" "vecperm")
(set_attr "isa" "p9v,*")])
-(define_expand "vec_unpacku_hi_v16qi"
- [(set (match_operand:V8HI 0 "register_operand" "=v")
- (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
- UNSPEC_VUPKHUB))]
- "TARGET_ALTIVEC"
-{
- rtx vzero = gen_reg_rtx (V8HImode);
- rtx mask = gen_reg_rtx (V16QImode);
- rtvec v = rtvec_alloc (16);
- bool be = BYTES_BIG_ENDIAN;
-
- emit_insn (gen_altivec_vspltish (vzero, const0_rtx));
-
- RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, be ? 16 : 7);
- RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, be ? 0 : 16);
- RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, be ? 16 : 6);
- RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, be ? 1 : 16);
- RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, be ? 16 : 5);
- RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, be ? 2 : 16);
- RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, be ? 16 : 4);
- RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, be ? 3 : 16);
- RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, be ? 16 : 3);
- RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, be ? 4 : 16);
- RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, be ? 16 : 2);
- RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, be ? 5 : 16);
- RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, be ? 16 : 1);
- RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, be ? 6 : 16);
- RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, be ? 16 : 0);
- RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, be ? 7 : 16);
-
- emit_insn (gen_vec_initv16qiqi (mask, gen_rtx_PARALLEL (V16QImode, v)));
- emit_insn (gen_vperm_v16qiv8hi (operands[0], operands[1], vzero, mask));
- DONE;
-})
-
-(define_expand "vec_unpacku_hi_v8hi"
- [(set (match_operand:V4SI 0 "register_operand" "=v")
- (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
- UNSPEC_VUPKHUH))]
+(define_expand "vec_unpacku_hi_<VP_small_lc>"
+ [(set (match_operand:VP 0 "register_operand" "=v")
+ (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")]
+ UNSPEC_VUPKHU))]
"TARGET_ALTIVEC"
{
- rtx vzero = gen_reg_rtx (V4SImode);
- rtx mask = gen_reg_rtx (V16QImode);
- rtvec v = rtvec_alloc (16);
- bool be = BYTES_BIG_ENDIAN;
+ rtx vzero = gen_reg_rtx (<VP_small>mode);
+ emit_insn (gen_altivec_vspltis<VU_char> (vzero, const0_rtx));
- emit_insn (gen_altivec_vspltisw (vzero, const0_rtx));
-
- RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, be ? 16 : 7);
- RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, be ? 17 : 6);
- RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, be ? 0 : 17);
- RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, be ? 1 : 16);
- RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, be ? 16 : 5);
- RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, be ? 17 : 4);
- RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, be ? 2 : 17);
- RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, be ? 3 : 16);
- RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, be ? 16 : 3);
- RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, be ? 17 : 2);
- RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, be ? 4 : 17);
- RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, be ? 5 : 16);
- RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, be ? 16 : 1);
- RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, be ? 17 : 0);
- RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, be ? 6 : 17);
- RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, be ? 7 : 16);
-
- emit_insn (gen_vec_initv16qiqi (mask, gen_rtx_PARALLEL (V16QImode, v)));
- emit_insn (gen_vperm_v8hiv4si (operands[0], operands[1], vzero, mask));
- DONE;
-})
+ rtx res = gen_reg_rtx (<VP_small>mode);
+ rtx op1 = operands[1];
-(define_expand "vec_unpacku_lo_v16qi"
- [(set (match_operand:V8HI 0 "register_operand" "=v")
- (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
- UNSPEC_VUPKLUB))]
- "TARGET_ALTIVEC"
-{
- rtx vzero = gen_reg_rtx (V8HImode);
- rtx mask = gen_reg_rtx (V16QImode);
- rtvec v = rtvec_alloc (16);
- bool be = BYTES_BIG_ENDIAN;
-
- emit_insn (gen_altivec_vspltish (vzero, const0_rtx));
-
- RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, be ? 16 : 15);
- RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, be ? 8 : 16);
- RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, be ? 16 : 14);
- RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, be ? 9 : 16);
- RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, be ? 16 : 13);
- RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, be ? 10 : 16);
- RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, be ? 16 : 12);
- RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, be ? 11 : 16);
- RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, be ? 16 : 11);
- RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, be ? 12 : 16);
- RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, be ? 16 : 10);
- RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, be ? 13 : 16);
- RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, be ? 16 : 9);
- RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, be ? 14 : 16);
- RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, be ? 16 : 8);
- RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, be ? 15 : 16);
+ if (BYTES_BIG_ENDIAN)
+ emit_insn (gen_altivec_vmrgh<VU_char> (res, vzero, op1));
+ else
+ emit_insn (gen_altivec_vmrgl<VU_char> (res, op1, vzero));
- emit_insn (gen_vec_initv16qiqi (mask, gen_rtx_PARALLEL (V16QImode, v)));
- emit_insn (gen_vperm_v16qiv8hi (operands[0], operands[1], vzero, mask));
+ emit_insn (gen_move_insn (operands[0], gen_lowpart (<MODE>mode, res)));
DONE;
})
-(define_expand "vec_unpacku_lo_v8hi"
- [(set (match_operand:V4SI 0 "register_operand" "=v")
- (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
- UNSPEC_VUPKLUH))]
+(define_expand "vec_unpacku_lo_<VP_small_lc>"
+ [(set (match_operand:VP 0 "register_operand" "=v")
+ (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")]
+ UNSPEC_VUPKLU))]
"TARGET_ALTIVEC"
{
- rtx vzero = gen_reg_rtx (V4SImode);
- rtx mask = gen_reg_rtx (V16QImode);
- rtvec v = rtvec_alloc (16);
- bool be = BYTES_BIG_ENDIAN;
+ rtx vzero = gen_reg_rtx (<VP_small>mode);
+ emit_insn (gen_altivec_vspltis<VU_char> (vzero, const0_rtx));
- emit_insn (gen_altivec_vspltisw (vzero, const0_rtx));
-
- RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, be ? 16 : 15);
- RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, be ? 17 : 14);
- RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, be ? 8 : 17);
- RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, be ? 9 : 16);
- RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, be ? 16 : 13);
- RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, be ? 17 : 12);
- RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, be ? 10 : 17);
- RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, be ? 11 : 16);
- RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, be ? 16 : 11);
- RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, be ? 17 : 10);
- RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, be ? 12 : 17);
- RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, be ? 13 : 16);
- RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, be ? 16 : 9);
- RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, be ? 17 : 8);
- RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, be ? 14 : 17);
- RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, be ? 15 : 16);
+ rtx res = gen_reg_rtx (<VP_small>mode);
+ rtx op1 = operands[1];
- emit_insn (gen_vec_initv16qiqi (mask, gen_rtx_PARALLEL (V16QImode, v)));
- emit_insn (gen_vperm_v8hiv4si (operands[0], operands[1], vzero, mask));
+ if (BYTES_BIG_ENDIAN)
+ emit_insn (gen_altivec_vmrgl<VU_char> (res, vzero, op1));
+ else
+ emit_insn (gen_altivec_vmrgh<VU_char> (res, op1, vzero));
+
+ emit_insn (gen_move_insn (operands[0], gen_lowpart (<MODE>mode, res)));
DONE;
})
diff --git a/gcc/config/rs6000/rs6000-builtin-new.def b/gcc/config/rs6000/rs6000-builtin-new.def
index 2a2c913..b6fc994 100644
--- a/gcc/config/rs6000/rs6000-builtin-new.def
+++ b/gcc/config/rs6000/rs6000-builtin-new.def
@@ -2438,3 +2438,894 @@
const double __builtin_vsx_xscvspdpn (vf);
XSCVSPDPN vsx_xscvspdpn {}
+
+
+; Power9 vector builtins.
+[power9-vector]
+ const vss __builtin_altivec_convert_4f32_8f16 (vf, vf);
+ CONVERT_4F32_8F16 convert_4f32_8f16 {}
+
+ const vss __builtin_altivec_convert_4f32_8i16 (vf, vf);
+ CONVERT_4F32_8I16 convert_4f32_8i16 {}
+
+ const signed int __builtin_altivec_first_match_index_v16qi (vsc, vsc);
+ VFIRSTMATCHINDEX_V16QI first_match_index_v16qi {}
+
+ const signed int __builtin_altivec_first_match_index_v8hi (vss, vss);
+ VFIRSTMATCHINDEX_V8HI first_match_index_v8hi {}
+
+ const signed int __builtin_altivec_first_match_index_v4si (vsi, vsi);
+ VFIRSTMATCHINDEX_V4SI first_match_index_v4si {}
+
+ const signed int __builtin_altivec_first_match_or_eos_index_v16qi (vsc, vsc);
+ VFIRSTMATCHOREOSINDEX_V16QI first_match_or_eos_index_v16qi {}
+
+ const signed int __builtin_altivec_first_match_or_eos_index_v8hi (vss, vss);
+ VFIRSTMATCHOREOSINDEX_V8HI first_match_or_eos_index_v8hi {}
+
+ const signed int __builtin_altivec_first_match_or_eos_index_v4si (vsi, vsi);
+ VFIRSTMATCHOREOSINDEX_V4SI first_match_or_eos_index_v4si {}
+
+ const signed int __builtin_altivec_first_mismatch_index_v16qi (vsc, vsc);
+ VFIRSTMISMATCHINDEX_V16QI first_mismatch_index_v16qi {}
+
+ const signed int __builtin_altivec_first_mismatch_index_v8hi (vss, vss);
+ VFIRSTMISMATCHINDEX_V8HI first_mismatch_index_v8hi {}
+
+ const signed int __builtin_altivec_first_mismatch_index_v4si (vsi, vsi);
+ VFIRSTMISMATCHINDEX_V4SI first_mismatch_index_v4si {}
+
+ const signed int __builtin_altivec_first_mismatch_or_eos_index_v16qi (vsc, vsc);
+ VFIRSTMISMATCHOREOSINDEX_V16QI first_mismatch_or_eos_index_v16qi {}
+
+ const signed int __builtin_altivec_first_mismatch_or_eos_index_v8hi (vss, vss);
+ VFIRSTMISMATCHOREOSINDEX_V8HI first_mismatch_or_eos_index_v8hi {}
+
+ const signed int __builtin_altivec_first_mismatch_or_eos_index_v4si (vsi, vsi);
+ VFIRSTMISMATCHOREOSINDEX_V4SI first_mismatch_or_eos_index_v4si {}
+
+ const vsc __builtin_altivec_vadub (vsc, vsc);
+ VADUB vaduv16qi3 {}
+
+ const vss __builtin_altivec_vaduh (vss, vss);
+ VADUH vaduv8hi3 {}
+
+ const vsi __builtin_altivec_vaduw (vsi, vsi);
+ VADUW vaduv4si3 {}
+
+ const vsll __builtin_altivec_vbpermd (vsll, vsc);
+ VBPERMD altivec_vbpermd {}
+
+ const signed int __builtin_altivec_vclzlsbb_v16qi (vsc);
+ VCLZLSBB_V16QI vclzlsbb_v16qi {}
+
+ const signed int __builtin_altivec_vclzlsbb_v4si (vsi);
+ VCLZLSBB_V4SI vclzlsbb_v4si {}
+
+ const signed int __builtin_altivec_vclzlsbb_v8hi (vss);
+ VCLZLSBB_V8HI vclzlsbb_v8hi {}
+
+ const vsc __builtin_altivec_vctzb (vsc);
+ VCTZB ctzv16qi2 {}
+
+ const vsll __builtin_altivec_vctzd (vsll);
+ VCTZD ctzv2di2 {}
+
+ const vss __builtin_altivec_vctzh (vss);
+ VCTZH ctzv8hi2 {}
+
+ const vsi __builtin_altivec_vctzw (vsi);
+ VCTZW ctzv4si2 {}
+
+ const signed int __builtin_altivec_vctzlsbb_v16qi (vsc);
+ VCTZLSBB_V16QI vctzlsbb_v16qi {}
+
+ const signed int __builtin_altivec_vctzlsbb_v4si (vsi);
+ VCTZLSBB_V4SI vctzlsbb_v4si {}
+
+ const signed int __builtin_altivec_vctzlsbb_v8hi (vss);
+ VCTZLSBB_V8HI vctzlsbb_v8hi {}
+
+ const signed int __builtin_altivec_vcmpaeb_p (vsc, vsc);
+ VCMPAEB_P vector_ae_v16qi_p {}
+
+ const signed int __builtin_altivec_vcmpaed_p (vsll, vsll);
+ VCMPAED_P vector_ae_v2di_p {}
+
+ const signed int __builtin_altivec_vcmpaedp_p (vd, vd);
+ VCMPAEDP_P vector_ae_v2df_p {}
+
+ const signed int __builtin_altivec_vcmpaefp_p (vf, vf);
+ VCMPAEFP_P vector_ae_v4sf_p {}
+
+ const signed int __builtin_altivec_vcmpaeh_p (vss, vss);
+ VCMPAEH_P vector_ae_v8hi_p {}
+
+ const signed int __builtin_altivec_vcmpaew_p (vsi, vsi);
+ VCMPAEW_P vector_ae_v4si_p {}
+
+ const vsc __builtin_altivec_vcmpneb (vsc, vsc);
+ VCMPNEB vcmpneb {}
+
+ const signed int __builtin_altivec_vcmpneb_p (vsc, vsc);
+ VCMPNEB_P vector_ne_v16qi_p {}
+
+ const signed int __builtin_altivec_vcmpned_p (vsll, vsll);
+ VCMPNED_P vector_ne_v2di_p {}
+
+ const signed int __builtin_altivec_vcmpnedp_p (vd, vd);
+ VCMPNEDP_P vector_ne_v2df_p {}
+
+ const signed int __builtin_altivec_vcmpnefp_p (vf, vf);
+ VCMPNEFP_P vector_ne_v4sf_p {}
+
+ const vss __builtin_altivec_vcmpneh (vss, vss);
+ VCMPNEH vcmpneh {}
+
+ const signed int __builtin_altivec_vcmpneh_p (vss, vss);
+ VCMPNEH_P vector_ne_v8hi_p {}
+
+ const vsi __builtin_altivec_vcmpnew (vsi, vsi);
+ VCMPNEW vcmpnew {}
+
+ const signed int __builtin_altivec_vcmpnew_p (vsi, vsi);
+ VCMPNEW_P vector_ne_v4si_p {}
+
+ const vsc __builtin_altivec_vcmpnezb (vsc, vsc);
+ CMPNEZB vcmpnezb {}
+
+ const signed int __builtin_altivec_vcmpnezb_p (signed int, vsc, vsc);
+ VCMPNEZB_P vector_nez_v16qi_p {pred}
+
+ const vss __builtin_altivec_vcmpnezh (vss, vss);
+ CMPNEZH vcmpnezh {}
+
+ const signed int __builtin_altivec_vcmpnezh_p (signed int, vss, vss);
+ VCMPNEZH_P vector_nez_v8hi_p {pred}
+
+ const vsi __builtin_altivec_vcmpnezw (vsi, vsi);
+ CMPNEZW vcmpnezw {}
+
+ const signed int __builtin_altivec_vcmpnezw_p (signed int, vsi, vsi);
+ VCMPNEZW_P vector_nez_v4si_p {pred}
+
+ const signed int __builtin_altivec_vextublx (signed int, vsc);
+ VEXTUBLX vextublx {}
+
+ const signed int __builtin_altivec_vextubrx (signed int, vsc);
+ VEXTUBRX vextubrx {}
+
+ const signed int __builtin_altivec_vextuhlx (signed int, vss);
+ VEXTUHLX vextuhlx {}
+
+ const signed int __builtin_altivec_vextuhrx (signed int, vss);
+ VEXTUHRX vextuhrx {}
+
+ const signed int __builtin_altivec_vextuwlx (signed int, vsi);
+ VEXTUWLX vextuwlx {}
+
+ const signed int __builtin_altivec_vextuwrx (signed int, vsi);
+ VEXTUWRX vextuwrx {}
+
+ const vsq __builtin_altivec_vmsumudm (vsll, vsll, vsq);
+ VMSUMUDM altivec_vmsumudm {}
+
+ const vsll __builtin_altivec_vprtybd (vsll);
+ VPRTYBD parityv2di2 {}
+
+ const vsq __builtin_altivec_vprtybq (vsq);
+ VPRTYBQ parityv1ti2 {}
+
+ const vsi __builtin_altivec_vprtybw (vsi);
+ VPRTYBW parityv4si2 {}
+
+ const vsll __builtin_altivec_vrldmi (vsll, vsll, vsll);
+ VRLDMI altivec_vrldmi {}
+
+ const vsll __builtin_altivec_vrldnm (vsll, vsll);
+ VRLDNM altivec_vrldnm {}
+
+ const vsi __builtin_altivec_vrlwmi (vsi, vsi, vsi);
+ VRLWMI altivec_vrlwmi {}
+
+ const vsi __builtin_altivec_vrlwnm (vsi, vsi);
+ VRLWNM altivec_vrlwnm {}
+
+ const vsll __builtin_altivec_vsignextsb2d (vsc);
+ VSIGNEXTSB2D vsignextend_qi_v2di {}
+
+ const vsi __builtin_altivec_vsignextsb2w (vsc);
+ VSIGNEXTSB2W vsignextend_qi_v4si {}
+
+ const vsll __builtin_altivec_visgnextsh2d (vss);
+ VSIGNEXTSH2D vsignextend_hi_v2di {}
+
+ const vsi __builtin_altivec_vsignextsh2w (vss);
+ VSIGNEXTSH2W vsignextend_hi_v4si {}
+
+ const vsll __builtin_altivec_vsignextsw2d (vsi);
+ VSIGNEXTSW2D vsignextend_si_v2di {}
+
+ const vsc __builtin_altivec_vslv (vsc, vsc);
+ VSLV vslv {}
+
+ const vsc __builtin_altivec_vsrv (vsc, vsc);
+ VSRV vsrv {}
+
+ const signed int __builtin_scalar_byte_in_range (signed int, signed int);
+ CMPRB cmprb {}
+
+ const signed int __builtin_scalar_byte_in_either_range (signed int, signed int);
+ CMPRB2 cmprb2 {}
+
+ const vsll __builtin_vsx_extract4b (vsc, const int[0,12]);
+ EXTRACT4B extract4b {}
+
+ const vd __builtin_vsx_extract_exp_dp (vd);
+ VEEDP xvxexpdp {}
+
+ const vf __builtin_vsx_extract_exp_sp (vf);
+ VEESP xvxexpsp {}
+
+ const vd __builtin_vsx_extract_sig_dp (vd);
+ VESDP xvxsigdp {}
+
+ const vf __builtin_vsx_extract_sig_sp (vf);
+ VESSP xvxsigsp {}
+
+ const vsc __builtin_vsx_insert4b (vsi, vsc, const int[0,12]);
+ INSERT4B insert4b {}
+
+ const vd __builtin_vsx_insert_exp_dp (vd, vd);
+ VIEDP xviexpdp {}
+
+ const vf __builtin_vsx_insert_exp_sp (vf, vf);
+ VIESP xviexpsp {}
+
+ const signed int __builtin_vsx_scalar_cmp_exp_dp_eq (double, double);
+ VSCEDPEQ xscmpexpdp_eq {}
+
+ const signed int __builtin_vsx_scalar_cmp_exp_dp_gt (double, double);
+ VSCEDPGT xscmpexpdp_gt {}
+
+ const signed int __builtin_vsx_scalar_cmp_exp_dp_lt (double, double);
+ VSCEDPLT xscmpexpdp_lt {}
+
+ const signed int __builtin_vsx_scalar_cmp_exp_dp_unordered (double, double);
+ VSCEDPUO xscmpexpdp_unordered {}
+
+ const signed int __builtin_vsx_scalar_test_data_class_dp (double, const int<7>);
+ VSTDCDP xststdcdp {}
+
+ const signed int __builtin_vsx_scalar_test_data_class_sp (float, const int<7>);
+ VSTDCSP xststdcsp {}
+
+ const signed int __builtin_vsx_scalar_test_neg_dp (double);
+ VSTDCNDP xststdcnegdp {}
+
+ const signed int __builtin_vsx_scalar_test_neg_sp (float);
+ VSTDCNSP xststdcnegsp {}
+
+ const vsll __builtin_vsx_test_data_class_dp (vd, const int<7>);
+ VTDCDP xvtstdcdp {}
+
+ const vsi __builtin_vsx_test_data_class_sp (vf, const int<7>);
+ VTDCSP xvtstdcsp {}
+
+ const vf __builtin_vsx_vextract_fp_from_shorth (vss);
+ VEXTRACT_FP_FROM_SHORTH vextract_fp_from_shorth {}
+
+ const vf __builtin_vsx_vextract_fp_from_shortl (vss);
+ VEXTRACT_FP_FROM_SHORTL vextract_fp_from_shortl {}
+
+ const vd __builtin_vsx_xxbrd_v2df (vd);
+ XXBRD_V2DF p9_xxbrd_v2df {}
+
+ const vsll __builtin_vsx_xxbrd_v2di (vsll);
+ XXBRD_V2DI p9_xxbrd_v2di {}
+
+ const vss __builtin_vsx_xxbrh_v8hi (vss);
+ XXBRH_V8HI p9_xxbrh_v8hi {}
+
+ const vsc __builtin_vsx_xxbrq_v16qi (vsc);
+ XXBRQ_V16QI p9_xxbrq_v16qi {}
+
+ const vsq __builtin_vsx_xxbrq_v1ti (vsq);
+ XXBRQ_V1TI p9_xxbrq_v1ti {}
+
+ const vf __builtin_vsx_xxbrw_v4sf (vf);
+ XXBRW_V4SF p9_xxbrw_v4sf {}
+
+ const vsi __builtin_vsx_xxbrw_v4si (vsi);
+ XXBRW_V4SI p9_xxbrw_v4si {}
+
+
+; Miscellaneous P9 functions
+[power9]
+ signed long long __builtin_darn ();
+ DARN darn {}
+
+ signed int __builtin_darn_32 ();
+ DARN_32 darn_32 {}
+
+ signed long long __builtin_darn_raw ();
+ DARN_RAW darn_raw {}
+
+ double __builtin_mffsl ();
+ MFFSL rs6000_mffsl {}
+
+ const signed int __builtin_dtstsfi_eq_dd (const int<6>, _Decimal64);
+ TSTSFI_EQ_DD dfptstsfi_eq_dd {}
+
+ const signed int __builtin_dtstsfi_eq_td (const int<6>, _Decimal128);
+ TSTSFI_EQ_TD dfptstsfi_eq_td {}
+
+ const signed int __builtin_dtstsfi_gt_dd (const int<6>, _Decimal64);
+ TSTSFI_GT_DD dfptstsfi_gt_dd {}
+
+ const signed int __builtin_dtstsfi_gt_td (const int<6>, _Decimal128);
+ TSTSFI_GT_TD dfptstsfi_gt_td {}
+
+ const signed int __builtin_dtstsfi_lt_dd (const int<6>, _Decimal64);
+ TSTSFI_LT_DD dfptstsfi_lt_dd {}
+
+ const signed int __builtin_dtstsfi_lt_td (const int<6>, _Decimal128);
+ TSTSFI_LT_TD dfptstsfi_lt_td {}
+
+ const signed int __builtin_dtstsfi_ov_dd (const int<6>, _Decimal64);
+ TSTSFI_OV_DD dfptstsfi_unordered_dd {}
+
+ const signed int __builtin_dtstsfi_ov_td (const int<6>, _Decimal128);
+ TSTSFI_OV_TD dfptstsfi_unordered_td {}
+
+
+[power9-64]
+ void __builtin_altivec_xst_len_r (vsc, void *, long);
+ XST_LEN_R xst_len_r {}
+
+ void __builtin_altivec_stxvl (vsc, void *, long);
+ STXVL stxvl {}
+
+ const signed int __builtin_scalar_byte_in_set (signed int, signed long long);
+ CMPEQB cmpeqb {}
+
+ pure vsc __builtin_vsx_lxvl (const void *, signed long);
+ LXVL lxvl {}
+
+ const signed long __builtin_vsx_scalar_extract_exp (double);
+ VSEEDP xsxexpdp {}
+
+ const signed long __builtin_vsx_scalar_extract_sig (double);
+ VSESDP xsxsigdp {}
+
+ const double __builtin_vsx_scalar_insert_exp (unsigned long long, unsigned long long);
+ VSIEDP xsiexpdp {}
+
+ const double __builtin_vsx_scalar_insert_exp_dp (double, unsigned long long);
+ VSIEDPF xsiexpdpf {}
+
+ pure vsc __builtin_vsx_xl_len_r (void *, signed long);
+ XL_LEN_R xl_len_r {}
+
+
+[power10]
+ const vbq __builtin_altivec_cmpge_1ti (vsq, vsq);
+ CMPGE_1TI vector_nltv1ti {}
+
+ const vbq __builtin_altivec_cmpge_u1ti (vuq, vuq);
+ CMPGE_U1TI vector_nltuv1ti {}
+
+ const vbq __builtin_altivec_cmple_1ti (vsq, vsq);
+ CMPLE_1TI vector_ngtv1ti {}
+
+ const vbq __builtin_altivec_cmple_u1ti (vuq, vuq);
+ CMPLE_U1TI vector_ngtuv1ti {}
+
+ const unsigned long long __builtin_altivec_cntmbb (vuc, const int<1>);
+ VCNTMBB vec_cntmb_v16qi {}
+
+ const unsigned long long __builtin_altivec_cntmbd (vull, const int<1>);
+ VCNTMBD vec_cntmb_v2di {}
+
+ const unsigned long long __builtin_altivec_cntmbh (vus, const int<1>);
+ VCNTMBH vec_cntmb_v8hi {}
+
+ const unsigned long long __builtin_altivec_cntmbw (vui, const int<1>);
+ VCNTMBW vec_cntmb_v4si {}
+
+ const vsq __builtin_altivec_div_v1ti (vsq, vsq);
+ DIV_V1TI vsx_div_v1ti {}
+
+ const vsq __builtin_altivec_dives (vsq, vsq);
+ DIVES_V1TI vsx_dives_v1ti {}
+
+ const vuq __builtin_altivec_diveu (vuq, vuq);
+ DIVEU_V1TI vsx_diveu_v1ti {}
+
+ const vsq __builtin_altivec_mods (vsq, vsq);
+ MODS_V1TI vsx_mods_v1ti {}
+
+ const vuq __builtin_altivec_modu (vuq, vuq);
+ MODU_V1TI vsx_modu_v1ti {}
+
+ const vuc __builtin_altivec_mtvsrbm (unsigned long long);
+ MTVSRBM vec_mtvsr_v16qi {}
+
+ const vull __builtin_altivec_mtvsrdm (unsigned long long);
+ MTVSRDM vec_mtvsr_v2di {}
+
+ const vus __builtin_altivec_mtvsrhm (unsigned long long);
+ MTVSRHM vec_mtvsr_v8hi {}
+
+ const vuq __builtin_altivec_mtvsrqm (unsigned long long);
+ MTVSRQM vec_mtvsr_v1ti {}
+
+ const vui __builtin_altivec_mtvsrwm (unsigned long long);
+ MTVSRWM vec_mtvsr_v4si {}
+
+ pure signed __int128 __builtin_altivec_se_lxvrbx (signed long, const signed char *);
+ SE_LXVRBX vsx_lxvrbx {lxvrse}
+
+ pure signed __int128 __builtin_altivec_se_lxvrhx (signed long, const signed short *);
+ SE_LXVRHX vsx_lxvrhx {lxvrse}
+
+ pure signed __int128 __builtin_altivec_se_lxvrwx (signed long, const signed int *);
+ SE_LXVRWX vsx_lxvrwx {lxvrse}
+
+ pure signed __int128 __builtin_altivec_se_lxvrdx (signed long, const signed long long *);
+ SE_LXVRDX vsx_lxvrdx {lxvrse}
+
+ void __builtin_altivec_tr_stxvrbx (vsq, signed long, signed char *);
+ TR_STXVRBX vsx_stxvrbx {stvec}
+
+ void __builtin_altivec_tr_stxvrhx (vsq, signed long, signed int *);
+ TR_STXVRHX vsx_stxvrhx {stvec}
+
+ void __builtin_altivec_tr_stxvrwx (vsq, signed long, signed short *);
+ TR_STXVRWX vsx_stxvrwx {stvec}
+
+ void __builtin_altivec_tr_stxvrdx (vsq, signed long, signed long long *);
+ TR_STXVRDX vsx_stxvrdx {stvec}
+
+ const vuq __builtin_altivec_udiv_v1ti (vuq, vuq);
+ UDIV_V1TI vsx_udiv_v1ti {}
+
+ const vull __builtin_altivec_vcfuged (vull, vull);
+ VCFUGED vcfuged {}
+
+ const vsc __builtin_altivec_vclrlb (vsc, signed int);
+ VCLRLB vclrlb {}
+
+ const vsc __builtin_altivec_vclrrb (vsc, signed int);
+ VCLRRB vclrrb {}
+
+ const signed int __builtin_altivec_vcmpaet_p (vsq, vsq);
+ VCMPAET_P vector_ae_v1ti_p {}
+
+ const vbq __builtin_altivec_vcmpequt (vsq, vsq);
+ VCMPEQUT vector_eqv1ti {}
+
+ const signed int __builtin_altivec_vcmpequt_p (signed int, vsq, vsq);
+ VCMPEQUT_P vector_eq_v1ti_p {pred}
+
+ const vbq __builtin_altivec_vcmpgtst (vsq, vsq);
+ VCMPGTST vector_gtv1ti {}
+
+ const signed int __builtin_altivec_vcmpgtst_p (signed int, vsq, vsq);
+ VCMPGTST_P vector_gt_v1ti_p {pred}
+
+ const vbq __builtin_altivec_vcmpgtut (vuq, vuq);
+ VCMPGTUT vector_gtuv1ti {}
+
+ const signed int __builtin_altivec_vcmpgtut_p (signed int, vuq, vuq);
+ VCMPGTUT_P vector_gtu_v1ti_p {pred}
+
+ const vbq __builtin_altivec_vcmpnet (vsq, vsq);
+ VCMPNET vcmpnet {}
+
+ const signed int __builtin_altivec_vcmpnet_p (vsq, vsq);
+ VCMPNET_P vector_ne_v1ti_p {}
+
+ const vull __builtin_altivec_vclzdm (vull, vull);
+ VCLZDM vclzdm {}
+
+ const vull __builtin_altivec_vctzdm (vull, vull);
+ VCTZDM vctzdm {}
+
+ const vsll __builtin_altivec_vdivesd (vsll, vsll);
+ VDIVESD dives_v2di {}
+
+ const vsi __builtin_altivec_vdivesw (vsi, vsi);
+ VDIVESW dives_v4si {}
+
+ const vull __builtin_altivec_vdiveud (vull, vull);
+ VDIVEUD diveu_v2di {}
+
+ const vui __builtin_altivec_vdiveuw (vui, vui);
+ VDIVEUW diveu_v4si {}
+
+ const vsll __builtin_altivec_vdivsd (vsll, vsll);
+ VDIVSD divv2di3 {}
+
+ const vsi __builtin_altivec_vdivsw (vsi, vsi);
+ VDIVSW divv4si3 {}
+
+ const vull __builtin_altivec_vdivud (vull, vull);
+ VDIVUD udivv2di3 {}
+
+ const vui __builtin_altivec_vdivuw (vui, vui);
+ VDIVUW udivv4si3 {}
+
+ const vuc __builtin_altivec_vexpandmb (vuc);
+ VEXPANDMB vec_expand_v16qi {}
+
+ const vull __builtin_altivec_vexpandmd (vull);
+ VEXPANDMD vec_expand_v2di {}
+
+ const vus __builtin_altivec_vexpandmh (vus);
+ VEXPANDMH vec_expand_v8hi {}
+
+ const vuq __builtin_altivec_vexpandmq (vuq);
+ VEXPANDMQ vec_expand_v1ti {}
+
+ const vui __builtin_altivec_vexpandmw (vui);
+ VEXPANDMW vec_expand_v4si {}
+
+ const vull __builtin_altivec_vextddvhx (vull, vull, unsigned int);
+ VEXTRACTDR vextractrv2di {}
+
+ const vull __builtin_altivec_vextddvlx (vull, vull, unsigned int);
+ VEXTRACTDL vextractlv2di {}
+
+ const vull __builtin_altivec_vextdubvhx (vuc, vuc, unsigned int);
+ VEXTRACTBR vextractrv16qi {}
+
+ const vull __builtin_altivec_vextdubvlx (vuc, vuc, unsigned int);
+ VEXTRACTBL vextractlv16qi {}
+
+ const vull __builtin_altivec_vextduhvhx (vus, vus, unsigned int);
+ VEXTRACTHR vextractrv8hi {}
+
+ const vull __builtin_altivec_vextduhvlx (vus, vus, unsigned int);
+ VEXTRACTHL vextractlv8hi {}
+
+ const vull __builtin_altivec_vextduwvhx (vui, vui, unsigned int);
+ VEXTRACTWR vextractrv4si {}
+
+ const vull __builtin_altivec_vextduwvlx (vui, vui, unsigned int);
+ VEXTRACTWL vextractlv4si {}
+
+ const signed int __builtin_altivec_vextractmb (vsc);
+ VEXTRACTMB vec_extract_v16qi {}
+
+ const signed int __builtin_altivec_vextractmd (vsll);
+ VEXTRACTMD vec_extract_v2di {}
+
+ const signed int __builtin_altivec_vextractmh (vss);
+ VEXTRACTMH vec_extract_v8hi {}
+
+ const signed int __builtin_altivec_vextractmq (vsq);
+ VEXTRACTMQ vec_extract_v1ti {}
+
+ const signed int __builtin_altivec_vextractmw (vsi);
+ VEXTRACTMW vec_extract_v4si {}
+
+ const unsigned long long __builtin_altivec_vgnb (vull, const int <2,7>);
+ VGNB vgnb {}
+
+ const vuc __builtin_altivec_vinsgubvlx (unsigned int, vuc, unsigned int);
+ VINSERTGPRBL vinsertgl_v16qi {}
+
+ const vsc __builtin_altivec_vinsgubvrx (signed int, vsc, signed int);
+ VINSERTGPRBR vinsertgr_v16qi {}
+
+ const vull __builtin_altivec_vinsgudvlx (unsigned int, vull, unsigned int);
+ VINSERTGPRDL vinsertgl_v2di {}
+
+ const vsll __builtin_altivec_vinsgudvrx (signed int, vsll, signed int);
+ VINSERTGPRDR vinsertgr_v2di {}
+
+ const vus __builtin_altivec_vinsguhvlx (unsigned int, vus, unsigned int);
+ VINSERTGPRHL vinsertgl_v8hi {}
+
+ const vss __builtin_altivec_vinsguhvrx (signed int, vss, signed int);
+ VINSERTGPRHR vinsertgr_v8hi {}
+
+ const vui __builtin_altivec_vinsguwvlx (unsigned int, vui, unsigned int);
+ VINSERTGPRWL vinsertgl_v4si {}
+
+ const vsi __builtin_altivec_vinsguwvrx (signed int, vsi, signed int);
+ VINSERTGPRWR vinsertgr_v4si {}
+
+ const vuc __builtin_altivec_vinsvubvlx (vuc, vuc, unsigned int);
+ VINSERTVPRBL vinsertvl_v16qi {}
+
+ const vsc __builtin_altivec_vinsvubvrx (vsc, vsc, signed int);
+ VINSERTVPRBR vinsertvr_v16qi {}
+
+ const vus __builtin_altivec_vinsvuhvlx (vus, vus, unsigned int);
+ VINSERTVPRHL vinsertvl_v8hi {}
+
+ const vss __builtin_altivec_vinsvuhvrx (vss, vss, signed int);
+ VINSERTVPRHR vinsertvr_v8hi {}
+
+ const vui __builtin_altivec_vinsvuwvlx (vui, vui, unsigned int);
+ VINSERTVPRWL vinsertvl_v4si {}
+
+ const vsi __builtin_altivec_vinsvuwvrx (vsi, vsi, signed int);
+ VINSERTVPRWR vinsertvr_v4si {}
+
+ const vsll __builtin_altivec_vmodsd (vsll, vsll);
+ VMODSD modv2di3 {}
+
+ const vsi __builtin_altivec_vmodsw (vsi, vsi);
+ VMODSW modv4si3 {}
+
+ const vull __builtin_altivec_vmodud (vull, vull);
+ VMODUD umodv2di3 {}
+
+ const vui __builtin_altivec_vmoduw (vui, vui);
+ VMODUW umodv4si3 {}
+
+ const vsq __builtin_altivec_vmulesd (vsll, vsll);
+ VMULESD vec_widen_smult_even_v2di {}
+
+ const vuq __builtin_altivec_vmuleud (vull, vull);
+ VMULEUD vec_widen_umult_even_v2di {}
+
+ const vsll __builtin_altivec_vmulhsd (vsll, vsll);
+ VMULHSD smulv2di3_highpart {}
+
+ const vsi __builtin_altivec_vmulhsw (vsi, vsi);
+ VMULHSW smulv4si3_highpart {}
+
+ const vull __builtin_altivec_vmulhud (vull, vull);
+ VMULHUD umulv2di3_highpart {}
+
+ const vui __builtin_altivec_vmulhuw (vui, vui);
+ VMULHUW umulv4si3_highpart {}
+
+ const vsll __builtin_altivec_vmulld (vsll, vsll);
+ VMULLD mulv2di3 {}
+
+ const vsq __builtin_altivec_vmulosd (vsll, vsll);
+ VMULOSD vec_widen_smult_odd_v2di {}
+
+ const vuq __builtin_altivec_vmuloud (vull, vull);
+ VMULOUD vec_widen_umult_odd_v2di {}
+
+ const vsq __builtin_altivec_vnor_v1ti (vsq, vsq);
+ VNOR_V1TI norv1ti3 {}
+
+ const vuq __builtin_altivec_vnor_v1ti_uns (vuq, vuq);
+ VNOR_V1TI_UNS norv1ti3 {}
+
+ const vull __builtin_altivec_vpdepd (vull, vull);
+ VPDEPD vpdepd {}
+
+ const vull __builtin_altivec_vpextd (vull, vull);
+ VPEXTD vpextd {}
+
+ const vull __builtin_altivec_vreplace_un_uv2di (vull, unsigned long long, const int<4>);
+ VREPLACE_UN_UV2DI vreplace_un_v2di {}
+
+ const vui __builtin_altivec_vreplace_un_uv4si (vui, unsigned int, const int<4>);
+ VREPLACE_UN_UV4SI vreplace_un_v4si {}
+
+ const vd __builtin_altivec_vreplace_un_v2df (vd, double, const int<4>);
+ VREPLACE_UN_V2DF vreplace_un_v2df {}
+
+ const vsll __builtin_altivec_vreplace_un_v2di (vsll, signed long long, const int<4>);
+ VREPLACE_UN_V2DI vreplace_un_v2di {}
+
+ const vf __builtin_altivec_vreplace_un_v4sf (vf, float, const int<4>);
+ VREPLACE_UN_V4SF vreplace_un_v4sf {}
+
+ const vsi __builtin_altivec_vreplace_un_v4si (vsi, signed int, const int<4>);
+ VREPLACE_UN_V4SI vreplace_un_v4si {}
+
+ const vull __builtin_altivec_vreplace_uv2di (vull, unsigned long long, const int<1>);
+ VREPLACE_ELT_UV2DI vreplace_elt_v2di {}
+
+ const vui __builtin_altivec_vreplace_uv4si (vui, unsigned int, const int<2>);
+ VREPLACE_ELT_UV4SI vreplace_elt_v4si {}
+
+ const vd __builtin_altivec_vreplace_v2df (vd, double, const int<1>);
+ VREPLACE_ELT_V2DF vreplace_elt_v2df {}
+
+ const vsll __builtin_altivec_vreplace_v2di (vsll, signed long long, const int<1>);
+ VREPLACE_ELT_V2DI vreplace_elt_v2di {}
+
+ const vf __builtin_altivec_vreplace_v4sf (vf, float, const int<2>);
+ VREPLACE_ELT_V4SF vreplace_elt_v4sf {}
+
+ const vsi __builtin_altivec_vreplace_v4si (vsi, signed int, const int<2>);
+ VREPLACE_ELT_V4SI vreplace_elt_v4si {}
+
+ const vsq __builtin_altivec_vrlq (vsq, vuq);
+ VRLQ vrotlv1ti3 {}
+
+ const vsq __builtin_altivec_vrlqmi (vsq, vsq, vuq);
+ VRLQMI altivec_vrlqmi {}
+
+ const vsq __builtin_altivec_vrlqnm (vsq, vuq);
+ VRLQNM altivec_vrlqnm {}
+
+ const vsq __builtin_altivec_vsignext (vsll);
+ VSIGNEXTSD2Q vsignextend_v2di_v1ti {}
+
+ const vsc __builtin_altivec_vsldb_v16qi (vsc, vsc, const int<3>);
+ VSLDB_V16QI vsldb_v16qi {}
+
+ const vsll __builtin_altivec_vsldb_v2di (vsll, vsll, const int<3>);
+ VSLDB_V2DI vsldb_v2di {}
+
+ const vsi __builtin_altivec_vsldb_v4si (vsi, vsi, const int<3>);
+ VSLDB_V4SI vsldb_v4si {}
+
+ const vss __builtin_altivec_vsldb_v8hi (vss, vss, const int<3>);
+ VSLDB_V8HI vsldb_v8hi {}
+
+ const vsq __builtin_altivec_vslq (vsq, vuq);
+ VSLQ vashlv1ti3 {}
+
+ const vsq __builtin_altivec_vsraq (vsq, vuq);
+ VSRAQ vashrv1ti3 {}
+
+ const vsc __builtin_altivec_vsrdb_v16qi (vsc, vsc, const int<3>);
+ VSRDB_V16QI vsrdb_v16qi {}
+
+ const vsll __builtin_altivec_vsrdb_v2di (vsll, vsll, const int<3>);
+ VSRDB_V2DI vsrdb_v2di {}
+
+ const vsi __builtin_altivec_vsrdb_v4si (vsi, vsi, const int<3>);
+ VSRDB_V4SI vsrdb_v4si {}
+
+ const vss __builtin_altivec_vsrdb_v8hi (vss, vss, const int<3>);
+ VSRDB_V8HI vsrdb_v8hi {}
+
+ const vsq __builtin_altivec_vsrq (vsq, vuq);
+ VSRQ vlshrv1ti3 {}
+
+ const vsc __builtin_altivec_vstribl (vsc);
+ VSTRIBL vstril_v16qi {}
+
+ const signed int __builtin_altivec_vstribl_p (vsc);
+ VSTRIBL_P vstril_p_v16qi {}
+
+ const vsc __builtin_altivec_vstribr (vsc);
+ VSTRIBR vstrir_v16qi {}
+
+ const signed int __builtin_altivec_vstribr_p (vsc);
+ VSTRIBR_P vstrir_p_v16qi {}
+
+ const vss __builtin_altivec_vstrihl (vss);
+ VSTRIHL vstril_v8hi {}
+
+ const signed int __builtin_altivec_vstrihl_p (vss);
+ VSTRIHL_P vstril_p_v8hi {}
+
+ const vss __builtin_altivec_vstrihr (vss);
+ VSTRIHR vstrir_v8hi {}
+
+ const signed int __builtin_altivec_vstrihr_p (vss);
+ VSTRIHR_P vstrir_p_v8hi {}
+
+ const signed int __builtin_vsx_xvtlsbb_all_ones (vsc);
+ XVTLSBB_ONES xvtlsbbo {}
+
+ const signed int __builtin_vsx_xvtlsbb_all_zeros (vsc);
+ XVTLSBB_ZEROS xvtlsbbz {}
+
+ const vf __builtin_vsx_vxxsplti32dx_v4sf (vf, const int<1>, float);
+ VXXSPLTI32DX_V4SF xxsplti32dx_v4sf {}
+
+ const vsi __builtin_vsx_vxxsplti32dx_v4si (vsi, const int<1>, signed int);
+ VXXSPLTI32DX_V4SI xxsplti32dx_v4si {}
+
+ const vd __builtin_vsx_vxxspltidp (float);
+ VXXSPLTIDP xxspltidp_v2df {}
+
+ const vf __builtin_vsx_vxxspltiw_v4sf (float);
+ VXXSPLTIW_V4SF xxspltiw_v4sf {}
+
+ const vsi __builtin_vsx_vxxspltiw_v4si (signed int);
+ VXXSPLTIW_V4SI xxspltiw_v4si {}
+
+ const vuc __builtin_vsx_xvcvbf16spn (vuc);
+ XVCVBF16SPN vsx_xvcvbf16spn {}
+
+ const vuc __builtin_vsx_xvcvspbf16 (vuc);
+ XVCVSPBF16 vsx_xvcvspbf16 {}
+
+ const vuc __builtin_vsx_xxblend_v16qi (vuc, vuc, vuc);
+ VXXBLEND_V16QI xxblend_v16qi {}
+
+ const vd __builtin_vsx_xxblend_v2df (vd, vd, vd);
+ VXXBLEND_V2DF xxblend_v2df {}
+
+ const vull __builtin_vsx_xxblend_v2di (vull, vull, vull);
+ VXXBLEND_V2DI xxblend_v2di {}
+
+ const vf __builtin_vsx_xxblend_v4sf (vf, vf, vf);
+ VXXBLEND_V4SF xxblend_v4sf {}
+
+ const vui __builtin_vsx_xxblend_v4si (vui, vui, vui);
+ VXXBLEND_V4SI xxblend_v4si {}
+
+ const vus __builtin_vsx_xxblend_v8hi (vus, vus, vus);
+ VXXBLEND_V8HI xxblend_v8hi {}
+
+ const vull __builtin_vsx_xxeval (vull, vull, vull, const int <8>);
+ XXEVAL xxeval {}
+
+ const vuc __builtin_vsx_xxgenpcvm_v16qi (vuc, const int <2>);
+ XXGENPCVM_V16QI xxgenpcvm_v16qi {}
+
+ const vull __builtin_vsx_xxgenpcvm_v2di (vull, const int <2>);
+ XXGENPCVM_V2DI xxgenpcvm_v2di {}
+
+ const vui __builtin_vsx_xxgenpcvm_v4si (vui, const int <2>);
+ XXGENPCVM_V4SI xxgenpcvm_v4si {}
+
+ const vus __builtin_vsx_xxgenpcvm_v8hi (vus, const int <2>);
+ XXGENPCVM_V8HI xxgenpcvm_v8hi {}
+
+ const vuc __builtin_vsx_xxpermx_uv16qi (vuc, vuc, vuc, const int<3>);
+ XXPERMX_UV16QI xxpermx {}
+
+ const vull __builtin_vsx_xxpermx_uv2di (vull, vull, vuc, const int<3>);
+ XXPERMX_UV2DI xxpermx {}
+
+ const vui __builtin_vsx_xxpermx_uv4si (vui, vui, vuc, const int<3>);
+ XXPERMX_UV4SI xxpermx {}
+
+ const vus __builtin_vsx_xxpermx_uv8hi (vus, vus, vuc, const int<3>);
+ XXPERMX_UV8HI xxpermx {}
+
+ const vsc __builtin_vsx_xxpermx_v16qi (vsc, vsc, vuc, const int<3>);
+ XXPERMX_V16QI xxpermx {}
+
+ const vd __builtin_vsx_xxpermx_v2df (vd, vd, vuc, const int<3>);
+ XXPERMX_V2DF xxpermx {}
+
+ const vsll __builtin_vsx_xxpermx_v2di (vsll, vsll, vuc, const int<3>);
+ XXPERMX_V2DI xxpermx {}
+
+ const vf __builtin_vsx_xxpermx_v4sf (vf, vf, vuc, const int<3>);
+ XXPERMX_V4SF xxpermx {}
+
+ const vsi __builtin_vsx_xxpermx_v4si (vsi, vsi, vuc, const int<3>);
+ XXPERMX_V4SI xxpermx {}
+
+ const vss __builtin_vsx_xxpermx_v8hi (vss, vss, vuc, const int<3>);
+ XXPERMX_V8HI xxpermx {}
+
+ pure unsigned __int128 __builtin_altivec_ze_lxvrbx (signed long, const unsigned char *);
+ ZE_LXVRBX vsx_lxvrbx {lxvrze}
+
+ pure unsigned __int128 __builtin_altivec_ze_lxvrhx (signed long, const unsigned short *);
+ ZE_LXVRHX vsx_lxvrhx {lxvrze}
+
+ pure unsigned __int128 __builtin_altivec_ze_lxvrwx (signed long, const unsigned int *);
+ ZE_LXVRWX vsx_lxvrwx {lxvrze}
+
+ pure unsigned __int128 __builtin_altivec_ze_lxvrdx (signed long, const unsigned long long *);
+ ZE_LXVRDX vsx_lxvrdx {lxvrze}
+
+
+[power10-64]
+ const unsigned long long __builtin_cfuged (unsigned long long, unsigned long long);
+ CFUGED cfuged {}
+
+ const unsigned long long __builtin_cntlzdm (unsigned long long, unsigned long long);
+ CNTLZDM cntlzdm {}
+
+ const unsigned long long __builtin_cnttzdm (unsigned long long, unsigned long long);
+ CNTTZDM cnttzdm {}
+
+ const unsigned long long __builtin_pdepd (unsigned long long, unsigned long long);
+ PDEPD pdepd {}
+
+ const unsigned long long __builtin_pextd (unsigned long long, unsigned long long);
+ PEXTD pextd {}
diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index 3c3108a..fd7f24d 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -13294,6 +13294,7 @@ rs6000_init_builtins (void)
{
tree tdecl;
tree ftype;
+ tree t;
machine_mode mode;
if (TARGET_DEBUG_BUILTIN)
@@ -13304,25 +13305,63 @@ rs6000_init_builtins (void)
V2DI_type_node = rs6000_vector_type (TARGET_POWERPC64 ? "__vector long"
: "__vector long long",
long_long_integer_type_node, 2);
+ ptr_V2DI_type_node
+ = build_pointer_type (build_qualified_type (V2DI_type_node,
+ TYPE_QUAL_CONST));
+
V2DF_type_node = rs6000_vector_type ("__vector double", double_type_node, 2);
+ ptr_V2DF_type_node
+ = build_pointer_type (build_qualified_type (V2DF_type_node,
+ TYPE_QUAL_CONST));
+
V4SI_type_node = rs6000_vector_type ("__vector signed int",
intSI_type_node, 4);
+ ptr_V4SI_type_node
+ = build_pointer_type (build_qualified_type (V4SI_type_node,
+ TYPE_QUAL_CONST));
+
V4SF_type_node = rs6000_vector_type ("__vector float", float_type_node, 4);
+ ptr_V4SF_type_node
+ = build_pointer_type (build_qualified_type (V4SF_type_node,
+ TYPE_QUAL_CONST));
+
V8HI_type_node = rs6000_vector_type ("__vector signed short",
intHI_type_node, 8);
+ ptr_V8HI_type_node
+ = build_pointer_type (build_qualified_type (V8HI_type_node,
+ TYPE_QUAL_CONST));
+
V16QI_type_node = rs6000_vector_type ("__vector signed char",
intQI_type_node, 16);
+ ptr_V16QI_type_node
+ = build_pointer_type (build_qualified_type (V16QI_type_node,
+ TYPE_QUAL_CONST));
unsigned_V16QI_type_node = rs6000_vector_type ("__vector unsigned char",
unsigned_intQI_type_node, 16);
+ ptr_unsigned_V16QI_type_node
+ = build_pointer_type (build_qualified_type (unsigned_V16QI_type_node,
+ TYPE_QUAL_CONST));
+
unsigned_V8HI_type_node = rs6000_vector_type ("__vector unsigned short",
unsigned_intHI_type_node, 8);
+ ptr_unsigned_V8HI_type_node
+ = build_pointer_type (build_qualified_type (unsigned_V8HI_type_node,
+ TYPE_QUAL_CONST));
+
unsigned_V4SI_type_node = rs6000_vector_type ("__vector unsigned int",
unsigned_intSI_type_node, 4);
+ ptr_unsigned_V4SI_type_node
+ = build_pointer_type (build_qualified_type (unsigned_V4SI_type_node,
+ TYPE_QUAL_CONST));
+
unsigned_V2DI_type_node = rs6000_vector_type (TARGET_POWERPC64
? "__vector unsigned long"
: "__vector unsigned long long",
long_long_unsigned_type_node, 2);
+ ptr_unsigned_V2DI_type_node
+ = build_pointer_type (build_qualified_type (unsigned_V2DI_type_node,
+ TYPE_QUAL_CONST));
opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
@@ -13336,9 +13375,15 @@ rs6000_init_builtins (void)
{
V1TI_type_node = rs6000_vector_type ("__vector __int128",
intTI_type_node, 1);
+ ptr_V1TI_type_node
+ = build_pointer_type (build_qualified_type (V1TI_type_node,
+ TYPE_QUAL_CONST));
unsigned_V1TI_type_node
= rs6000_vector_type ("__vector unsigned __int128",
unsigned_intTI_type_node, 1);
+ ptr_unsigned_V1TI_type_node
+ = build_pointer_type (build_qualified_type (unsigned_V1TI_type_node,
+ TYPE_QUAL_CONST));
}
/* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
@@ -13372,6 +13417,76 @@ rs6000_init_builtins (void)
dfloat128_type_internal_node = dfloat128_type_node;
void_type_internal_node = void_type_node;
+ ptr_intQI_type_node
+ = build_pointer_type (build_qualified_type (intQI_type_internal_node,
+ TYPE_QUAL_CONST));
+ ptr_uintQI_type_node
+ = build_pointer_type (build_qualified_type (uintQI_type_internal_node,
+ TYPE_QUAL_CONST));
+ ptr_intHI_type_node
+ = build_pointer_type (build_qualified_type (intHI_type_internal_node,
+ TYPE_QUAL_CONST));
+ ptr_uintHI_type_node
+ = build_pointer_type (build_qualified_type (uintHI_type_internal_node,
+ TYPE_QUAL_CONST));
+ ptr_intSI_type_node
+ = build_pointer_type (build_qualified_type (intSI_type_internal_node,
+ TYPE_QUAL_CONST));
+ ptr_uintSI_type_node
+ = build_pointer_type (build_qualified_type (uintSI_type_internal_node,
+ TYPE_QUAL_CONST));
+ ptr_intDI_type_node
+ = build_pointer_type (build_qualified_type (intDI_type_internal_node,
+ TYPE_QUAL_CONST));
+ ptr_uintDI_type_node
+ = build_pointer_type (build_qualified_type (uintDI_type_internal_node,
+ TYPE_QUAL_CONST));
+ ptr_intTI_type_node
+ = build_pointer_type (build_qualified_type (intTI_type_internal_node,
+ TYPE_QUAL_CONST));
+ ptr_uintTI_type_node
+ = build_pointer_type (build_qualified_type (uintTI_type_internal_node,
+ TYPE_QUAL_CONST));
+
+ t = build_qualified_type (long_integer_type_internal_node, TYPE_QUAL_CONST);
+ ptr_long_integer_type_node = build_pointer_type (t);
+
+ t = build_qualified_type (long_unsigned_type_internal_node, TYPE_QUAL_CONST);
+ ptr_long_unsigned_type_node = build_pointer_type (t);
+
+ ptr_float_type_node
+ = build_pointer_type (build_qualified_type (float_type_internal_node,
+ TYPE_QUAL_CONST));
+ ptr_double_type_node
+ = build_pointer_type (build_qualified_type (double_type_internal_node,
+ TYPE_QUAL_CONST));
+ ptr_long_double_type_node
+ = build_pointer_type (build_qualified_type (long_double_type_internal_node,
+ TYPE_QUAL_CONST));
+ if (dfloat64_type_node)
+ {
+ t = build_qualified_type (dfloat64_type_internal_node, TYPE_QUAL_CONST);
+ ptr_dfloat64_type_node = build_pointer_type (t);
+ }
+ else
+ ptr_dfloat64_type_node = NULL;
+
+ if (dfloat128_type_node)
+ {
+ t = build_qualified_type (dfloat128_type_internal_node, TYPE_QUAL_CONST);
+ ptr_dfloat128_type_node = build_pointer_type (t);
+ }
+ else
+ ptr_dfloat128_type_node = NULL;
+
+ t = build_qualified_type (long_long_integer_type_internal_node,
+ TYPE_QUAL_CONST);
+ ptr_long_long_integer_type_node = build_pointer_type (t);
+
+ t = build_qualified_type (long_long_unsigned_type_internal_node,
+ TYPE_QUAL_CONST);
+ ptr_long_long_unsigned_type_node = build_pointer_type (t);
+
/* 128-bit floating point support. KFmode is IEEE 128-bit floating point.
IFmode is the IBM extended 128-bit format that is a pair of doubles.
TFmode will be either IEEE 128-bit floating point or the IBM double-double
@@ -13399,7 +13514,8 @@ rs6000_init_builtins (void)
SET_TYPE_MODE (ibm128_float_type_node, IFmode);
layout_type (ibm128_float_type_node);
}
-
+ t = build_qualified_type (ibm128_float_type_node, TYPE_QUAL_CONST);
+ ptr_ibm128_float_type_node = build_pointer_type (t);
lang_hooks.types.register_builtin_type (ibm128_float_type_node,
"__ibm128");
@@ -13407,7 +13523,8 @@ rs6000_init_builtins (void)
ieee128_float_type_node = long_double_type_node;
else
ieee128_float_type_node = float128_type_node;
-
+ t = build_qualified_type (ieee128_float_type_node, TYPE_QUAL_CONST);
+ ptr_ieee128_float_type_node = build_pointer_type (t);
lang_hooks.types.register_builtin_type (ieee128_float_type_node,
"__ieee128");
}
@@ -13427,6 +13544,8 @@ rs6000_init_builtins (void)
TYPE_USER_ALIGN (vector_pair_type_node) = 0;
lang_hooks.types.register_builtin_type (vector_pair_type_node,
"__vector_pair");
+ t = build_qualified_type (vector_pair_type_node, TYPE_QUAL_CONST);
+ ptr_vector_pair_type_node = build_pointer_type (t);
vector_quad_type_node = make_node (OPAQUE_TYPE);
SET_TYPE_MODE (vector_quad_type_node, XOmode);
@@ -13437,6 +13556,8 @@ rs6000_init_builtins (void)
TYPE_USER_ALIGN (vector_quad_type_node) = 0;
lang_hooks.types.register_builtin_type (vector_quad_type_node,
"__vector_quad");
+ t = build_qualified_type (vector_quad_type_node, TYPE_QUAL_CONST);
+ ptr_vector_quad_type_node = build_pointer_type (t);
}
/* Initialize the modes for builtin_function_type, mapping a machine mode to
@@ -13487,18 +13608,41 @@ rs6000_init_builtins (void)
bool_V16QI_type_node = rs6000_vector_type ("__vector __bool char",
bool_char_type_node, 16);
+ ptr_bool_V16QI_type_node
+ = build_pointer_type (build_qualified_type (bool_V16QI_type_node,
+ TYPE_QUAL_CONST));
+
bool_V8HI_type_node = rs6000_vector_type ("__vector __bool short",
bool_short_type_node, 8);
+ ptr_bool_V8HI_type_node
+ = build_pointer_type (build_qualified_type (bool_V8HI_type_node,
+ TYPE_QUAL_CONST));
+
bool_V4SI_type_node = rs6000_vector_type ("__vector __bool int",
bool_int_type_node, 4);
+ ptr_bool_V4SI_type_node
+ = build_pointer_type (build_qualified_type (bool_V4SI_type_node,
+ TYPE_QUAL_CONST));
+
bool_V2DI_type_node = rs6000_vector_type (TARGET_POWERPC64
? "__vector __bool long"
: "__vector __bool long long",
bool_long_long_type_node, 2);
+ ptr_bool_V2DI_type_node
+ = build_pointer_type (build_qualified_type (bool_V2DI_type_node,
+ TYPE_QUAL_CONST));
+
bool_V1TI_type_node = rs6000_vector_type ("__vector __bool __int128",
intTI_type_node, 1);
+ ptr_bool_V1TI_type_node
+ = build_pointer_type (build_qualified_type (bool_V1TI_type_node,
+ TYPE_QUAL_CONST));
+
pixel_V8HI_type_node = rs6000_vector_type ("__vector __pixel",
pixel_type_node, 8);
+ ptr_pixel_V8HI_type_node
+ = build_pointer_type (build_qualified_type (pixel_V8HI_type_node,
+ TYPE_QUAL_CONST));
pcvoid_type_node
= build_pointer_type (build_qualified_type (void_type_node,
TYPE_QUAL_CONST));
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index c5d20d2..3eba1c0 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -2461,6 +2461,47 @@ enum rs6000_builtin_type_index
RS6000_BTI_vector_pair, /* unsigned 256-bit types (vector pair). */
RS6000_BTI_vector_quad, /* unsigned 512-bit types (vector quad). */
RS6000_BTI_const_ptr_void, /* const pointer to void */
+ RS6000_BTI_ptr_V16QI,
+ RS6000_BTI_ptr_V1TI,
+ RS6000_BTI_ptr_V2DI,
+ RS6000_BTI_ptr_V2DF,
+ RS6000_BTI_ptr_V4SI,
+ RS6000_BTI_ptr_V4SF,
+ RS6000_BTI_ptr_V8HI,
+ RS6000_BTI_ptr_unsigned_V16QI,
+ RS6000_BTI_ptr_unsigned_V1TI,
+ RS6000_BTI_ptr_unsigned_V8HI,
+ RS6000_BTI_ptr_unsigned_V4SI,
+ RS6000_BTI_ptr_unsigned_V2DI,
+ RS6000_BTI_ptr_bool_V16QI,
+ RS6000_BTI_ptr_bool_V8HI,
+ RS6000_BTI_ptr_bool_V4SI,
+ RS6000_BTI_ptr_bool_V2DI,
+ RS6000_BTI_ptr_bool_V1TI,
+ RS6000_BTI_ptr_pixel_V8HI,
+ RS6000_BTI_ptr_INTQI,
+ RS6000_BTI_ptr_UINTQI,
+ RS6000_BTI_ptr_INTHI,
+ RS6000_BTI_ptr_UINTHI,
+ RS6000_BTI_ptr_INTSI,
+ RS6000_BTI_ptr_UINTSI,
+ RS6000_BTI_ptr_INTDI,
+ RS6000_BTI_ptr_UINTDI,
+ RS6000_BTI_ptr_INTTI,
+ RS6000_BTI_ptr_UINTTI,
+ RS6000_BTI_ptr_long_integer,
+ RS6000_BTI_ptr_long_unsigned,
+ RS6000_BTI_ptr_float,
+ RS6000_BTI_ptr_double,
+ RS6000_BTI_ptr_long_double,
+ RS6000_BTI_ptr_dfloat64,
+ RS6000_BTI_ptr_dfloat128,
+ RS6000_BTI_ptr_ieee128_float,
+ RS6000_BTI_ptr_ibm128_float,
+ RS6000_BTI_ptr_vector_pair,
+ RS6000_BTI_ptr_vector_quad,
+ RS6000_BTI_ptr_long_long,
+ RS6000_BTI_ptr_long_long_unsigned,
RS6000_BTI_MAX
};
@@ -2517,6 +2558,47 @@ enum rs6000_builtin_type_index
#define vector_pair_type_node (rs6000_builtin_types[RS6000_BTI_vector_pair])
#define vector_quad_type_node (rs6000_builtin_types[RS6000_BTI_vector_quad])
#define pcvoid_type_node (rs6000_builtin_types[RS6000_BTI_const_ptr_void])
+#define ptr_V16QI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_V16QI])
+#define ptr_V1TI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_V1TI])
+#define ptr_V2DI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_V2DI])
+#define ptr_V2DF_type_node (rs6000_builtin_types[RS6000_BTI_ptr_V2DF])
+#define ptr_V4SI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_V4SI])
+#define ptr_V4SF_type_node (rs6000_builtin_types[RS6000_BTI_ptr_V4SF])
+#define ptr_V8HI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_V8HI])
+#define ptr_unsigned_V16QI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_unsigned_V16QI])
+#define ptr_unsigned_V1TI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_unsigned_V1TI])
+#define ptr_unsigned_V8HI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_unsigned_V8HI])
+#define ptr_unsigned_V4SI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_unsigned_V4SI])
+#define ptr_unsigned_V2DI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_unsigned_V2DI])
+#define ptr_bool_V16QI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_bool_V16QI])
+#define ptr_bool_V8HI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_bool_V8HI])
+#define ptr_bool_V4SI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_bool_V4SI])
+#define ptr_bool_V2DI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_bool_V2DI])
+#define ptr_bool_V1TI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_bool_V1TI])
+#define ptr_pixel_V8HI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_pixel_V8HI])
+#define ptr_intQI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_INTQI])
+#define ptr_uintQI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_UINTQI])
+#define ptr_intHI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_INTHI])
+#define ptr_uintHI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_UINTHI])
+#define ptr_intSI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_INTSI])
+#define ptr_uintSI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_UINTSI])
+#define ptr_intDI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_INTDI])
+#define ptr_uintDI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_UINTDI])
+#define ptr_intTI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_INTTI])
+#define ptr_uintTI_type_node (rs6000_builtin_types[RS6000_BTI_ptr_UINTTI])
+#define ptr_long_integer_type_node (rs6000_builtin_types[RS6000_BTI_ptr_long_integer])
+#define ptr_long_unsigned_type_node (rs6000_builtin_types[RS6000_BTI_ptr_long_unsigned])
+#define ptr_float_type_node (rs6000_builtin_types[RS6000_BTI_ptr_float])
+#define ptr_double_type_node (rs6000_builtin_types[RS6000_BTI_ptr_double])
+#define ptr_long_double_type_node (rs6000_builtin_types[RS6000_BTI_ptr_long_double])
+#define ptr_dfloat64_type_node (rs6000_builtin_types[RS6000_BTI_ptr_dfloat64])
+#define ptr_dfloat128_type_node (rs6000_builtin_types[RS6000_BTI_ptr_dfloat128])
+#define ptr_ieee128_float_type_node (rs6000_builtin_types[RS6000_BTI_ptr_ieee128_float])
+#define ptr_ibm128_float_type_node (rs6000_builtin_types[RS6000_BTI_ptr_ibm128_float])
+#define ptr_vector_pair_type_node (rs6000_builtin_types[RS6000_BTI_ptr_vector_pair])
+#define ptr_vector_quad_type_node (rs6000_builtin_types[RS6000_BTI_ptr_vector_quad])
+#define ptr_long_long_integer_type_node (rs6000_builtin_types[RS6000_BTI_ptr_long_long])
+#define ptr_long_long_unsigned_type_node (rs6000_builtin_types[RS6000_BTI_ptr_long_long_unsigned])
extern GTY(()) tree rs6000_builtin_types[RS6000_BTI_MAX];
extern GTY(()) tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];
diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md
index e4ca6e9..bf033e3 100644
--- a/gcc/config/rs6000/vsx.md
+++ b/gcc/config/rs6000/vsx.md
@@ -374,7 +374,7 @@
UNSPEC_VDIVEU
UNSPEC_XXEVAL
UNSPEC_XXSPLTIW
- UNSPEC_XXSPLTID
+ UNSPEC_XXSPLTIDP
UNSPEC_XXSPLTI32DX
UNSPEC_XXBLEND
UNSPEC_XXPERMX
@@ -6414,7 +6414,7 @@
UNSPEC_XXSPLTIW))]
"TARGET_POWER10"
"xxspltiw %x0,%1"
- [(set_attr "type" "vecsimple")
+ [(set_attr "type" "vecperm")
(set_attr "prefixed" "yes")])
(define_expand "xxspltiw_v4sf"
@@ -6434,14 +6434,14 @@
UNSPEC_XXSPLTIW))]
"TARGET_POWER10"
"xxspltiw %x0,%1"
- [(set_attr "type" "vecsimple")
+ [(set_attr "type" "vecperm")
(set_attr "prefixed" "yes")])
;; XXSPLTIDP built-in function support
(define_expand "xxspltidp_v2df"
[(set (match_operand:V2DF 0 "register_operand" )
(unspec:V2DF [(match_operand:SF 1 "const_double_operand")]
- UNSPEC_XXSPLTID))]
+ UNSPEC_XXSPLTIDP))]
"TARGET_POWER10"
{
long value = rs6000_const_f32_to_i32 (operands[1]);
@@ -6452,10 +6452,10 @@
(define_insn "xxspltidp_v2df_inst"
[(set (match_operand:V2DF 0 "register_operand" "=wa")
(unspec:V2DF [(match_operand:SI 1 "c32bit_cint_operand" "n")]
- UNSPEC_XXSPLTID))]
+ UNSPEC_XXSPLTIDP))]
"TARGET_POWER10"
"xxspltidp %x0,%1"
- [(set_attr "type" "vecsimple")
+ [(set_attr "type" "vecperm")
(set_attr "prefixed" "yes")])
;; XXSPLTI32DX built-in function support
@@ -6476,7 +6476,7 @@
GEN_INT (index), operands[3]));
DONE;
}
- [(set_attr "type" "vecsimple")])
+ [(set_attr "type" "vecperm")])
(define_insn "xxsplti32dx_v4si_inst"
[(set (match_operand:V4SI 0 "register_operand" "=wa")
@@ -6486,7 +6486,7 @@
UNSPEC_XXSPLTI32DX))]
"TARGET_POWER10"
"xxsplti32dx %x0,%2,%3"
- [(set_attr "type" "vecsimple")
+ [(set_attr "type" "vecperm")
(set_attr "prefixed" "yes")])
(define_expand "xxsplti32dx_v4sf"
@@ -6515,7 +6515,7 @@
UNSPEC_XXSPLTI32DX))]
"TARGET_POWER10"
"xxsplti32dx %x0,%2,%3"
- [(set_attr "type" "vecsimple")
+ [(set_attr "type" "vecperm")
(set_attr "prefixed" "yes")])
;; XXBLEND built-in function support
@@ -6527,7 +6527,7 @@
UNSPEC_XXBLEND))]
"TARGET_POWER10"
"xxblendv<VM3_char> %x0,%x1,%x2,%x3"
- [(set_attr "type" "vecsimple")
+ [(set_attr "type" "vecperm")
(set_attr "prefixed" "yes")])
;; XXPERMX built-in function support
@@ -6562,7 +6562,7 @@
DONE;
}
- [(set_attr "type" "vecsimple")])
+ [(set_attr "type" "vecperm")])
(define_insn "xxpermx_inst"
[(set (match_operand:V2DI 0 "register_operand" "+v")
@@ -6573,7 +6573,7 @@
UNSPEC_XXPERMX))]
"TARGET_POWER10"
"xxpermx %x0,%x1,%x2,%x3,%4"
- [(set_attr "type" "vecsimple")
+ [(set_attr "type" "vecperm")
(set_attr "prefixed" "yes")])
;; XXEVAL built-in function support
@@ -6586,6 +6586,6 @@
UNSPEC_XXEVAL))]
"TARGET_POWER10"
"xxeval %0,%1,%2,%3,%4"
- [(set_attr "type" "vecsimple")
+ [(set_attr "type" "vecperm")
(set_attr "prefixed" "yes")])
diff --git a/gcc/coretypes.h b/gcc/coretypes.h
index 406572e..726fcad 100644
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -154,6 +154,7 @@ struct cl_option_handlers;
struct diagnostic_context;
class pretty_printer;
class diagnostic_event_id_t;
+typedef const char * (*diagnostic_input_charset_callback)(const char *);
template<typename T> struct array_traits;
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index ddea2a2..0b92ee4 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,15 @@
+2021-08-25 Andrew Pinski <apinski@marvell.com>
+
+ PR c++/66590
+ * cp-objcp-common.c (cxx_block_may_fallthru): Handle
+ CLEANUP_STMT for the case which will be try/finally.
+
+2021-08-25 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/102019
+ * init.c (build_value_init_noctor): Ignore unnamed zero-width
+ bitfields.
+
2021-08-23 Jakub Jelinek <jakub@redhat.com>
* parser.c (cp_parser_omp_clause_num_tasks,
diff --git a/gcc/cp/cp-objcp-common.c b/gcc/cp/cp-objcp-common.c
index 98fd962..28f2d7b 100644
--- a/gcc/cp/cp-objcp-common.c
+++ b/gcc/cp/cp-objcp-common.c
@@ -317,6 +317,15 @@ cxx_block_may_fallthru (const_tree stmt)
return true;
return block_may_fallthru (ELSE_CLAUSE (stmt));
+ case CLEANUP_STMT:
+ /* Just handle the try/finally cases. */
+ if (!CLEANUP_EH_ONLY (stmt))
+ {
+ return (block_may_fallthru (CLEANUP_BODY (stmt))
+ && block_may_fallthru (CLEANUP_EXPR (stmt)));
+ }
+ return true;
+
default:
return c_block_may_fallthru (stmt);
}
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 229c84e..1426f9a 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -427,6 +427,11 @@ build_value_init_noctor (tree type, tsubst_flags_t complain)
== NULL_TREE))
continue;
+ /* Ignore unnamed zero-width bitfields. */
+ if (DECL_UNNAMED_BIT_FIELD (field)
+ && integer_zerop (DECL_SIZE (field)))
+ continue;
+
/* We could skip vfields and fields of types with
user-defined constructors, but I think that won't improve
performance at all; it should be simpler in general just
diff --git a/gcc/d/ChangeLog b/gcc/d/ChangeLog
index 3bf2eec..db85ffc 100644
--- a/gcc/d/ChangeLog
+++ b/gcc/d/ChangeLog
@@ -1,3 +1,10 @@
+2021-08-25 Lewis Hyatt <lhyatt@gmail.com>
+
+ PR other/93067
+ * d-lang.cc (d_input_charset_callback): New function.
+ (d_init): Call new function
+ diagnostic_initialize_input_context().
+
2021-07-30 Iain Buclaw <ibuclaw@gdcproject.org>
* expr.cc (binary_op): Remove dead code.
diff --git a/gcc/d/d-lang.cc b/gcc/d/d-lang.cc
index 4386a48..fa29a46a 100644
--- a/gcc/d/d-lang.cc
+++ b/gcc/d/d-lang.cc
@@ -50,6 +50,7 @@ along with GCC; see the file COPYING3. If not see
#include "output.h"
#include "print-tree.h"
#include "debug.h"
+#include "input.h"
#include "d-tree.h"
#include "id.h"
@@ -362,6 +363,19 @@ d_option_lang_mask (void)
return CL_D;
}
+/* Implements input charset and BOM skipping configuration for
+ diagnostics. */
+static const char *d_input_charset_callback (const char * /*filename*/)
+{
+ /* TODO: The input charset is automatically determined by code in
+ dmd/dmodule.c based on the contents of the file. If this detection
+ logic were factored out and could be reused here, then we would be able
+ to return UTF-16 or UTF-32 as needed here. For now, we return always
+ NULL, which means no conversion is necessary, i.e. the input is assumed
+ to be UTF-8 when diagnostics read this file. */
+ return nullptr;
+}
+
/* Implements the lang_hooks.init routine for language D. */
static bool
@@ -373,6 +387,11 @@ d_init (void)
Expression::_init ();
Objc::_init ();
+ /* Diagnostics input init, to enable BOM skipping and
+ input charset conversion. */
+ diagnostic_initialize_input_context (global_dc,
+ d_input_charset_callback, true);
+
/* Back-end init. */
global_binding_level = ggc_cleared_alloc <binding_level> ();
current_binding_level = global_binding_level;
diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c
index 8361f68..b3afbea 100644
--- a/gcc/diagnostic.c
+++ b/gcc/diagnostic.c
@@ -293,6 +293,17 @@ diagnostic_urls_init (diagnostic_context *context, int value /*= -1 */)
= determine_url_format ((diagnostic_url_rule_t) value);
}
+/* Create the file_cache, if not already created, and tell it how to
+ translate files on input. */
+void diagnostic_initialize_input_context (diagnostic_context *context,
+ diagnostic_input_charset_callback ccb,
+ bool should_skip_bom)
+{
+ if (!context->m_file_cache)
+ context->m_file_cache = new file_cache;
+ context->m_file_cache->initialize_input_context (ccb, should_skip_bom);
+}
+
/* Do any cleaning up required after the last diagnostic is emitted. */
void
diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h
index 7227dae..f90d20a 100644
--- a/gcc/diagnostic.h
+++ b/gcc/diagnostic.h
@@ -446,6 +446,25 @@ extern void diagnostic_show_locus (diagnostic_context *,
diagnostic_t diagnostic_kind);
extern void diagnostic_show_any_path (diagnostic_context *, diagnostic_info *);
+/* Because we read source files a second time after the frontend did it the
+ first time, we need to know how the frontend handled things like character
+ set conversion and UTF-8 BOM stripping, in order to make everything
+ consistent. This function needs to be called by each frontend that requires
+ non-default behavior, to inform the diagnostics infrastructure how input is
+ to be processed. The default behavior is to do no conversion and not to
+ strip a UTF-8 BOM.
+
+ The callback should return the input charset to be used to convert the given
+ file's contents to UTF-8, or it should return NULL if no conversion is needed
+ for this file. SHOULD_SKIP_BOM only applies in case no conversion was
+ performed, and if true, it will cause a UTF-8 BOM to be skipped at the
+ beginning of the file. (In case a conversion was performed, the BOM is
+ rather skipped as part of the conversion process.) */
+
+void diagnostic_initialize_input_context (diagnostic_context *context,
+ diagnostic_input_charset_callback ccb,
+ bool should_skip_bom);
+
/* Force diagnostics controlled by OPTIDX to be kind KIND. */
extern diagnostic_t diagnostic_classify_diagnostic (diagnostic_context *,
int /* optidx */,
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 671b9bf..f4f6121 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -2782,16 +2782,16 @@ On some targets the attributes also accept an integer argument to
specify a priority to control the order in which constructor and
destructor functions are run. A constructor
with a smaller priority number runs before a constructor with a larger
-priority number; the opposite relationship holds for destructors. So,
-if you have a constructor that allocates a resource and a destructor
-that deallocates the same resource, both functions typically have the
-same priority. The priorities for constructor and destructor
-functions are the same as those specified for namespace-scope C++
-objects (@pxref{C++ Attributes}). However, at present, the order in which
-constructors for C++ objects with static storage duration and functions
-decorated with attribute @code{constructor} are invoked is unspecified.
-In mixed declarations, attribute @code{init_priority} can be used to
-impose a specific ordering.
+priority number; the opposite relationship holds for destructors. Note
+that priorities 0-100 are reserved. So, if you have a constructor that
+allocates a resource and a destructor that deallocates the same
+resource, both functions typically have the same priority. The
+priorities for constructor and destructor functions are the same as
+those specified for namespace-scope C++ objects (@pxref{C++ Attributes}).
+However, at present, the order in which constructors for C++ objects
+with static storage duration and functions decorated with attribute
+@code{constructor} are invoked is unspecified. In mixed declarations,
+attribute @code{init_priority} can be used to impose a specific ordering.
Using the argument forms of the @code{constructor} and @code{destructor}
attributes on targets where the feature is not supported is rejected with
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 164f586..185b7d2 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -13386,6 +13386,10 @@ Setting to 0 disables the analysis completely.
@item modref-max-escape-points
Specifies the maximum number of escape points tracked by modref per SSA-name.
+@item modref-max-adjustments
+Specifies the maximum number the access range is enlarged during modref dataflow
+analysis.
+
@item profile-func-internal-id
A parameter to control whether to use function internal id in profile
database lookup. If the value is 0, the compiler uses an id that
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 307886d..9679f35 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,16 @@
+2021-08-25 Lewis Hyatt <lhyatt@gmail.com>
+
+ PR other/93067
+ * cpp.c (gfc_cpp_post_options): Call new function
+ diagnostic_initialize_input_context().
+
+2021-08-24 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/98411
+ * trans-decl.c (gfc_finish_var_decl): Adjust check to handle
+ implicit SAVE as well as variables in the main program. Improve
+ warning message text.
+
2021-08-23 Tobias Burnus <tobias@codesourcery.com>
* openmp.c (gfc_match_dupl_check, gfc_match_dupl_memorder,
diff --git a/gcc/fortran/cpp.c b/gcc/fortran/cpp.c
index 419cd6a..83c4517 100644
--- a/gcc/fortran/cpp.c
+++ b/gcc/fortran/cpp.c
@@ -493,6 +493,12 @@ gfc_cpp_post_options (void)
cpp_post_options (cpp_in);
+
+ /* Let diagnostics infrastructure know how to convert input files the same
+ way libcpp will do it, namely, with no charset conversion but with
+ skipping of a UTF-8 BOM if present. */
+ diagnostic_initialize_input_context (global_dc, nullptr, true);
+
gfc_cpp_register_include_paths ();
}
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index 784f7b6..bed61e2 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -743,8 +743,10 @@ gfc_finish_var_decl (tree decl, gfc_symbol * sym)
/* Keep variables larger than max-stack-var-size off stack. */
if (!(sym->ns->proc_name && sym->ns->proc_name->attr.recursive)
+ && !(sym->ns->proc_name && sym->ns->proc_name->attr.is_main_program)
&& !sym->attr.automatic
&& sym->attr.save != SAVE_EXPLICIT
+ && sym->attr.save != SAVE_IMPLICIT
&& INTEGER_CST_P (DECL_SIZE_UNIT (decl))
&& !gfc_can_put_var_on_stack (DECL_SIZE_UNIT (decl))
/* Put variable length auto array pointers always into stack. */
@@ -757,13 +759,17 @@ gfc_finish_var_decl (tree decl, gfc_symbol * sym)
{
if (flag_max_stack_var_size > 0)
gfc_warning (OPT_Wsurprising,
- "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 using %<-frecursive%>, or increase the"
- " %<-fmax-stack-var-size=%> limit, or change the code to"
- " use an ALLOCATABLE array.",
+ "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.",
sym->name, &sym->declared_at);
TREE_STATIC (decl) = 1;
diff --git a/gcc/gimple-range-cache.cc b/gcc/gimple-range-cache.cc
index 4138d05..facf981 100644
--- a/gcc/gimple-range-cache.cc
+++ b/gcc/gimple-range-cache.cc
@@ -628,20 +628,32 @@ ssa_global_cache::clear ()
void
ssa_global_cache::dump (FILE *f)
{
- unsigned x;
- int_range_max r;
- fprintf (f, "Non-varying global ranges:\n");
- fprintf (f, "=========================:\n");
- for ( x = 1; x < num_ssa_names; x++)
- if (gimple_range_ssa_p (ssa_name (x)) &&
- get_global_range (r, ssa_name (x)) && !r.varying_p ())
- {
- print_generic_expr (f, ssa_name (x), TDF_NONE);
- fprintf (f, " : ");
- r.dump (f);
- fprintf (f, "\n");
- }
- fputc ('\n', f);
+ /* Cleared after the table header has been printed. */
+ bool print_header = true;
+ for (unsigned x = 1; x < num_ssa_names; x++)
+ {
+ int_range_max r;
+ if (gimple_range_ssa_p (ssa_name (x)) &&
+ get_global_range (r, ssa_name (x)) && !r.varying_p ())
+ {
+ if (print_header)
+ {
+ /* Print the header only when there's something else
+ to print below. */
+ fprintf (f, "Non-varying global ranges:\n");
+ fprintf (f, "=========================:\n");
+ print_header = false;
+ }
+
+ print_generic_expr (f, ssa_name (x), TDF_NONE);
+ fprintf (f, " : ");
+ r.dump (f);
+ fprintf (f, "\n");
+ }
+ }
+
+ if (!print_header)
+ fputc ('\n', f);
}
// --------------------------------------------------------------------------
diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc
index ef3afea..d74cea3 100644
--- a/gcc/gimple-range.cc
+++ b/gcc/gimple-range.cc
@@ -259,16 +259,11 @@ gimple_ranger::range_of_stmt (irange &r, gimple *s, tree name)
void
gimple_ranger::export_global_ranges ()
{
- unsigned x;
- int_range_max r;
- if (dump_file)
- {
- fprintf (dump_file, "Exported global range table\n");
- fprintf (dump_file, "===========================\n");
- }
-
- for ( x = 1; x < num_ssa_names; x++)
+ /* Cleared after the table header has been printed. */
+ bool print_header = true;
+ for (unsigned x = 1; x < num_ssa_names; x++)
{
+ int_range_max r;
tree name = ssa_name (x);
if (name && !SSA_NAME_IN_FREE_LIST (name)
&& gimple_range_ssa_p (name)
@@ -276,21 +271,29 @@ gimple_ranger::export_global_ranges ()
&& !r.varying_p())
{
bool updated = update_global_range (r, name);
+ if (!updated || !dump_file || !(dump_flags & TDF_DETAILS))
+ continue;
- if (updated && dump_file)
+ if (print_header)
{
- value_range vr = r;
- print_generic_expr (dump_file, name , TDF_SLIM);
- fprintf (dump_file, " --> ");
- vr.dump (dump_file);
+ /* Print the header only when there's something else
+ to print below. */
+ fprintf (dump_file, "Exported global range table:\n");
+ fprintf (dump_file, "============================\n");
+ print_header = false;
+ }
+
+ value_range vr = r;
+ print_generic_expr (dump_file, name , TDF_SLIM);
+ fprintf (dump_file, " : ");
+ vr.dump (dump_file);
+ fprintf (dump_file, "\n");
+ int_range_max same = vr;
+ if (same != r)
+ {
+ fprintf (dump_file, " irange : ");
+ r.dump (dump_file);
fprintf (dump_file, "\n");
- int_range_max same = vr;
- if (same != r)
- {
- fprintf (dump_file, " irange : ");
- r.dump (dump_file);
- fprintf (dump_file, "\n");
- }
}
}
}
diff --git a/gcc/gimple-ssa-warn-access.cc b/gcc/gimple-ssa-warn-access.cc
index 4a2dd9a..5df97a6 100644
--- a/gcc/gimple-ssa-warn-access.cc
+++ b/gcc/gimple-ssa-warn-access.cc
@@ -704,6 +704,15 @@ maybe_warn_for_bound (opt_code opt, location_t loc, GimpleOrTree exp, tree func,
if (opt == OPT_Wstringop_overread)
{
bool maybe = pad && pad->src.phi ();
+ if (maybe)
+ {
+ /* Issue a "maybe" warning only if the PHI refers to objects
+ at least one of which has more space remaining than the bound.
+ Otherwise, if the bound is greater, use the definitive form. */
+ offset_int remmax = pad->src.size_remaining ();
+ if (remmax < wi::to_offset (bndrng[0]))
+ maybe = false;
+ }
if (tree_int_cst_lt (maxobjsize, bndrng[0]))
{
@@ -788,6 +797,15 @@ maybe_warn_for_bound (opt_code opt, location_t loc, GimpleOrTree exp, tree func,
}
bool maybe = pad && pad->dst.phi ();
+ if (maybe)
+ {
+ /* Issue a "maybe" warning only if the PHI refers to objects
+ at least one of which has more space remaining than the bound.
+ Otherwise, if the bound is greater, use the definitive form. */
+ offset_int remmax = pad->dst.size_remaining ();
+ if (remmax < wi::to_offset (bndrng[0]))
+ maybe = false;
+ }
if (tree_int_cst_lt (maxobjsize, bndrng[0]))
{
if (bndrng[0] == bndrng[1])
@@ -1418,7 +1436,7 @@ check_access (GimpleOrTree exp, tree dstwrite,
location_t loc = get_location (exp);
tree size = dstsize;
if (pad && pad->mode == access_read_only)
- size = wide_int_to_tree (sizetype, pad->src.sizrng[1]);
+ size = wide_int_to_tree (sizetype, pad->src.size_remaining ());
if (range[0] && maxread && tree_fits_uhwi_p (size))
{
diff --git a/gcc/input.c b/gcc/input.c
index de20d98..4b80986 100644
--- a/gcc/input.c
+++ b/gcc/input.c
@@ -22,7 +22,6 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h"
#include "intl.h"
#include "diagnostic.h"
-#include "diagnostic-core.h"
#include "selftest.h"
#include "cpplib.h"
@@ -30,6 +29,20 @@ along with GCC; see the file COPYING3. If not see
#define HAVE_ICONV 0
#endif
+/* Input charset configuration. */
+static const char *default_charset_callback (const char *)
+{
+ return nullptr;
+}
+
+void
+file_cache::initialize_input_context (diagnostic_input_charset_callback ccb,
+ bool should_skip_bom)
+{
+ in_context.ccb = (ccb ? ccb : default_charset_callback);
+ in_context.should_skip_bom = should_skip_bom;
+}
+
/* This is a cache used by get_next_line to store the content of a
file to be searched for file lines. */
class file_cache_slot
@@ -51,7 +64,8 @@ public:
void inc_use_count () { m_use_count++; }
- void create (const char *file_path, FILE *fp, unsigned highest_use_count);
+ bool create (const file_cache::input_context &in_context,
+ const char *file_path, FILE *fp, unsigned highest_use_count);
void evict ();
private:
@@ -110,6 +124,10 @@ public:
far. */
char *m_data;
+ /* The allocated buffer to be freed may start a little earlier than DATA,
+ e.g. if a UTF8 BOM was skipped at the beginning. */
+ int m_alloc_offset;
+
/* The size of the DATA array above.*/
size_t m_size;
@@ -147,6 +165,17 @@ public:
doesn't explode. We thus scale total_lines down to
line_record_size. */
vec<line_info, va_heap> m_line_record;
+
+ void offset_buffer (int offset)
+ {
+ gcc_assert (offset < 0 ? m_alloc_offset + offset >= 0
+ : (size_t) offset <= m_size);
+ gcc_assert (m_data);
+ m_alloc_offset += offset;
+ m_data += offset;
+ m_size -= offset;
+ }
+
};
/* Current position in real source file. */
@@ -419,21 +448,25 @@ file_cache::add_file (const char *file_path)
unsigned highest_use_count = 0;
file_cache_slot *r = evicted_cache_tab_entry (&highest_use_count);
- r->create (file_path, fp, highest_use_count);
+ if (!r->create (in_context, file_path, fp, highest_use_count))
+ return NULL;
return r;
}
/* Populate this slot for use on FILE_PATH and FP, dropping any
existing cached content within it. */
-void
-file_cache_slot::create (const char *file_path, FILE *fp,
+bool
+file_cache_slot::create (const file_cache::input_context &in_context,
+ const char *file_path, FILE *fp,
unsigned highest_use_count)
{
m_file_path = file_path;
if (m_fp)
fclose (m_fp);
m_fp = fp;
+ if (m_alloc_offset)
+ offset_buffer (-m_alloc_offset);
m_nb_read = 0;
m_line_start_idx = 0;
m_line_num = 0;
@@ -443,6 +476,36 @@ file_cache_slot::create (const char *file_path, FILE *fp,
m_use_count = ++highest_use_count;
m_total_lines = total_lines_num (file_path);
m_missing_trailing_newline = true;
+
+
+ /* Check the input configuration to determine if we need to do any
+ transformations, such as charset conversion or BOM skipping. */
+ if (const char *input_charset = in_context.ccb (file_path))
+ {
+ /* Need a full-blown conversion of the input charset. */
+ fclose (m_fp);
+ m_fp = NULL;
+ const cpp_converted_source cs
+ = cpp_get_converted_source (file_path, input_charset);
+ if (!cs.data)
+ return false;
+ if (m_data)
+ XDELETEVEC (m_data);
+ m_data = cs.data;
+ m_nb_read = m_size = cs.len;
+ m_alloc_offset = cs.data - cs.to_free;
+ }
+ else if (in_context.should_skip_bom)
+ {
+ if (read_data ())
+ {
+ const int offset = cpp_check_utf8_bom (m_data, m_nb_read);
+ offset_buffer (offset);
+ m_nb_read -= offset;
+ }
+ }
+
+ return true;
}
/* file_cache's ctor. */
@@ -450,6 +513,7 @@ file_cache_slot::create (const char *file_path, FILE *fp,
file_cache::file_cache ()
: m_file_slots (new file_cache_slot[num_file_slots])
{
+ initialize_input_context (nullptr, false);
}
/* file_cache's dtor. */
@@ -478,8 +542,8 @@ file_cache::lookup_or_add_file (const char *file_path)
file_cache_slot::file_cache_slot ()
: m_use_count (0), m_file_path (NULL), m_fp (NULL), m_data (0),
- m_size (0), m_nb_read (0), m_line_start_idx (0), m_line_num (0),
- m_total_lines (0), m_missing_trailing_newline (true)
+ m_alloc_offset (0), m_size (0), m_nb_read (0), m_line_start_idx (0),
+ m_line_num (0), m_total_lines (0), m_missing_trailing_newline (true)
{
m_line_record.create (0);
}
@@ -495,6 +559,7 @@ file_cache_slot::~file_cache_slot ()
}
if (m_data)
{
+ offset_buffer (-m_alloc_offset);
XDELETEVEC (m_data);
m_data = 0;
}
@@ -509,7 +574,7 @@ file_cache_slot::~file_cache_slot ()
bool
file_cache_slot::needs_read_p () const
{
- return (m_nb_read == 0
+ return m_fp && (m_nb_read == 0
|| m_nb_read == m_size
|| (m_line_start_idx >= m_nb_read - 1));
}
@@ -531,9 +596,20 @@ file_cache_slot::maybe_grow ()
if (!needs_grow_p ())
return;
- size_t size = m_size == 0 ? buffer_size : m_size * 2;
- m_data = XRESIZEVEC (char, m_data, size);
- m_size = size;
+ if (!m_data)
+ {
+ gcc_assert (m_size == 0 && m_alloc_offset == 0);
+ m_size = buffer_size;
+ m_data = XNEWVEC (char, m_size);
+ }
+ else
+ {
+ const int offset = m_alloc_offset;
+ offset_buffer (-offset);
+ m_size *= 2;
+ m_data = XRESIZEVEC (char, m_data, m_size);
+ offset_buffer (offset);
+ }
}
/* Read more data into the cache. Extends the cache if need be.
@@ -632,7 +708,7 @@ file_cache_slot::get_next_line (char **line, ssize_t *line_len)
m_missing_trailing_newline = false;
}
- if (ferror (m_fp))
+ if (m_fp && ferror (m_fp))
return false;
/* At this point, we've found the end of the of line. It either
diff --git a/gcc/input.h b/gcc/input.h
index bbcec84..e688107 100644
--- a/gcc/input.h
+++ b/gcc/input.h
@@ -111,6 +111,15 @@ class file_cache
file_cache_slot *lookup_or_add_file (const char *file_path);
void forcibly_evict_file (const char *file_path);
+ /* See comments in diagnostic.h about the input conversion context. */
+ struct input_context
+ {
+ diagnostic_input_charset_callback ccb;
+ bool should_skip_bom;
+ };
+ void initialize_input_context (diagnostic_input_charset_callback ccb,
+ bool should_skip_bom);
+
private:
file_cache_slot *evicted_cache_tab_entry (unsigned *highest_use_count);
file_cache_slot *add_file (const char *file_path);
@@ -119,6 +128,7 @@ class file_cache
private:
static const size_t num_file_slots = 16;
file_cache_slot *m_file_slots;
+ input_context in_context;
};
extern expanded_location
diff --git a/gcc/ipa-modref-tree.c b/gcc/ipa-modref-tree.c
index 64e57f5..69395b0 100644
--- a/gcc/ipa-modref-tree.c
+++ b/gcc/ipa-modref-tree.c
@@ -41,7 +41,7 @@ test_insert_search_collapse ()
ASSERT_FALSE (t->every_base);
/* Insert into an empty tree. */
- t->insert (1, 2, a);
+ t->insert (1, 2, a, false);
ASSERT_NE (t->bases, NULL);
ASSERT_EQ (t->bases->length (), 1);
ASSERT_FALSE (t->every_base);
@@ -59,7 +59,7 @@ test_insert_search_collapse ()
ASSERT_EQ (ref_node->ref, 2);
/* Insert when base exists but ref does not. */
- t->insert (1, 3, a);
+ t->insert (1, 3, a, false);
ASSERT_NE (t->bases, NULL);
ASSERT_EQ (t->bases->length (), 1);
ASSERT_EQ (t->search (1), base_node);
@@ -72,7 +72,7 @@ test_insert_search_collapse ()
/* Insert when base and ref exist, but access is not dominated by nor
dominates other accesses. */
- t->insert (1, 2, a);
+ t->insert (1, 2, a, false);
ASSERT_EQ (t->bases->length (), 1);
ASSERT_EQ (t->search (1), base_node);
@@ -80,12 +80,12 @@ test_insert_search_collapse ()
ASSERT_NE (ref_node, NULL);
/* Insert when base and ref exist and access is dominated. */
- t->insert (1, 2, a);
+ t->insert (1, 2, a, false);
ASSERT_EQ (t->search (1), base_node);
ASSERT_EQ (base_node->search (2), ref_node);
/* Insert ref to trigger ref list collapse for base 1. */
- t->insert (1, 4, a);
+ t->insert (1, 4, a, false);
ASSERT_EQ (t->search (1), base_node);
ASSERT_EQ (base_node->refs, NULL);
ASSERT_EQ (base_node->search (2), NULL);
@@ -93,7 +93,7 @@ test_insert_search_collapse ()
ASSERT_TRUE (base_node->every_ref);
/* Further inserts to collapsed ref list are ignored. */
- t->insert (1, 5, a);
+ t->insert (1, 5, a, false);
ASSERT_EQ (t->search (1), base_node);
ASSERT_EQ (base_node->refs, NULL);
ASSERT_EQ (base_node->search (2), NULL);
@@ -101,13 +101,13 @@ test_insert_search_collapse ()
ASSERT_TRUE (base_node->every_ref);
/* Insert base to trigger base list collapse. */
- t->insert (5, 6, a);
+ t->insert (5, 6, a, false);
ASSERT_TRUE (t->every_base);
ASSERT_EQ (t->bases, NULL);
ASSERT_EQ (t->search (1), NULL);
/* Further inserts to collapsed base list are ignored. */
- t->insert (7, 8, a);
+ t->insert (7, 8, a, false);
ASSERT_TRUE (t->every_base);
ASSERT_EQ (t->bases, NULL);
ASSERT_EQ (t->search (1), NULL);
@@ -123,22 +123,22 @@ test_merge ()
modref_access_node a = unspecified_modref_access_node;
t1 = new modref_tree<alias_set_type>(3, 4, 1);
- t1->insert (1, 1, a);
- t1->insert (1, 2, a);
- t1->insert (1, 3, a);
- t1->insert (2, 1, a);
- t1->insert (3, 1, a);
+ t1->insert (1, 1, a, false);
+ t1->insert (1, 2, a, false);
+ t1->insert (1, 3, a, false);
+ t1->insert (2, 1, a, false);
+ t1->insert (3, 1, a, false);
t2 = new modref_tree<alias_set_type>(10, 10, 10);
- t2->insert (1, 2, a);
- t2->insert (1, 3, a);
- t2->insert (1, 4, a);
- t2->insert (3, 2, a);
- t2->insert (3, 3, a);
- t2->insert (3, 4, a);
- t2->insert (3, 5, a);
-
- t1->merge (t2, NULL);
+ t2->insert (1, 2, a, false);
+ t2->insert (1, 3, a, false);
+ t2->insert (1, 4, a, false);
+ t2->insert (3, 2, a, false);
+ t2->insert (3, 3, a, false);
+ t2->insert (3, 4, a, false);
+ t2->insert (3, 5, a, false);
+
+ t1->merge (t2, NULL, false);
ASSERT_FALSE (t1->every_base);
ASSERT_NE (t1->bases, NULL);
diff --git a/gcc/ipa-modref-tree.h b/gcc/ipa-modref-tree.h
index 2e26b75..6f6932f 100644
--- a/gcc/ipa-modref-tree.h
+++ b/gcc/ipa-modref-tree.h
@@ -34,6 +34,7 @@ along with GCC; see the file COPYING3. If not see
Again ref is an template to allow LTO streaming.
3) Access: this level represent info about individual accesses. Presently
we record whether access is through a dereference of a function parameter
+ and if so we record the access range.
*/
#ifndef GCC_MODREF_TREE_H
@@ -57,6 +58,9 @@ struct GTY(()) modref_access_node
a function parameter. */
int parm_index;
bool parm_offset_known;
+ /* Number of times interval was extended during dataflow.
+ This has to be limited in order to keep dataflow finite. */
+ unsigned char adjustments;
/* Return true if access node holds no useful info. */
bool useful_p () const
@@ -84,6 +88,8 @@ struct GTY(()) modref_access_node
&& !known_eq (parm_offset, a.parm_offset))
return false;
}
+ if (range_info_useful_p () != a.range_info_useful_p ())
+ return false;
if (range_info_useful_p ()
&& (!known_eq (a.offset, offset)
|| !known_eq (a.size, size)
@@ -92,16 +98,24 @@ struct GTY(()) modref_access_node
return true;
}
/* Return true A is a subaccess. */
- bool contains (modref_access_node &a) const
+ bool contains (const modref_access_node &a) const
{
- if (parm_index != a.parm_index)
- return false;
+ poly_int64 aoffset_adj = 0;
if (parm_index >= 0)
{
- if (parm_offset_known
- && (!a.parm_offset_known
- || !known_eq (parm_offset, a.parm_offset)))
+ if (parm_index != a.parm_index)
return false;
+ if (parm_offset_known)
+ {
+ if (!a.parm_offset_known)
+ return false;
+ /* Accesses are never below parm_offset, so look
+ for smaller offset. */
+ if (!known_le (parm_offset, a.parm_offset))
+ return false;
+ aoffset_adj = (a.parm_offset - parm_offset)
+ << LOG2_BITS_PER_UNIT;
+ }
}
if (range_info_useful_p ())
{
@@ -111,20 +125,181 @@ struct GTY(()) modref_access_node
to fit the store, so smaller or unknown sotre is more general
than large store. */
if (known_size_p (size)
- && !known_le (size, a.size))
+ && (!known_size_p (a.size)
+ || !known_le (size, a.size)))
return false;
if (known_size_p (max_size))
- return known_subrange_p (a.offset, a.max_size, offset, max_size);
+ return known_subrange_p (a.offset + aoffset_adj,
+ a.max_size, offset, max_size);
else
- return known_le (offset, a.offset);
+ return known_le (offset, a.offset + aoffset_adj);
}
return true;
}
+ /* Update access range to new parameters.
+ If RECORD_ADJUSTMENTS is true, record number of changes in the access
+ and if threshold is exceeded start dropping precision
+ so only constantly many updates are possible. This makes dataflow
+ to converge. */
+ void update (poly_int64 parm_offset1,
+ poly_int64 offset1, poly_int64 size1, poly_int64 max_size1,
+ bool record_adjustments)
+ {
+ if (known_eq (offset, offset1)
+ && known_eq (size, size1)
+ && known_eq (max_size, max_size1))
+ return;
+ if (!record_adjustments
+ || (++adjustments) < param_modref_max_adjustments)
+ {
+ parm_offset = parm_offset1;
+ offset = offset1;
+ size = size1;
+ max_size = max_size1;
+ }
+ else
+ {
+ if (dump_file)
+ fprintf (dump_file,
+ "--param param=modref-max-adjustments limit reached:");
+ if (!known_eq (parm_offset, parm_offset1))
+ {
+ if (dump_file)
+ fprintf (dump_file, " parm_offset cleared");
+ parm_offset_known = false;
+ }
+ if (!known_eq (size, size1))
+ {
+ size = -1;
+ if (dump_file)
+ fprintf (dump_file, " size cleared");
+ }
+ if (!known_eq (max_size, max_size1))
+ {
+ max_size = -1;
+ if (dump_file)
+ fprintf (dump_file, " max_size cleared");
+ }
+ if (!known_eq (offset, offset1))
+ {
+ offset = 0;
+ if (dump_file)
+ fprintf (dump_file, " offset cleared");
+ }
+ if (dump_file)
+ fprintf (dump_file, "\n");
+ }
+ }
+ /* Merge in access A if it is possible to do without losing
+ precision. Return true if successful.
+ If RECORD_ADJUSTMENTs is true, remember how many interval
+ was prolonged and punt when there are too many. */
+ bool merge (const modref_access_node &a, bool record_adjustments)
+ {
+ poly_int64 aoffset_adj = 0, offset_adj = 0;
+ poly_int64 new_parm_offset = parm_offset;
+
+ /* We assume that containment was tested earlier. */
+ gcc_checking_assert (!contains (a) && !a.contains (*this));
+ if (parm_index >= 0)
+ {
+ if (parm_index != a.parm_index)
+ return false;
+ if (parm_offset_known)
+ {
+ if (!a.parm_offset_known)
+ return false;
+ if (known_le (a.parm_offset, parm_offset))
+ {
+ offset_adj = (parm_offset - a.parm_offset)
+ << LOG2_BITS_PER_UNIT;
+ aoffset_adj = 0;
+ new_parm_offset = a.parm_offset;
+ }
+ else if (known_le (parm_offset, a.parm_offset))
+ {
+ aoffset_adj = (a.parm_offset - parm_offset)
+ << LOG2_BITS_PER_UNIT;
+ offset_adj = 0;
+ }
+ else
+ return false;
+ }
+ }
+ /* See if we can merge ranges. */
+ if (range_info_useful_p ())
+ {
+ poly_int64 offset1 = offset + offset_adj;
+ poly_int64 aoffset1 = a.offset + aoffset_adj;
+
+ /* In this case we have containment that should be
+ handled earlier. */
+ gcc_checking_assert (a.range_info_useful_p ());
+
+ /* If a.size is less specified than size, merge only
+ if intervals are otherwise equivalent. */
+ if (known_size_p (size)
+ && (!known_size_p (a.size) || known_lt (a.size, size)))
+ {
+ if (((known_size_p (max_size) || known_size_p (a.max_size))
+ && !known_eq (max_size, a.max_size))
+ || !known_eq (offset1, aoffset1))
+ return false;
+ update (new_parm_offset, offset1, a.size, max_size,
+ record_adjustments);
+ return true;
+ }
+ /* If sizes are same, we can extend the interval. */
+ if ((known_size_p (size) || known_size_p (a.size))
+ && !known_eq (size, a.size))
+ return false;
+ if (known_le (offset1, aoffset1))
+ {
+ if (!known_size_p (max_size))
+ {
+ update (new_parm_offset, offset1, size, max_size,
+ record_adjustments);
+ return true;
+ }
+ else if (known_ge (offset1 + max_size, aoffset1))
+ {
+ poly_int64 new_max_size = max_size;
+ if (known_le (max_size, a.max_size + aoffset1 - offset1))
+ new_max_size = a.max_size + aoffset1 - offset1;
+ update (new_parm_offset, offset1, size, new_max_size,
+ record_adjustments);
+ return true;
+ }
+ }
+ else if (known_le (aoffset1, offset1))
+ {
+ if (!known_size_p (a.max_size))
+ {
+ update (new_parm_offset, aoffset1, size, a.max_size,
+ record_adjustments);
+ return true;
+ }
+ else if (known_ge (aoffset1 + a.max_size, offset1))
+ {
+ poly_int64 new_max_size = a.max_size;
+ if (known_le (a.max_size, max_size + offset1 - aoffset1))
+ new_max_size = max_size + offset1 - aoffset1;
+ update (new_parm_offset, aoffset1, size, new_max_size,
+ record_adjustments);
+ return true;
+ }
+ }
+ return false;
+ }
+ update (new_parm_offset, offset + offset_adj,
+ size, max_size, record_adjustments);
+ return true;
+ }
};
/* Access node specifying no useful info. */
const modref_access_node unspecified_modref_access_node
- = {0, -1, -1, 0, -1, false};
+ = {0, -1, -1, 0, -1, false, 0};
template <typename T>
struct GTY((user)) modref_ref_node
@@ -149,8 +324,10 @@ struct GTY((user)) modref_ref_node
/* Insert access with OFFSET and SIZE.
Collapse tree if it has more than MAX_ACCESSES entries.
+ If RECORD_ADJUSTMENTs is true avoid too many interval extensions.
Return true if record was changed. */
- bool insert_access (modref_access_node a, size_t max_accesses)
+ bool insert_access (modref_access_node a, size_t max_accesses,
+ bool record_adjustments)
{
/* If this base->ref pair has no access information, bail out. */
if (every_access)
@@ -176,7 +353,17 @@ struct GTY((user)) modref_ref_node
return false;
if (a.contains (*a2))
{
- *a2 = a;
+ a.adjustments = 0;
+ a2->parm_index = a.parm_index;
+ a2->parm_offset_known = a.parm_offset_known;
+ a2->update (a.parm_offset, a.offset, a.size, a.max_size,
+ record_adjustments);
+ try_merge_with (i);
+ return true;
+ }
+ if (a2->merge (a, record_adjustments))
+ {
+ try_merge_with (i);
return true;
}
gcc_checking_assert (!(a == *a2));
@@ -192,9 +379,28 @@ struct GTY((user)) modref_ref_node
collapse ();
return true;
}
+ a.adjustments = 0;
vec_safe_push (accesses, a);
return true;
}
+private:
+ /* Try to optimize the access list after entry INDEX was modified. */
+ void
+ try_merge_with (size_t index)
+ {
+ modref_access_node *a2;
+ size_t i;
+
+ FOR_EACH_VEC_SAFE_ELT (accesses, i, a2)
+ if (i != index)
+ if ((*accesses)[index].contains (*a2)
+ || (*accesses)[index].merge (*a2, false))
+ {
+ if (index == accesses->length () - 1)
+ index = i;
+ accesses->unordered_remove (i);
+ }
+ }
};
/* Base of an access. */
@@ -342,7 +548,8 @@ struct GTY((user)) modref_tree
/* Insert memory access to the tree.
Return true if something changed. */
- bool insert (T base, T ref, modref_access_node a)
+ bool insert (T base, T ref, modref_access_node a,
+ bool record_adjustments)
{
if (every_base)
return false;
@@ -387,7 +594,8 @@ struct GTY((user)) modref_tree
{
if (ref_node->every_access)
return changed;
- changed |= ref_node->insert_access (a, max_accesses);
+ changed |= ref_node->insert_access (a, max_accesses,
+ record_adjustments);
/* See if we failed to add useful access. */
if (ref_node->every_access)
{
@@ -456,7 +664,8 @@ struct GTY((user)) modref_tree
PARM_MAP, if non-NULL, maps parm indexes of callee to caller. -2 is used
to signalize that parameter is local and does not need to be tracked.
Return true if something has changed. */
- bool merge (modref_tree <T> *other, vec <modref_parm_map> *parm_map)
+ bool merge (modref_tree <T> *other, vec <modref_parm_map> *parm_map,
+ bool record_accesses)
{
if (!other || every_base)
return false;
@@ -501,7 +710,8 @@ struct GTY((user)) modref_tree
{
changed |= insert (base_node->base,
ref_node->ref,
- unspecified_modref_access_node);
+ unspecified_modref_access_node,
+ record_accesses);
}
else
FOR_EACH_VEC_SAFE_ELT (ref_node->accesses, k, access_node)
@@ -525,7 +735,8 @@ struct GTY((user)) modref_tree
= (*parm_map) [a.parm_index].parm_index;
}
}
- changed |= insert (base_node->base, ref_node->ref, a);
+ changed |= insert (base_node->base, ref_node->ref, a,
+ record_accesses);
}
}
}
@@ -537,7 +748,7 @@ struct GTY((user)) modref_tree
/* Copy OTHER to THIS. */
void copy_from (modref_tree <T> *other)
{
- merge (other, NULL);
+ merge (other, NULL, false);
}
/* Search BASE in tree; return NULL if failed. */
diff --git a/gcc/ipa-modref.c b/gcc/ipa-modref.c
index 6ab687a..0d5ab9c 100644
--- a/gcc/ipa-modref.c
+++ b/gcc/ipa-modref.c
@@ -426,6 +426,8 @@ dump_access (modref_access_node *a, FILE *out)
print_dec ((poly_int64_pod)a->size, out, SIGNED);
fprintf (out, " max_size:");
print_dec ((poly_int64_pod)a->max_size, out, SIGNED);
+ if (a->adjustments)
+ fprintf (out, " adjusted %i times", a->adjustments);
}
fprintf (out, "\n");
}
@@ -656,7 +658,7 @@ get_access (ao_ref *ref)
base = ao_ref_base (ref);
modref_access_node a = {ref->offset, ref->size, ref->max_size,
- 0, -1, false};
+ 0, -1, false, 0};
if (TREE_CODE (base) == MEM_REF || TREE_CODE (base) == TARGET_MEM_REF)
{
tree memref = base;
@@ -708,7 +710,7 @@ record_access (modref_records *tt, ao_ref *ref)
fprintf (dump_file, " - Recording base_set=%i ref_set=%i parm=%i\n",
base_set, ref_set, a.parm_index);
}
- tt->insert (base_set, ref_set, a);
+ tt->insert (base_set, ref_set, a, false);
}
/* IPA version of record_access_tree. */
@@ -774,7 +776,7 @@ record_access_lto (modref_records_lto *tt, ao_ref *ref)
a.parm_index);
}
- tt->insert (base_type, ref_type, a);
+ tt->insert (base_type, ref_type, a, false);
}
/* Returns true if and only if we should store the access to EXPR.
@@ -858,12 +860,15 @@ parm_map_for_arg (gimple *stmt, int i)
/* Merge side effects of call STMT to function with CALLEE_SUMMARY
int CUR_SUMMARY. Return true if something changed.
- If IGNORE_STORES is true, do not merge stores. */
+ If IGNORE_STORES is true, do not merge stores.
+ If RECORD_ADJUSTMENTS is true cap number of adjustments to
+ a given access to make dataflow finite. */
bool
merge_call_side_effects (modref_summary *cur_summary,
gimple *stmt, modref_summary *callee_summary,
- bool ignore_stores, cgraph_node *callee_node)
+ bool ignore_stores, cgraph_node *callee_node,
+ bool record_adjustments)
{
auto_vec <modref_parm_map, 32> parm_map;
bool changed = false;
@@ -902,11 +907,13 @@ merge_call_side_effects (modref_summary *cur_summary,
fprintf (dump_file, "\n");
/* Merge with callee's summary. */
- changed |= cur_summary->loads->merge (callee_summary->loads, &parm_map);
+ changed |= cur_summary->loads->merge (callee_summary->loads, &parm_map,
+ record_adjustments);
if (!ignore_stores)
{
changed |= cur_summary->stores->merge (callee_summary->stores,
- &parm_map);
+ &parm_map,
+ record_adjustments);
if (!cur_summary->writes_errno
&& callee_summary->writes_errno)
{
@@ -941,7 +948,7 @@ get_access_for_fnspec (gcall *call, attr_fnspec &fnspec,
}
modref_access_node a = {0, -1, -1,
map.parm_offset, map.parm_index,
- map.parm_offset_known};
+ map.parm_offset_known, 0};
poly_int64 size_hwi;
if (size
&& poly_int_tree_p (size, &size_hwi)
@@ -1044,12 +1051,14 @@ process_fnspec (modref_summary *cur_summary,
cur_summary->loads->insert (0, 0,
get_access_for_fnspec (call,
fnspec, i,
- map));
+ map),
+ false);
if (cur_summary_lto)
cur_summary_lto->loads->insert (0, 0,
get_access_for_fnspec (call,
fnspec, i,
- map));
+ map),
+ false);
}
}
if (ignore_stores)
@@ -1077,12 +1086,14 @@ process_fnspec (modref_summary *cur_summary,
cur_summary->stores->insert (0, 0,
get_access_for_fnspec (call,
fnspec, i,
- map));
+ map),
+ false);
if (cur_summary_lto)
cur_summary_lto->stores->insert (0, 0,
get_access_for_fnspec (call,
fnspec, i,
- map));
+ map),
+ false);
}
if (fnspec.errno_maybe_written_p () && flag_errno_math)
{
@@ -1168,7 +1179,7 @@ analyze_call (modref_summary *cur_summary, modref_summary_lto *cur_summary_lto,
}
merge_call_side_effects (cur_summary, stmt, callee_summary, ignore_stores,
- callee_node);
+ callee_node, false);
return true;
}
@@ -2134,6 +2145,7 @@ analyze_function (function *f, bool ipa)
if (!ipa)
{
bool changed = true;
+ bool first = true;
while (changed)
{
changed = false;
@@ -2144,13 +2156,14 @@ analyze_function (function *f, bool ipa)
ignore_stores_p (current_function_decl,
gimple_call_flags
(recursive_calls[i])),
- fnode);
+ fnode, !first);
if (!summary->useful_p (ecf_flags, false))
{
remove_summary (lto, nolto, ipa);
return;
}
}
+ first = false;
}
}
if (summary && !summary->useful_p (ecf_flags))
@@ -2501,11 +2514,11 @@ read_modref_records (lto_input_block *ib, struct data_in *data_in,
}
}
modref_access_node a = {offset, size, max_size, parm_offset,
- parm_index, parm_offset_known};
+ parm_index, parm_offset_known, false};
if (nolto_ref_node)
- nolto_ref_node->insert_access (a, max_accesses);
+ nolto_ref_node->insert_access (a, max_accesses, false);
if (lto_ref_node)
- lto_ref_node->insert_access (a, max_accesses);
+ lto_ref_node->insert_access (a, max_accesses, false);
}
}
}
@@ -3187,16 +3200,18 @@ ipa_merge_modref_summary_after_inlining (cgraph_edge *edge)
if (!ignore_stores)
{
if (to_info && callee_info)
- to_info->stores->merge (callee_info->stores, &parm_map);
+ to_info->stores->merge (callee_info->stores, &parm_map, false);
if (to_info_lto && callee_info_lto)
- to_info_lto->stores->merge (callee_info_lto->stores, &parm_map);
+ to_info_lto->stores->merge (callee_info_lto->stores, &parm_map,
+ false);
}
if (!(flags & (ECF_CONST | ECF_NOVOPS)))
{
if (to_info && callee_info)
- to_info->loads->merge (callee_info->loads, &parm_map);
+ to_info->loads->merge (callee_info->loads, &parm_map, false);
if (to_info_lto && callee_info_lto)
- to_info_lto->loads->merge (callee_info_lto->loads, &parm_map);
+ to_info_lto->loads->merge (callee_info_lto->loads, &parm_map,
+ false);
}
}
@@ -3346,7 +3361,7 @@ get_access_for_fnspec (cgraph_edge *e, attr_fnspec &fnspec,
size = TYPE_SIZE_UNIT (get_parm_type (e->callee->decl, i));
modref_access_node a = {0, -1, -1,
map.parm_offset, map.parm_index,
- map.parm_offset_known};
+ map.parm_offset_known, 0};
poly_int64 size_hwi;
if (size
&& poly_int_tree_p (size, &size_hwi)
@@ -3399,10 +3414,10 @@ propagate_unknown_call (cgraph_node *node,
}
if (cur_summary)
changed |= cur_summary->loads->insert
- (0, 0, get_access_for_fnspec (e, fnspec, i, map));
+ (0, 0, get_access_for_fnspec (e, fnspec, i, map), false);
if (cur_summary_lto)
changed |= cur_summary_lto->loads->insert
- (0, 0, get_access_for_fnspec (e, fnspec, i, map));
+ (0, 0, get_access_for_fnspec (e, fnspec, i, map), false);
}
}
if (ignore_stores_p (node->decl, ecf_flags))
@@ -3429,10 +3444,10 @@ propagate_unknown_call (cgraph_node *node,
}
if (cur_summary)
changed |= cur_summary->stores->insert
- (0, 0, get_access_for_fnspec (e, fnspec, i, map));
+ (0, 0, get_access_for_fnspec (e, fnspec, i, map), false);
if (cur_summary_lto)
changed |= cur_summary_lto->stores->insert
- (0, 0, get_access_for_fnspec (e, fnspec, i, map));
+ (0, 0, get_access_for_fnspec (e, fnspec, i, map), false);
}
}
if (fnspec.errno_maybe_written_p () && flag_errno_math)
@@ -3491,6 +3506,7 @@ static void
modref_propagate_in_scc (cgraph_node *component_node)
{
bool changed = true;
+ bool first = true;
int iteration = 0;
while (changed)
@@ -3628,11 +3644,12 @@ modref_propagate_in_scc (cgraph_node *component_node)
if (callee_summary)
{
changed |= cur_summary->loads->merge
- (callee_summary->loads, &parm_map);
+ (callee_summary->loads, &parm_map, !first);
if (!ignore_stores)
{
changed |= cur_summary->stores->merge
- (callee_summary->stores, &parm_map);
+ (callee_summary->stores, &parm_map,
+ !first);
if (!cur_summary->writes_errno
&& callee_summary->writes_errno)
{
@@ -3644,11 +3661,13 @@ modref_propagate_in_scc (cgraph_node *component_node)
if (callee_summary_lto)
{
changed |= cur_summary_lto->loads->merge
- (callee_summary_lto->loads, &parm_map);
+ (callee_summary_lto->loads, &parm_map,
+ !first);
if (!ignore_stores)
{
changed |= cur_summary_lto->stores->merge
- (callee_summary_lto->stores, &parm_map);
+ (callee_summary_lto->stores, &parm_map,
+ !first);
if (!cur_summary_lto->writes_errno
&& callee_summary_lto->writes_errno)
{
@@ -3674,6 +3693,7 @@ modref_propagate_in_scc (cgraph_node *component_node)
}
}
iteration++;
+ first = false;
}
if (dump_file)
fprintf (dump_file,
diff --git a/gcc/multiple_target.c b/gcc/multiple_target.c
index 6c05658..28d5f95 100644
--- a/gcc/multiple_target.c
+++ b/gcc/multiple_target.c
@@ -166,9 +166,8 @@ create_dispatcher_calls (struct cgraph_node *node)
}
}
- symtab->change_decl_assembler_name (node->decl,
- clone_function_name_numbered (
- node->decl, "default"));
+ tree fname = clone_function_name (node->decl, "default");
+ symtab->change_decl_assembler_name (node->decl, fname);
if (node->definition)
{
@@ -309,9 +308,9 @@ create_target_clone (cgraph_node *node, bool definition, char *name,
if (definition)
{
- new_node = node->create_version_clone_with_body (vNULL, NULL,
- NULL, NULL,
- NULL, name, attributes);
+ new_node
+ = node->create_version_clone_with_body (vNULL, NULL, NULL, NULL, NULL,
+ name, attributes, false);
if (new_node == NULL)
return NULL;
new_node->force_output = true;
@@ -322,9 +321,8 @@ create_target_clone (cgraph_node *node, bool definition, char *name,
new_node = cgraph_node::get_create (new_decl);
DECL_ATTRIBUTES (new_decl) = attributes;
/* Generate a new name for the new version. */
- symtab->change_decl_assembler_name (new_node->decl,
- clone_function_name_numbered (
- node->decl, name));
+ tree fname = clone_function_name (node->decl, name);
+ symtab->change_decl_assembler_name (new_node->decl, fname);
}
return new_node;
}
diff --git a/gcc/params.opt b/gcc/params.opt
index f414dc1..cec43d2 100644
--- a/gcc/params.opt
+++ b/gcc/params.opt
@@ -1013,6 +1013,10 @@ Maximum depth of DFS walk used by modref escape analysis.
Common Joined UInteger Var(param_modref_max_escape_points) Init(256) Param Optimization
Maximum number of escape points tracked by modref per SSA-name.
+-param=modref-max-adjustments=
+Common Joined UInteger Var(param_modref_max_adjustments) Init(8) IntegerRange (0, 254) Param Optimization
+Maximum number of times a given range is adjusted during the dataflow
+
-param=tm-max-aggregate-size=
Common Joined UInteger Var(param_tm_max_aggregate_size) Init(9) Param Optimization
Size in bytes after which thread-local aggregates should be instrumented with the logging functions instead of save/restore pairs.
diff --git a/gcc/pointer-query.cc b/gcc/pointer-query.cc
index 99caf78..ba8f8a9 100644
--- a/gcc/pointer-query.cc
+++ b/gcc/pointer-query.cc
@@ -634,10 +634,10 @@ access_ref::phi () const
return as_a <gphi *> (def_stmt);
}
-/* Determine and return the largest object to which *THIS. If *THIS
- refers to a PHI and PREF is nonnull, fill *PREF with the details
- of the object determined by compute_objsize(ARG, OSTYPE) for each
- PHI argument ARG. */
+/* Determine and return the largest object to which *THIS refers. If
+ *THIS refers to a PHI and PREF is nonnull, fill *PREF with the details
+ of the object determined by compute_objsize(ARG, OSTYPE) for each PHI
+ argument ARG. */
tree
access_ref::get_ref (vec<access_ref> *all_refs,
@@ -659,21 +659,25 @@ access_ref::get_ref (vec<access_ref> *all_refs,
if (!psnlim->visit_phi (ref))
return NULL_TREE;
- /* Reflects the range of offsets of all PHI arguments refer to the same
- object (i.e., have the same REF). */
- access_ref same_ref;
- /* The conservative result of the PHI reflecting the offset and size
- of the largest PHI argument, regardless of whether or not they all
- refer to the same object. */
pointer_query empty_qry;
if (!qry)
qry = &empty_qry;
+ /* The conservative result of the PHI reflecting the offset and size
+ of the largest PHI argument, regardless of whether or not they all
+ refer to the same object. */
access_ref phi_ref;
if (pref)
{
+ /* The identity of the object has not been determined yet but
+ PREF->REF is set by the caller to the PHI for convenience.
+ The size is negative/invalid and the offset is zero (it's
+ updated only after the identity of the object has been
+ established). */
+ gcc_assert (pref->sizrng[0] < 0);
+ gcc_assert (pref->offrng[0] == 0 && pref->offrng[1] == 0);
+
phi_ref = *pref;
- same_ref = *pref;
}
/* Set if any argument is a function array (or VLA) parameter not
@@ -682,8 +686,6 @@ access_ref::get_ref (vec<access_ref> *all_refs,
/* The size of the smallest object referenced by the PHI arguments. */
offset_int minsize = 0;
const offset_int maxobjsize = wi::to_offset (max_object_size ());
- /* The offset of the PHI, not reflecting those of its arguments. */
- const offset_int orng[2] = { phi_ref.offrng[0], phi_ref.offrng[1] };
const unsigned nargs = gimple_phi_num_args (phi_stmt);
for (unsigned i = 0; i < nargs; ++i)
@@ -695,28 +697,31 @@ access_ref::get_ref (vec<access_ref> *all_refs,
/* A PHI with all null pointer arguments. */
return NULL_TREE;
- /* Add PREF's offset to that of the argument. */
- phi_arg_ref.add_offset (orng[0], orng[1]);
if (TREE_CODE (arg) == SSA_NAME)
qry->put_ref (arg, phi_arg_ref);
if (all_refs)
all_refs->safe_push (phi_arg_ref);
- const bool arg_known_size = (phi_arg_ref.sizrng[0] != 0
- || phi_arg_ref.sizrng[1] != maxobjsize);
-
parmarray |= phi_arg_ref.parmarray;
const bool nullp = integer_zerop (arg) && (i || i + 1 < nargs);
if (phi_ref.sizrng[0] < 0)
{
+ /* If PHI_REF doesn't contain a meaningful result yet set it
+ to the result for the first argument. */
if (!nullp)
- same_ref = phi_arg_ref;
- phi_ref = phi_arg_ref;
+ phi_ref = phi_arg_ref;
+
+ /* Set if the current argument refers to one or more objects of
+ known size (or range of sizes), as opposed to referring to
+ one or more unknown object(s). */
+ const bool arg_known_size = (phi_arg_ref.sizrng[0] != 0
+ || phi_arg_ref.sizrng[1] != maxobjsize);
if (arg_known_size)
minsize = phi_arg_ref.sizrng[0];
+
continue;
}
@@ -740,8 +745,10 @@ access_ref::get_ref (vec<access_ref> *all_refs,
offset_int phirem[2];
phirem[1] = phi_ref.size_remaining (phirem);
- if (phi_arg_ref.ref != same_ref.ref)
- same_ref.ref = NULL_TREE;
+ /* Reset the PHI's BASE0 flag if any of the nonnull arguments
+ refers to an object at an unknown offset. */
+ if (!phi_arg_ref.base0)
+ phi_ref.base0 = false;
if (phirem[1] < argrem[1]
|| (phirem[1] == argrem[1]
@@ -749,32 +756,13 @@ access_ref::get_ref (vec<access_ref> *all_refs,
/* Use the argument with the most space remaining as the result,
or the larger one if the space is equal. */
phi_ref = phi_arg_ref;
-
- /* Set SAME_REF.OFFRNG to the maximum range of all arguments. */
- if (phi_arg_ref.offrng[0] < same_ref.offrng[0])
- same_ref.offrng[0] = phi_arg_ref.offrng[0];
- if (same_ref.offrng[1] < phi_arg_ref.offrng[1])
- same_ref.offrng[1] = phi_arg_ref.offrng[1];
}
- if (!same_ref.ref && same_ref.offrng[0] != 0)
- /* Clear BASE0 if not all the arguments refer to the same object and
- if not all their offsets are zero-based. This allows the final
- PHI offset to out of bounds for some arguments but not for others
- (or negative even of all the arguments are BASE0), which is overly
- permissive. */
- phi_ref.base0 = false;
-
- if (same_ref.ref)
- phi_ref = same_ref;
- else
- {
- /* Replace the lower bound of the largest argument with the size
- of the smallest argument, and set PARMARRAY if any argument
- was one. */
- phi_ref.sizrng[0] = minsize;
- phi_ref.parmarray = parmarray;
- }
+ /* Replace the lower bound of the largest argument with the size
+ of the smallest argument, and set PARMARRAY if any argument
+ was one. */
+ phi_ref.sizrng[0] = minsize;
+ phi_ref.parmarray = parmarray;
if (phi_ref.sizrng[0] < 0)
{
@@ -804,6 +792,14 @@ access_ref::size_remaining (offset_int *pmin /* = NULL */) const
if (!pmin)
pmin = &minbuf;
+ if (sizrng[0] < 0)
+ {
+ /* If the identity of the object hasn't been determined return
+ the maximum size range. */
+ *pmin = 0;
+ return wi::to_offset (max_object_size ());
+ }
+
/* add_offset() ensures the offset range isn't inverted. */
gcc_checking_assert (offrng[0] <= offrng[1]);
@@ -1597,6 +1593,11 @@ compute_objsize_r (tree ptr, int ostype, access_ref *pref,
{
pref->ref = ptr;
+ /* Reset the offset in case it was set by a prior call and not
+ cleared by the caller. The offset is only adjusted after
+ the identity of the object has been determined. */
+ pref->offrng[0] = pref->offrng[1] = 0;
+
if (!addr && POINTER_TYPE_P (TREE_TYPE (ptr)))
{
/* Set the maximum size if the reference is to the pointer
@@ -1607,6 +1608,9 @@ compute_objsize_r (tree ptr, int ostype, access_ref *pref,
return true;
}
+ /* Valid offsets into the object are nonnegative. */
+ pref->base0 = true;
+
if (tree size = decl_init_size (ptr, false))
if (TREE_CODE (size) == INTEGER_CST)
{
@@ -1960,6 +1964,11 @@ compute_objsize (tree ptr, int ostype, access_ref *pref,
{
pointer_query qry;
qry.rvals = rvals;
+
+ /* Clear and invalidate in case *PREF is being reused. */
+ pref->offrng[0] = pref->offrng[1] = 0;
+ pref->sizrng[0] = pref->sizrng[1] = -1;
+
ssa_name_limit_t snlim;
if (!compute_objsize_r (ptr, ostype, pref, snlim, &qry))
return NULL_TREE;
@@ -1982,6 +1991,10 @@ compute_objsize (tree ptr, int ostype, access_ref *pref, pointer_query *ptr_qry)
else
ptr_qry = &qry;
+ /* Clear and invalidate in case *PREF is being reused. */
+ pref->offrng[0] = pref->offrng[1] = 0;
+ pref->sizrng[0] = pref->sizrng[1] = -1;
+
ssa_name_limit_t snlim;
if (!compute_objsize_r (ptr, ostype, pref, snlim, ptr_qry))
return NULL_TREE;
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 8eea9fb..c81e27e 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -841,7 +841,7 @@ simplify_context::simplify_truncation (machine_mode mode, rtx op,
{
unsigned int int_op_prec = GET_MODE_PRECISION (int_op_mode);
unsigned int subreg_prec = GET_MODE_PRECISION (subreg_mode);
- if (int_op_prec > subreg_mode)
+ if (int_op_prec > subreg_prec)
{
if (int_mode == subreg_mode)
return SUBREG_REG (op);
@@ -851,7 +851,7 @@ simplify_context::simplify_truncation (machine_mode mode, rtx op,
}
/* Simplification of (truncate:A (subreg:B X:C 0)) where
A is narrower than B and B is narrower than C. */
- else if (int_op_prec < subreg_mode
+ else if (int_op_prec < subreg_prec
&& GET_MODE_PRECISION (int_mode) < int_op_prec)
return simplify_gen_unary (TRUNCATE, int_mode,
SUBREG_REG (op), subreg_mode);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 5c49bd3..251af30 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,158 @@
+2021-08-25 Martin Sebor <msebor@redhat.com>
+
+ * gcc.dg/tree-ssa/evrp1.c: Add -details to dump option.
+ * gcc.dg/tree-ssa/evrp2.c: Same.
+ * gcc.dg/tree-ssa/evrp3.c: Same.
+ * gcc.dg/tree-ssa/evrp4.c: Same.
+ * gcc.dg/tree-ssa/evrp6.c: Same.
+ * gcc.dg/tree-ssa/pr64130.c: Same.
+
+2021-08-25 Michael Meissner <meissner@linux.ibm.com>
+
+ PR target/94630
+ * gcc.target/powerpc/pr70117.c: Specify that we need the long double
+ type to be IBM 128-bit. Remove the code to use __ibm128.
+ * c-c++-common/dfp/convert-bfp-11.c: Specify that we need the long
+ double type to be IBM 128-bit. Run the test at -O2 optimization.
+ * lib/target-supports.exp (add_options_for_long_double_ibm128): New
+ function.
+ (check_effective_target_long_double_ibm128): New function.
+ (add_options_for_long_double_ieee128): New function.
+ (check_effective_target_long_double_ieee128): New function.
+ (add_options_for_long_double_64bit): New function.
+ (check_effective_target_long_double_64bit): New function.
+
+2021-08-25 Andrew Pinski <apinski@marvell.com>
+
+ PR c++/66590
+ * g++.dg/warn/Wreturn-5.C: New test.
+
+2021-08-25 Jan Hubicka <hubicka@ucw.cz>
+
+ * gcc.dg/ipa/modref-1.c: Update testcase.
+ * gcc.dg/tree-ssa/modref-4.c: Update testcase.
+ * gcc.dg/tree-ssa/modref-8.c: New test.
+
+2021-08-25 Lewis Hyatt <lhyatt@gmail.com>
+
+ PR other/93067
+ * gcc.dg/diagnostic-input-charset-1.c: New test.
+ * gcc.dg/diagnostic-input-utf8-bom.c: New test.
+
+2021-08-25 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/102046
+ * gcc.dg/vect/pr102046.c: New testcase.
+
+2021-08-25 Hongyu Wang <hongyu.wang@intel.com>
+
+ PR target/101716
+ * gcc.target/i386/pr101716.c: New test.
+
+2021-08-25 Jiufu Guo <guojiufu@linux.ibm.com>
+
+ PR tree-optimization/101145
+ * gcc.dg/vect/pr101145.c: New test.
+ * gcc.dg/vect/pr101145.inc: New test.
+ * gcc.dg/vect/pr101145_1.c: New test.
+ * gcc.dg/vect/pr101145_2.c: New test.
+ * gcc.dg/vect/pr101145_3.c: New test.
+ * gcc.dg/vect/pr101145inf.c: New test.
+ * gcc.dg/vect/pr101145inf.inc: New test.
+ * gcc.dg/vect/pr101145inf_1.c: New test.
+
+2021-08-25 konglin1 <lingling.kong@intel.com>
+
+ PR target/101471
+ * gcc.target/i386/avx512f-pr101471.c: New test.
+
+2021-08-25 Kewen Lin <linkw@linux.ibm.com>
+
+ * gcc.target/powerpc/unpack-vectorize-1.c: New test.
+ * gcc.target/powerpc/unpack-vectorize-1.h: New test.
+ * gcc.target/powerpc/unpack-vectorize-2.c: New test.
+ * gcc.target/powerpc/unpack-vectorize-2.h: New test.
+ * gcc.target/powerpc/unpack-vectorize-3.c: New test.
+ * gcc.target/powerpc/unpack-vectorize-3.h: New test.
+ * gcc.target/powerpc/unpack-vectorize-run-1.c: New test.
+ * gcc.target/powerpc/unpack-vectorize-run-2.c: New test.
+ * gcc.target/powerpc/unpack-vectorize-run-3.c: New test.
+ * gcc.target/powerpc/unpack-vectorize.h: New test.
+
+2021-08-25 liuhongt <hongtao.liu@intel.com>
+
+ PR target/101989
+ * gcc.target/i386/avx2-shiftqihi-constant-1.c: Add -mno-avx512f.
+ * gcc.target/i386/sse2-shiftqihi-constant-1.c: Add -mno-avx
+
+2021-08-24 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/98411
+ * gfortran.dg/pr98411.f90: Adjust testcase options to restrict to
+ F2008, and verify case of implicit SAVE.
+
+2021-08-24 Martin Sebor <msebor@redhat.com>
+
+ PR middle-end/101600
+ PR middle-end/101977
+ * g++.dg/pr100574.C: Prune out valid warning.
+ * gcc.dg/pr20126.c: Same.
+ * gcc.dg/Wstringop-overread.c: Adjust text of expected warnings.
+ Add new instances.
+ * gcc.dg/warn-strnlen-no-nul.c: Same.
+ * g++.dg/warn/Warray-bounds-26.C: New test.
+ * gcc.dg/Warray-bounds-88.c: New test.
+
+2021-08-24 Andrew MacLeod <amacleod@redhat.com>
+
+ * gcc.dg/predict-1.c: Disable evrp.
+ * gcc.dg/tree-ssa/evrp-trans.c: New.
+
+2021-08-24 H.J. Lu <hjl.tools@gmail.com>
+
+ PR target/102021
+ * gcc.target/i386/pr100865-10b.c: Expect vzeroupper.
+ * gcc.target/i386/pr100865-4b.c: Likewise.
+ * gcc.target/i386/pr100865-6b.c: Expect vmovdqu and vzeroupper.
+ * gcc.target/i386/pr100865-7b.c: Likewise.
+ * gcc.target/i386/pr102021.c: New test.
+
+2021-08-24 Richard Earnshaw <rearnsha@arm.com>
+
+ PR target/102035
+ * gcc.target/arm/cmse/mainline/8_1m/soft/cmse-13a.c: New test.
+ * gcc.target/arm/cmse/mainline/8_1m/soft/cmse-7a.c: Likewise.
+ * gcc.target/arm/cmse/mainline/8_1m/soft/cmse-8a.c: Likewise.
+ * gcc.target/arm/cmse/mainline/8_1m/softfp-sp/cmse-7a.c: Likewise.
+ * gcc.target/arm/cmse/mainline/8_1m/softfp-sp/cmse-8a.c: Likewise.
+ * gcc.target/arm/cmse/mainline/8_1m/softfp/cmse-13a.c: Likewise.
+ * gcc.target/arm/cmse/mainline/8_1m/softfp/cmse-7a.c: Likewise.
+ * gcc.target/arm/cmse/mainline/8_1m/softfp/cmse-8a.c: Likewise.
+
+2021-08-24 Richard Earnshaw <rearnsha@arm.com>
+
+ * lib/target-supports.exp (check_effective_target_arm_cmse_hw):
+ Check the CMSE feature register, rather than relying on the
+ SG operation causing an execution fault.
+
+2021-08-24 liuhongt <hongtao.liu@intel.com>
+
+ PR target/101989
+ * gcc.target/i386/pr101989-broadcast-1.c: New test.
+
+2021-08-24 liuhongt <hongtao.liu@intel.com>
+
+ PR target/101989
+ * gcc.target/i386/pr101989-1.c: New test.
+ * gcc.target/i386/pr101989-2.c: New test.
+ * gcc.target/i386/avx512bw-shiftqihi-constant-1.c: Adjust testcase.
+
+2021-08-24 Roger Sayle <roger@nextmovesoftware.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/102029
+ * gcc.dg/fold-convlshift-3.c: New test case.
+
2021-08-23 David Malcolm <dmalcolm@redhat.com>
* gcc.dg/analyzer/switch.c: Remove xfail. Add various tests.
diff --git a/gcc/testsuite/c-c++-common/dfp/convert-bfp-11.c b/gcc/testsuite/c-c++-common/dfp/convert-bfp-11.c
index 95c433d..c09c834 100644
--- a/gcc/testsuite/c-c++-common/dfp/convert-bfp-11.c
+++ b/gcc/testsuite/c-c++-common/dfp/convert-bfp-11.c
@@ -1,9 +1,16 @@
-/* { dg-skip-if "" { ! "powerpc*-*-linux*" } } */
+/* { dg-require-effective-target dfp } */
-/* Test decimal float conversions to and from IBM 128-bit long double.
- Checks are skipped at runtime if long double is not 128 bits.
- Don't force 128-bit long doubles because runtime support depends
- on glibc. */
+/* We need the long double type to be IBM 128-bit because the CONVERT_TO_PINF
+ tests will fail if we use IEEE 128-bit floating point. This is due to IEEE
+ 128-bit having a larger exponent range than IBM 128-bit extended double. So
+ tests that would generate an infinity with IBM 128-bit will generate a
+ normal number with IEEE 128-bit. */
+
+/* { dg-require-effective-target long_double_ibm128 } */
+/* { dg-options "-O2" } */
+/* { dg-add-options long_double_ibm128 } */
+
+/* Test decimal float conversions to and from IBM 128-bit long double. */
#include "convert.h"
@@ -36,9 +43,6 @@ CONVERT_TO_PINF (312, tf, sd, 1.6e+308L, d32)
int
main ()
{
- if (sizeof (long double) != 16)
- return 0;
-
convert_101 ();
convert_102 ();
diff --git a/gcc/testsuite/g++.dg/pr100574.C b/gcc/testsuite/g++.dg/pr100574.C
index 42ba040..0df62aa 100644
--- a/gcc/testsuite/g++.dg/pr100574.C
+++ b/gcc/testsuite/g++.dg/pr100574.C
@@ -40,6 +40,8 @@ template <typename _Tp, typename _Alloc>
template <typename...>
void vector<_Tp, _Alloc>::_M_realloc_insert() {
__alloc_traits::pointer __trans_tmp_5;
+ /* __len is used uninitialized below, which might trigger warnings,
+ even without -Wall (and other than -Wuninitialized). */
long __len(__len || max_size()), __elems_before;
__trans_tmp_5 = _M_allocate___n
? __alloc_traits::allocate(_M_impl, _M_allocate___n)
@@ -62,3 +64,5 @@ void ReadTrackChunk()
case MIDIST_PITCHBEND:
block.data.push_back();
}
+
+// { dg-prune-output "warning" }
diff --git a/gcc/testsuite/g++.dg/warn/Warray-bounds-26.C b/gcc/testsuite/g++.dg/warn/Warray-bounds-26.C
new file mode 100644
index 0000000..f72ac9d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Warray-bounds-26.C
@@ -0,0 +1,27 @@
+/* PR middle-end/101600 - Spurious -Warray-bounds downcasting a polymorphic
+ pointer
+ { dg-do compile }
+ { dg-options "-O2 -Wall" } */
+
+struct S1 { virtual ~S1(); };
+struct S2 { int m; };
+struct S3 { virtual ~S3(); };
+struct S4: S1, S2, S3 {};
+
+int f1 ();
+
+void f2 (S3 *);
+
+void f3 (S2 *p)
+{
+ for (int i = f1 (); f1 (); )
+ {
+ if (i == 0)
+ {
+ p = 0;
+ break;
+ }
+ }
+
+ f2 (static_cast<S4 *>(p)); // { dg-bogus "-Warray-bounds" }
+}
diff --git a/gcc/testsuite/g++.dg/warn/Wreturn-5.C b/gcc/testsuite/g++.dg/warn/Wreturn-5.C
new file mode 100644
index 0000000..543e33e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wreturn-5.C
@@ -0,0 +1,15 @@
+// PR C++/66590
+// { dg-do compile }
+// { dg-options "-Wall" }
+
+struct A{ ~A();};
+
+int f(int x)
+{
+ A a;
+ switch (x)
+ {
+ case 1: { A tmp; return 1; } break;
+ default: return 0;
+ }
+} // { dg-bogus "control reaches end of non-void function" }
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-88.c b/gcc/testsuite/gcc.dg/Warray-bounds-88.c
new file mode 100644
index 0000000..8cee8d2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-88.c
@@ -0,0 +1,134 @@
+/* PR middle-end/101977 - bogus -Warray-bounds on a negative index into
+ a parameter in conditional with null
+ { dg-do compile }
+ { dg-options "-O2 -Wall" } */
+
+struct A { int i; };
+struct B { struct A a1; struct A a2; };
+
+
+void nowarn_p_0_0 (struct A *p, int i)
+{
+ struct A *q = i < 0 ? p : 0 < i ? (struct A*)0 : 0;
+ struct B *r = (struct B*)((char *)q - __builtin_offsetof (struct B, a2));
+ r->a1.i = 0;
+}
+
+void nowarn_0_p_0 (struct A *p, int i)
+{
+ struct A *q = i < 0 ? 0 : 0 < i ? p : 0;
+ struct B *r = (struct B*)((char *)q - __builtin_offsetof (struct B, a2));
+ r->a1.i = 0; // { dg-bogus "-Warray-bounds" }
+}
+
+void nowarn_0_0_p (struct A *p, int i)
+{
+ struct A *q = i < 0 ? 0 : 0 < i ? 0 : p;
+ struct B *r = (struct B*)((char *)q - __builtin_offsetof (struct B, a2));
+ r->a1.i = 0; // { dg-bogus "-Warray-bounds" }
+}
+
+
+void nowarn_p_q_0 (struct A *p, struct A *q, int i)
+{
+ struct A *r = i < 0 ? p : 0 < i ? q : 0;
+ struct B *s = (struct B*)((char *)r - __builtin_offsetof (struct B, a2));
+ s->a1.i = 0; // { dg-bogus "-Warray-bounds" }
+}
+
+void nowarn_p_0_q (struct A *p, struct A *q, int i)
+{
+ struct A *r = i < 0 ? p : 0 < i ? 0 : q;
+ struct B *s = (struct B*)((char *)r - __builtin_offsetof (struct B, a2));
+ s->a1.i = 0; // { dg-bogus "-Warray-bounds" }
+}
+
+void nowarn_0_p_q (struct A *p, struct A *q, int i)
+{
+ struct A *r = i < 0 ? 0 : 0 < i ? p : q;
+ struct B *s = (struct B*)((char *)r - __builtin_offsetof (struct B, a2));
+ s->a1.i = 0;
+}
+
+
+void nowarn_p_q_r (struct A *p, struct A *q, struct A *r, int i)
+{
+ struct A *s = i < 0 ? p : 0 < i ? q : r;
+ struct B *t = (struct B*)((char *)s - __builtin_offsetof (struct B, a2));
+ t->a1.i = 0;
+}
+
+
+extern struct B b1, b2, b3;
+
+void nowarn_p_b1_0 (struct A *p, int i)
+{
+ struct A *r = i < 0 ? p : 0 < i ? &b1.a2 : 0;
+ struct B *s = (struct B*)((char *)r - __builtin_offsetof (struct B, a2));
+ s->a1.i = 0; // { dg-bogus "-Warray-bounds" }
+}
+
+void nowarn_p_0_b1 (struct A *p, int i)
+{
+ struct A *r = i < 0 ? p : 0 < i ? 0 : &b1.a2;
+ struct B *s = (struct B*)((char *)r - __builtin_offsetof (struct B, a2));
+ s->a1.i = 0; // { dg-bogus "-Warray-bounds" }
+}
+
+void nowarn_0_p_b1 (struct A *p, int i)
+{
+ struct A *r = i < 0 ? 0 : 0 < i ? p : &b1.a2;
+ struct B *s = (struct B*)((char *)r - __builtin_offsetof (struct B, a2));
+ s->a1.i = 0;
+}
+
+
+void nowarn_p_b1_b2 (struct A *p, int i)
+{
+ struct A *s = i < 0 ? p : 0 < i ? &b1.a2 : &b2.a2;
+ struct B *t = (struct B*)((char *)s - __builtin_offsetof (struct B, a2));
+ t->a1.i = 0;
+}
+
+void nowarn_b1_p_b2 (struct A *p, int i)
+{
+ struct A *s = i < 0 ? &b1.a2 : 0 < i ? p : &b2.a2;
+ struct B *t = (struct B*)((char *)s - __builtin_offsetof (struct B, a2));
+ t->a1.i = 0;
+}
+
+void nowarn_b1_b2_p (struct A *p, int i)
+{
+ struct A *s = i < 0 ? &b1.a2 : 0 < i ? &b2.a2 : p;
+ struct B *t = (struct B*)((char *)s - __builtin_offsetof (struct B, a2));
+ t->a1.i = 0;
+}
+
+void nowarn_b1_b2_b3 (struct A *p, int i)
+{
+ struct A *s = i < 0 ? &b1.a2 : 0 < i ? &b2.a2 : &b3.a2;
+ struct B *t = (struct B*)((char *)s - __builtin_offsetof (struct B, a2));
+ t->a1.i = 0;
+}
+
+
+void nowarn_0_b1_b2 (int i)
+{
+ struct A *s = i < 0 ? 0 : 0 < i ? &b1.a2 : &b2.a2;
+ struct B *t = (struct B*)((char *)s - __builtin_offsetof (struct B, a2));
+ t->a1.i = 0;
+}
+
+void warn_b1_0_b2 (int i)
+{
+ struct A *s = i < 0 ? &b1.a2 : 0 < i ? 0 : &b2.a2;
+ struct B *t = (struct B*)((char *)s - __builtin_offsetof (struct B, a2));
+ t->a1.i = 0;
+}
+
+void warn_b1_b2_0 (int i)
+{
+ struct A *s = i < 0 ? &b1.a2 : 0 < i ? &b2.a2 : 0;
+ struct B *t = (struct B*)((char *)s - __builtin_offsetof (struct B, a2));
+ t->a1.i = 0;
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overread.c b/gcc/testsuite/gcc.dg/Wstringop-overread.c
index 0343e43..7db7402 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overread.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overread.c
@@ -317,9 +317,9 @@ void test_strnlen_array (int i, int i0, unsigned n)
T (strnlen (a1, n));
T (strnlen (a1 + 1, 0));
- T (strnlen (a1 + 1, 1)); // { dg-warning "'strnlen' reading 1 byte from a region of size 0" }
+ T (strnlen (a1 + 1, 1)); // { dg-warning "'strnlen' specified bound 1 exceeds source size 0" }
T (strnlen (a1 + 1, i0));
- T (strnlen (a1 + 1, i0 + 1)); // { dg-warning "'strnlen' reading between 1 and \[0-9\]+ bytes from a region of size 0" }
+ T (strnlen (a1 + 1, i0 + 1)); // { dg-warning "'strnlen' specified bound \\\[1, \\d+] exceeds source size 0" }
T (strnlen (a1 + 1, n));
T (strnlen (a1 + i, 0));
T (strnlen (a1 + i, 1));
@@ -335,7 +335,7 @@ void test_strnlen_array (int i, int i0, unsigned n)
T (strnlen (a1 + i0, 2)); // { dg-warning "'strnlen' specified bound 2 exceeds source size 1" }
T (strnlen (a1 + i0, n));
T (strnlen (a1 + i0 + 1, 0));
- T (strnlen (a1 + i0 + 1, 1)); // { dg-warning "'strnlen' reading 1 byte from a region of size 0" }
+ T (strnlen (a1 + i0 + 1, 1)); // { dg-warning "'strnlen' specified bound 1 exceeds source size 0" }
T (strnlen (a1 + i0 + 1, n));
T (strnlen (a2, 0));
@@ -344,10 +344,10 @@ void test_strnlen_array (int i, int i0, unsigned n)
T (strnlen (a2, n));
T (strnlen (a2 + 1, 0));
T (strnlen (a2 + 1, 1));
- T (strnlen (a2 + 1, 2)); // { dg-warning "'strnlen' specified bound 2 exceeds source size 1" "pr87492" { xfail *-*-* } }
+ T (strnlen (a2 + 1, 2)); // { dg-warning "'strnlen' specified bound 2 exceeds source size 1" "pr87492" }
T (strnlen (a2 + 1, n));
T (strnlen (a2 + 2, 0));
- T (strnlen (a2 + 2, 1)); // { dg-warning "'strnlen' reading 1 byte from a region of size 0" }
+ T (strnlen (a2 + 2, 1)); // { dg-warning "'strnlen' specified bound 1 exceeds source size 0" }
T (strnlen (a2 + 2, n));
T (strnlen (a2 + i, 0));
T (strnlen (a2 + i, 1));
@@ -365,13 +365,13 @@ void test_strnlen_array (int i, int i0, unsigned n)
T (strnlen (a2 + i0 + 1, 0));
T (strnlen (a2 + i0 + 1, 1));
- T (strnlen (a2 + i0 + 1, 2));
+ T (strnlen (a2 + i0 + 1, 2)); // { dg-warning "'strnlen' specified bound 2 exceeds source size 1" }
T (strnlen (a2 + i0 + 1, n));
T (strnlen (a2 + i0 + 2, 0));
- T (strnlen (a2 + i0 + 2, 1)); // { dg-warning "'strnlen' reading 1 byte from a region of size 0" }
+ T (strnlen (a2 + i0 + 2, 1)); // { dg-warning "'strnlen' specified bound 1 exceeds source size 0" }
T (strnlen (a2 + i0 + 2, i0));
- T (strnlen (a2 + i0 + 2, i0 + 1)); // { dg-warning "'strnlen' reading between 1 and \[0-9\]+ bytes from a region of size 0" }
+ T (strnlen (a2 + i0 + 2, i0 + 1)); // { dg-warning "'strnlen' specified bound \\\[1, \\d+] exceeds source size 0" }
T (strnlen (a2 + i0 + 2, n));
}
@@ -512,9 +512,9 @@ void test_strndup_array (int i, int i0, unsigned n)
T (strndup (a1, 2)); // { dg-warning "'strndup' specified bound 2 exceeds source size 1" }
T (strndup (a1, n));
T (strndup (a1 + 1, 0));
- T (strndup (a1 + 1, 1)); // { dg-warning "'strndup' reading 1 byte from a region of size 0" }
+ T (strndup (a1 + 1, 1)); // { dg-warning "'strndup' specified bound 1 exceeds source size 0" }
T (strndup (a1 + 1, i0));
- T (strndup (a1 + 1, i0 + 1)); // { dg-warning "'strndup' reading between 1 and \[0-9\]+ bytes from a region of size 0" }
+ T (strndup (a1 + 1, i0 + 1)); // { dg-warning "'strndup' specified bound \\\[1, \\d+] exceeds source size 0" }
T (strndup (a1 + 1, n));
T (strndup (a1 + i, 0));
T (strndup (a1 + i, 1));
@@ -529,7 +529,7 @@ void test_strndup_array (int i, int i0, unsigned n)
T (strndup (a1 + i0, 1));
T (strndup (a1 + i0, n));
T (strndup (a1 + i0 + 1, 0));
- T (strndup (a1 + i0 + 1, 1)); // { dg-warning "'strndup' reading 1 byte from a region of size 0" }
+ T (strndup (a1 + i0 + 1, 1)); // { dg-warning "'strndup' specified bound 1 exceeds source size 0" }
T (strndup (a1 + i0 + 1, n));
T (strndup (a2, 0));
@@ -538,10 +538,10 @@ void test_strndup_array (int i, int i0, unsigned n)
T (strndup (a2, n));
T (strndup (a2 + 1, 0));
T (strndup (a2 + 1, 1));
- T (strndup (a2 + 1, 2));
+ T (strndup (a2 + 1, 2)); // { dg-warning "'strndup' specified bound 2 exceeds source size 1" }
T (strndup (a2 + 1, n));
T (strndup (a2 + 2, 0));
- T (strndup (a2 + 2, 1)); // { dg-warning "'strndup' reading 1 byte from a region of size 0" }
+ T (strndup (a2 + 2, 1)); // { dg-warning "'strndup' specified bound 1 exceeds source size 0" }
T (strndup (a2 + 2, n));
T (strndup (a2 + i, 0));
T (strndup (a2 + i, 1));
@@ -559,13 +559,13 @@ void test_strndup_array (int i, int i0, unsigned n)
T (strndup (a2 + i0 + 1, 0));
T (strndup (a2 + i0 + 1, 1));
- T (strndup (a2 + i0 + 1, 2));
+ T (strndup (a2 + i0 + 1, 2)); // { dg-warning "'strndup' specified bound 2 exceeds source size 1" }
T (strndup (a2 + i0 + 1, n));
T (strndup (a2 + i0 + 2, 0));
- T (strndup (a2 + i0 + 2, 1)); // { dg-warning "'strndup' reading 1 byte from a region of size 0" }
+ T (strndup (a2 + i0 + 2, 1)); // { dg-warning "'strndup' specified bound 1 exceeds source size 0" }
T (strndup (a2 + i0 + 2, i0));
- T (strndup (a2 + i0 + 2, i0 + 1)); // { dg-warning "'strndup' reading between 1 and \[0-9\]+ bytes from a region of size 0" }
+ T (strndup (a2 + i0 + 2, i0 + 1)); // { dg-warning "'strndup' specified bound \\\[1, \\d+] exceeds source size 0" }
T (strndup (a2 + i0 + 2, n));
}
diff --git a/gcc/testsuite/gcc.dg/diagnostic-input-charset-1.c b/gcc/testsuite/gcc.dg/diagnostic-input-charset-1.c
new file mode 100644
index 0000000..4e56833
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/diagnostic-input-charset-1.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-require-iconv "CP850" } */
+/* { dg-options "-finput-charset=CP850 -fdiagnostics-show-caret" } */
+
+/* Test that diagnostics are converted to UTF-8; this file is encoded in
+ CP850. Why CP850? -finput-charset only supports encodings that are a
+ superset of ASCII. But encodings that look like latin-1 are automatically
+ converted by expect to UTF-8, and hence by the time dg sees them, it can't
+ verify they were actually output in UTF-8. So codepage 850 was chosen as one
+ that is hopefully available and meets the requirements of matching ASCII and
+ not matching latin-1. */
+const char *section = "õ"
+/* { dg-error "expected .* at end of input" "" { target *-*-*} .-1 } */
+/* { dg-begin-multiline-output "" }
+ const char *section = "§"
+ ^~~~~
+ { dg-end-multiline-output "" } */
diff --git a/gcc/testsuite/gcc.dg/diagnostic-input-utf8-bom.c b/gcc/testsuite/gcc.dg/diagnostic-input-utf8-bom.c
new file mode 100644
index 0000000..1a3f352
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/diagnostic-input-utf8-bom.c
@@ -0,0 +1,14 @@
+int 1;
+/* { dg-do compile } */
+/* { dg-options "-fdiagnostics-show-caret" } */
+
+/* This file begins with a UTF-8 byte order mark. Verify that diagnostics
+ still point to the right place, since the stripping of the BOM happens twice,
+ once when libcpp reads the file, and once when diagnostics infrastucture
+ reads it. */
+
+/* { dg-error "expected .* before numeric constant" "" { target *-*-*} 1 } */
+/* { dg-begin-multiline-output "" }
+ int 1;
+ ^
+ { dg-end-multiline-output "" } */
diff --git a/gcc/testsuite/gcc.dg/ipa/modref-1.c b/gcc/testsuite/gcc.dg/ipa/modref-1.c
index 858567d..5314e7d 100644
--- a/gcc/testsuite/gcc.dg/ipa/modref-1.c
+++ b/gcc/testsuite/gcc.dg/ipa/modref-1.c
@@ -10,15 +10,15 @@ void a(char *ptr, char *ptr2)
__attribute__((noinline))
void b(char *ptr)
{
- a(ptr+1,&ptr[2]);
+ a(ptr+1,&ptr[3]);
}
int main()
{
- char c[3]={0,1,0};
+ char c[4]={0,1,0,0};
b(c);
- return c[0]+c[2];
+ return c[0]+c[3];
}
/* Check that both param offsets are determined correctly. */
/* { dg-final { scan-ipa-dump "param offset:1" "modref" } } */
-/* { dg-final { scan-ipa-dump "param offset:2" "modref" } } */
+/* { dg-final { scan-ipa-dump "param offset:3" "modref" } } */
diff --git a/gcc/testsuite/gcc.dg/pr20126.c b/gcc/testsuite/gcc.dg/pr20126.c
index a421ce1..10aeec7 100644
--- a/gcc/testsuite/gcc.dg/pr20126.c
+++ b/gcc/testsuite/gcc.dg/pr20126.c
@@ -34,6 +34,10 @@ foo (S *x, S *y)
while (e <= g)
{
const char *t = e + 1;
+ /* The pointer E below increases but the bound H stays constant,
+ letting the latter exceed the size remaining in the argument
+ pointed to by the formed, which might be detected by
+ -Wstringop-overread. */
if (__builtin_memcmp (e, f, h) == 0)
return 1;
e = t;
@@ -48,3 +52,5 @@ main (void)
abort ();
return 0;
}
+
+/* { dg-prune-output "-Wstringop-overread" } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/evrp1.c b/gcc/testsuite/gcc.dg/tree-ssa/evrp1.c
index 8c6e4e6..f5f38c4 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/evrp1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/evrp1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-evrp" } */
+/* { dg-options "-O2 -fdump-tree-evrp-details" } */
int foo (int i);
int bar (int j)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/evrp2.c b/gcc/testsuite/gcc.dg/tree-ssa/evrp2.c
index e6d4235..fc92cdf 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/evrp2.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/evrp2.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-evrp" } */
+/* { dg-options "-O2 -fdump-tree-evrp-details" } */
int foo (int i);
int bar2 (int j)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/evrp3.c b/gcc/testsuite/gcc.dg/tree-ssa/evrp3.c
index 1a3bbd5..805652b 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/evrp3.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/evrp3.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-evrp" } */
+/* { dg-options "-O2 -fdump-tree-evrp-details" } */
int foo (int i);
void bar (int j)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/evrp4.c b/gcc/testsuite/gcc.dg/tree-ssa/evrp4.c
index 6710e6b..e3f4531 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/evrp4.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/evrp4.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-evrp" } */
+/* { dg-options "-O2 -fdump-tree-evrp-details" } */
int foo (int *p);
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/evrp6.c b/gcc/testsuite/gcc.dg/tree-ssa/evrp6.c
index 35d4d74..aaeec68 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/evrp6.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/evrp6.c
@@ -1,6 +1,5 @@
-
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-evrp" } */
+/* { dg-options "-O2 -fdump-tree-evrp-details" } */
extern void abort (void);
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/modref-4.c b/gcc/testsuite/gcc.dg/tree-ssa/modref-4.c
index 3ac217b..a277c70 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/modref-4.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/modref-4.c
@@ -10,17 +10,17 @@ void a(char *ptr, char *ptr2)
__attribute__((noinline))
void b(char *ptr)
{
- a(ptr+1,&ptr[2]);
+ a(ptr+1,&ptr[3]);
}
int main()
{
- char c[4]={0,1,2,0};
+ char c[5]={0,1,2,0,0};
b(c);
- return c[0]+c[3];
+ return c[0]+c[4];
}
/* Check that both param offsets are determined correctly and the computation
is optimized out. */
/* { dg-final { scan-tree-dump "param offset:1" "modref1" } } */
-/* { dg-final { scan-tree-dump "param offset:2" "modref1" } } */
+/* { dg-final { scan-tree-dump "param offset:3" "modref1" } } */
/* { dg-final { scan-tree-dump "return 0" "modref1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/modref-8.c b/gcc/testsuite/gcc.dg/tree-ssa/modref-8.c
new file mode 100644
index 0000000..15ae4ac
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/modref-8.c
@@ -0,0 +1,25 @@
+/* { dg-options "-O2 --param modref-max-adjustments=8 -fdump-tree-modref1" } */
+/* { dg-do compile } */
+void
+set (char *p)
+{
+ p[1]=1;
+ p[0]=0;
+ p[2]=2;
+ p[4]=4;
+ p[3]=3;
+}
+
+void
+recurse (char *p, int n)
+{
+ *p = 0;
+ if (n)
+ recurse (p+1,n-1);
+}
+/* { dg-final { scan-tree-dump-not "param=modref-max-accesses" "modref1" } } */
+/* { dg-final { scan-tree-dump "param=modref-max-adjustments" "modref1" } } */
+/* In set all accesses should merge together. */
+/* { dg-final { scan-tree-dump "access: Parm 0 param offset:0 offset:0 size:8 max_size:40" "modref1" } } */
+/* In recurse we should cap the recrusion after 8 attempts and set max_size to -1. */
+/* { dg-final { scan-tree-dump "access: Parm 0 param offset:0 offset:0 size:8 max_size:-1 adjusted 8 times" "modref1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr64130.c b/gcc/testsuite/gcc.dg/tree-ssa/pr64130.c
index 28ffbb7..b694ec1 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr64130.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr64130.c
@@ -1,6 +1,5 @@
-
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-evrp" } */
+/* { dg-options "-O2 -fdump-tree-evrp-details" } */
__extension__ typedef __UINT32_TYPE__ uint32_t;
diff --git a/gcc/testsuite/gcc.dg/vect/pr101145.c b/gcc/testsuite/gcc.dg/vect/pr101145.c
new file mode 100644
index 0000000..74031b0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr101145.c
@@ -0,0 +1,187 @@
+/* { dg-require-effective-target vect_int } */
+/* { dg-options "-O3 -fdump-tree-vect-details" } */
+#include <limits.h>
+
+unsigned __attribute__ ((noinline))
+foo (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned n)
+{
+ while (n < ++l)
+ *a++ = *b++ + 1;
+ return l;
+}
+
+unsigned __attribute__ ((noinline))
+foo_1 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned)
+{
+ while (UINT_MAX - 64 < ++l)
+ *a++ = *b++ + 1;
+ return l;
+}
+
+unsigned __attribute__ ((noinline))
+foo_2 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned n)
+{
+ l = UINT_MAX - 32;
+ while (n < ++l)
+ *a++ = *b++ + 1;
+ return l;
+}
+
+unsigned __attribute__ ((noinline))
+foo_3 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned n)
+{
+ while (n <= ++l)
+ *a++ = *b++ + 1;
+ return l;
+}
+
+unsigned __attribute__ ((noinline))
+foo_4 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned n)
+{ // infininate
+ while (0 <= ++l)
+ *a++ = *b++ + 1;
+ return l;
+}
+
+unsigned __attribute__ ((noinline))
+foo_5 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned n)
+{
+ //no loop
+ l = UINT_MAX;
+ while (n < ++l)
+ *a++ = *b++ + 1;
+ return l;
+}
+
+unsigned __attribute__ ((noinline))
+bar (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned n)
+{
+ while (--l < n)
+ *a++ = *b++ + 1;
+ return l;
+}
+
+unsigned __attribute__ ((noinline))
+bar_1 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned)
+{
+ while (--l < 64)
+ *a++ = *b++ + 1;
+ return l;
+}
+
+unsigned __attribute__ ((noinline))
+bar_2 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned n)
+{
+ l = 32;
+ while (--l < n)
+ *a++ = *b++ + 1;
+ return l;
+}
+
+
+int a[3200], b[3200];
+int fail;
+
+int
+main ()
+{
+ unsigned l, n;
+ unsigned res;
+ /* l > n*/
+ n = UINT_MAX - 64;
+ l = n + 32;
+ res = foo (a, b, l, n);
+ if (res != 0)
+ fail++;
+
+ l = n;
+ res = foo (a, b, l, n);
+ if (res != 0)
+ fail++;
+
+ l = n - 1;
+ res = foo (a, b, l, n);
+ if (res != l + 1)
+ fail++;
+
+ l = n - 32;
+ res = foo (a, b, l, n);
+ if (res != l + 1)
+ fail++;
+
+ l = UINT_MAX;
+ res = foo (a, b, l, n);
+ if (res != 0)
+ fail++;
+
+ l = n + 32;
+ res = foo_1 (a, b, l, n);
+ if (res != 0)
+ fail++;
+
+ l = n + 32;
+ res = foo_2 (a, b, l, n);
+ if (res != 0)
+ fail++;
+
+ l = n;
+ res = foo_3 (a, b, l, n);
+ if (res != 0)
+ fail++;
+
+ l = n - 1;
+ res = foo_3 (a, b, l, n);
+ if (res != 0)
+ fail++;
+
+ l = n - 2;
+ res = foo_3 (a, b, l, n);
+ if (res != l + 1)
+ fail++;
+
+ res = foo_5 (a, b, l, n);
+ if (res != 0)
+ fail++;
+
+ n = 64;
+ l = n - 32;
+ res = bar (a, b, l, n);
+ res++;
+ if (res != 0)
+ fail++;
+
+ l = n;
+ res = bar (a, b, l, n);
+ res++;
+ if (res != 0)
+ fail++;
+
+ l = n + 1;
+ res = bar (a, b, l, n);
+ res++;
+ if (res != l)
+ fail++;
+
+ l = 0;
+ res = bar (a, b, l, n);
+ res++;
+ if (res != l)
+ fail++;
+
+ l = 32;
+ res = bar_1 (a, b, l, n);
+ res++;
+ if (res != 0)
+ fail++;
+
+ res = bar_1 (a, b, l, n);
+ res++;
+ if (res != 0)
+ fail++;
+
+ if (fail)
+ __builtin_abort ();
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 7 "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr101145.inc b/gcc/testsuite/gcc.dg/vect/pr101145.inc
new file mode 100644
index 0000000..615d2e5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr101145.inc
@@ -0,0 +1,65 @@
+TYPE __attribute__ ((noinline))
+foo_sign (int *__restrict__ a, int *__restrict__ b, TYPE l, TYPE n)
+{
+ TYPE i;
+ for (i = l; n < i; i += C)
+ *a++ = *b++ + 1;
+ return i;
+}
+
+TYPE __attribute__ ((noinline))
+bar_sign (int *__restrict__ a, int *__restrict__ b, TYPE l, TYPE n)
+{
+ TYPE i;
+ for (i = l; i < n; i -= C)
+ *a++ = *b++ + 1;
+ return i;
+}
+
+int __attribute__ ((noinline)) neq (int a, int b) { return a != b; }
+
+int a[1000], b[1000];
+int fail;
+
+int
+main ()
+{
+ TYPE res;
+ TYPE l;
+ TYPE n;
+ n = N_BASE;
+ l = n - C;
+ res = foo_sign (a, b, l, n);
+ if (res != l)
+ fail++;
+
+ l = n;
+ res = foo_sign (a, b, l, n);
+ if (res != l)
+ fail++;
+
+ l = n + C;
+ res = foo_sign (a, b, l, n);
+ if (neq ((res - MIN) / C, 0))
+ fail++;
+
+ n = N_BASE_DOWN;
+ l = n - C;
+ res = bar_sign (a, b, l, n);
+ if (neq ((MAX - res) / C, 0))
+ fail++;
+
+ l = n;
+ res = bar_sign (a, b, l, n);
+ if (res != l)
+ fail++;
+
+ l = n + C;
+ res = bar_sign (a, b, l, n);
+ if (res != l)
+ fail++;
+
+ if (fail)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/pr101145_1.c b/gcc/testsuite/gcc.dg/vect/pr101145_1.c
new file mode 100644
index 0000000..8bc26e2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr101145_1.c
@@ -0,0 +1,13 @@
+/* { dg-require-effective-target vect_int } */
+/* { dg-options "-O3 -fdump-tree-vect-details" } */
+#define TYPE signed char
+#define MIN -128
+#define MAX 127
+#define N_BASE (MAX - 32)
+#define N_BASE_DOWN (MIN + 32)
+
+#define C 3
+
+#include "pr101145.inc"
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr101145_2.c b/gcc/testsuite/gcc.dg/vect/pr101145_2.c
new file mode 100644
index 0000000..b14c4b4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr101145_2.c
@@ -0,0 +1,13 @@
+/* { dg-require-effective-target vect_int } */
+/* { dg-options "-O3 -fdump-tree-vect-details" } */
+#define TYPE unsigned char
+#define MIN 0
+#define MAX 255
+#define N_BASE (MAX - 32 + 1)
+#define N_BASE_DOWN (MIN + 32)
+
+#define C 2
+
+#include "pr101145.inc"
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr101145_3.c b/gcc/testsuite/gcc.dg/vect/pr101145_3.c
new file mode 100644
index 0000000..99289af
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr101145_3.c
@@ -0,0 +1,13 @@
+/* { dg-require-effective-target vect_int } */
+/* { dg-options "-O3 -fdump-tree-vect-details" } */
+#define TYPE int *
+#define MIN ((TYPE)0)
+#define MAX ((TYPE)((long long)-1))
+#define N_BASE (MIN - 32)
+#define N_BASE_DOWN (MIN + 32)
+
+#define C 1
+
+#include "pr101145.inc"
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr101145inf.c b/gcc/testsuite/gcc.dg/vect/pr101145inf.c
new file mode 100644
index 0000000..ed49f56
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr101145inf.c
@@ -0,0 +1,25 @@
+/* { dg-do run { target *-*-linux* *-*-gnu* *-*-uclinux* } } */
+/* { dg-options "-O3" } */
+#include <limits.h>
+#include "pr101145inf.inc"
+
+__attribute__ ((noinline))
+unsigned foo(unsigned val, unsigned start)
+{
+ unsigned cnt = 0;
+ for (unsigned i = start; val <= i; i+=16)
+ cnt++;
+ return cnt;
+}
+
+void test_finite ()
+{
+ unsigned n = foo (16, UINT_MAX - 32);
+ if (n != 3)
+ __builtin_abort ();
+}
+
+void test_infinite ()
+{
+ foo (15, UINT_MAX - 32);
+}
diff --git a/gcc/testsuite/gcc.dg/vect/pr101145inf.inc b/gcc/testsuite/gcc.dg/vect/pr101145inf.inc
new file mode 100644
index 0000000..4aa3d04
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr101145inf.inc
@@ -0,0 +1,28 @@
+#include <unistd.h>
+#include <signal.h>
+#include <stdlib.h>
+
+void test_finite ();
+void test_infinite ();
+
+void do_exit (int i)
+{
+ exit (0);
+}
+
+int main(void)
+{
+ test_finite ();
+ struct sigaction s;
+ sigemptyset (&s.sa_mask);
+ s.sa_handler = do_exit;
+ s.sa_flags = 0;
+ sigaction (SIGALRM, &s, NULL);
+ alarm (1);
+
+ test_infinite ();
+
+ __builtin_abort ();
+ return 1;
+}
+
diff --git a/gcc/testsuite/gcc.dg/vect/pr101145inf_1.c b/gcc/testsuite/gcc.dg/vect/pr101145inf_1.c
new file mode 100644
index 0000000..4ee3e31
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr101145inf_1.c
@@ -0,0 +1,23 @@
+/* { dg-do run { target *-*-linux* *-*-gnu* *-*-uclinux* } } */
+/* { dg-options "-O3" } */
+#include <limits.h>
+#include "pr101145inf.inc"
+
+__attribute__ ((noinline))
+unsigned foo(unsigned val, unsigned start)
+{
+ unsigned cnt = 0;
+ for (unsigned i = start; i < val; i-=16)
+ cnt++;
+ return cnt;
+}
+
+void test_finite ()
+{
+ foo (UINT_MAX - 15, 32);
+}
+
+void test_infinite ()
+{
+ foo (UINT_MAX - 14, 32);
+}
diff --git a/gcc/testsuite/gcc.dg/vect/pr102046.c b/gcc/testsuite/gcc.dg/vect/pr102046.c
new file mode 100644
index 0000000..ae48b49
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr102046.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O3 -fvect-cost-model=dynamic" } */
+/* { dg-additional-options "-march=btver2" { target x86_64-*-* i?86-*-* } } */
+
+struct S
+{
+ unsigned a, b;
+};
+
+struct S g;
+
+void
+foo (struct S *o)
+{
+ struct S s = g;
+ s.b *= 3;
+ s.a -= s.a / 2;
+ *o = s;
+}
diff --git a/gcc/testsuite/gcc.dg/warn-strnlen-no-nul.c b/gcc/testsuite/gcc.dg/warn-strnlen-no-nul.c
index 2afd2b5..846e930 100644
--- a/gcc/testsuite/gcc.dg/warn-strnlen-no-nul.c
+++ b/gcc/testsuite/gcc.dg/warn-strnlen-no-nul.c
@@ -143,14 +143,17 @@ T (v0 ? b[1] : "", bsz);
T (v0 ? b[2] : "", bsz);
T (v0 ? b[3] : "", bsz);
-T (v0 ? "" : b[0], bsz + 1); /* { dg-warning "bound 6 may exceed source size 5" } */
-T (v0 ? "" : b[1], bsz + 1);
-T (v0 ? "" : b[2], bsz + 1);
-T (v0 ? "" : b[3], bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfail *-*-* } } */
-T (v0 ? b[0] : "", bsz + 1); /* { dg-warning "bound 6 may exceed source size 5" } */
-T (v0 ? b[1] : "", bsz + 1);
-T (v0 ? b[2] : "", bsz + 1);
-T (v0 ? b[3] : "", bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfail *-*-* } } */
+/* The warnings below are strictly correct but the strnlen calls are safe
+ because the reads are bounded by the length of the constant arguments.
+ It might make sense to relax the warning to avoid triggering for them. */
+T (v0 ? "" : b[0], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */
+T (v0 ? "" : b[1], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */
+T (v0 ? "" : b[2], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */
+T (v0 ? "" : b[3], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */
+T (v0 ? b[0] : "", bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */
+T (v0 ? b[1] : "", bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */
+T (v0 ? b[2] : "", bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */
+T (v0 ? b[3] : "", bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */
T (v0 ? "" : b[i0], bsz);
T (v0 ? "" : b[i1], bsz);
@@ -164,11 +167,11 @@ T (v0 ? b[i3] : "", bsz);
T (v0 ? "" : b[i0], bsz + 1);
T (v0 ? "" : b[i1], bsz + 1);
T (v0 ? "" : b[i2], bsz + 1);
-T (v0 ? "" : b[i3], bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfail *-*-* } } */
+T (v0 ? "" : b[i3], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" "pr86937" } */
T (v0 ? b[i0] : "", bsz + 1);
T (v0 ? b[i1] : "", bsz + 1);
T (v0 ? b[i2] : "", bsz + 1);
-T (v0 ? b[i3] : "", bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfail *-*-* } } */
+T (v0 ? b[i3] : "", bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" "pr86937" } */
T (v0 ? "1234" : b[3], bsz);
T (v0 ? "1234" : b[i3], bsz);
@@ -180,15 +183,15 @@ T (v0 ? b[0] : b[2], bsz);
T (v0 ? b[2] : b[3], bsz);
T (v0 ? b[3] : b[2], bsz);
-T (v0 ? "1234" : b[3], bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfail *-*-* } } */
-T (v0 ? "1234" : b[i3], bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfail *-*-* } } */
-T (v0 ? b[3] : "1234", bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfail *-*-* } } */
-T (v0 ? b[i3] : "1234", bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfail *-*-* } } */
+T (v0 ? "1234" : b[3], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */
+T (v0 ? "1234" : b[i3], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */
+T (v0 ? b[3] : "1234", bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */
+T (v0 ? b[i3] : "1234", bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */
-T (v0 ? a : b[3], bsz + 1); /* { dg-warning "bound 6 may exceed source size 5" "pr86937" { xfail *-*-*} } */
-T (v0 ? b[0] : b[2], bsz + 1); /* { dg-warning "bound 6 may exceed source size 5" "pr86937" } */
-T (v0 ? b[2] : b[3], bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfail *-*-* } } */
-T (v0 ? b[3] : b[2], bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfail *-*-* } } */
+T (v0 ? a : b[3], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */
+T (v0 ? b[0] : b[2], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */
+T (v0 ? b[2] : b[3], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */
+T (v0 ? b[3] : b[2], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */
struct A { char a[5], b[5]; };
diff --git a/gcc/testsuite/gcc.target/i386/avx2-shiftqihi-constant-1.c b/gcc/testsuite/gcc.target/i386/avx2-shiftqihi-constant-1.c
index 7206503..801f570 100644
--- a/gcc/testsuite/gcc.target/i386/avx2-shiftqihi-constant-1.c
+++ b/gcc/testsuite/gcc.target/i386/avx2-shiftqihi-constant-1.c
@@ -1,6 +1,6 @@
/* PR target/95524 */
/* { dg-do compile } */
-/* { dg-options "-O2 -mavx2" } */
+/* { dg-options "-O2 -mavx2 -mno-avx512f" } */
/* { dg-final { scan-assembler-times "vpand\[^\n\]*%ymm" 3 } } */
typedef char v32qi __attribute__ ((vector_size (32)));
typedef unsigned char v32uqi __attribute__ ((vector_size (32)));
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-pr101471.c b/gcc/testsuite/gcc.target/i386/avx512f-pr101471.c
new file mode 100644
index 0000000..4a0057b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512f-pr101471.c
@@ -0,0 +1,18 @@
+/* { dg-do run } */
+/* { dg-options "-mavx512dq -O0" } */
+/* { dg-require-effective-target avx512dq } */
+
+#include "avx512f-check.h"
+
+static void
+avx512f_test (void)
+{
+ __m512 x = {
+ 1, 1, 1, 1,
+ 1, 1, 1, 1,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0, };
+ int ret = _mm512_fpclass_ps_mask(x, 0x26);
+ if (ret != 65280)
+ __builtin_abort();
+}
diff --git a/gcc/testsuite/gcc.target/i386/mvc5.c b/gcc/testsuite/gcc.target/i386/mvc5.c
index 677f79f..0e02bf6 100644
--- a/gcc/testsuite/gcc.target/i386/mvc5.c
+++ b/gcc/testsuite/gcc.target/i386/mvc5.c
@@ -3,6 +3,10 @@
/* { dg-options "-fno-inline" } */
/* { dg-final { scan-assembler "foo,foo.resolver" } } */
+/* Verify that foo clones are not numbered. */
+/* { dg-final { scan-assembler "foo.default:" } } */
+/* { dg-final { scan-assembler "foo.avx:" } } */
+
__attribute__((target_clones("default","avx","avx2")))
int
foo ()
diff --git a/gcc/testsuite/gcc.target/i386/mvc7.c b/gcc/testsuite/gcc.target/i386/mvc7.c
index a3697ba..7fb9dde 100644
--- a/gcc/testsuite/gcc.target/i386/mvc7.c
+++ b/gcc/testsuite/gcc.target/i386/mvc7.c
@@ -1,7 +1,11 @@
/* { dg-do compile } */
/* { dg-require-ifunc "" } */
-/* { dg-final { scan-assembler "foo.resolver" } } */
-/* { dg-final { scan-assembler "avx" } } */
+
+/* Verify that foo clones are not numbered. */
+/* { dg-final { scan-assembler "foo.resolver," } } */
+/* { dg-final { scan-assembler "foo.default," } } */
+/* { dg-final { scan-assembler "foo.avx," } } */
+
/* { dg-final { scan-assembler "slm" } } */
/* { dg-final { scan-assembler "foo,foo.resolver" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr101716.c b/gcc/testsuite/gcc.target/i386/pr101716.c
new file mode 100644
index 0000000..5e3ea64
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr101716.c
@@ -0,0 +1,11 @@
+/* PR target/101716 */
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2" } */
+
+/* { dg-final { scan-assembler "leal\[\\t \]\[^\\n\]*eax" } } */
+/* { dg-final { scan-assembler-not "movl\[\\t \]\[^\\n\]*eax" } } */
+
+unsigned long long sample1(unsigned long long m) {
+ unsigned int t = -1;
+ return (m << 1) & t;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr95778-1.c b/gcc/testsuite/gcc.target/i386/pr95778-1.c
index 3238303..18f8383 100644
--- a/gcc/testsuite/gcc.target/i386/pr95778-1.c
+++ b/gcc/testsuite/gcc.target/i386/pr95778-1.c
@@ -17,5 +17,5 @@ g2(int *p)
return f2(p);
}
-/* { dg-final { scan-assembler "g2.default.1:\n\tjmp\tf2.default.1\n" } } */
-/* { dg-final { scan-assembler "g2.avx2.0:\n\tjmp\tf2.avx2.0\n" } } */
+/* { dg-final { scan-assembler "g2.default:\n\tjmp\tf2.default\n" } } */
+/* { dg-final { scan-assembler "g2.avx2:\n\tjmp\tf2.avx2\n" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr95778-2.c b/gcc/testsuite/gcc.target/i386/pr95778-2.c
index e88702d..9ef513a 100644
--- a/gcc/testsuite/gcc.target/i386/pr95778-2.c
+++ b/gcc/testsuite/gcc.target/i386/pr95778-2.c
@@ -17,5 +17,5 @@ g2(int *p)
return f2(p);
}
-/* { dg-final { scan-assembler "g2.default.1:\n\tjmp\tf2.default.1\n" } } */
-/* { dg-final { scan-assembler "g2.avx2.0:\n\tjmp\tf2.avx2.0\n" } } */
+/* { dg-final { scan-assembler "g2.default:\n\tjmp\tf2.default\n" } } */
+/* { dg-final { scan-assembler "g2.avx2:\n\tjmp\tf2.avx2\n" } } */
diff --git a/gcc/testsuite/gcc.target/i386/sse2-shiftqihi-constant-1.c b/gcc/testsuite/gcc.target/i386/sse2-shiftqihi-constant-1.c
index f1c68cb..015450f 100644
--- a/gcc/testsuite/gcc.target/i386/sse2-shiftqihi-constant-1.c
+++ b/gcc/testsuite/gcc.target/i386/sse2-shiftqihi-constant-1.c
@@ -1,6 +1,6 @@
/* PR target/95524 */
/* { dg-do compile } */
-/* { dg-options "-O2 -msse2" } */
+/* { dg-options "-O2 -msse2 -mno-avx" } */
/* { dg-final { scan-assembler-times "pand\[^\n\]*%xmm" 3 { xfail *-*-* } } } */
typedef char v16qi __attribute__ ((vector_size (16)));
typedef unsigned char v16uqi __attribute__ ((vector_size (16)));
diff --git a/gcc/testsuite/gcc.target/powerpc/pr70117.c b/gcc/testsuite/gcc.target/powerpc/pr70117.c
index 3bbd2c5..4a51f58 100644
--- a/gcc/testsuite/gcc.target/powerpc/pr70117.c
+++ b/gcc/testsuite/gcc.target/powerpc/pr70117.c
@@ -1,26 +1,18 @@
-/* { dg-do run { target { powerpc*-*-linux* powerpc*-*-darwin* powerpc*-*-aix* rs6000-*-* } } } */
-/* { dg-options "-std=c99 -mlong-double-128 -O2" } */
+/* { dg-do run } */
+/* { dg-require-effective-target long_double_ibm128 } */
+/* { dg-options "-std=c99 -O2" } */
+/* { dg-add-options long_double_ibm128 } */
#include <float.h>
-#if defined(__LONG_DOUBLE_IEEE128__)
-/* If long double is IEEE 128-bit, we need to use the __ibm128 type instead of
- long double. We can't use __ibm128 on systems that don't support IEEE
- 128-bit floating point, because the type is not enabled on those
- systems. */
-#define LDOUBLE __ibm128
-
-#elif defined(__LONG_DOUBLE_IBM128__)
-#define LDOUBLE long double
-
-#else
-#error "long double must be either IBM 128-bit or IEEE 128-bit"
+#ifndef __LONG_DOUBLE_IBM128__
+#error "long double must be IBM 128-bit"
#endif
union gl_long_double_union
{
struct { double hi; double lo; } dd;
- LDOUBLE ld;
+ long double ld;
};
/* This is gnulib's LDBL_MAX which, being 107 bits in precision, is
@@ -36,7 +28,7 @@ volatile double dnan = 0.0/0.0;
int
main (void)
{
- LDOUBLE ld;
+ long double ld;
ld = gl_LDBL_MAX.ld;
if (__builtin_isinf (ld))
diff --git a/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-1.c b/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-1.c
new file mode 100644
index 0000000..dceb5b8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-1.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_altivec_ok } */
+/* { dg-options "-maltivec -O2 -ftree-vectorize -fno-vect-cost-model -fno-unroll-loops -fdump-tree-vect-details" } */
+
+/* Test if unpack vectorization succeeds for type signed/unsigned
+ short and char. */
+
+#include "unpack-vectorize-1.h"
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 4 "vect" } } */
+/* { dg-final { scan-assembler-times {\mvupkhsb\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mvupklsb\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mvupkhsh\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mvupklsh\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mvmrghb\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mvmrglb\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mvmrghh\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mvmrglh\M} 2 } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-1.h b/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-1.h
new file mode 100644
index 0000000..1cb89ab
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-1.h
@@ -0,0 +1,14 @@
+#include "unpack-vectorize.h"
+
+DEF_ARR (si)
+DEF_ARR (ui)
+DEF_ARR (sh)
+DEF_ARR (uh)
+DEF_ARR (sc)
+DEF_ARR (uc)
+
+TEST1 (sh, si)
+TEST1 (uh, ui)
+TEST1 (sc, sh)
+TEST1 (uc, uh)
+
diff --git a/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-2.c b/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-2.c
new file mode 100644
index 0000000..4f2e6eb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-2.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-options "-mdejagnu-cpu=power7 -O2 -ftree-vectorize -fno-vect-cost-model -fno-unroll-loops -fdump-tree-vect-details" } */
+
+/* Test if unsigned int unpack vectorization succeeds. V2DImode is
+ supported since Power7 so guard it under Power7 and up. */
+
+#include "unpack-vectorize-2.h"
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
+/* { dg-final { scan-assembler-times {\mxxmrghw\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxxmrglw\M} 1 } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-2.h b/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-2.h
new file mode 100644
index 0000000..e199229
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-2.h
@@ -0,0 +1,7 @@
+#include "unpack-vectorize.h"
+
+DEF_ARR (ui)
+DEF_ARR (ull)
+
+TEST1 (ui, ull)
+
diff --git a/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-3.c b/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-3.c
new file mode 100644
index 0000000..520a279
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-3.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-mdejagnu-cpu=power8 -O2 -ftree-vectorize -fno-vect-cost-model -fno-unroll-loops -fdump-tree-vect-details" } */
+
+/* Test if signed int unpack vectorization succeeds. */
+
+#include "unpack-vectorize-3.h"
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
+/* { dg-final { scan-assembler-times {\mvupkhsw\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mvupklsw\M} 1 } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-3.h b/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-3.h
new file mode 100644
index 0000000..6a5191d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-3.h
@@ -0,0 +1,7 @@
+#include "unpack-vectorize.h"
+
+DEF_ARR (si)
+DEF_ARR (sll)
+
+TEST1 (si, sll)
+
diff --git a/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-run-1.c b/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-run-1.c
new file mode 100644
index 0000000..51f0e67
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-run-1.c
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+/* { dg-require-effective-target vmx_hw } */
+/* { dg-options "-maltivec -O2 -ftree-vectorize -fno-vect-cost-model" } */
+
+#include "unpack-vectorize-1.h"
+
+/* Test if unpack vectorization cases on signed/unsigned short and char
+ run successfully. */
+
+CHECK1 (sh, si)
+CHECK1 (uh, ui)
+CHECK1 (sc, sh)
+CHECK1 (uc, uh)
+
+int
+main ()
+{
+ check1_sh_si ();
+ check1_uh_ui ();
+ check1_sc_sh ();
+ check1_uc_uh ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-run-2.c b/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-run-2.c
new file mode 100644
index 0000000..6d24360
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-run-2.c
@@ -0,0 +1,16 @@
+/* { dg-do run } */
+/* { dg-require-effective-target vsx_hw } */
+/* { dg-options "-mdejagnu-cpu=power7 -O2 -ftree-vectorize -fno-vect-cost-model" } */
+
+#include "unpack-vectorize-2.h"
+
+/* Test if unpack vectorization cases on unsigned int run successfully. */
+
+CHECK1 (ui, ull)
+
+int
+main ()
+{
+ check1_ui_ull ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-run-3.c b/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-run-3.c
new file mode 100644
index 0000000..fec33c4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/unpack-vectorize-run-3.c
@@ -0,0 +1,16 @@
+/* { dg-do run } */
+/* { dg-require-effective-target p8vector_hw } */
+/* { dg-options "-mdejagnu-cpu=power8 -O2 -ftree-vectorize -fno-vect-cost-model" } */
+
+#include "unpack-vectorize-3.h"
+
+/* Test if unpack vectorization cases on signed int run successfully. */
+
+CHECK1 (si, sll)
+
+int
+main ()
+{
+ check1_si_sll ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/unpack-vectorize.h b/gcc/testsuite/gcc.target/powerpc/unpack-vectorize.h
new file mode 100644
index 0000000..11fa7d4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/unpack-vectorize.h
@@ -0,0 +1,42 @@
+typedef signed long long sll;
+typedef unsigned long long ull;
+typedef signed int si;
+typedef unsigned int ui;
+typedef signed short sh;
+typedef unsigned short uh;
+typedef signed char sc;
+typedef unsigned char uc;
+
+#ifndef ALIGN
+#define ALIGN 32
+#endif
+
+#define ALIGN_ATTR __attribute__((__aligned__(ALIGN)))
+
+#define N 128
+
+#define DEF_ARR(TYPE) \
+ TYPE TYPE##_a[N] ALIGN_ATTR; \
+ TYPE TYPE##_b[N] ALIGN_ATTR; \
+ TYPE TYPE##_c[N] ALIGN_ATTR;
+
+#define TEST1(NTYPE, WTYPE) \
+ __attribute__((noipa)) void test1_##NTYPE##_##WTYPE() { \
+ for (int i = 0; i < N; i++) \
+ WTYPE##_c[i] = NTYPE##_a[i] + NTYPE##_b[i]; \
+ }
+
+#define CHECK1(NTYPE, WTYPE) \
+ __attribute__((noipa, optimize(0))) void check1_##NTYPE##_##WTYPE() { \
+ for (int i = 0; i < N; i++) { \
+ NTYPE##_a[i] = 2 * i * sizeof(NTYPE) + 10; \
+ NTYPE##_b[i] = 7 * i * sizeof(NTYPE) / 5 - 10; \
+ } \
+ test1_##NTYPE##_##WTYPE(); \
+ for (int i = 0; i < N; i++) { \
+ WTYPE exp = NTYPE##_a[i] + NTYPE##_b[i]; \
+ if (WTYPE##_c[i] != exp) \
+ __builtin_abort(); \
+ } \
+ }
+
diff --git a/gcc/testsuite/gfortran.dg/pr98411.f90 b/gcc/testsuite/gfortran.dg/pr98411.f90
index 249afae..7c906a9 100644
--- a/gcc/testsuite/gfortran.dg/pr98411.f90
+++ b/gcc/testsuite/gfortran.dg/pr98411.f90
@@ -1,5 +1,5 @@
! { dg-do compile }
-! { dg-options "-Wall -fautomatic -fmax-stack-var-size=100" }
+! { dg-options "-std=f2008 -Wall -fautomatic -fmax-stack-var-size=100" }
! PR fortran/98411 - Pointless warning for static variables
module try
@@ -9,8 +9,10 @@ contains
subroutine initmodule
real, save :: b(1000)
logical :: c(1000) ! { dg-warning "moved from stack to static storage" }
+ integer :: e(1000) = 1
a(1) = 42
b(2) = 3.14
c(3) = .true.
+ e(5) = -1
end subroutine initmodule
end module try
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 06f5b1e..350dbdb 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -2360,6 +2360,134 @@ proc check_effective_target_ppc_ieee128_ok { } {
}]
}
+# Check if GCC and GLIBC supports explicitly specifying that the long double
+# format uses the IBM 128-bit extended double format. Under little endian
+# PowerPC Linux, you need GLIBC 2.32 or later to be able to use a different
+# long double format for running a program than the system default.
+
+proc check_effective_target_long_double_ibm128 { } {
+ return [check_runtime_nocache long_double_ibm128 {
+ #include <string.h>
+ #include <stdio.h>
+ /* use volatile to prevent optimization. */
+ volatile __ibm128 a = (__ibm128) 3.0;
+ volatile long double one = 1.0L;
+ volatile long double two = 2.0L;
+ volatile long double b;
+ char buffer[20];
+ int main()
+ {
+ __ibm128 a2;
+ long double b2;
+ if (sizeof (long double) != 16)
+ return 1;
+ b = one + two;
+ /* eliminate removing volatile cast warning. */
+ a2 = a;
+ b2 = b;
+ if (memcmp (&a2, &b2, 16) != 0)
+ return 1;
+ sprintf (buffer, "%lg", b);
+ return strcmp (buffer, "3") != 0;
+ }
+ } [add_options_for_long_double_ibm128 ""]]
+}
+
+# Return the appropriate options to specify that long double uses the IBM
+# 128-bit format on PowerPC.
+
+proc add_options_for_long_double_ibm128 { flags } {
+ if { [istarget powerpc*-*-*] } {
+ return "$flags -mlong-double-128 -Wno-psabi -mabi=ibmlongdouble"
+ }
+ return "$flags"
+}
+
+# Check if GCC and GLIBC supports explicitly specifying that the long double
+# format uses the IEEE 128-bit format. Under little endian PowerPC Linux, you
+# need GLIBC 2.32 or later to be able to use a different long double format for
+# running a program than the system default.
+
+proc check_effective_target_long_double_ieee128 { } {
+ return [check_runtime_nocache long_double_ieee128 {
+ #include <string.h>
+ #include <stdio.h>
+ /* use volatile to prevent optimization. */
+ volatile _Float128 a = 3.0f128;
+ volatile long double one = 1.0L;
+ volatile long double two = 2.0L;
+ volatile long double b;
+ char buffer[20];
+ int main()
+ {
+ _Float128 a2;
+ long double b2;
+ if (sizeof (long double) != 16)
+ return 1;
+ b = one + two;
+ /* eliminate removing volatile cast warning. */
+ a2 = a;
+ b2 = b;
+ if (memcmp (&a2, &b2, 16) != 0)
+ return 1;
+ sprintf (buffer, "%lg", b);
+ return strcmp (buffer, "3") != 0;
+ }
+ } [add_options_for_long_double_ieee128 ""]]
+}
+
+# Return the appropriate options to specify that long double uses the IBM
+# 128-bit format on PowerPC.
+proc add_options_for_long_double_ieee128 { flags } {
+ if { [istarget powerpc*-*-*] } {
+ return "$flags -mlong-double-128 -Wno-psabi -mabi=ieeelongdouble"
+ }
+ return "$flags"
+}
+
+# Check if GCC and GLIBC supports explicitly specifying that the long double
+# format uses the IEEE 64-bit. Under little endian PowerPC Linux, you need
+# GLIBC 2.32 or later to be able to use a different long double format for
+# running a program than the system default.
+
+proc check_effective_target_long_double_64bit { } {
+ return [check_runtime_nocache long_double_64bit {
+ #include <string.h>
+ #include <stdio.h>
+ /* use volatile to prevent optimization. */
+ volatile double a = 3.0;
+ volatile long double one = 1.0L;
+ volatile long double two = 2.0L;
+ volatile long double b;
+ char buffer[20];
+ int main()
+ {
+ double a2;
+ long double b2;
+ if (sizeof (long double) != 8)
+ return 1;
+ b = one + two;
+ /* eliminate removing volatile cast warning. */
+ a2 = a;
+ b2 = b;
+ if (memcmp (&a2, &b2, 16) != 0)
+ return 1;
+ sprintf (buffer, "%lg", b);
+ return strcmp (buffer, "3") != 0;
+ }
+ } [add_options_for_ppc_long_double_override_64bit ""]]
+}
+
+# Return the appropriate options to specify that long double uses the IEEE
+# 64-bit format on PowerPC.
+
+proc add_options_for_long_double_64bit { flags } {
+ if { [istarget powerpc*-*-*] } {
+ return "$flags -mlong-double-64"
+ }
+ return "$flags"
+}
+
# Return 1 if the target supports executing VSX instructions, 0
# otherwise. Cache the result.
diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
index 466158a..7af92d1 100644
--- a/gcc/tree-ssa-loop-niter.c
+++ b/gcc/tree-ssa-loop-niter.c
@@ -1474,6 +1474,93 @@ assert_loop_rolls_lt (tree type, affine_iv *iv0, affine_iv *iv1,
}
/* Determines number of iterations of loop whose ending condition
+ is IV0 < IV1 which likes: {base, -C} < n, or n < {base, C}.
+ The number of iterations is stored to NITER. */
+
+static bool
+number_of_iterations_until_wrap (class loop *, tree type, affine_iv *iv0,
+ affine_iv *iv1, class tree_niter_desc *niter)
+{
+ tree niter_type = unsigned_type_for (type);
+ tree step, num, assumptions, may_be_zero;
+ wide_int high, low, max, min;
+
+ may_be_zero = fold_build2 (LE_EXPR, boolean_type_node, iv1->base, iv0->base);
+ if (integer_onep (may_be_zero))
+ return false;
+
+ int prec = TYPE_PRECISION (type);
+ signop sgn = TYPE_SIGN (type);
+ min = wi::min_value (prec, sgn);
+ max = wi::max_value (prec, sgn);
+
+ /* n < {base, C}. */
+ if (integer_zerop (iv0->step) && !tree_int_cst_sign_bit (iv1->step))
+ {
+ step = iv1->step;
+ /* MIN + C - 1 <= n. */
+ tree last = wide_int_to_tree (type, min + wi::to_wide (step) - 1);
+ assumptions = fold_build2 (LE_EXPR, boolean_type_node, last, iv0->base);
+ if (integer_zerop (assumptions))
+ return false;
+
+ num = fold_build2 (MINUS_EXPR, niter_type, wide_int_to_tree (type, max),
+ iv1->base);
+ high = max;
+ if (TREE_CODE (iv1->base) == INTEGER_CST)
+ low = wi::to_wide (iv1->base) - 1;
+ else if (TREE_CODE (iv0->base) == INTEGER_CST)
+ low = wi::to_wide (iv0->base);
+ else
+ low = min;
+ }
+ /* {base, -C} < n. */
+ else if (tree_int_cst_sign_bit (iv0->step) && integer_zerop (iv1->step))
+ {
+ step = fold_build1 (NEGATE_EXPR, TREE_TYPE (iv0->step), iv0->step);
+ /* MAX - C + 1 >= n. */
+ tree last = wide_int_to_tree (type, max - wi::to_wide (step) + 1);
+ assumptions = fold_build2 (GE_EXPR, boolean_type_node, last, iv1->base);
+ if (integer_zerop (assumptions))
+ return false;
+
+ num = fold_build2 (MINUS_EXPR, niter_type, iv0->base,
+ wide_int_to_tree (type, min));
+ low = min;
+ if (TREE_CODE (iv0->base) == INTEGER_CST)
+ high = wi::to_wide (iv0->base) + 1;
+ else if (TREE_CODE (iv1->base) == INTEGER_CST)
+ high = wi::to_wide (iv1->base);
+ else
+ high = max;
+ }
+ else
+ return false;
+
+ /* (delta + step - 1) / step */
+ step = fold_convert (niter_type, step);
+ num = fold_convert (niter_type, num);
+ num = fold_build2 (PLUS_EXPR, niter_type, num, step);
+ niter->niter = fold_build2 (FLOOR_DIV_EXPR, niter_type, num, step);
+
+ widest_int delta, s;
+ delta = widest_int::from (high, sgn) - widest_int::from (low, sgn);
+ s = wi::to_widest (step);
+ delta = delta + s - 1;
+ niter->max = wi::udiv_floor (delta, s);
+
+ niter->may_be_zero = may_be_zero;
+
+ if (!integer_nonzerop (assumptions))
+ niter->assumptions = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
+ niter->assumptions, assumptions);
+
+ niter->control.no_overflow = false;
+
+ return true;
+}
+
+/* Determines number of iterations of loop whose ending condition
is IV0 < IV1. TYPE is the type of the iv. The number of
iterations is stored to NITER. BNDS bounds the difference
IV1->base - IV0->base. EXIT_MUST_BE_TAKEN is true if we know
@@ -1501,6 +1588,11 @@ number_of_iterations_lt (class loop *loop, tree type, affine_iv *iv0,
niter->bound = iv0->base;
}
+ /* {base, -C} < n, or n < {base, C} */
+ if (tree_int_cst_sign_bit (iv0->step)
+ || (!integer_zerop (iv1->step) && !tree_int_cst_sign_bit (iv1->step)))
+ return number_of_iterations_until_wrap (loop, type, iv0, iv1, niter);
+
delta = fold_build2 (MINUS_EXPR, niter_type,
fold_convert (niter_type, iv1->base),
fold_convert (niter_type, iv0->base));
@@ -1665,62 +1757,6 @@ dump_affine_iv (FILE *file, affine_iv *iv)
}
}
-/* Given exit condition IV0 CODE IV1 in TYPE, this function adjusts
- the condition for loop-until-wrap cases. For example:
- (unsigned){8, -1}_loop < 10 => {0, 1} != 9
- 10 < (unsigned){0, max - 7}_loop => {0, 1} != 8
- Return true if condition is successfully adjusted. */
-
-static bool
-adjust_cond_for_loop_until_wrap (tree type, affine_iv *iv0, tree_code *code,
- affine_iv *iv1)
-{
- /* Only support simple cases for the moment. */
- if (TREE_CODE (iv0->base) != INTEGER_CST
- || TREE_CODE (iv1->base) != INTEGER_CST)
- return false;
-
- tree niter_type = unsigned_type_for (type), high, low;
- /* Case: i-- < 10. */
- if (integer_zerop (iv1->step))
- {
- /* TODO: Should handle case in which abs(step) != 1. */
- if (!integer_minus_onep (iv0->step))
- return false;
- /* Give up on infinite loop. */
- if (*code == LE_EXPR
- && tree_int_cst_equal (iv1->base, TYPE_MAX_VALUE (type)))
- return false;
- high = fold_build2 (PLUS_EXPR, niter_type,
- fold_convert (niter_type, iv0->base),
- build_int_cst (niter_type, 1));
- low = fold_convert (niter_type, TYPE_MIN_VALUE (type));
- }
- else if (integer_zerop (iv0->step))
- {
- /* TODO: Should handle case in which abs(step) != 1. */
- if (!integer_onep (iv1->step))
- return false;
- /* Give up on infinite loop. */
- if (*code == LE_EXPR
- && tree_int_cst_equal (iv0->base, TYPE_MIN_VALUE (type)))
- return false;
- high = fold_convert (niter_type, TYPE_MAX_VALUE (type));
- low = fold_build2 (MINUS_EXPR, niter_type,
- fold_convert (niter_type, iv1->base),
- build_int_cst (niter_type, 1));
- }
- else
- gcc_unreachable ();
-
- iv0->base = low;
- iv0->step = fold_convert (niter_type, integer_one_node);
- iv1->base = high;
- iv1->step = build_int_cst (niter_type, 0);
- *code = NE_EXPR;
- return true;
-}
-
/* Determine the number of iterations according to condition (for staying
inside loop) which compares two induction variables using comparison
operator CODE. The induction variable on left side of the comparison
@@ -1855,15 +1891,6 @@ number_of_iterations_cond (class loop *loop,
return true;
}
- /* Handle special case loops: while (i-- < 10) and while (10 < i++) by
- adjusting iv0, iv1 and code. */
- if (code != NE_EXPR
- && (tree_int_cst_sign_bit (iv0->step)
- || (!integer_zerop (iv1->step)
- && !tree_int_cst_sign_bit (iv1->step)))
- && !adjust_cond_for_loop_until_wrap (type, iv0, &code, iv1))
- return false;
-
/* OK, now we know we have a senseful loop. Handle several cases, depending
on what comparison operator is used. */
bound_difference (loop, iv1->base, iv0->base, &bnds);
diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index edc11c6..4d688c7 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -2311,6 +2311,10 @@ out:
}
if (dump_enabled_p ())
dump_printf (MSG_NOTE, "\n");
+ /* After swapping some operands we lost track whether an
+ operand has any pattern defs so be conservative here. */
+ if (oprnds_info[0]->any_pattern || oprnds_info[1]->any_pattern)
+ oprnds_info[0]->any_pattern = oprnds_info[1]->any_pattern = true;
/* And try again with scratch 'matches' ... */
bool *tem = XALLOCAVEC (bool, group_size);
if ((child = vect_build_slp_tree (vinfo, oprnd_info->def_stmts,
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index 688cad2..c32ff4a 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -1,3 +1,20 @@
+2021-08-25 Lewis Hyatt <lhyatt@gmail.com>
+
+ PR other/93067
+ * charset.c (init_iconv_desc): Adapt to permit PFILE argument to
+ be NULL.
+ (_cpp_convert_input): Likewise. Also move UTF-8 BOM logic to...
+ (cpp_check_utf8_bom): ...here. New function.
+ (cpp_input_conversion_is_trivial): New function.
+ * files.c (read_file_guts): Allow PFILE argument to be NULL. Add
+ INPUT_CHARSET argument as an alternate source of this information.
+ (read_file): Pass the new argument to read_file_guts.
+ (cpp_get_converted_source): New function.
+ * include/cpplib.h (struct cpp_converted_source): Declare.
+ (cpp_get_converted_source): Declare.
+ (cpp_input_conversion_is_trivial): Declare.
+ (cpp_check_utf8_bom): Declare.
+
2021-08-17 Jakub Jelinek <jakub@redhat.com>
* macro.c (vaopt_state): Add m_stringify member.
diff --git a/libcpp/charset.c b/libcpp/charset.c
index 99a9b73..61881f9 100644
--- a/libcpp/charset.c
+++ b/libcpp/charset.c
@@ -630,7 +630,11 @@ static const struct cpp_conversion conversion_tab[] = {
cset_converter structure for conversion from FROM to TO. If
iconv_open() fails, issue an error and return an identity
converter. Silently return an identity converter if FROM and TO
- are identical. */
+ are identical.
+
+ PFILE is only used for generating diagnostics; setting it to NULL
+ suppresses diagnostics. */
+
static struct cset_converter
init_iconv_desc (cpp_reader *pfile, const char *to, const char *from)
{
@@ -672,25 +676,31 @@ init_iconv_desc (cpp_reader *pfile, const char *to, const char *from)
if (ret.cd == (iconv_t) -1)
{
- if (errno == EINVAL)
- cpp_error (pfile, CPP_DL_ERROR, /* FIXME should be DL_SORRY */
- "conversion from %s to %s not supported by iconv",
- from, to);
- else
- cpp_errno (pfile, CPP_DL_ERROR, "iconv_open");
-
+ if (pfile)
+ {
+ if (errno == EINVAL)
+ cpp_error (pfile, CPP_DL_ERROR, /* FIXME should be DL_SORRY */
+ "conversion from %s to %s not supported by iconv",
+ from, to);
+ else
+ cpp_errno (pfile, CPP_DL_ERROR, "iconv_open");
+ }
ret.func = convert_no_conversion;
}
}
else
{
- cpp_error (pfile, CPP_DL_ERROR, /* FIXME: should be DL_SORRY */
- "no iconv implementation, cannot convert from %s to %s",
- from, to);
+ if (pfile)
+ {
+ cpp_error (pfile, CPP_DL_ERROR, /* FIXME: should be DL_SORRY */
+ "no iconv implementation, cannot convert from %s to %s",
+ from, to);
+ }
ret.func = convert_no_conversion;
ret.cd = (iconv_t) -1;
ret.width = -1;
}
+
return ret;
}
@@ -2122,6 +2132,25 @@ _cpp_interpret_identifier (cpp_reader *pfile, const uchar *id, size_t len)
buf, bufp - buf, HT_ALLOC));
}
+
+/* Utility to strip a UTF-8 byte order marking from the beginning
+ of a buffer. Returns the number of bytes to skip, which currently
+ will be either 0 or 3. */
+int
+cpp_check_utf8_bom (const char *data, size_t data_length)
+{
+
+#if HOST_CHARSET == HOST_CHARSET_ASCII
+ const unsigned char *udata = (const unsigned char *) data;
+ if (data_length >= 3 && udata[0] == 0xef && udata[1] == 0xbb
+ && udata[2] == 0xbf)
+ return 3;
+#endif
+
+ return 0;
+}
+
+
/* Convert an input buffer (containing the complete contents of one
source file) from INPUT_CHARSET to the source character set. INPUT
points to the input buffer, SIZE is its allocated size, and LEN is
@@ -2135,7 +2164,11 @@ _cpp_interpret_identifier (cpp_reader *pfile, const uchar *id, size_t len)
INPUT is expected to have been allocated with xmalloc. This
function will either set *BUFFER_START to INPUT, or free it and set
*BUFFER_START to a pointer to another xmalloc-allocated block of
- memory. */
+ memory.
+
+ PFILE is only used to generate diagnostics; setting it to NULL suppresses
+ diagnostics, and causes a return of NULL if there was any error instead. */
+
uchar *
_cpp_convert_input (cpp_reader *pfile, const char *input_charset,
uchar *input, size_t size, size_t len,
@@ -2158,17 +2191,27 @@ _cpp_convert_input (cpp_reader *pfile, const char *input_charset,
to.text = XNEWVEC (uchar, to.asize);
to.len = 0;
- if (!APPLY_CONVERSION (input_cset, input, len, &to))
- cpp_error (pfile, CPP_DL_ERROR,
- "failure to convert %s to %s",
- CPP_OPTION (pfile, input_charset), SOURCE_CHARSET);
-
+ const bool ok = APPLY_CONVERSION (input_cset, input, len, &to);
free (input);
- }
- /* Clean up the mess. */
- if (input_cset.func == convert_using_iconv)
- iconv_close (input_cset.cd);
+ /* Clean up the mess. */
+ if (input_cset.func == convert_using_iconv)
+ iconv_close (input_cset.cd);
+
+ /* Handle conversion failure. */
+ if (!ok)
+ {
+ if (!pfile)
+ {
+ XDELETEVEC (to.text);
+ *buffer_start = NULL;
+ *st_size = 0;
+ return NULL;
+ }
+ cpp_error (pfile, CPP_DL_ERROR, "failure to convert %s to %s",
+ input_charset, SOURCE_CHARSET);
+ }
+ }
/* Resize buffer if we allocated substantially too much, or if we
haven't enough space for the \n-terminator or following
@@ -2192,19 +2235,14 @@ _cpp_convert_input (cpp_reader *pfile, const char *input_charset,
buffer = to.text;
*st_size = to.len;
-#if HOST_CHARSET == HOST_CHARSET_ASCII
- /* The HOST_CHARSET test just above ensures that the source charset
- is UTF-8. So, ignore a UTF-8 BOM if we see one. Note that
- glib'c UTF-8 iconv() provider (as of glibc 2.7) does not ignore a
+
+ /* Ignore a UTF-8 BOM if we see one and the source charset is UTF-8. Note
+ that glib'c UTF-8 iconv() provider (as of glibc 2.7) does not ignore a
BOM -- however, even if it did, we would still need this code due
to the 'convert_no_conversion' case. */
- if (to.len >= 3 && to.text[0] == 0xef && to.text[1] == 0xbb
- && to.text[2] == 0xbf)
- {
- *st_size -= 3;
- buffer += 3;
- }
-#endif
+ const int bom_len = cpp_check_utf8_bom ((const char *) to.text, to.len);
+ *st_size -= bom_len;
+ buffer += bom_len;
*buffer_start = to.text;
return buffer;
@@ -2244,6 +2282,13 @@ _cpp_default_encoding (void)
return current_encoding;
}
+/* Check if the configured input charset requires no conversion, other than
+ possibly stripping a UTF-8 BOM. */
+bool cpp_input_conversion_is_trivial (const char *input_charset)
+{
+ return !strcasecmp (input_charset, SOURCE_CHARSET);
+}
+
/* Implementation of class cpp_string_location_reader. */
/* Constructor for cpp_string_location_reader. */
diff --git a/libcpp/files.c b/libcpp/files.c
index 6e20fc5..c93a03c 100644
--- a/libcpp/files.c
+++ b/libcpp/files.c
@@ -173,7 +173,7 @@ static bool pch_open_file (cpp_reader *pfile, _cpp_file *file,
static bool find_file_in_dir (cpp_reader *pfile, _cpp_file *file,
bool *invalid_pch, location_t loc);
static bool read_file_guts (cpp_reader *pfile, _cpp_file *file,
- location_t loc);
+ location_t loc, const char *input_charset);
static bool read_file (cpp_reader *pfile, _cpp_file *file,
location_t loc);
static struct cpp_dir *search_path_head (cpp_reader *, const char *fname,
@@ -671,9 +671,12 @@ _cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir,
Use LOC for any diagnostics.
+ PFILE may be NULL. In this case, no diagnostics are issued.
+
FIXME: Flush file cache and try again if we run out of memory. */
static bool
-read_file_guts (cpp_reader *pfile, _cpp_file *file, location_t loc)
+read_file_guts (cpp_reader *pfile, _cpp_file *file, location_t loc,
+ const char *input_charset)
{
ssize_t size, total, count;
uchar *buf;
@@ -681,8 +684,9 @@ read_file_guts (cpp_reader *pfile, _cpp_file *file, location_t loc)
if (S_ISBLK (file->st.st_mode))
{
- cpp_error_at (pfile, CPP_DL_ERROR, loc,
- "%s is a block device", file->path);
+ if (pfile)
+ cpp_error_at (pfile, CPP_DL_ERROR, loc,
+ "%s is a block device", file->path);
return false;
}
@@ -699,8 +703,9 @@ read_file_guts (cpp_reader *pfile, _cpp_file *file, location_t loc)
does not bite us. */
if (file->st.st_size > INTTYPE_MAXIMUM (ssize_t))
{
- cpp_error_at (pfile, CPP_DL_ERROR, loc,
- "%s is too large", file->path);
+ if (pfile)
+ cpp_error_at (pfile, CPP_DL_ERROR, loc,
+ "%s is too large", file->path);
return false;
}
@@ -733,29 +738,29 @@ read_file_guts (cpp_reader *pfile, _cpp_file *file, location_t loc)
if (count < 0)
{
- cpp_errno_filename (pfile, CPP_DL_ERROR, file->path, loc);
+ if (pfile)
+ cpp_errno_filename (pfile, CPP_DL_ERROR, file->path, loc);
free (buf);
return false;
}
- if (regular && total != size && STAT_SIZE_RELIABLE (file->st))
+ if (pfile && regular && total != size && STAT_SIZE_RELIABLE (file->st))
cpp_error_at (pfile, CPP_DL_WARNING, loc,
"%s is shorter than expected", file->path);
file->buffer = _cpp_convert_input (pfile,
- CPP_OPTION (pfile, input_charset),
+ input_charset,
buf, size + 16, total,
&file->buffer_start,
&file->st.st_size);
- file->buffer_valid = true;
-
- return true;
+ file->buffer_valid = file->buffer;
+ return file->buffer_valid;
}
/* Convenience wrapper around read_file_guts that opens the file if
necessary and closes the file descriptor after reading. FILE must
have been passed through find_file() at some stage. Use LOC for
- any diagnostics. */
+ any diagnostics. Unlike read_file_guts(), PFILE may not be NULL. */
static bool
read_file (cpp_reader *pfile, _cpp_file *file, location_t loc)
{
@@ -773,7 +778,8 @@ read_file (cpp_reader *pfile, _cpp_file *file, location_t loc)
return false;
}
- file->dont_read = !read_file_guts (pfile, file, loc);
+ file->dont_read = !read_file_guts (pfile, file, loc,
+ CPP_OPTION (pfile, input_charset));
close (file->fd);
file->fd = -1;
@@ -2145,3 +2151,25 @@ _cpp_has_header (cpp_reader *pfile, const char *fname, int angle_brackets,
return file->err_no != ENOENT;
}
+/* Read a file and convert to input charset, the same as if it were being read
+ by a cpp_reader. */
+
+cpp_converted_source
+cpp_get_converted_source (const char *fname, const char *input_charset)
+{
+ cpp_converted_source res = {};
+ _cpp_file file = {};
+ file.fd = -1;
+ file.name = lbasename (fname);
+ file.path = fname;
+ if (!open_file (&file))
+ return res;
+ const bool ok = read_file_guts (NULL, &file, 0, input_charset);
+ close (file.fd);
+ if (!ok)
+ return res;
+ res.to_free = (char *) file.buffer_start;
+ res.data = (char *) file.buffer;
+ res.len = file.st.st_size;
+ return res;
+}
diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h
index 7e84063..af14291 100644
--- a/libcpp/include/cpplib.h
+++ b/libcpp/include/cpplib.h
@@ -1379,6 +1379,20 @@ extern struct _cpp_file *cpp_get_file (cpp_buffer *);
extern cpp_buffer *cpp_get_prev (cpp_buffer *);
extern void cpp_clear_file_cache (cpp_reader *);
+/* cpp_get_converted_source returns the contents of the given file, as it exists
+ after cpplib has read it and converted it from the input charset to the
+ source charset. Return struct will be zero-filled if the data could not be
+ read for any reason. The data starts at the DATA pointer, but the TO_FREE
+ pointer is what should be passed to free(), as there may be an offset. */
+struct cpp_converted_source
+{
+ char *to_free;
+ char *data;
+ size_t len;
+};
+cpp_converted_source cpp_get_converted_source (const char *fname,
+ const char *input_charset);
+
/* In pch.c */
struct save_macro_data;
extern int cpp_save_state (cpp_reader *, FILE *);
@@ -1449,6 +1463,7 @@ class cpp_display_width_computation {
/* Convenience functions that are simple use cases for class
cpp_display_width_computation. Tab characters will be expanded to spaces
as determined by TABSTOP. */
+
int cpp_byte_column_to_display_column (const char *data, int data_length,
int column, int tabstop);
inline int cpp_display_width (const char *data, int data_length,
@@ -1461,4 +1476,7 @@ int cpp_display_column_to_byte_column (const char *data, int data_length,
int display_col, int tabstop);
int cpp_wcwidth (cppchar_t c);
+bool cpp_input_conversion_is_trivial (const char *input_charset);
+int cpp_check_utf8_bom (const char *data, size_t data_length);
+
#endif /* ! LIBCPP_CPPLIB_H */
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index 9f6d04e..32556aa 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,9 @@
+2021-08-24 Richard Earnshaw <rearnsha@arm.com>
+
+ PR target/102035
+ * config/arm/cmse_nonsecure_call.S (__gnu_cmse_nonsecure_call):
+ Add vlldm erratum work-around.
+
2021-08-21 John David Anglin <danglin@gcc.gnu.org>
* config.host: Remove extra_parts from hppa[12]*-*-hpux11* case.
diff --git a/libgcc/config/i386/cygming-crtend.c b/libgcc/config/i386/cygming-crtend.c
index c7ba109..4ab6342 100644
--- a/libgcc/config/i386/cygming-crtend.c
+++ b/libgcc/config/i386/cygming-crtend.c
@@ -56,7 +56,10 @@ static EH_FRAME_SECTION_CONST int __FRAME_END__[]
extern void __gcc_register_frame (void);
extern void __gcc_deregister_frame (void);
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wprio-ctor-dtor"
static void register_frame_ctor (void) __attribute__ ((constructor (0)));
+#pragma GCC diagnostic pop
static void
register_frame_ctor (void)
@@ -65,7 +68,10 @@ register_frame_ctor (void)
}
#if !DEFAULT_USE_CXA_ATEXIT
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wprio-ctor-dtor"
static void deregister_frame_dtor (void) __attribute__ ((destructor (0)));
+#pragma GCC diagnostic pop
static void
deregister_frame_dtor (void)
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index e5e7daa..70f97a5 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,68 @@
+2021-08-25 Jonathan Wakely <jwakely@redhat.com>
+
+ * testsuite/17_intro/names.cc: Check 'sz'.
+
+2021-08-25 Jonathan Wakely <jwakely@redhat.com>
+
+ * testsuite/17_intro/names.cc: Adjust for Windows.
+
+2021-08-25 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/std/valarray: Uglify 'func' parameters.
+ * testsuite/17_intro/names.cc: Add 'func' to checks.
+
+2021-08-25 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/102064
+ * include/bits/stl_uninitialized.h (_GLIBCXX_USE_ASSIGN_FOR_INIT):
+ Define macro to check conditions for optimizing trivial cases.
+ (__check_constructible): New function to do static assert.
+ (uninitialized_copy, uninitialized_fill, uninitialized_fill_n):
+ Use new macro.
+ * testsuite/20_util/specialized_algorithms/uninitialized_copy/1.cc:
+ Adjust dg-error pattern.
+ * testsuite/23_containers/vector/cons/89164.cc: Likewise. Add
+ C++17-specific checks from 89164_c++17.cc.
+ * testsuite/23_containers/vector/cons/89164_c++17.cc: Removed.
+ * testsuite/20_util/specialized_algorithms/uninitialized_copy/102064.cc:
+ New test.
+ * testsuite/20_util/specialized_algorithms/uninitialized_copy_n/102064.cc:
+ New test.
+ * testsuite/20_util/specialized_algorithms/uninitialized_fill/102064.cc:
+ New test.
+ * testsuite/20_util/specialized_algorithms/uninitialized_fill_n/102064.cc:
+ New test.
+
+2021-08-25 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/102048
+ * include/ext/rope (rope::erase(size_type)): Remove broken
+ function.
+
+2021-08-24 Jonathan Wakely <jwakely@redhat.com>
+
+ * doc/xml/manual/status_cxx2020.xml: Update table.
+ * doc/html/manual/status.html: Regenerate.
+
+2021-08-24 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/std/type_traits (is_layout_compatible): Define.
+ (is_corresponding_member): Define.
+ * include/std/version (__cpp_lib_is_layout_compatible): Define.
+ * testsuite/20_util/is_layout_compatible/is_corresponding_member.cc:
+ New test.
+ * testsuite/20_util/is_layout_compatible/value.cc: New test.
+ * testsuite/20_util/is_layout_compatible/version.cc: New test.
+ * testsuite/20_util/is_pointer_interconvertible/with_class.cc:
+ New test.
+ * testsuite/23_containers/span/layout_compat.cc: Do not use real
+ std::is_layout_compatible trait if available.
+
+2021-08-24 Jonathan Wakely <jwakely@redhat.com>
+
+ * src/c++11/cxx11-shim_facets.cc: Fix mismatched class-key in
+ explicit instantiation definitions.
+
2021-08-23 Jonathan Wakely <jwakely@redhat.com>
* include/std/ranges (basic_istream_view): Add default template
diff --git a/libstdc++-v3/doc/html/manual/status.html b/libstdc++-v3/doc/html/manual/status.html
index 0ce624b..ad61231 100644
--- a/libstdc++-v3/doc/html/manual/status.html
+++ b/libstdc++-v3/doc/html/manual/status.html
@@ -1324,10 +1324,10 @@ or any notes about the implementation.
</td><td align="center"> 9.1 </td><td align="left"> </td></tr><tr><td align="left"> Traits for [Un]bounded Arrays </td><td align="left">
<a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1357r1.pdf" target="_top">
P1357R1 </a>
- </td><td align="center"> 9.1 </td><td align="left"> <code class="code">__cpp_lib_bounded_array_traits &gt;= 201902L</code> </td></tr><tr bgcolor="#C8B0B0"><td align="left"> Layout-compatibility and pointer-interconvertibility traits </td><td align="left">
+ </td><td align="center"> 9.1 </td><td align="left"> <code class="code">__cpp_lib_bounded_array_traits &gt;= 201902L</code> </td></tr><tr><td align="left"> Layout-compatibility and pointer-interconvertibility traits </td><td align="left">
<a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0466r5.pdf" target="_top">
P0466R5 </a>
- </td><td align="center"> </td><td align="left">
+ </td><td align="center"> 12 </td><td align="left">
<div class="informaltable"><table class="informaltable" border="0"><colgroup><col /></colgroup><tbody><tr><td> <code class="code">__cpp_lib_is_layout_compatible &gt;= 201907L</code> </td></tr><tr><td> <code class="code">__cpp_lib_is_pointer_interconvertible &gt;= 201907L</code> </td></tr></tbody></table></div>
</td></tr><tr><td align="left"> Integrating feature-test macros into the C++ WD </td><td align="left">
<a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0941r2.html" target="_top">
diff --git a/libstdc++-v3/doc/xml/manual/status_cxx2020.xml b/libstdc++-v3/doc/xml/manual/status_cxx2020.xml
index a729ddd..26c8829 100644
--- a/libstdc++-v3/doc/xml/manual/status_cxx2020.xml
+++ b/libstdc++-v3/doc/xml/manual/status_cxx2020.xml
@@ -294,13 +294,12 @@ or any notes about the implementation.
</row>
<row>
- <?dbhtml bgcolor="#C8B0B0" ?>
<entry> Layout-compatibility and pointer-interconvertibility traits </entry>
<entry>
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0466r5.pdf">
P0466R5 </link>
</entry>
- <entry align="center"> </entry>
+ <entry align="center"> 12 </entry>
<entry>
<informaltable colsep="0" rowsep="0" rowheader="norowheader" frame="none"><tgroup cols="1"><tbody>
<row><entry> <code>__cpp_lib_is_layout_compatible &gt;= 201907L</code> </entry></row>
diff --git a/libstdc++-v3/include/bits/stl_uninitialized.h b/libstdc++-v3/include/bits/stl_uninitialized.h
index f7b2481..ddc1405 100644
--- a/libstdc++-v3/include/bits/stl_uninitialized.h
+++ b/libstdc++-v3/include/bits/stl_uninitialized.h
@@ -77,6 +77,36 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// @cond undocumented
+#if __cplusplus >= 201103L
+ template<typename _ValueType, typename _Tp>
+ constexpr bool
+ __check_constructible()
+ {
+ // Trivial types can have deleted constructors, but std::copy etc.
+ // only use assignment (or memmove) not construction, so we need an
+ // explicit check that construction from _Tp is actually valid,
+ // otherwise some ill-formed uses of std::uninitialized_xxx would
+ // compile without errors. This gives a nice clear error message.
+ static_assert(is_constructible<_ValueType, _Tp>::value,
+ "result type must be constructible from input type");
+
+ return true;
+ }
+
+// If the type is trivial we don't need to construct it, just assign to it.
+// But trivial types can still have deleted or inaccessible assignment,
+// so don't try to use std::copy or std::fill etc. if we can't assign.
+# define _GLIBCXX_USE_ASSIGN_FOR_INIT(T, U) \
+ __is_trivial(T) && __is_assignable(T&, U) \
+ && std::__check_constructible<T, U>()
+#else
+// No need to check if is_constructible<T, U> for C++98. Trivial types have
+// no user-declared constructors, so if the assignment is valid, construction
+// should be too.
+# define _GLIBCXX_USE_ASSIGN_FOR_INIT(T, U) \
+ __is_trivial(T) && __is_assignable(T&, U)
+#endif
+
template<bool _TrivialValueTypes>
struct __uninitialized_copy
{
@@ -130,24 +160,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_ValueType1;
typedef typename iterator_traits<_ForwardIterator>::value_type
_ValueType2;
+
+ // _ValueType1 must be trivially-copyable to use memmove, so don't
+ // both optimizing to std::copy if it isn't.
+ // XXX Unnecessary because std::copy would check it anyway?
+ const bool __can_memmove = __is_trivial(_ValueType1);
+
#if __cplusplus < 201103L
- const bool __assignable = true;
+ typedef typename iterator_traits<_InputIterator>::reference _From;
#else
- // Trivial types can have deleted copy constructor, but the std::copy
- // optimization that uses memmove would happily "copy" them anyway.
- static_assert(is_constructible<_ValueType2, decltype(*__first)>::value,
- "result type must be constructible from value type of input range");
-
- typedef typename iterator_traits<_InputIterator>::reference _RefType1;
- typedef typename iterator_traits<_ForwardIterator>::reference _RefType2;
- // Trivial types can have deleted assignment, so using std::copy
- // would be ill-formed. Require assignability before using std::copy:
- const bool __assignable = is_assignable<_RefType2, _RefType1>::value;
+ using _From = decltype(*__first);
#endif
+ const bool __assignable
+ = _GLIBCXX_USE_ASSIGN_FOR_INIT(_ValueType2, _From);
- return std::__uninitialized_copy<__is_trivial(_ValueType1)
- && __is_trivial(_ValueType2)
- && __assignable>::
+ return std::__uninitialized_copy<__can_memmove && __assignable>::
__uninit_copy(__first, __last, __result);
}
@@ -203,20 +230,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
typedef typename iterator_traits<_ForwardIterator>::value_type
_ValueType;
-#if __cplusplus < 201103L
- const bool __assignable = true;
-#else
- // Trivial types can have deleted copy constructor, but the std::fill
- // optimization that uses memmove would happily "copy" them anyway.
- static_assert(is_constructible<_ValueType, const _Tp&>::value,
- "result type must be constructible from input type");
- // Trivial types can have deleted assignment, so using std::fill
- // would be ill-formed. Require assignability before using std::fill:
- const bool __assignable = is_copy_assignable<_ValueType>::value;
-#endif
+ // Trivial types do not need a constructor to begin their lifetime,
+ // so try to use std::fill to benefit from its memset optimization.
+ const bool __can_fill
+ = _GLIBCXX_USE_ASSIGN_FOR_INIT(_ValueType, const _Tp&);
- std::__uninitialized_fill<__is_trivial(_ValueType) && __assignable>::
+ std::__uninitialized_fill<__can_fill>::
__uninit_fill(__first, __last, __x);
}
@@ -276,27 +296,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_ValueType;
// Trivial types do not need a constructor to begin their lifetime,
- // so try to use std::fill_n to benefit from its memmove optimization.
+ // so try to use std::fill_n to benefit from its optimizations.
+ const bool __can_fill
+ = _GLIBCXX_USE_ASSIGN_FOR_INIT(_ValueType, const _Tp&)
// For arbitrary class types and floating point types we can't assume
// that __n > 0 and std::__size_to_integer(__n) > 0 are equivalent,
// so only use std::fill_n when _Size is already an integral type.
-#if __cplusplus < 201103L
- const bool __can_fill = __is_integer<_Size>::__value;
-#else
- // Trivial types can have deleted copy constructor, but the std::fill_n
- // optimization that uses memmove would happily "copy" them anyway.
- static_assert(is_constructible<_ValueType, const _Tp&>::value,
- "result type must be constructible from input type");
+ && __is_integer<_Size>::__value;
- // Trivial types can have deleted assignment, so using std::fill_n
- // would be ill-formed. Require assignability before using std::fill_n:
- constexpr bool __can_fill
- = __and_<is_integral<_Size>, is_copy_assignable<_ValueType>>::value;
-#endif
- return __uninitialized_fill_n<__is_trivial(_ValueType) && __can_fill>::
+ return __uninitialized_fill_n<__can_fill>::
__uninit_fill_n(__first, __n, __x);
}
+#undef _GLIBCXX_USE_ASSIGN_FOR_INIT
+
/// @cond undocumented
// Extensions: versions of uninitialized_copy, uninitialized_fill,
@@ -864,6 +877,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __n The number of elements to copy.
* @param __result An output iterator.
* @return __result + __n
+ * @since C++11
*
* Like copy_n(), but does not require an initialized output range.
*/
@@ -894,6 +908,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @brief Default-initializes objects in the range [first,last).
* @param __first A forward iterator.
* @param __last A forward iterator.
+ * @since C++17
*/
template <typename _ForwardIterator>
inline void
@@ -908,6 +923,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __first A forward iterator.
* @param __count The number of objects to construct.
* @return __first + __count
+ * @since C++17
*/
template <typename _ForwardIterator, typename _Size>
inline _ForwardIterator
@@ -920,6 +936,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @brief Value-initializes objects in the range [first,last).
* @param __first A forward iterator.
* @param __last A forward iterator.
+ * @since C++17
*/
template <typename _ForwardIterator>
inline void
@@ -934,6 +951,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __first A forward iterator.
* @param __count The number of objects to construct.
* @return __result + __count
+ * @since C++17
*/
template <typename _ForwardIterator, typename _Size>
inline _ForwardIterator
@@ -948,6 +966,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __last An input iterator.
* @param __result An output iterator.
* @return __result + (__first - __last)
+ * @since C++17
*/
template <typename _InputIterator, typename _ForwardIterator>
inline _ForwardIterator
@@ -965,6 +984,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __count The number of objects to initialize.
* @param __result An output iterator.
* @return __result + __count
+ * @since C++17
*/
template <typename _InputIterator, typename _Size, typename _ForwardIterator>
inline pair<_InputIterator, _ForwardIterator>
diff --git a/libstdc++-v3/include/ext/rope b/libstdc++-v3/include/ext/rope
index 9681dbc..d4406a9 100644
--- a/libstdc++-v3/include/ext/rope
+++ b/libstdc++-v3/include/ext/rope
@@ -2401,11 +2401,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
this->_M_tree_ptr = __result;
}
- // Erase, single character
- void
- erase(size_type __p)
- { erase(__p, __p + 1); }
-
// Insert, iterator variants.
iterator
insert(const iterator& __p, const rope& __r)
diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index 1571800..a0010d9 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -3414,6 +3414,31 @@ template<typename _Ret, typename _Fn, typename... _Args>
inline constexpr bool is_unbounded_array_v
= is_unbounded_array<_Tp>::value;
+#if __has_builtin(__is_layout_compatible)
+
+ /// @since C++20
+ template<typename _Tp, typename _Up>
+ struct is_layout_compatible
+ : bool_constant<__is_layout_compatible(_Tp, _Up)>
+ { };
+
+ /// @ingroup variable_templates
+ /// @since C++20
+ template<typename _Tp, typename _Up>
+ constexpr bool is_layout_compatible_v
+ = __is_layout_compatible(_Tp, _Up);
+
+#if __has_builtin(__builtin_is_corresponding_member)
+#define __cpp_lib_is_layout_compatible 201907L
+
+ /// @since C++20
+ template<typename _S1, typename _S2, typename _M1, typename _M2>
+ constexpr bool
+ is_corresponding_member(_M1 _S1::*__m1, _M2 _S2::*__m2) noexcept
+ { return __builtin_is_corresponding_member(__m1, __m2); }
+#endif
+#endif
+
#if __has_builtin(__is_pointer_interconvertible_base_of)
/// True if `_Derived` is standard-layout and has a base class of type `_Base`
/// @since C++20
diff --git a/libstdc++-v3/include/std/valarray b/libstdc++-v3/include/std/valarray
index ad3e14e..5adc942 100644
--- a/libstdc++-v3/include/std/valarray
+++ b/libstdc++-v3/include/std/valarray
@@ -536,25 +536,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @brief Apply a function to the array.
*
* Returns a new valarray with elements assigned to the result of
- * applying func to the corresponding element of this array. The new
+ * applying __func to the corresponding element of this array. The new
* array has the same size as this one.
*
- * @param func Function of Tp returning Tp to apply.
+ * @param __func Function of Tp returning Tp to apply.
* @return New valarray with transformed elements.
*/
- _Expr<_ValFunClos<_ValArray, _Tp>, _Tp> apply(_Tp func(_Tp)) const;
+ _Expr<_ValFunClos<_ValArray, _Tp>, _Tp> apply(_Tp __func(_Tp)) const;
/**
* @brief Apply a function to the array.
*
* Returns a new valarray with elements assigned to the result of
- * applying func to the corresponding element of this array. The new
+ * applying __func to the corresponding element of this array. The new
* array has the same size as this one.
*
- * @param func Function of const Tp& returning Tp to apply.
+ * @param __func Function of const Tp& returning Tp to apply.
* @return New valarray with transformed elements.
*/
- _Expr<_RefFunClos<_ValArray, _Tp>, _Tp> apply(_Tp func(const _Tp&)) const;
+ _Expr<_RefFunClos<_ValArray, _Tp>, _Tp> apply(_Tp __func(const _Tp&)) const;
/**
* @brief Resize array.
@@ -1062,18 +1062,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<class _Tp>
inline _Expr<_ValFunClos<_ValArray, _Tp>, _Tp>
- valarray<_Tp>::apply(_Tp func(_Tp)) const
+ valarray<_Tp>::apply(_Tp __func(_Tp)) const
{
typedef _ValFunClos<_ValArray, _Tp> _Closure;
- return _Expr<_Closure, _Tp>(_Closure(*this, func));
+ return _Expr<_Closure, _Tp>(_Closure(*this, __func));
}
template<class _Tp>
inline _Expr<_RefFunClos<_ValArray, _Tp>, _Tp>
- valarray<_Tp>::apply(_Tp func(const _Tp &)) const
+ valarray<_Tp>::apply(_Tp __func(const _Tp &)) const
{
typedef _RefFunClos<_ValArray, _Tp> _Closure;
- return _Expr<_Closure, _Tp>(_Closure(*this, func));
+ return _Expr<_Closure, _Tp>(_Closure(*this, __func));
}
#define _DEFINE_VALARRAY_UNARY_OPERATOR(_Op, _Name) \
diff --git a/libstdc++-v3/include/std/version b/libstdc++-v3/include/std/version
index 925f277..70d573b 100644
--- a/libstdc++-v3/include/std/version
+++ b/libstdc++-v3/include/std/version
@@ -236,6 +236,10 @@
#ifdef _GLIBCXX_HAS_GTHREADS
# define __cpp_lib_jthread 201911L
#endif
+#if __has_builtin(__is_layout_compatible) \
+ && __has_builtin(__builtin_is_corresponding_member)
+# define __cpp_lib_is_layout_compatible 201907L
+#endif
#if __has_builtin(__is_pointer_interconvertible_base_of) \
&& __has_builtin(__builtin_is_pointer_interconvertible_with_class)
# define __cpp_lib_is_pointer_interconvertible 201907L
diff --git a/libstdc++-v3/testsuite/17_intro/names.cc b/libstdc++-v3/testsuite/17_intro/names.cc
index aca7a8e..b945511 100644
--- a/libstdc++-v3/testsuite/17_intro/names.cc
+++ b/libstdc++-v3/testsuite/17_intro/names.cc
@@ -106,7 +106,9 @@
#endif
#define z (
+#define func (
#define tmp (
+#define sz (
#if __cplusplus < 201103L
#define uses_allocator (
@@ -286,4 +288,14 @@
#endif // __VXWORKS__
+#ifdef _WIN32
+#undef Value
+// <stdlib.h> defines _CRT_FLOAT::f
+#undef f
+// <stdlib.h> defines _CRT_DOUBLE::x and _LONGDOUBLE::x
+#undef x
+// <math.h> defines _complex::x and _complex::y
+#undef y
+#endif
+
#include <bits/stdc++.h>
diff --git a/libstdc++-v3/testsuite/20_util/is_layout_compatible/is_corresponding_member.cc b/libstdc++-v3/testsuite/20_util/is_layout_compatible/is_corresponding_member.cc
new file mode 100644
index 0000000..69b359a
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/is_layout_compatible/is_corresponding_member.cc
@@ -0,0 +1,19 @@
+// { dg-options "-std=gnu++20" }
+// { dg-do compile { target c++20 } }
+#include <type_traits>
+
+using std::is_corresponding_member;
+
+struct A { int a; };
+struct B { int b; };
+struct C: public A, public B { }; // not a standard-layout class
+
+static_assert( is_corresponding_member( &C::a, &C::b ) );
+// Succeeds because arguments have types int A::* and int B::*
+
+constexpr int C::*a = &C::a;
+constexpr int C::*b = &C::b;
+static_assert( ! is_corresponding_member( a, b ) );
+// Not corresponding members, because arguments both have type int C::*
+
+static_assert( noexcept(!is_corresponding_member(a, b)) );
diff --git a/libstdc++-v3/testsuite/20_util/is_layout_compatible/value.cc b/libstdc++-v3/testsuite/20_util/is_layout_compatible/value.cc
new file mode 100644
index 0000000..7686b34
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/is_layout_compatible/value.cc
@@ -0,0 +1,56 @@
+// { dg-options "-std=gnu++20" }
+// { dg-do compile { target c++20 } }
+#include <type_traits>
+
+#ifndef __cpp_lib_is_layout_compatible
+# error "Feature test macro for is_layout_compatible is missing in <type_traits>"
+#elif __cpp_lib_is_layout_compatible < 201907L
+# error "Feature test macro for is_layout_compatible has wrong value in <type_traits>"
+#endif
+
+template<typename T, typename U>
+concept variable_template_is_correct
+ = std::is_layout_compatible_v<T, U> == std::is_layout_compatible<T, U>::value;
+
+template<typename T, typename U>
+requires variable_template_is_correct<T, U>
+constexpr bool is_layout_compatible = std::is_layout_compatible_v<T, U>;
+
+static_assert( is_layout_compatible<void, void> );
+static_assert( is_layout_compatible<int, int> );
+static_assert( ! is_layout_compatible<int, int[]> );
+static_assert( ! is_layout_compatible<int, int[1]> );
+static_assert( is_layout_compatible<int[], int[]> );
+static_assert( is_layout_compatible<int[1], int[1]> );
+static_assert( ! is_layout_compatible<int[1], int[]> );
+static_assert( ! is_layout_compatible<int[1], int[2]> );
+
+struct Incomplete;
+// The standard says these are undefined, but they should work really:
+// static_assert( is_layout_compatible<Incomplete, Incomplete> );
+// static_assert( ! is_layout_compatible<Incomplete[], Incomplete> );
+static_assert( is_layout_compatible<Incomplete[], Incomplete[]> );
+
+enum E1 : int { };
+enum E2 : int;
+static_assert( is_layout_compatible<E1, E2> );
+enum E3 : unsigned int;
+static_assert( ! is_layout_compatible<E1, E3> );
+enum E4 : char { };
+enum E5 : signed char { };
+enum E6 : unsigned char { };
+static_assert( ! is_layout_compatible<E4, E5> );
+static_assert( ! is_layout_compatible<E4, E6> );
+static_assert( ! is_layout_compatible<E5, E6> );
+
+struct A { int a; };
+struct B { const int b; };
+static_assert( is_layout_compatible<A, B> );
+static_assert( is_layout_compatible<B, A> );
+
+struct C : A { };
+struct D : B { };
+static_assert( is_layout_compatible<C, D> );
+
+struct E : A { int i; }; // not standard-layout
+static_assert( ! is_layout_compatible<E, A> );
diff --git a/libstdc++-v3/testsuite/20_util/is_layout_compatible/version.cc b/libstdc++-v3/testsuite/20_util/is_layout_compatible/version.cc
new file mode 100644
index 0000000..1a32275
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/is_layout_compatible/version.cc
@@ -0,0 +1,10 @@
+// { dg-options "-std=gnu++20" }
+// { dg-do compile { target c++20 } }
+
+#include <version>
+
+#ifndef __cpp_lib_is_layout_compatible
+# error "Feature test macro for is_layout_compatible is missing in <version>"
+#elif __cpp_lib_is_pointer_interconvertible < 201907L
+# error "Feature test macro for is_layout_compatible has wrong value in <version>"
+#endif
diff --git a/libstdc++-v3/testsuite/20_util/is_pointer_interconvertible/with_class.cc b/libstdc++-v3/testsuite/20_util/is_pointer_interconvertible/with_class.cc
new file mode 100644
index 0000000..28de9b4
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/is_pointer_interconvertible/with_class.cc
@@ -0,0 +1,29 @@
+// { dg-options "-std=gnu++20" }
+// { dg-do compile { target c++20 } }
+#include <type_traits>
+
+struct A { int i; long l; };
+
+static_assert( std::is_pointer_interconvertible_with_class(&A::i) );
+static_assert( ! std::is_pointer_interconvertible_with_class(&A::l) );
+
+constexpr int A::*a = nullptr;
+static_assert( ! std::is_pointer_interconvertible_with_class(a) );
+static_assert( noexcept( std::is_pointer_interconvertible_with_class(a) ) );
+
+struct B { const int i; };
+static_assert( std::is_pointer_interconvertible_with_class(&B::i) );
+
+struct C { int f(); };
+static_assert( ! std::is_pointer_interconvertible_with_class(&C::f) );
+
+struct D : A { };
+static_assert( std::is_pointer_interconvertible_with_class(&D::i) );
+
+struct E : A { int j; };
+// This works because the type of &E::i is int A::* and A is standard-layout:
+static_assert( std::is_pointer_interconvertible_with_class(&E::i) );
+constexpr int E::*e = a;
+// This fails because E is not standard-layout:
+static_assert( ! std::is_pointer_interconvertible_with_class(e) );
+static_assert( ! std::is_pointer_interconvertible_with_class(&E::j) );
diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy/1.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy/1.cc
index 9678749..6b43b58 100644
--- a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy/1.cc
+++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy/1.cc
@@ -34,4 +34,4 @@ test01(T* result)
T t[1];
std::uninitialized_copy(t, t+1, result); // { dg-error "here" }
}
-// { dg-error "constructible from value" "" { target *-*-* } 0 }
+// { dg-error "must be constructible from input type" "" { target *-*-* } 0 }
diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy/102064.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy/102064.cc
new file mode 100644
index 0000000..27d37aa
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy/102064.cc
@@ -0,0 +1,52 @@
+// { dg-do compile }
+
+#include <memory>
+#include <algorithm>
+
+struct X;
+
+struct Y
+{
+ operator X() const;
+};
+
+struct X
+{
+private:
+ void operator=(const Y&);
+};
+
+Y::operator X() const { return X(); }
+
+#if __cplusplus >= 201103L
+static_assert( std::is_trivial<X>::value, "" );
+#endif
+
+void test01_pr102064()
+{
+ unsigned char buf[sizeof(X)];
+ X* addr = reinterpret_cast<X*>(buf);
+ const Y y[1] = { };
+ std::uninitialized_copy(y, y + 1, addr);
+}
+
+#if __cplusplus >= 201103L
+struct Z
+{
+ Z() = default;
+ Z(int) { }
+ Z(const Z&) = default;
+ Z& operator=(const Z&) = default;
+ Z& operator=(int) = delete;
+};
+
+static_assert( std::is_trivial<Z>::value, "" );
+
+void test02_pr102064()
+{
+ unsigned char buf[sizeof(Z)];
+ Z* addr = reinterpret_cast<Z*>(buf);
+ const int i[1] = { 99 };
+ std::uninitialized_copy(i, i + 1, addr);
+}
+#endif
diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy_n/102064.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy_n/102064.cc
new file mode 100644
index 0000000..963e153
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy_n/102064.cc
@@ -0,0 +1,48 @@
+// { dg-do compile { target c++11 } }
+
+#include <memory>
+#include <algorithm>
+
+struct X;
+
+struct Y
+{
+ operator X() const;
+};
+
+struct X
+{
+private:
+ void operator=(const Y&);
+};
+
+Y::operator X() const { return X(); }
+
+static_assert( std::is_trivial<X>::value, "" );
+
+void test01_pr102064()
+{
+ unsigned char buf[sizeof(X)];
+ X* addr = reinterpret_cast<X*>(buf);
+ const Y y[1] = { };
+ std::uninitialized_copy_n(y, 1, addr);
+}
+
+struct Z
+{
+ Z() = default;
+ Z(int) { }
+ Z(const Z&) = default;
+ Z& operator=(const Z&) = default;
+ Z& operator=(int) = delete;
+};
+
+static_assert( std::is_trivial<Z>::value, "" );
+
+void test02_pr102064()
+{
+ unsigned char buf[sizeof(Z)];
+ Z* addr = reinterpret_cast<Z*>(buf);
+ const int i[1] = { 99 };
+ std::uninitialized_copy_n(i, 1, addr);
+}
diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill/102064.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill/102064.cc
new file mode 100644
index 0000000..7eb49b5
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill/102064.cc
@@ -0,0 +1,51 @@
+// { dg-do compile }
+
+#include <memory>
+#include <algorithm>
+
+struct X;
+
+struct Y
+{
+ operator X() const;
+};
+
+struct X
+{
+private:
+ void operator=(const Y&);
+};
+
+Y::operator X() const { return X(); }
+
+#if __cplusplus >= 201103L
+static_assert( std::is_trivial<X>::value, "" );
+#endif
+
+void test01_pr102064()
+{
+ unsigned char buf[sizeof(X)];
+ X* addr = reinterpret_cast<X*>(buf);
+ Y y;
+ std::uninitialized_fill(addr, addr + 1, y);
+}
+
+#if __cplusplus >= 201103L
+struct Z
+{
+ Z() = default;
+ Z(int) { }
+ Z(const Z&) = default;
+ Z& operator=(const Z&) = default;
+ Z& operator=(int) = delete;
+};
+
+static_assert( std::is_trivial<Z>::value, "" );
+
+void test02_pr102064()
+{
+ unsigned char buf[sizeof(Z)];
+ Z* addr = reinterpret_cast<Z*>(buf);
+ std::uninitialized_fill(addr, addr + 1, 99);
+}
+#endif
diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill_n/102064.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill_n/102064.cc
new file mode 100644
index 0000000..e4f2139
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill_n/102064.cc
@@ -0,0 +1,51 @@
+// { dg-do compile }
+
+#include <memory>
+#include <algorithm>
+
+struct X;
+
+struct Y
+{
+ operator X() const;
+};
+
+struct X
+{
+private:
+ void operator=(const Y&);
+};
+
+Y::operator X() const { return X(); }
+
+#if __cplusplus >= 201103L
+static_assert( std::is_trivial<X>::value, "" );
+#endif
+
+void test01_pr102064()
+{
+ unsigned char buf[sizeof(X)];
+ X* addr = reinterpret_cast<X*>(buf);
+ Y y;
+ std::uninitialized_fill_n(addr, 1, y);
+}
+
+#if __cplusplus >= 201103L
+struct Z
+{
+ Z() = default;
+ Z(int) { }
+ Z(const Z&) = default;
+ Z& operator=(const Z&) = default;
+ Z& operator=(int) = delete;
+};
+
+static_assert( std::is_trivial<Z>::value, "" );
+
+void test02_pr102064()
+{
+ unsigned char buf[sizeof(Z)];
+ Z* addr = reinterpret_cast<Z*>(buf);
+ std::uninitialized_fill_n(addr, 1, 99);
+}
+#endif
diff --git a/libstdc++-v3/testsuite/23_containers/span/layout_compat.cc b/libstdc++-v3/testsuite/23_containers/span/layout_compat.cc
index 04947e9..bb560fe 100644
--- a/libstdc++-v3/testsuite/23_containers/span/layout_compat.cc
+++ b/libstdc++-v3/testsuite/23_containers/span/layout_compat.cc
@@ -27,22 +27,23 @@
struct iovec { void* iov_base; std::size_t iov_len; };
#endif
-#if __cpp_lib_is_layout_compatible
-using std::is_layout_compatible_v;
-#else
-// A poor substitute for is_layout_compatible_v
+// std::span cannot possibly be layout-compatible with struct iovec because
+// iovec::iov_base is a void* and span<void> is ill-formed. Additionally,
+// the libstdc++ std::span uses [[no_unique_address]] on the second member,
+// so that it's not present for a span of static extent, and that affects
+// layout-compatibility too.
+// Use this to check the size and alignment are compatible.
template<typename T, typename U>
- constexpr bool is_layout_compatible_v
+ constexpr bool same_size_and_alignment
= std::is_standard_layout_v<T> && std::is_standard_layout_v<U>
&& sizeof(T) == sizeof(U) && alignof(T) == alignof(U);
-#endif
void
test_pr95609()
{
using rbuf = std::span<const std::byte>;
- using wbuf = std::span<std::byte>;
+ static_assert(same_size_and_alignment<rbuf, struct iovec>);
- static_assert(is_layout_compatible_v<rbuf, struct iovec>);
- static_assert(is_layout_compatible_v<wbuf, struct iovec>);
+ using wbuf = std::span<std::byte>;
+ static_assert(same_size_and_alignment<wbuf, struct iovec>);
}
diff --git a/libstdc++-v3/testsuite/23_containers/vector/cons/89164.cc b/libstdc++-v3/testsuite/23_containers/vector/cons/89164.cc
index c308c97..302af9c 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/cons/89164.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/cons/89164.cc
@@ -36,5 +36,15 @@ void test01()
// Should not be able to create vector using uninitialized_fill_n:
std::vector<X> v2{2u, X{}}; // { dg-error "here" }
}
-// { dg-error "constructible from value" "" { target *-*-* } 0 }
-// { dg-error "constructible from input" "" { target *-*-* } 0 }
+
+void test02()
+{
+#if __cplusplus >= 201703L
+ struct Y : X { };
+ // Can create initializer_list<Y> with C++17 guaranteed copy elision,
+ // but shouldn't be able to copy from it with uninitialized_copy:
+ std::vector<Y> v3{Y{}, Y{}, Y{}}; // { dg-error "here" "" { target c++17 } }
+#endif
+}
+
+// { dg-error "must be constructible from input type" "" { target *-*-* } 0 }
diff --git a/libstdc++-v3/testsuite/23_containers/vector/cons/89164_c++17.cc b/libstdc++-v3/testsuite/23_containers/vector/cons/89164_c++17.cc
deleted file mode 100644
index 78aadc4..0000000
--- a/libstdc++-v3/testsuite/23_containers/vector/cons/89164_c++17.cc
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright (C) 2019-2021 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library. This library 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.
-
-// This library 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 this library; see the file COPYING3. If not see
-// <http://www.gnu.org/licenses/>.
-
-// { dg-do compile { target c++17 } }
-
-#include <vector>
-
-// PR libstdc++/89164
-
-struct X
-{
- X() = default;
- X(const X&) = delete;
-};
-
-void test01()
-{
- X x[1];
- // Should not be able to create vector using uninitialized_copy:
- std::vector<X> v1{x, x+1}; // { dg-error "here" }
-
- // Should not be able to create vector using uninitialized_fill_n:
- std::vector<X> v2{2u, X{}}; // { dg-error "here" }
-}
-
-void test02()
-{
-#if __cplusplus >= 201703L
- // Can create initializer_list<X> with C++17 guaranteed copy elision,
- // but shouldn't be able to copy from it with uninitialized_copy:
- std::vector<X> v3{X{}, X{}, X{}}; // { dg-error "here" }
-#endif
-}
-// { dg-error "constructible from value" "" { target *-*-* } 0 }
-// { dg-error "constructible from input" "" { target *-*-* } 0 }