Merge master r12-8312.

	* Merge master r12-8312-gb85e79dce149.
diff --git a/ChangeLog b/ChangeLog
index bbb29b0..55fedd0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2022-04-19  Richard Henderson  <rth@gcc.gnu.org>
+
+	* MAINTAINERS: Update my email address.
+
 2022-04-01  Qian Jianhua  <qianjh@fujitsu.com>
 
 	* MAINTAINERS: Update my email address.
diff --git a/MAINTAINERS b/MAINTAINERS
index 30f81b3..1597350 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -53,7 +53,7 @@
 aarch64 port		Richard Sandiford	<richard.sandiford@arm.com>
 aarch64 port		Marcus Shawcroft	<marcus.shawcroft@arm.com>
 aarch64 port		Kyrylo Tkachov		<kyrylo.tkachov@arm.com>
-alpha port		Richard Henderson	<rth@twiddle.net>
+alpha port		Richard Henderson	<rth@gcc.gnu.org>
 amdgcn port		Julian Brown		<julian@codesourcery.com>
 amdgcn port		Andrew Stubbs		<ams@codesourcery.com>
 arc port		Joern Rennecke		<gnu@amylaar.uk>
diff --git a/contrib/ChangeLog b/contrib/ChangeLog
index 4ba5286..c35edcc 100644
--- a/contrib/ChangeLog
+++ b/contrib/ChangeLog
@@ -1,3 +1,13 @@
+2022-04-25  Martin Liska  <mliska@suse.cz>
+
+	* filter-clang-warnings.py: Filter out
+	-Wc++20-attribute-extensions in lex.cc.
+
+2022-04-25  Martin Liska  <mliska@suse.cz>
+
+	* filter-clang-warnings.py: Filter out
+	-Wbitwise-instead-of-logical.
+
 2022-04-04  Martin Liska  <mliska@suse.cz>
 
 	* gcc-changelog/git_update_version.py: Ignore the revision.
diff --git a/contrib/filter-clang-warnings.py b/contrib/filter-clang-warnings.py
index e00570b..942cd30 100755
--- a/contrib/filter-clang-warnings.py
+++ b/contrib/filter-clang-warnings.py
@@ -38,7 +38,8 @@
                  'when in C++ mode, this behavior is deprecated',
                  '-Wignored-attributes', '-Wgnu-zero-variadic-macro-arguments',
                  '-Wformat-security', '-Wundefined-internal',
-                 '-Wunknown-warning-option', '-Wc++20-extensions'],
+                 '-Wunknown-warning-option', '-Wc++20-extensions',
+                 '-Wbitwise-instead-of-logical'],
             'insn-modes.cc': ['-Wshift-count-overflow'],
             'insn-emit.cc': ['-Wtautological-compare'],
             'insn-attrtab.cc': ['-Wparentheses-equality'],
@@ -52,7 +53,8 @@
             'genautomata.cc': ['-Wstring-plus-int'],
             'fold-const-call.cc': ['-Wreturn-type'],
             'gfortran.texi': [''],
-            'libtool': ['']
+            'libtool': [''],
+            'lex.cc': ['-Wc++20-attribute-extensions'],
     }
 
     for name, ignores in ignores.items():
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8376a11..a93b56c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,838 @@
+2022-04-27  Lulu Cheng  <chenglulu@loongson.cn>
+
+	* config/loongarch/loongarch.md: Add fdiv define_expand template,
+	then generate floating-point division and floating-point reciprocal
+	instructions.
+
+2022-04-27  Lulu Cheng  <chenglulu@loongson.cn>
+
+	* config/loongarch/loongarch.md: Add '(clobber (mem:BLK (scratch)))'
+	to PLV instruction templates.
+
+2022-04-27  Richard Biener  <rguenther@suse.de>
+
+	PR middle-end/104492
+	* gimple-ssa-warn-access.cc
+	(pass_waccess::warn_invalid_pointer): Exclude equality compare
+	diagnostics for all kind of invalidations.
+	(pass_waccess::check_dangling_uses): Fix post-dominator query.
+	(pass_waccess::check_pointer_uses): Likewise.
+
+2022-04-27  Andreas Krebbel  <krebbel@linux.ibm.com>
+
+	PR target/102024
+	* config/s390/s390-protos.h (s390_function_arg_vector): Remove
+	prototype.
+	* config/s390/s390.cc (s390_single_field_struct_p): New function.
+	(s390_function_arg_vector): Invoke s390_single_field_struct_p.
+	(s390_function_arg_float): Likewise.
+
+2022-04-27  Jakub Jelinek  <jakub@redhat.com>
+
+	PR sanitizer/105396
+	* asan.cc (asan_redzone_buffer::emit_redzone_byte): Handle the case
+	where offset is bigger than off but smaller than m_prev_offset + 32
+	bits by pushing one or more 0 bytes.  Sink the
+	m_shadow_bytes.safe_push (value); flush_if_full (); statements from
+	all cases to the end of the function.
+
+2022-04-27  Kewen Lin  <linkw@linux.ibm.com>
+
+	PR target/105271
+	* config/rs6000/rs6000-builtins.def (NEG_V2DI): Move to [power8-vector]
+	stanza.
+
+2022-04-26  Thomas Schwinge  <thomas@codesourcery.com>
+
+	* config/gcn/gcn.cc (gcn_print_lds_decl): Make "gang-private
+	data-share memory exhausted" error more verbose.
+
+2022-04-26  Martin Liska  <mliska@suse.cz>
+
+	PR lto/105364
+	* lto-wrapper.cc (print_lto_docs_link): Use global_dc.
+	(run_gcc): Parse OPT_fdiagnostics_urls_.
+	(main): Initialize global_dc.
+
+2022-04-26  Jakub Jelinek  <jakub@redhat.com>
+
+	PR rtl-optimization/105314
+	* ifcvt.cc (noce_try_store_flag_mask): Don't require that the non-zero
+	operand is equal to if_info->x, instead use the non-zero operand
+	as one of the operands of AND with if_info->x as target.
+
+2022-04-26  Jakub Jelinek  <jakub@redhat.com>
+
+	PR tree-optimization/105374
+	* tree-ssa-reassoc.cc (eliminate_redundant_comparison): Punt if
+	!fold_convertible_p rather than assuming fold_convert must succeed.
+
+2022-04-26  Jakub Jelinek  <jakub@redhat.com>
+
+	PR target/105367
+	* config/i386/i386.cc (ix86_veclibabi_svml, ix86_veclibabi_acml): Pass
+	el_mode == DFmode ? double_type_node : float_type_node instead of
+	TREE_TYPE (type_in) as first arguments to mathfn_built_in.
+
+2022-04-25  David Malcolm  <dmalcolm@redhat.com>
+
+	PR analyzer/104308
+	* gimple-fold.cc (gimple_fold_builtin_memory_op): Explicitly set
+	the location of new_stmt in all places that don't already set it,
+	whether explicitly, or via a call to gsi_replace.
+
+2022-04-25  Paul A. Clarke  <pc@us.ibm.com>
+
+	* doc/extend.texi (Other Builtins): Correct reference to 'modff'.
+
+2022-04-25  Andrew MacLeod  <amacleod@redhat.com>
+
+	PR tree-optimization/105276
+	* gimple-range.cc (gimple_ranger::prefill_stmt_dependencies): Include
+	existing global range with calculated value.
+
+2022-04-25  Richard Biener  <rguenther@suse.de>
+
+	PR tree-optimization/105368
+	* tree-ssa-math-opts.cc (powi_cost): Use absu_hwi.
+
+2022-04-25  Richard Biener  <rguenther@suse.de>
+
+	PR tree-optimization/100810
+	* tree-ssa-loop-ivopts.cc (struct iv_cand): Add involves_undefs flag.
+	(find_ssa_undef): New function.
+	(add_candidate_1): Avoid adding derived candidates with
+	undefined SSA names and mark the original ones.
+	(determine_group_iv_cost_generic): Reject rewriting
+	uses with a different IV when that involves undefined SSA names.
+
+2022-04-25  Steven G. Kargl  <kargl@gcc.gnu.org>
+
+	PR target/89125
+	* config/freebsd.h: Define TARGET_LIBC_HAS_FUNCTION to be
+	bsd_libc_has_function.
+	* targhooks.cc (bsd_libc_has_function): New function.
+	Expand the supported math functions to inclue C99 libm.
+	* targhooks.h (bsd_libc_has_function): New Prototype.
+
+2022-04-25  Richard Biener  <rguenther@suse.de>
+
+	PR rtl-optimization/105231
+	* combine.cc (distribute_notes): Assert that a REG_EH_REGION
+	with landing pad > 0 is from i3.  Put any REG_EH_REGION note
+	on i3 or drop it if the insn can not trap.
+	(try_combine): Ensure that we can merge REG_EH_REGION notes
+	with non-call exceptions.  Ensure we are not splitting a
+	trapping part of an insn with non-call exceptions when there
+	is any REG_EH_REGION note to preserve.
+
+2022-04-25  Hongyu Wang  <hongyu.wang@intel.com>
+
+	PR target/105339
+	* config/i386/avx512fintrin.h (_mm512_scalef_round_pd):
+	Add parentheses for parameters and djust format.
+	(_mm512_mask_scalef_round_pd): Ditto.
+	(_mm512_maskz_scalef_round_pd): Ditto.
+	(_mm512_scalef_round_ps): Ditto.
+	(_mm512_mask_scalef_round_ps): Ditto.
+	(_mm512_maskz_scalef_round_ps): Ditto.
+	(_mm_scalef_round_sd): Use _mm_undefined_pd.
+	(_mm_scalef_round_ss): Use _mm_undefined_ps.
+	(_mm_mask_scalef_round_sd): New macro.
+	(_mm_mask_scalef_round_ss): Ditto.
+	(_mm_maskz_scalef_round_sd): Ditto.
+	(_mm_maskz_scalef_round_ss): Ditto.
+
+2022-04-23  Jakub Jelinek  <jakub@redhat.com>
+
+	PR target/105338
+	* config/i386/i386-expand.cc (ix86_expand_int_movcc): Handle
+	op0 == cst1 ? op0 : op3 like op0 == cst1 ? cst1 : op3 for the non-cmov
+	cases.
+
+2022-04-22  Segher Boessenkool  <segher@kernel.crashing.org>
+
+	PR target/105334
+	* config/rs6000/rs6000.md (pack<mode> for FMOVE128): New expander.
+	(pack<mode> for FMOVE128): Rename and split the insn_and_split to...
+	(pack<mode>_hard for FMOVE128): ... this...
+	(pack<mode>_soft for FMOVE128): ... and this.
+
+2022-04-22  Paul A. Clarke  <pc@us.ibm.com>
+
+	* doc/extend.texi: Correct "This" to "These".
+
+2022-04-22  Jakub Jelinek  <jakub@redhat.com>
+
+	PR rtl-optimization/105333
+	* rtlanal.cc (replace_rtx): Use simplify_subreg or
+	simplify_unary_operation if CONST_SCALAR_INT_P rather than just
+	CONST_INT_P.
+
+2022-04-21  Segher Boessenkool  <segher@kernel.crashing.org>
+
+	PR target/103197
+	PR target/102146
+	* config/rs6000/rs6000.md (zero_extendqi<mode>2 for EXTQI): Disparage
+	the "Z" alternatives in {l,st}{f,xs}iwzx.
+	(zero_extendhi<mode>2 for EXTHI): Ditto.
+	(zero_extendsi<mode>2 for EXTSI): Ditto.
+	(*movsi_internal1): Ditto.
+	(*mov<mode>_internal1 for QHI): Ditto.
+	(movsd_hardfloat): Ditto.
+
+2022-04-21  Martin Liska  <mliska@suse.cz>
+
+	* configure.ac: Enable compressed debug sections for mold
+	linker.
+	* configure: Regenerate.
+
+2022-04-21  Jakub Jelinek  <jakub@redhat.com>
+
+	PR debug/105203
+	* emit-rtl.cc (emit_copy_of_insn_after): Don't call mark_jump_label
+	on DEBUG_INSNs.
+
+2022-04-20  Richard Biener  <rguenther@suse.de>
+
+	PR tree-optimization/104912
+	* tree-vect-loop-manip.cc (vect_loop_versioning): Split
+	the cost model check to a separate BB to make sure it is
+	checked first and not combined with other version checks.
+
+2022-04-20  Richard Biener  <rguenther@suse.de>
+
+	PR tree-optimization/105312
+	* gimple-isel.cc (gimple_expand_vec_cond_expr): Query both
+	VCOND and VCONDU for EQ and NE.
+
+2022-04-20  Jan Hubicka  <hubicka@ucw.cz>
+
+	PR ipa/103818
+	* ipa-modref-tree.cc (modref_access_node::closer_pair_p): Use
+	poly_offset_int to avoid overflow.
+	(modref_access_node::update2): likewise.
+
+2022-04-20  Jakub Jelinek  <jakub@redhat.com>
+
+	PR ipa/105306
+	* cgraph.cc (cgraph_node::create): Set node->semantic_interposition
+	to opt_for_fn (decl, flag_semantic_interposition).
+	* cgraphclones.cc (cgraph_node::create_clone): Copy over
+	semantic_interposition flag.
+
+2022-04-19  Sergei Trofimovich  <siarheit@google.com>
+
+	PR gcov-profile/105282
+	* value-prof.cc (stream_out_histogram_value): Allow negative counts
+	on HIST_TYPE_INDIR_CALL.
+
+2022-04-19  Jakub Jelinek  <jakub@redhat.com>
+
+	PR target/105257
+	* config/sparc/sparc.cc (epilogue_renumber): If ORIGINAL_REGNO,
+	use gen_raw_REG instead of gen_rtx_REG and copy over also
+	ORIGINAL_REGNO.  Use return 0; instead of /* fallthrough */.
+
+2022-04-19  Richard Biener  <rguenther@suse.de>
+
+	PR tree-optimization/104010
+	PR tree-optimization/103941
+	* tree-vect-slp.cc (vect_bb_slp_scalar_cost): When
+	we run into stmts in patterns continue walking those
+	for uses outside of the vectorized region instead of
+	marking the lane live.
+
+2022-04-18  Hans-Peter Nilsson  <hp@axis.com>
+
+	* doc/install.texi <CRIS>: Remove references to removed websites and
+	adjust for cris-*-elf being the only remaining toolchain.
+
+2022-04-18  Hans-Peter Nilsson  <hp@axis.com>
+
+	* doc/invoke.texi <CRIS>: Remove references to options for removed
+	subtarget cris-axis-linux-gnu and tweak wording accordingly.
+
+2022-04-16  Gerald Pfeifer  <gerald@pfeifer.com>
+
+	* doc/install.texi (Specific): Adjust mingw-w64 download link.
+
+2022-04-15  Hongyu Wang  <hongyu.wang@intel.com>
+
+	* config/i386/smmintrin.h: Correct target pragma from sse4.1
+	and sse4.2 to crc32 for crc32 intrinsics.
+
+2022-04-14  Indu Bhagat  <indu.bhagat@oracle.com>
+
+	PR debug/105089
+	* ctfc.cc (ctf_dvd_ignore_insert): New function.
+	(ctf_dvd_ignore_lookup): Likewise.
+	(ctf_add_variable): Keep track of non-defining decl DIEs.
+	(new_ctf_container): Initialize the new hash-table.
+	(ctfc_delete_container): Empty hash-table.
+	* ctfc.h (struct ctf_container): Add new hash-table.
+	(ctf_dvd_ignore_lookup): New declaration.
+	(ctf_add_variable): Add additional argument.
+	* ctfout.cc (ctf_dvd_preprocess_cb): Skip adding CTF variable
+	record for non-defining decl for which a defining decl exists
+	in the same TU.
+	(ctf_preprocess): Defer updating the number of global objts
+	until here.
+	(output_ctf_header): Use ctfc_vars_list_count as some CTF
+	variables may not make it to the final output.
+	(output_ctf_vars): Likewise.
+	* dwarf2ctf.cc (gen_ctf_variable): Skip generating CTF variable
+	if this is known to be a non-defining decl DIE.
+
+2022-04-14  Indu Bhagat  <indu.bhagat@oracle.com>
+
+	* ctfc.h (struct ctf_container): Introduce a new member.
+	* ctfout.cc (ctf_list_add_ctf_vars): Use it instead of static
+	variable.
+
+2022-04-14  Jakub Jelinek  <jakub@redhat.com>
+
+	PR target/105247
+	* simplify-rtx.cc (simplify_const_binary_operation): For shifts
+	or rotates by VOIDmode constant integer shift count use word_mode
+	for the operand if int_mode is narrower than word.
+
+2022-04-14  Robin Dapp  <rdapp@linux.ibm.com>
+
+	* config/s390/s390.cc (s390_get_sched_attrmask): Add z16.
+	(s390_get_unit_mask): Likewise.
+	(s390_is_fpd): Likewise.
+	(s390_is_fxd): Likewise.
+	* config/s390/s390.h (s390_tune_attr): Set max tune level to z16.
+	* config/s390/s390.md (z900,z990,z9_109,z9_ec,z10,z196,zEC12,z13,z14,z15):
+	Add z16.
+	(z900,z990,z9_109,z9_ec,z10,z196,zEC12,z13,z14,z15,z16):
+	Likewise.
+	* config/s390/3931.md: New file.
+
+2022-04-13  Richard Sandiford  <richard.sandiford@arm.com>
+
+	PR tree-optimization/105254
+	* config/aarch64/aarch64.cc
+	(aarch64_vector_costs::determine_suggested_unroll_factor): Take a
+	loop_vec_info as argument.  Restrict the unroll factor to values
+	that divide the VF.
+	(aarch64_vector_costs::finish_cost): Update call accordingly.
+
+2022-04-13  Richard Biener  <rguenther@suse.de>
+
+	PR tree-optimization/105263
+	* tree-ssa-reassoc.cc (try_special_add_to_ops): Do not consume
+	negates in multiplication chains with DFP.
+
+2022-04-13  Jakub Jelinek  <jakub@redhat.com>
+
+	PR middle-end/105253
+	* tree.cc (tree_builtin_call_types_compatible_p): If PROP_gimple,
+	use useless_type_conversion_p checks instead of TYPE_MAIN_VARIANT
+	comparisons or tree_nop_conversion_p checks.
+
+2022-04-13  Hongyu Wang  <hongyu.wang@intel.com>
+
+	PR target/103069
+	* config/i386/i386-expand.cc (ix86_expand_cmpxchg_loop):
+	  Add missing set to target_val at pause label.
+
+2022-04-13  Jakub Jelinek  <jakub@redhat.com>
+
+	PR target/105234
+	* attribs.cc (decl_attributes): Don't set
+	DECL_FUNCTION_SPECIFIC_TARGET if target_option_default_node is
+	NULL.
+
+2022-04-13  Richard Biener  <rguenther@suse.de>
+
+	PR tree-optimization/105250
+	* fold-const.cc (fold_convertible_p): Revert
+	r12-7979-geaaf77dd85c333, instead check for size equality
+	of the vector types involved.
+
+2022-04-13  Richard Biener  <rguenther@suse.de>
+
+	Revert:
+	2022-04-13  Richard Biener  <rguenther@suse.de>
+
+	PR tree-optimization/104912
+	* tree-vect-loop-manip.cc (vect_loop_versioning): Split
+	the cost model check to a separate BB to make sure it is
+	checked first and not combined with other version checks.
+
+2022-04-13  Richard Biener  <rguenther@suse.de>
+
+	PR tree-optimization/104912
+	* tree-vect-loop-manip.cc (vect_loop_versioning): Split
+	the cost model check to a separate BB to make sure it is
+	checked first and not combined with other version checks.
+
+2022-04-13  Jakub Jelinek  <jakub@redhat.com>
+
+	* tree-scalar-evolution.cc (expression_expensive_p): Fix a comment typo.
+
+2022-04-12  Antoni Boucher  <bouanto@zoho.com>
+
+	PR jit/104072
+	* reginfo.cc: New functions (clear_global_regs_cache,
+	reginfo_cc_finalize) to avoid an issue where compiling the same
+	code multiple times gives an error about assigning the same
+	register to 2 global variables.
+	* rtl.h: New function (reginfo_cc_finalize).
+	* toplev.cc: Call it.
+
+2022-04-12  Antoni Boucher  <bouanto@zoho.com>
+
+	PR jit/104071
+	* toplev.cc: Call the new function tree_cc_finalize in
+	toplev::finalize.
+	* tree.cc: New functions (clear_nonstandard_integer_type_cache
+	and tree_cc_finalize) to clear the cache of non-standard integer
+	types to avoid having issues with some optimizations of
+	bitcast where the SSA_NAME will have a size of a cached
+	integer type that should have been invalidated, causing a
+	comparison of integer constant to fail.
+	* tree.h: New function (tree_cc_finalize).
+
+2022-04-12  Thomas Schwinge  <thomas@codesourcery.com>
+
+	PR target/97348
+	* config/nvptx/nvptx.h (ASM_SPEC): Don't set.
+	* config/nvptx/nvptx.opt (misa): Adjust comment.
+
+2022-04-12  Thomas Schwinge  <thomas@codesourcery.com>
+
+	Revert:
+	2022-03-03  Tom de Vries  <tdevries@suse.de>
+
+	* config/nvptx/nvptx.h (ASM_SPEC): Add %{misa=sm_30:--no-verify}.
+
+2022-04-12  Thomas Schwinge  <thomas@codesourcery.com>
+
+	Revert:
+	2022-03-31  Tom de Vries  <tdevries@suse.de>
+
+	* config/nvptx/nvptx.h (ASM_SPEC): Use "-m sm_35" for -misa=sm_30.
+
+2022-04-12  Richard Biener  <rguenther@suse.de>
+
+	PR ipa/104303
+	* tree-ssa-dce.cc (mark_stmt_if_obviously_necessary): Do not
+	include local escaped memory as obviously necessary stores.
+
+2022-04-12  Richard Biener  <rguenther@suse.de>
+
+	PR tree-optimization/105235
+	* tree-ssa-math-opts.cc (execute_cse_conv_1): Clean EH and
+	return whether the CFG changed.
+	(execute_cse_sincos_1): Adjust.
+
+2022-04-12  Przemyslaw Wirkus  <Przemyslaw.Wirkus@arm.com>
+
+	PR target/104144
+	* config/arm/t-aprofile (MULTI_ARCH_OPTS_A): Remove Armv9-a options.
+	(MULTI_ARCH_DIRS_A): Remove Armv9-a diretories.
+	(MULTILIB_REQUIRED): Don't require Armv9-a libraries.
+	(MULTILIB_MATCHES): Treat Armv9-a as equivalent to Armv8-a.
+	(MULTILIB_REUSE): Remove remap rules for Armv9-a.
+	* config/arm/t-multilib (v9_a_nosimd_variants): Delete.
+	(MULTILIB_MATCHES): Remove mappings for v9_a_nosimd_variants.
+
+2022-04-12  Richard Biener  <rguenther@suse.de>
+
+	PR tree-optimization/105232
+	* tree.cc (component_ref_size): Bail out for too large
+	or non-constant sizes.
+
+2022-04-12  Richard Biener  <rguenther@suse.de>
+
+	PR tree-optimization/105226
+	* tree-vect-loop-manip.cc (vect_loop_versioning): Verify
+	we can split the exit of an outer loop we choose to version.
+
+2022-04-12  Jakub Jelinek  <jakub@redhat.com>
+
+	* config/i386/i386-expand.cc (ix86_emit_i387_sinh, ix86_emit_i387_cosh,
+	ix86_emit_i387_tanh, ix86_emit_i387_asinh, ix86_emit_i387_acosh,
+	ix86_emit_i387_atanh, ix86_emit_i387_log1p, ix86_emit_i387_round,
+	ix86_emit_swdivsf, ix86_emit_swsqrtsf,
+	ix86_expand_atomic_fetch_op_loop, ix86_expand_cmpxchg_loop):
+	Formatting fix.
+	* config/i386/i386.cc (warn_once_call_ms2sysv_xlogues): Likewise.
+
+2022-04-12  Jakub Jelinek  <jakub@redhat.com>
+
+	PR target/105214
+	* config/i386/i386-expand.cc (ix86_emit_i387_log1p): Call
+	do_pending_stack_adjust.
+
+2022-04-12  Jakub Jelinek  <jakub@redhat.com>
+
+	PR rtl-optimization/105211
+	* builtins.cc (expand_builtin_int_roundingfn_2): If mathfn_built_in_1
+	fails for TREE_TYPE (arg), retry it with
+	TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl))) and if even that
+	fails, emit call normally.
+
+2022-04-12  Andreas Krebbel  <krebbel@linux.ibm.com>
+
+	* common/config/s390/s390-common.cc: Rename PF_ARCH14 to PF_Z16.
+	* config.gcc: Add z16 as march/mtune switch.
+	* config/s390/driver-native.cc (s390_host_detect_local_cpu):
+	Recognize z16 with -march=native.
+	* config/s390/s390-opts.h (enum processor_type): Rename
+	PROCESSOR_ARCH14 to PROCESSOR_3931_Z16.
+	* config/s390/s390.cc (PROCESSOR_ARCH14): Rename to ...
+	(PROCESSOR_3931_Z16): ... throughout the file.
+	(s390_processor processor_table): Add z16 as cpu string.
+	* config/s390/s390.h (enum processor_flags): Rename PF_ARCH14 to
+	PF_Z16.
+	(TARGET_CPU_ARCH14): Rename to ...
+	(TARGET_CPU_Z16): ... this.
+	(TARGET_CPU_ARCH14_P): Rename to ...
+	(TARGET_CPU_Z16_P): ... this.
+	(TARGET_ARCH14): Rename to ...
+	(TARGET_Z16): ... this.
+	(TARGET_ARCH14_P): Rename to ...
+	(TARGET_Z16_P): ... this.
+	* config/s390/s390.md (cpu_facility): Rename arch14 to z16 and
+	check TARGET_Z16 instead of TARGET_ARCH14.
+	* config/s390/s390.opt: Add z16 to processor_type.
+	* doc/invoke.texi: Document z16 and arch14.
+
+2022-04-12  chenglulu  <chenglulu@loongson.cn>
+
+	* config/loongarch/loongarch.cc: Fix bug for
+	tmpdir-g++.dg-struct-layout-1/t033.
+
+2022-04-11  Peter Bergner  <bergner@linux.ibm.com>
+
+	PR target/104894
+	* config/rs6000/rs6000.cc (rs6000_sibcall_aix): Handle pcrel sibcalls
+	to longcall functions.
+
+2022-04-11  Jason Merrill  <jason@redhat.com>
+
+	* ipa-free-lang-data.cc (free_lang_data_in_decl): Fix typos.
+
+2022-04-11  Segher Boessenkool  <segher@kernel.crashing.org>
+
+	PR target/105213
+	PR target/103623
+	* config/rs6000/rs6000.md (unpack<mode>_nodm): Add m,r,i alternative.
+
+2022-04-11  Jakub Jelinek  <jakub@redhat.com>
+
+	PR tree-optimization/105218
+	* tree-ssa-phiopt.cc (value_replacement): If middle_bb has
+	more than one predecessor or phi's bb more than 2 predecessors,
+	reset phi result uses instead of adding a debug temp.
+
+2022-04-11  Kito Cheng  <kito.cheng@sifive.com>
+
+	PR target/104853
+	* config.gcc: Pass -misa-spec to arch-canonicalize and
+	multilib-generator.
+	* config/riscv/arch-canonicalize: Adding -misa-spec option.
+	(SUPPORTED_ISA_SPEC): New.
+	(arch_canonicalize): New argument `isa_spec`.
+	Handle multiple ISA spec versions.
+	* config/riscv/multilib-generator: Adding -misa-spec option.
+
+2022-04-11  Kito Cheng  <kito.cheng@sifive.com>
+
+	* config/riscv/arch-canonicalize: Add TODO item.
+	(IMPLIED_EXT): Sync.
+	(arch_canonicalize): Checking until no change.
+
+2022-04-11  Tamar Christina  <tamar.christina@arm.com>
+
+	PR target/105197
+	* tree-vect-stmts.cc (vectorizable_condition): Prevent cond swap when
+	not masked.
+
+2022-04-11  Jason Merrill  <jason@redhat.com>
+
+	PR c++/100370
+	* pointer-query.cc (compute_objsize_r) [POINTER_PLUS_EXPR]: Require
+	deref == -1.
+
+2022-04-11  Jakub Jelinek  <jakub@redhat.com>
+
+	PR tree-optimization/104639
+	* tree-ssa-phiopt.cc: Include tree-ssa-propagate.h.
+	(value_replacement): Optimize (x != cst1 ? x : cst2) != cst3
+	into x != cst3.
+
+2022-04-11  Jeff Law  <jeffreyalaw@gmail.com>
+
+	* config/bfin/bfin.md (rol_one): Fix pattern to indicate the
+	sign bit of the source ends up in CC.
+
+2022-04-09  Jan Hubicka  <hubicka@ucw.cz>
+
+	PR ipa/103376
+	* cgraphunit.cc (cgraph_node::analyze): update semantic_interposition
+	flag.
+
+2022-04-09  Jan Hubicka  <hubicka@ucw.cz>
+
+	* ipa-modref.cc (ipa_merge_modref_summary_after_inlining): Propagate
+	nondeterministic and side_effects flags.
+
+2022-04-08  Andre Vieira  <andre.simoesdiasvieira@arm.com>
+
+	PR target/105157
+	* config.gcc: Shift ext_mask by TARGET_CPU_NBITS.
+	* config/aarch64/aarch64.h (TARGET_CPU_NBITS): New macro.
+	(TARGET_CPU_MASK): Likewise.
+	(TARGET_CPU_DEFAULT): Use TARGET_CPU_NBITS.
+	* config/aarch64/aarch64.cc (aarch64_get_tune_cpu): Use TARGET_CPU_MASK.
+	(aarch64_get_arch): Likewise.
+	(aarch64_override_options): Use TARGET_CPU_NBITS.
+
+2022-04-08  Richard Biener  <rguenther@suse.de>
+
+	PR tree-optimization/105198
+	* tree-predcom.cc (find_looparound_phi): Check whether
+	the found memory location of the entry value is clobbered
+	inbetween the value we want to use and loop entry.
+
+2022-04-08  Jakub Jelinek  <jakub@redhat.com>
+
+	PR tree-optimization/105189
+	* fold-const.cc (make_range_step): Fix up handling of
+	(unsigned) x +[low, -] ranges for signed x if low fits into
+	typeof (x).
+
+2022-04-08  Richard Biener  <rguenther@suse.de>
+
+	PR tree-optimization/105175
+	* tree-vect-stmts.cc (vectorizable_operation): Suppress
+	-Wvector-operation-performance if using emulated vectors.
+	* tree-vect-generic.cc (expand_vector_piecewise): Do not diagnose
+	-Wvector-operation-performance when suppressed.
+	(expand_vector_parallel): Likewise.
+	(expand_vector_comparison): Likewise.
+	(expand_vector_condition): Likewise.
+	(lower_vec_perm): Likewise.
+	(expand_vector_conversion): Likewise.
+
+2022-04-07  Tamar Christina  <tamar.christina@arm.com>
+
+	PR target/104409
+	* config/aarch64/aarch64-builtins.cc (handle_arm_acle_h): New.
+	(aarch64_general_init_builtins): Move LS64 code.
+	* config/aarch64/aarch64-c.cc (aarch64_pragma_aarch64): Support
+	arm_acle.h
+	* config/aarch64/aarch64-protos.h (handle_arm_acle_h): New.
+	* config/aarch64/arm_acle.h: Add pragma GCC aarch64 "arm_acle.h".
+
+2022-04-07  Richard Biener  <rguenther@suse.de>
+	    Jan Hubicka  <hubicka@ucw.cz>
+
+	PR ipa/104303
+	* tree-ssa-alias.h (ptr_deref_may_alias_global_p,
+	ref_may_alias_global_p, ref_may_alias_global_p,
+	stmt_may_clobber_global_p, pt_solution_includes_global): Add
+	bool parameters indicating whether escaped locals should be
+	considered global.
+	* tree-ssa-structalias.cc (pt_solution_includes_global):
+	When the new escaped_nonlocal_p flag is true also consider
+	pt->vars_contains_escaped.
+	* tree-ssa-alias.cc (ptr_deref_may_alias_global_p):
+	Pass down new escaped_nonlocal_p flag.
+	(ref_may_alias_global_p): Likewise.
+	(stmt_may_clobber_global_p): Likewise.
+	(ref_may_alias_global_p_1): Likewise.  For decls also
+	query the escaped solution if true.
+	(ref_may_access_global_memory_p): Remove.
+	(modref_may_conflict): Use ref_may_alias_global_p with
+	escaped locals considered global.
+	(ref_maybe_used_by_stmt_p): Adjust.
+	* ipa-fnsummary.cc (points_to_local_or_readonly_memory_p):
+	Likewise.
+	* tree-ssa-dse.cc (dse_classify_store): Likewise.
+	* trans-mem.cc (thread_private_new_memory): Likewise, but
+	consider escaped locals global.
+	* tree-ssa-dce.cc (mark_stmt_if_obviously_necessary): Likewise.
+
+2022-04-07  Richard Biener  <rguenther@suse.de>
+
+	PR tree-optimization/105185
+	* tree-ssa-sccvn.cc (visit_reference_op_call): Simplify
+	modref query again.
+
+2022-04-07  Tamar Christina  <tamar.christina@arm.com>
+
+	PR target/104049
+	* config/aarch64/aarch64-simd.md
+	(aarch64_reduc_plus_internal<mode>): Fix RTL and rename to...
+	(reduc_plus_scal_<mode>): ... This.
+	(reduc_plus_scal_v4sf): Moved.
+	(aarch64_reduc_plus_internalv2si): Fix RTL and rename to...
+	(reduc_plus_scal_v2si): ... This.
+
+2022-04-07  Jakub Jelinek  <jakub@redhat.com>
+
+	PR tree-optimization/102586
+	* langhooks.h (struct lang_hooks_for_types): Add classtype_as_base
+	langhook.
+	* langhooks-def.h (LANG_HOOKS_CLASSTYPE_AS_BASE): Define.
+	(LANG_HOOKS_FOR_TYPES_INITIALIZER): Add it.
+	* gimple-fold.cc (clear_padding_type): Use ftype instead of
+	TREE_TYPE (field) some more.  For artificial FIELD_DECLs without
+	name try the lang_hooks.types.classtype_as_base langhook and
+	if it returns non-NULL, use that instead of ftype for recursive call.
+
+2022-04-07  Jakub Jelinek  <jakub@redhat.com>
+
+	PR tree-optimization/105150
+	* tree.cc (tree_builtin_call_types_compatible_p): New function.
+	(get_call_combined_fn): Use it.
+
+2022-04-07  Richard Biener  <rguenther@suse.de>
+
+	PR middle-end/105165
+	* tree-complex.cc (expand_complex_asm): Sorry for asm goto
+	_Complex outputs.
+
+2022-04-07  liuhongt  <hongtao.liu@intel.com>
+
+	* config/i386/sse.md (<sse2_avx2>_andnot<mode>3_mask):
+	Removed.
+	(<sse>_andnot<mode>3<mask_name>): Disable V*HFmode patterns
+	for mask_applied.
+	(<code><mode>3<mask_name>): Ditto.
+	(*<code><mode>3<mask_name>): Ditto.
+	(VFB_128_256): Adjust condition of V8HF/V16HFmode according to
+	real instruction.
+	(VFB_512): Ditto.
+	(VFB): Ditto.
+
+2022-04-06  Jakub Jelinek  <jakub@redhat.com>
+
+	PR rtl-optimization/104985
+	* combine.cc (struct undo): Add where.regno member.
+	(do_SUBST_MODE): Rename to ...
+	(subst_mode): ... this.  Change first argument from rtx * into int,
+	operate on regno_reg_rtx[regno] and save regno into where.regno.
+	(SUBST_MODE): Remove.
+	(try_combine): Use subst_mode instead of SUBST_MODE, change first
+	argument from regno_reg_rtx[whatever] to whatever.  For UNDO_MODE, use
+	regno_reg_rtx[undo->where.regno] instead of *undo->where.r.
+	(undo_to_marker): For UNDO_MODE, use regno_reg_rtx[undo->where.regno]
+	instead of *undo->where.r.
+	(simplify_set): Use subst_mode instead of SUBST_MODE, change first
+	argument from regno_reg_rtx[whatever] to whatever.
+
+2022-04-06  Jakub Jelinek  <jakub@redhat.com>
+
+	PR target/105069
+	* config/sh/sh.opt (mdiv=): Add Save.
+
+2022-04-06  Martin Liska  <mliska@suse.cz>
+
+	PR driver/105096
+	* common.opt: Document properly based on what it does.
+	* gcc.cc (display_help): Unify with what we have in common.opt.
+	* opts.cc (common_handle_option): Do not print undocumented
+	options.
+
+2022-04-06  Xi Ruoyao  <xry111@mengyan1223.wang>
+
+	* config/mips/mips.cc (mips_fpr_return_fields): Ignore
+	cxx17_empty_base_field_p fields and set an indicator.
+	(mips_return_in_msb): Adjust for mips_fpr_return_fields change.
+	(mips_function_value_1): Inform psABI change about C++17 empty
+	bases.
+
+2022-04-06  Jakub Jelinek  <jakub@redhat.com>
+
+	PR tree-optimization/105150
+	* gimple.cc (gimple_builtin_call_types_compatible_p): Use
+	builtin_decl_explicit here...
+	(gimple_call_builtin_p, gimple_call_combined_fn): ... rather than
+	here.
+
+2022-04-06  Richard Biener  <rguenther@suse.de>
+
+	PR tree-optimization/105173
+	* tree-ssa-reassoc.cc (find_insert_point): Get extra
+	insert_before output argument and compute it.
+	(insert_stmt_before_use): Adjust.
+	(rewrite_expr_tree): Likewise.
+
+2022-04-06  Richard Biener  <rguenther@suse.de>
+
+	PR ipa/105166
+	* ipa-modref-tree.cc (modref_access_node::get_ao_ref ): Bail
+	out for non-pointer arguments.
+
+2022-04-06  Richard Biener  <rguenther@suse.de>
+
+	PR tree-optimization/105163
+	* tree-ssa-reassoc.cc (repropagate_negates): Avoid propagating
+	negated abnormals.
+
+2022-04-06  Jakub Jelinek  <jakub@redhat.com>
+
+	PR tree-optimization/105150
+	* gimple.cc (gimple_call_builtin_p, gimple_call_combined_fn):
+	For BUILT_IN_NORMAL calls, call gimple_builtin_call_types_compatible_p
+	preferrably on builtin_decl_explicit decl rather than fndecl.
+	* tree-ssa-strlen.cc (valid_builtin_call): Don't call
+	gimple_builtin_call_types_compatible_p here.
+
+2022-04-06  Richard Sandiford  <richard.sandiford@arm.com>
+
+	PR tree-optimization/103761
+	* tree-vect-stmts.cc (check_load_store_for_partial_vectors): Replace
+	the ncopies parameter with an slp_node parameter.  Calculate the
+	number of vectors based on it and vectype.  Rename lambda to
+	group_memory_nvectors.
+	(vectorizable_store, vectorizable_load): Update calls accordingly.
+
+2022-04-06  Martin Liska  <mliska@suse.cz>
+
+	* doc/invoke.texi: Document it.
+
+2022-04-06  Richard Biener  <rguenther@suse.de>
+
+	PR tree-optimization/105148
+	* tree-ssa-loop-ivopts.cc (idx_record_use): Walk raw operands
+	2 and 3 of ARRAY_REFs.
+
+2022-04-06  Roger Sayle  <roger@nextmovesoftware.com>
+
+	* config/i386/sse.md (ANDNOT_MODE): New mode iterator for TF and V1TI.
+	(*andnottf3): Replace with...
+	(*andnot<mode>3): New define_insn using ANDNOT_MODE.
+
+2022-04-06  Richard Biener  <rguenther@suse.de>
+
+	PR tree-optimization/105142
+	* gimple-fold.h (maybe_fold_and_comparisons): Add defaulted
+	basic-block parameter.
+	(maybe_fold_or_comparisons): Likewise.
+	* gimple-fold.cc (follow_outer_ssa_edges): New.
+	(maybe_fold_comparisons_from_match_pd): Use follow_outer_ssa_edges
+	when an outer condition basic-block is specified.
+	(and_comparisons_1, and_var_with_comparison,
+	and_var_with_comparison_1, or_comparisons_1,
+	or_var_with_comparison, or_var_with_comparison_1): Receive and pass
+	down the outer condition basic-block.
+	* tree-ssa-ifcombine.cc (ifcombine_ifandif): Pass down the
+	basic-block of the outer condition.
+
+2022-04-06  Kewen Lin  <linkw@linux.ibm.com>
+
+	PR target/105002
+	* config/rs6000/rs6000.cc (rs6000_maybe_emit_maxc_minc): Support more
+	comparison codes UNLT/UNLE/UNGT/UNGE.
+
 2022-04-05  David Malcolm  <dmalcolm@redhat.com>
 
 	* doc/extend.texi (Common Function Attributes): Document that
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index d9e2507..04ee20d 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20220406
+20220428
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 932a666..3a7b8ed 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,14 @@
+2022-04-27  Sebastian Huber  <sebastian.huber@embedded-brains.de>
+
+	* tracebak.c: Add support for ARM RTEMS. Add support for RTEMS to PPC
+	ELF.  Add support for RTEMS to SPARC.  Merge aarch64 support of Linux
+	and RTEMS.
+
+2022-04-27  Pierre-Marie de Rodat  <derodat@adacore.com>
+
+	PR ada/104027
+	* gnat1drv.adb: Remove the goto End_Of_Program.
+
 2022-03-24  Pascal Obry  <obry@adacore.com>
 
 	PR ada/104767
diff --git a/gcc/ada/gnat1drv.adb b/gcc/ada/gnat1drv.adb
index f85bc13..0a11619 100644
--- a/gcc/ada/gnat1drv.adb
+++ b/gcc/ada/gnat1drv.adb
@@ -1429,11 +1429,6 @@
             Ecode := E_Success;
             Back_End.Gen_Or_Update_Object_File;
 
-            --  Use a goto instead of calling Exit_Program so that finalization
-            --  occurs normally.
-
-            goto End_Of_Program;
-
          --  Otherwise the unit is missing a crucial piece that prevents code
          --  generation.
 
diff --git a/gcc/ada/tracebak.c b/gcc/ada/tracebak.c
index 54e547d2..6cc5d30 100644
--- a/gcc/ada/tracebak.c
+++ b/gcc/ada/tracebak.c
@@ -316,6 +316,13 @@
 #define PC_ADJUST -2
 #define USING_ARM_UNWINDING 1
 
+/*---------------------- ARM RTEMS ------------------------------------ -*/
+#elif (defined (__arm__) && defined (__rtems__))
+
+#define USE_GCC_UNWINDER
+#define PC_ADJUST -2
+#define USING_ARM_UNWINDING 1
+
 /*---------------------- PPC AIX/PPC Lynx 178/Older Darwin --------------*/
 #elif ((defined (_POWER) && defined (_AIX)) || \
        (defined (__powerpc__) && defined (__Lynx__) && !defined(__ELF__)) || \
@@ -370,11 +377,12 @@
 
 #define BASE_SKIP 1
 
-/*----------- PPC ELF (GNU/Linux & VxWorks & Lynx178e) -------------------*/
+/*----------- PPC ELF (GNU/Linux & VxWorks & Lynx178e & RTEMS ) ----------*/
 
 #elif (defined (_ARCH_PPC) && defined (__vxworks)) ||  \
   (defined (__powerpc__) && defined (__Lynx__) && defined(__ELF__)) || \
-  (defined (__linux__) && defined (__powerpc__))
+  (defined (__linux__) && defined (__powerpc__)) || \
+  (defined (__powerpc__) && defined (__rtems__))
 
 #if defined (_ARCH_PPC64) && !defined (__USING_SJLJ_EXCEPTIONS__)
 #define USE_GCC_UNWINDER
@@ -404,9 +412,9 @@
 
 #define BASE_SKIP 1
 
-/*-------------------------- SPARC Solaris -----------------------------*/
+/*-------------------------- SPARC Solaris or RTEMS --------------------*/
 
-#elif defined (__sun__) && defined (__sparc__)
+#elif (defined (__sun__) || defined (__rtems__)) && defined (__sparc__)
 
 #define USE_GENERIC_UNWINDER
 
@@ -551,21 +559,9 @@
 #error Unhandled QNX architecture.
 #endif
 
-/*---------------------------- RTEMS ---------------------------------*/
+/*------------------- aarch64-linux or aarch64-rtems -----------------*/
 
-#elif defined (__rtems__)
-
-#define USE_GCC_UNWINDER
-
-#if defined (__aarch64__)
-#define PC_ADJUST -4
-#else
-#error Unhandled RTEMS architecture.
-#endif
-
-/*------------------- aarch64-linux ----------------------------------*/
-
-#elif (defined (__aarch64__) && defined (__linux__))
+#elif (defined (__aarch64__) && (defined (__linux__) || defined (__rtems__)))
 
 #define USE_GCC_UNWINDER
 #define PC_ADJUST -4
diff --git a/gcc/analyzer/ChangeLog b/gcc/analyzer/ChangeLog
index 123e8cb..9ab6169 100644
--- a/gcc/analyzer/ChangeLog
+++ b/gcc/analyzer/ChangeLog
@@ -1,3 +1,77 @@
+2022-04-25  David Malcolm  <dmalcolm@redhat.com>
+
+	PR analyzer/105365
+	PR analyzer/105366
+	* svalue.cc
+	(cmp_cst): Rename to...
+	(cmp_csts_same_type): ...this.  Convert all recursive calls to
+	calls to...
+	(cmp_csts_and_types): ....this new function.
+	(svalue::cmp_ptr): Update for renaming of cmp_cst
+
+2022-04-14  David Malcolm  <dmalcolm@redhat.com>
+
+	PR analyzer/105264
+	* region-model-reachability.cc (reachable_regions::handle_parm):
+	Use maybe_get_deref_base_region rather than just region_svalue, to
+	handle pointer arithmetic also.
+	* svalue.cc (svalue::maybe_get_deref_base_region): New.
+	* svalue.h (svalue::maybe_get_deref_base_region): New decl.
+
+2022-04-14  David Malcolm  <dmalcolm@redhat.com>
+
+	PR analyzer/105252
+	* svalue.cc (cmp_cst): When comparing VECTOR_CSTs, compare the
+	types of the encoded elements before calling cmp_cst on them.
+
+2022-04-09  David Malcolm  <dmalcolm@redhat.com>
+
+	PR analyzer/103892
+	* region-model-manager.cc
+	(region_model_manager::get_unknown_symbolic_region): New,
+	extracted from...
+	(region_model_manager::get_field_region): ...here.
+	(region_model_manager::get_element_region): Use it here.
+	(region_model_manager::get_offset_region): Likewise.
+	(region_model_manager::get_sized_region): Likewise.
+	(region_model_manager::get_cast_region): Likewise.
+	(region_model_manager::get_bit_range): Likewise.
+	* region-model.h
+	(region_model_manager::get_unknown_symbolic_region): New decl.
+	* region.cc (symbolic_region::symbolic_region): Handle sval_ptr
+	having NULL type.
+	(symbolic_region::dump_to_pp): Handle having NULL type.
+
+2022-04-07  David Malcolm  <dmalcolm@redhat.com>
+
+	PR analyzer/102208
+	* store.cc (binding_map::remove_overlapping_bindings): Add
+	"always_overlap" param, using it to generalize to the case where
+	we want to remove all bindings.  Update "uncertainty" logic to
+	only record maybe-bound values for cases where there is a symbolic
+	write involved.
+	(binding_cluster::mark_region_as_unknown): Split param "reg" into
+	"reg_to_bind" and "reg_for_overlap".
+	(binding_cluster::maybe_get_compound_binding): Pass "false" to
+	binding_map::remove_overlapping_bindings new "always_overlap" param.
+	(binding_cluster::remove_overlapping_bindings): Determine
+	"always_overlap" and pass it to
+	binding_map::remove_overlapping_bindings.
+	(store::set_value): Pass uncertainty to remove_overlapping_bindings
+	call.  Update for new param of
+	binding_cluster::mark_region_as_unknown, passing both the base
+	region of the iter_cluster, and the lhs_reg.
+	(store::mark_region_as_unknown): Update for new param of
+	binding_cluster::mark_region_as_unknown, passing "reg" for both.
+	(store::remove_overlapping_bindings): Add param "uncertainty", and
+	pass it on to call to
+	binding_cluster::remove_overlapping_bindings.
+	* store.h (binding_map::remove_overlapping_bindings): Add
+	"always_overlap" param.
+	(binding_cluster::mark_region_as_unknown): Split param "reg" into
+	"reg_to_bind" and "reg_for_overlap".
+	(store::remove_overlapping_bindings): Add param "uncertainty".
+
 2022-03-29  David Malcolm  <dmalcolm@redhat.com>
 
 	PR testsuite/105085
diff --git a/gcc/analyzer/region-model-manager.cc b/gcc/analyzer/region-model-manager.cc
index 56d6076..4ec275e 100644
--- a/gcc/analyzer/region-model-manager.cc
+++ b/gcc/analyzer/region-model-manager.cc
@@ -1362,6 +1362,19 @@
   return reg;
 }
 
+/* Return the region for an unknown access of type REGION_TYPE,
+   creating it if necessary.
+   This is a symbolic_region, where the pointer is an unknown_svalue
+   of type &REGION_TYPE.  */
+
+const region *
+region_model_manager::get_unknown_symbolic_region (tree region_type)
+{
+  tree ptr_type = region_type ? build_pointer_type (region_type) : NULL_TREE;
+  const svalue *unknown_ptr = get_or_create_unknown_svalue (ptr_type);
+  return get_symbolic_region (unknown_ptr);
+}
+
 /* Return the region that describes accessing field FIELD of PARENT,
    creating it if necessary.  */
 
@@ -1372,12 +1385,7 @@
 
   /* (*UNKNOWN_PTR).field is (*UNKNOWN_PTR_OF_&FIELD_TYPE).  */
   if (parent->symbolic_for_unknown_ptr_p ())
-    {
-      tree ptr_to_field_type = build_pointer_type (TREE_TYPE (field));
-      const svalue *unknown_ptr_to_field
-	= get_or_create_unknown_svalue (ptr_to_field_type);
-      return get_symbolic_region (unknown_ptr_to_field);
-    }
+    return get_unknown_symbolic_region (TREE_TYPE (field));
 
   field_region::key_t key (parent, field);
   if (field_region *reg = m_field_regions.get (key))
@@ -1397,6 +1405,10 @@
 					  tree element_type,
 					  const svalue *index)
 {
+  /* (UNKNOWN_PTR[IDX]) is (UNKNOWN_PTR).  */
+  if (parent->symbolic_for_unknown_ptr_p ())
+    return get_unknown_symbolic_region (element_type);
+
   element_region::key_t key (parent, element_type, index);
   if (element_region *reg = m_element_regions.get (key))
     return reg;
@@ -1416,6 +1428,10 @@
 					 tree type,
 					 const svalue *byte_offset)
 {
+  /* (UNKNOWN_PTR + OFFSET) is (UNKNOWN_PTR).  */
+  if (parent->symbolic_for_unknown_ptr_p ())
+    return get_unknown_symbolic_region (type);
+
   /* If BYTE_OFFSET is zero, return PARENT.  */
   if (tree cst_offset = byte_offset->maybe_get_constant ())
     if (zerop (cst_offset))
@@ -1451,6 +1467,9 @@
 					tree type,
 					const svalue *byte_size_sval)
 {
+  if (parent->symbolic_for_unknown_ptr_p ())
+    return get_unknown_symbolic_region (type);
+
   if (byte_size_sval->get_type () != size_type_node)
     byte_size_sval = get_or_create_cast (size_type_node, byte_size_sval);
 
@@ -1486,6 +1505,9 @@
   if (type == original_region->get_type ())
     return original_region;
 
+  if (original_region->symbolic_for_unknown_ptr_p ())
+    return get_unknown_symbolic_region (type);
+
   cast_region::key_t key (original_region, type);
   if (cast_region *reg = m_cast_regions.get (key))
     return reg;
@@ -1558,6 +1580,9 @@
 {
   gcc_assert (parent);
 
+  if (parent->symbolic_for_unknown_ptr_p ())
+    return get_unknown_symbolic_region (type);
+
   bit_range_region::key_t key (parent, type, bits);
   if (bit_range_region *reg = m_bit_range_regions.get (key))
     return reg;
diff --git a/gcc/analyzer/region-model-reachability.cc b/gcc/analyzer/region-model-reachability.cc
index b876b8f..12d09c3 100644
--- a/gcc/analyzer/region-model-reachability.cc
+++ b/gcc/analyzer/region-model-reachability.cc
@@ -252,12 +252,8 @@
     m_mutable_svals.add (sval);
   else
     m_reachable_svals.add (sval);
-  if (const region_svalue *parm_ptr
-      = sval->dyn_cast_region_svalue ())
-    {
-      const region *pointee_reg = parm_ptr->get_pointee ();
-      add (pointee_reg, is_mutable);
-    }
+  if (const region *base_reg = sval->maybe_get_deref_base_region ())
+    add (base_reg, is_mutable);
   /* Treat all svalues within a compound_svalue as reachable.  */
   if (const compound_svalue *compound_sval
       = sval->dyn_cast_compound_svalue ())
diff --git a/gcc/analyzer/region-model.h b/gcc/analyzer/region-model.h
index 2384171..eff3d49 100644
--- a/gcc/analyzer/region-model.h
+++ b/gcc/analyzer/region-model.h
@@ -327,6 +327,8 @@
   const region *get_bit_range (const region *parent, tree type,
 			       const bit_range &bits);
 
+  const region *get_unknown_symbolic_region (tree region_type);
+
   const region *
   get_region_for_unexpected_tree_code (region_model_context *ctxt,
 				       tree t,
diff --git a/gcc/analyzer/region.cc b/gcc/analyzer/region.cc
index 749e618..1a7949b3f 100644
--- a/gcc/analyzer/region.cc
+++ b/gcc/analyzer/region.cc
@@ -1016,7 +1016,9 @@
 symbolic_region::symbolic_region (unsigned id, region *parent,
 				  const svalue *sval_ptr)
 : region (complexity::from_pair (parent, sval_ptr), id, parent,
-	  TREE_TYPE (sval_ptr->get_type ())),
+	  (sval_ptr->get_type ()
+	   ? TREE_TYPE (sval_ptr->get_type ())
+	   : NULL_TREE)),
   m_sval_ptr (sval_ptr)
 {
 }
@@ -1045,8 +1047,11 @@
     {
       pp_string (pp, "symbolic_region(");
       get_parent_region ()->dump_to_pp (pp, simple);
-      pp_string (pp, ", ");
-      print_quoted_type (pp, get_type ());
+      if (get_type ())
+	{
+	  pp_string (pp, ", ");
+	  print_quoted_type (pp, get_type ());
+	}
       pp_string (pp, ", ");
       m_sval_ptr->dump_to_pp (pp, simple);
       pp_string (pp, ")");
diff --git a/gcc/analyzer/store.cc b/gcc/analyzer/store.cc
index 0014633..35f66a4 100644
--- a/gcc/analyzer/store.cc
+++ b/gcc/analyzer/store.cc
@@ -997,27 +997,61 @@
        value:  {BITS_WITHIN(bytes 4-7, inner_val: INIT_VAL((*INIT_VAL(p_33(D))).arr))}
 
    If UNCERTAINTY is non-NULL, use it to record any svalues that
-   were removed, as being maybe-bound.  */
+   were removed, as being maybe-bound.
+
+   If ALWAYS_OVERLAP, then assume that DROP_KEY can overlap anything
+   in the map, due to one or both of the underlying clusters being
+   symbolic (but not the same symbolic region).  Hence even if DROP_KEY is a
+   concrete binding it could actually be referring to the same memory as
+   distinct concrete bindings in the map.  Remove all bindings, but
+   register any svalues with *UNCERTAINTY.  */
 
 void
 binding_map::remove_overlapping_bindings (store_manager *mgr,
 					  const binding_key *drop_key,
-					  uncertainty_t *uncertainty)
+					  uncertainty_t *uncertainty,
+					  bool always_overlap)
 {
+  /* Get the bindings of interest within this map.  */
   auto_vec<const binding_key *> bindings;
-  get_overlapping_bindings (drop_key, &bindings);
+  if (always_overlap)
+    for (auto iter : *this)
+      bindings.safe_push (iter.first); /* Add all bindings.  */
+  else
+    /* Just add overlapping bindings.  */
+    get_overlapping_bindings (drop_key, &bindings);
 
   unsigned i;
   const binding_key *iter_binding;
   FOR_EACH_VEC_ELT (bindings, i, iter_binding)
     {
+      /* Record any svalues that were removed to *UNCERTAINTY as being
+	 maybe-bound, provided at least some part of the binding is symbolic.
+
+	 Specifically, if at least one of the bindings is symbolic, or we
+	 have ALWAYS_OVERLAP for the case where we have possibly aliasing
+	 regions, then we don't know that the svalue has been overwritten,
+	 and should record that to *UNCERTAINTY.
+
+	 However, if we have concrete keys accessing within the same symbolic
+	 region, then we *know* that the symbolic region has been overwritten,
+	 so we don't record it to *UNCERTAINTY, as this could be a genuine
+	 leak.  */
       const svalue *old_sval = get (iter_binding);
-      if (uncertainty)
+      if (uncertainty
+	  && (drop_key->symbolic_p ()
+	      || iter_binding->symbolic_p ()
+	      || always_overlap))
 	uncertainty->on_maybe_bound_sval (old_sval);
 
       /* Begin by removing the old binding. */
       m_map.remove (iter_binding);
 
+      /* Don't attempt to handle prefixes/suffixes for the
+	 "always_overlap" case; everything's being removed.  */
+      if (always_overlap)
+	continue;
+
       /* Now potentially add the prefix and suffix.  */
       if (const concrete_binding *drop_ckey
 	  = drop_key->dyn_cast_concrete_binding ())
@@ -1335,22 +1369,30 @@
   fill_region (mgr, reg, zero_sval);
 }
 
-/* Mark REG within this cluster as being unknown.
+/* Mark REG_TO_BIND within this cluster as being unknown.
+
+   Remove any bindings overlapping REG_FOR_OVERLAP.
    If UNCERTAINTY is non-NULL, use it to record any svalues that
-   had bindings to them removed, as being maybe-bound.  */
+   had bindings to them removed, as being maybe-bound.
+
+   REG_TO_BIND and REG_FOR_OVERLAP are the same for
+   store::mark_region_as_unknown, but are different in
+   store::set_value's alias handling, for handling the case where
+   we have a write to a symbolic REG_FOR_OVERLAP. */
 
 void
 binding_cluster::mark_region_as_unknown (store_manager *mgr,
-					 const region *reg,
+					 const region *reg_to_bind,
+					 const region *reg_for_overlap,
 					 uncertainty_t *uncertainty)
 {
-  remove_overlapping_bindings (mgr, reg, uncertainty);
+  remove_overlapping_bindings (mgr, reg_for_overlap, uncertainty);
 
   /* Add a default binding to "unknown".  */
   region_model_manager *sval_mgr = mgr->get_svalue_manager ();
   const svalue *sval
-    = sval_mgr->get_or_create_unknown_svalue (reg->get_type ());
-  bind (mgr, reg, sval);
+    = sval_mgr->get_or_create_unknown_svalue (reg_to_bind->get_type ());
+  bind (mgr, reg_to_bind, sval);
 }
 
 /* Purge state involving SVAL.  */
@@ -1595,7 +1637,7 @@
 		 it overlaps with offset_concrete_key.  */
 	      default_map.remove_overlapping_bindings (mgr,
 						       offset_concrete_key,
-						       NULL);
+						       NULL, false);
 	    }
 	  else if (bound_range.contains_p (reg_range, &subrange))
 	    {
@@ -1629,7 +1671,7 @@
 		 it overlaps with overlap_concrete_key.  */
 	      default_map.remove_overlapping_bindings (mgr,
 						       overlap_concrete_key,
-						       NULL);
+						       NULL, false);
 	    }
 	}
       else
@@ -1652,7 +1694,13 @@
 }
 
 /* Remove, truncate, and/or split any bindings within this map that
-   overlap REG.
+   could overlap REG.
+
+   If REG's base region or this cluster is symbolic and they're different
+   base regions, then remove everything in this cluster's map, on the
+   grounds that REG could be referring to the same memory as anything
+   in the map.
+
    If UNCERTAINTY is non-NULL, use it to record any svalues that
    were removed, as being maybe-bound.  */
 
@@ -1663,7 +1711,19 @@
 {
   const binding_key *reg_binding = binding_key::make (mgr, reg);
 
-  m_map.remove_overlapping_bindings (mgr, reg_binding, uncertainty);
+  const region *cluster_base_reg = get_base_region ();
+  const region *other_base_reg = reg->get_base_region ();
+  /* If at least one of the base regions involved is symbolic, and they're
+     not the same base region, then consider everything in the map as
+     potentially overlapping with reg_binding (even if it's a concrete
+     binding and things in the map are concrete - they could be referring
+     to the same memory when the symbolic base regions are taken into
+     account).  */
+  bool always_overlap = (cluster_base_reg != other_base_reg
+			 && (cluster_base_reg->get_kind () == RK_SYMBOLIC
+			     || other_base_reg->get_kind () == RK_SYMBOLIC));
+  m_map.remove_overlapping_bindings (mgr, reg_binding, uncertainty,
+				     always_overlap);
 }
 
 /* Attempt to merge CLUSTER_A and CLUSTER_B into OUT_CLUSTER, using
@@ -2368,7 +2428,7 @@
   logger *logger = mgr->get_logger ();
   LOG_SCOPE (logger);
 
-  remove_overlapping_bindings (mgr, lhs_reg);
+  remove_overlapping_bindings (mgr, lhs_reg, uncertainty);
 
   rhs_sval = simplify_for_binding (rhs_sval);
 
@@ -2438,8 +2498,14 @@
 		  lhs_reg->dump_to_pp (pp, true);
 		  logger->end_log_line ();
 		}
-	      iter_cluster->mark_region_as_unknown (mgr, iter_base_reg,
-						    uncertainty);
+	      /* Mark all of iter_cluster's iter_base_reg as unknown,
+		 using LHS_REG when considering overlaps, to handle
+		 symbolic vs concrete issues.  */
+	      iter_cluster->mark_region_as_unknown
+		(mgr,
+		 iter_base_reg, /* reg_to_bind */
+		 lhs_reg, /* reg_for_overlap */
+		 uncertainty);
 	      break;
 
 	    case tristate::TS_TRUE:
@@ -2603,7 +2669,7 @@
       || !base_reg->tracked_p ())
     return;
   binding_cluster *cluster = get_or_create_cluster (base_reg);
-  cluster->mark_region_as_unknown (mgr, reg, uncertainty);
+  cluster->mark_region_as_unknown (mgr, reg, reg, uncertainty);
 }
 
 /* Purge state involving SVAL.  */
@@ -2826,10 +2892,14 @@
 }
 
 /* Remove all bindings overlapping REG within this store, removing
-   any clusters that become redundant.  */
+   any clusters that become redundant.
+
+   If UNCERTAINTY is non-NULL, use it to record any svalues that
+   were removed, as being maybe-bound.  */
 
 void
-store::remove_overlapping_bindings (store_manager *mgr, const region *reg)
+store::remove_overlapping_bindings (store_manager *mgr, const region *reg,
+				    uncertainty_t *uncertainty)
 {
   const region *base_reg = reg->get_base_region ();
   if (binding_cluster **cluster_slot = m_cluster_map.get (base_reg))
@@ -2842,7 +2912,7 @@
 	  delete cluster;
 	  return;
 	}
-      cluster->remove_overlapping_bindings (mgr, reg, NULL);
+      cluster->remove_overlapping_bindings (mgr, reg, uncertainty);
     }
 }
 
diff --git a/gcc/analyzer/store.h b/gcc/analyzer/store.h
index 89bb352..17485b7 100644
--- a/gcc/analyzer/store.h
+++ b/gcc/analyzer/store.h
@@ -509,7 +509,8 @@
 
   void remove_overlapping_bindings (store_manager *mgr,
 				    const binding_key *drop_key,
-				    uncertainty_t *uncertainty);
+				    uncertainty_t *uncertainty,
+				    bool always_overlap);
 
 private:
   void get_overlapping_bindings (const binding_key *key,
@@ -574,7 +575,9 @@
   void purge_region (store_manager *mgr, const region *reg);
   void fill_region (store_manager *mgr, const region *reg, const svalue *sval);
   void zero_fill_region (store_manager *mgr, const region *reg);
-  void mark_region_as_unknown (store_manager *mgr, const region *reg,
+  void mark_region_as_unknown (store_manager *mgr,
+			       const region *reg_to_bind,
+			       const region *reg_for_overlap,
 			       uncertainty_t *uncertainty);
   void purge_state_involving (const svalue *sval,
 			      region_model_manager *sval_mgr);
@@ -765,7 +768,8 @@
 			  region_model_manager *mgr);
 
 private:
-  void remove_overlapping_bindings (store_manager *mgr, const region *reg);
+  void remove_overlapping_bindings (store_manager *mgr, const region *reg,
+				    uncertainty_t *uncertainty);
   tristate eval_alias_1 (const region *base_reg_a,
 			 const region *base_reg_b) const;
 
diff --git a/gcc/analyzer/svalue.cc b/gcc/analyzer/svalue.cc
index 553edae..ed289c6 100644
--- a/gcc/analyzer/svalue.cc
+++ b/gcc/analyzer/svalue.cc
@@ -59,6 +59,8 @@
 
 namespace ana {
 
+static int cmp_csts_and_types (const_tree cst1, const_tree cst2);
+
 /* class svalue and its various subclasses.  */
 
 /* class svalue.  */
@@ -304,7 +306,7 @@
    of the same type.  */
 
 static int
-cmp_cst (const_tree cst1, const_tree cst2)
+cmp_csts_same_type (const_tree cst1, const_tree cst2)
 {
   gcc_assert (TREE_TYPE (cst1) == TREE_TYPE (cst2));
   gcc_assert (TREE_CODE (cst1) == TREE_CODE (cst2));
@@ -323,9 +325,10 @@
 		     TREE_REAL_CST_PTR (cst2),
 		     sizeof (real_value));
     case COMPLEX_CST:
-      if (int cmp_real = cmp_cst (TREE_REALPART (cst1), TREE_REALPART (cst2)))
+      if (int cmp_real = cmp_csts_and_types (TREE_REALPART (cst1),
+					     TREE_REALPART (cst2)))
 	return cmp_real;
-      return cmp_cst (TREE_IMAGPART (cst1), TREE_IMAGPART (cst2));
+      return cmp_csts_and_types (TREE_IMAGPART (cst1), TREE_IMAGPART (cst2));
     case VECTOR_CST:
       if (int cmp_log2_npatterns
 	    = ((int)VECTOR_CST_LOG2_NPATTERNS (cst1)
@@ -337,13 +340,29 @@
 	return cmp_nelts_per_pattern;
       unsigned encoded_nelts = vector_cst_encoded_nelts (cst1);
       for (unsigned i = 0; i < encoded_nelts; i++)
-	if (int el_cmp = cmp_cst (VECTOR_CST_ENCODED_ELT (cst1, i),
-				  VECTOR_CST_ENCODED_ELT (cst2, i)))
-	  return el_cmp;
+	{
+	  const_tree elt1 = VECTOR_CST_ENCODED_ELT (cst1, i);
+	  const_tree elt2 = VECTOR_CST_ENCODED_ELT (cst2, i);
+	  if (int el_cmp = cmp_csts_and_types (elt1, elt2))
+	    return el_cmp;
+	}
       return 0;
     }
 }
 
+/* Comparator for imposing a deterministic order on constants that might
+   not be of the same type.  */
+
+static int
+cmp_csts_and_types (const_tree cst1, const_tree cst2)
+{
+  int t1 = TYPE_UID (TREE_TYPE (cst1));
+  int t2 = TYPE_UID (TREE_TYPE (cst2));
+  if (int cmp_type = t1 - t2)
+    return cmp_type;
+  return cmp_csts_same_type (cst1, cst2);
+}
+
 /* Comparator for imposing a deterministic order on svalues.  */
 
 int
@@ -375,7 +394,7 @@
 	const constant_svalue *constant_sval2 = (const constant_svalue *)sval2;
 	const_tree cst1 = constant_sval1->get_constant ();
 	const_tree cst2 = constant_sval2->get_constant ();
-	return cmp_cst (cst1, cst2);
+	return cmp_csts_same_type (cst1, cst2);
       }
       break;
     case SK_UNKNOWN:
@@ -644,6 +663,48 @@
   return false;
 }
 
+/* If this svalue is a pointer, attempt to determine the base region it points
+   to.  Return NULL on any problems.  */
+
+const region *
+svalue::maybe_get_deref_base_region () const
+{
+  const svalue *iter = this;
+  while (1)
+    {
+      switch (iter->get_kind ())
+	{
+	default:
+	  return NULL;
+
+	case SK_REGION:
+	  {
+	    const region_svalue *region_sval
+	      = as_a <const region_svalue *> (iter);
+	    return region_sval->get_pointee ()->get_base_region ();
+	  }
+
+	case SK_BINOP:
+	  {
+	    const binop_svalue *binop_sval
+	      = as_a <const binop_svalue *> (iter);
+	    switch (binop_sval->get_op ())
+	      {
+	      case POINTER_PLUS_EXPR:
+		/* If we have a symbolic value expressing pointer arithmetic,
+		   use the LHS.  */
+		iter = binop_sval->get_arg0 ();
+		continue;
+
+	      default:
+		return NULL;
+	      }
+	    return NULL;
+	  }
+	}
+    }
+}
+
 /* class region_svalue : public svalue.  */
 
 /* Implementation of svalue::dump_to_pp vfunc for region_svalue.  */
diff --git a/gcc/analyzer/svalue.h b/gcc/analyzer/svalue.h
index 4bbe858..29ea2ee 100644
--- a/gcc/analyzer/svalue.h
+++ b/gcc/analyzer/svalue.h
@@ -175,6 +175,8 @@
      per-type and thus it's meaningless for them to "have state".  */
   virtual bool can_have_associated_state_p () const { return true; }
 
+  const region *maybe_get_deref_base_region () const;
+
  protected:
   svalue (complexity c, tree type)
   : m_complexity (c), m_type (type)
diff --git a/gcc/asan.cc b/gcc/asan.cc
index 7c57cbc..ef59b77 100644
--- a/gcc/asan.cc
+++ b/gcc/asan.cc
@@ -1497,10 +1497,14 @@
   HOST_WIDE_INT off
     = m_prev_offset + ASAN_SHADOW_GRANULARITY * m_shadow_bytes.length ();
   if (off == offset)
+    /* Consecutive shadow memory byte.  */;
+  else if (offset < m_prev_offset + (HOST_WIDE_INT) (ASAN_SHADOW_GRANULARITY
+						     * RZ_BUFFER_SIZE)
+	   && !m_shadow_bytes.is_empty ())
     {
-      /* Consecutive shadow memory byte.  */
-      m_shadow_bytes.safe_push (value);
-      flush_if_full ();
+      /* Shadow memory byte with a small gap.  */
+      for (; off < offset; off += ASAN_SHADOW_GRANULARITY)
+	m_shadow_bytes.safe_push (0);
     }
   else
     {
@@ -1521,9 +1525,9 @@
       m_shadow_mem = adjust_address (m_shadow_mem, VOIDmode,
 				     diff >> ASAN_SHADOW_SHIFT);
       m_prev_offset = offset;
-      m_shadow_bytes.safe_push (value);
-      flush_if_full ();
     }
+  m_shadow_bytes.safe_push (value);
+  flush_if_full ();
 }
 
 /* Emit RTX emission of the content of the buffer.  */
diff --git a/gcc/attribs.cc b/gcc/attribs.cc
index 497dcff..b219f87 100644
--- a/gcc/attribs.cc
+++ b/gcc/attribs.cc
@@ -636,15 +636,20 @@
       && !DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node))
     {
       DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node) = optimization_current_node;
-      tree cur_tree
-	= build_target_option_node (&global_options, &global_options_set);
-      tree old_tree = DECL_FUNCTION_SPECIFIC_TARGET (*node);
-      if (!old_tree)
-	old_tree = target_option_default_node;
-      /* The changes on optimization options can cause the changes in
-	 target options, update it accordingly if it's changed.  */
-      if (old_tree != cur_tree)
-	DECL_FUNCTION_SPECIFIC_TARGET (*node) = cur_tree;
+      /* Don't set DECL_FUNCTION_SPECIFIC_TARGET for targets that don't
+	 support #pragma GCC target or target attribute.  */
+      if (target_option_default_node)
+	{
+	  tree cur_tree
+	    = build_target_option_node (&global_options, &global_options_set);
+	  tree old_tree = DECL_FUNCTION_SPECIFIC_TARGET (*node);
+	  if (!old_tree)
+	    old_tree = target_option_default_node;
+	  /* The changes on optimization options can cause the changes in
+	     target options, update it accordingly if it's changed.  */
+	  if (old_tree != cur_tree)
+	    DECL_FUNCTION_SPECIFIC_TARGET (*node) = cur_tree;
+	}
     }
 
   /* If this is a function and the user used #pragma GCC target, add the
diff --git a/gcc/builtins.cc b/gcc/builtins.cc
index 4c6c293..5b085e3 100644
--- a/gcc/builtins.cc
+++ b/gcc/builtins.cc
@@ -2967,16 +2967,28 @@
 	 BUILT_IN_IROUND and if __builtin_iround is called directly, emit
 	 a call to lround in the hope that the target provides at least some
 	 C99 functions.  This should result in the best user experience for
-	 not full C99 targets.  */
-      tree fallback_fndecl = mathfn_built_in_1
-	(TREE_TYPE (arg), as_combined_fn (fallback_fn), 0);
+	 not full C99 targets.
+	 As scalar float conversions with same mode are useless in GIMPLE,
+	 we can end up e.g. with _Float32 argument passed to float builtin,
+	 try to get the type from the builtin prototype first.  */
+      tree fallback_fndecl = NULL_TREE;
+      if (tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
+        fallback_fndecl
+          = mathfn_built_in_1 (TREE_VALUE (argtypes),
+			       as_combined_fn (fallback_fn), 0);
+      if (fallback_fndecl == NULL_TREE)
+	fallback_fndecl
+	  = mathfn_built_in_1 (TREE_TYPE (arg),
+			       as_combined_fn (fallback_fn), 0);
+      if (fallback_fndecl)
+	{
+	  exp = build_call_nofold_loc (EXPR_LOCATION (exp),
+				       fallback_fndecl, 1, arg);
 
-      exp = build_call_nofold_loc (EXPR_LOCATION (exp),
-				   fallback_fndecl, 1, arg);
-
-      target = expand_call (exp, NULL_RTX, target == const0_rtx);
-      target = maybe_emit_group_store (target, TREE_TYPE (exp));
-      return convert_to_mode (mode, target, 0);
+	  target = expand_call (exp, NULL_RTX, target == const0_rtx);
+	  target = maybe_emit_group_store (target, TREE_TYPE (exp));
+	  return convert_to_mode (mode, target, 0);
+	}
     }
 
   return expand_call (exp, target, target == const0_rtx);
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 5ca3182..d7447d0 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,16 @@
+2022-04-26  Patrick Palka  <ppalka@redhat.com>
+
+	PR c++/105304
+	* c-common.cc (verify_tree) [restart]: Move up to before the
+	NULL test.
+
+2022-04-11  Jakub Jelinek  <jakub@redhat.com>
+
+	PR c++/105186
+	* c-common.cc (c_common_nodes_and_builtins): After registering __int%d
+	and __int%d__ builtin types, initialize corresponding ridpointers
+	entry.
+
 2022-03-30  Marek Polacek  <polacek@redhat.com>
 
 	PR c++/101030
diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index d034837..bb0544e 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -2009,12 +2009,12 @@
   enum tree_code code;
   enum tree_code_class cl;
 
+ restart:
   /* X may be NULL if it is the operand of an empty statement expression
      ({ }).  */
   if (x == NULL)
     return;
 
- restart:
   code = TREE_CODE (x);
   cl = TREE_CODE_CLASS (code);
 
@@ -4278,6 +4278,8 @@
       sprintf (name, "__int%d__", int_n_data[i].bitsize);
       record_builtin_type ((enum rid)(RID_FIRST_INT_N + i), name,
 			   int_n_trees[i].signed_type);
+      ridpointers[RID_FIRST_INT_N + i]
+	= DECL_NAME (TYPE_NAME (int_n_trees[i].signed_type));
 
       sprintf (name, "__int%d unsigned", int_n_data[i].bitsize);
       record_builtin_type (RID_MAX, name, int_n_trees[i].unsigned_type);
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index ea25ddb..b0fef44 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,8 @@
+2022-04-08  Jakub Jelinek  <jakub@redhat.com>
+
+	PR c/105149
+	* c-typeck.cc (c_build_va_arg): Reject function types.
+
 2022-03-22  Marek Polacek  <polacek@redhat.com>
 
 	PR c/82283
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 6c4af5e..e130196 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -15896,6 +15896,12 @@
 		"type %qT", type);
       return error_mark_node;
     }
+  else if (TREE_CODE (type) == FUNCTION_TYPE)
+    {
+      error_at (loc2, "second argument to %<va_arg%> is a function type %qT",
+		type);
+      return error_mark_node;
+    }
   else if (warn_cxx_compat && TREE_CODE (type) == ENUMERAL_TYPE)
     warning_at (loc2, OPT_Wc___compat,
 		"C++ requires promoted type, not enum type, in %<va_arg%>");
diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index b923a59..0159eaa 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -507,6 +507,7 @@
   gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
 
   node->decl = decl;
+  node->semantic_interposition = opt_for_fn (decl, flag_semantic_interposition);
 
   if ((flag_openacc || flag_openmp)
       && lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl)))
@@ -3487,7 +3488,11 @@
 	     "returns a pointer");
       error_found = true;
     }
-  if (definition && externally_visible
+  if (definition
+      && externally_visible
+      /* For aliases in lto1 free_lang_data doesn't guarantee preservation
+	 of opt_for_fn (decl, flag_semantic_interposition).  See PR105399.  */
+      && (!alias || !in_lto_p)
       && semantic_interposition
 	 != opt_for_fn (decl, flag_semantic_interposition))
     {
diff --git a/gcc/cgraphclones.cc b/gcc/cgraphclones.cc
index 60da1e8..eb0fa87 100644
--- a/gcc/cgraphclones.cc
+++ b/gcc/cgraphclones.cc
@@ -394,6 +394,7 @@
   new_node->versionable = versionable;
   new_node->can_change_signature = can_change_signature;
   new_node->redefined_extern_inline = redefined_extern_inline;
+  new_node->semantic_interposition = semantic_interposition;
   new_node->tm_may_enter_irr = tm_may_enter_irr;
   new_node->externally_visible = false;
   new_node->no_reorder = no_reorder;
diff --git a/gcc/cgraphunit.cc b/gcc/cgraphunit.cc
index 01f4e28..bc3dc75 100644
--- a/gcc/cgraphunit.cc
+++ b/gcc/cgraphunit.cc
@@ -621,6 +621,7 @@
   tree decl = this->decl;
   location_t saved_loc = input_location;
   input_location = DECL_SOURCE_LOCATION (decl);
+  semantic_interposition = opt_for_fn (decl, flag_semantic_interposition);
 
   if (thunk)
     {
diff --git a/gcc/combine.cc b/gcc/combine.cc
index 53dcac9..9a34ef8 100644
--- a/gcc/combine.cc
+++ b/gcc/combine.cc
@@ -2569,6 +2569,7 @@
   rtx new_other_notes;
   int i;
   scalar_int_mode dest_mode, temp_mode;
+  bool has_non_call_exception = false;
 
   /* Immediately return if any of I0,I1,I2 are the same insn (I3 can
      never be).  */
@@ -2951,6 +2952,32 @@
       return 0;
     }
 
+  /* With non-call exceptions we can end up trying to combine multiple
+     insns with possible EH side effects.  Make sure we can combine
+     that to a single insn which means there must be at most one insn
+     in the combination with an EH side effect.  */
+  if (cfun->can_throw_non_call_exceptions)
+    {
+      if (find_reg_note (i3, REG_EH_REGION, NULL_RTX)
+	  || find_reg_note (i2, REG_EH_REGION, NULL_RTX)
+	  || (i1 && find_reg_note (i1, REG_EH_REGION, NULL_RTX))
+	  || (i0 && find_reg_note (i0, REG_EH_REGION, NULL_RTX)))
+	{
+	  has_non_call_exception = true;
+	  if (insn_could_throw_p (i3)
+	      + insn_could_throw_p (i2)
+	      + (i1 ? insn_could_throw_p (i1) : 0)
+	      + (i0 ? insn_could_throw_p (i0) : 0) > 1)
+	    {
+	      if (dump_file && (dump_flags & TDF_DETAILS))
+		fprintf (dump_file, "Can't combine multiple insns with EH "
+			 "side-effects\n");
+	      undo_all ();
+	      return 0;
+	    }
+	}
+    }
+
   /* Record whether i2 and i3 are trivial moves.  */
   i2_was_move = is_just_move (i2);
   i3_was_move = is_just_move (i3);
@@ -3685,7 +3712,13 @@
 	      || !modified_between_p (*split, i2, i3))
 	  /* We can't overwrite I2DEST if its value is still used by
 	     NEWPAT.  */
-	  && ! reg_referenced_p (i2dest, newpat))
+	  && ! reg_referenced_p (i2dest, newpat)
+	  /* We should not split a possibly trapping part when we
+	     care about non-call EH and have REG_EH_REGION notes
+	     to distribute.  */
+	  && ! (cfun->can_throw_non_call_exceptions
+		&& has_non_call_exception
+		&& may_trap_p (*split)))
 	{
 	  rtx newdest = i2dest;
 	  enum rtx_code split_code = GET_CODE (*split);
@@ -14175,23 +14208,35 @@
 	  break;
 
 	case REG_EH_REGION:
-	  /* These notes must remain with the call or trapping instruction.  */
-	  if (CALL_P (i3))
-	    place = i3;
-	  else if (i2 && CALL_P (i2))
-	    place = i2;
-	  else
-	    {
-	      gcc_assert (cfun->can_throw_non_call_exceptions);
-	      if (may_trap_p (i3))
-		place = i3;
-	      else if (i2 && may_trap_p (i2))
-		place = i2;
-	      /* ??? Otherwise assume we've combined things such that we
-		 can now prove that the instructions can't trap.  Drop the
-		 note in this case.  */
-	    }
-	  break;
+	  {
+	    /* The landing pad handling needs to be kept in sync with the
+	       prerequisite checking in try_combine.  */
+	    int lp_nr = INTVAL (XEXP (note, 0));
+	    /* A REG_EH_REGION note transfering control can only ever come
+	       from i3.  */
+	    if (lp_nr > 0)
+	      gcc_assert (from_insn == i3);
+	    /* We are making sure there is a single effective REG_EH_REGION
+	       note and it's valid to put it on i3.  */
+	    if (!insn_could_throw_p (from_insn))
+	      /* Throw away stra notes on insns that can never throw.  */
+	      ;
+	    else
+	      {
+		if (CALL_P (i3))
+		  place = i3;
+		else
+		  {
+		    gcc_assert (cfun->can_throw_non_call_exceptions);
+		    /* If i3 can still trap preserve the note, otherwise we've
+		       combined things such that we can now prove that the
+		       instructions can't trap.  Drop the note in this case.  */
+		    if (may_trap_p (i3))
+		      place = i3;
+		  }
+	      }
+	    break;
+	  }
 
 	case REG_ARGS_SIZE:
 	  /* ??? How to distribute between i3-i1.  Assume i3 contains the
diff --git a/gcc/common/config/s390/s390-common.cc b/gcc/common/config/s390/s390-common.cc
index caec2f1..72a5ef4 100644
--- a/gcc/common/config/s390/s390-common.cc
+++ b/gcc/common/config/s390/s390-common.cc
@@ -50,10 +50,10 @@
     /* z15 */    PF_IEEE_FLOAT | PF_ZARCH | PF_LONG_DISPLACEMENT
 		 | PF_EXTIMM | PF_DFP | PF_Z10 | PF_Z196 | PF_ZEC12 | PF_TX
 		 | PF_Z13 | PF_VX | PF_VXE | PF_Z14 | PF_VXE2 | PF_Z15,
-    /* arch14 */ PF_IEEE_FLOAT | PF_ZARCH | PF_LONG_DISPLACEMENT
+    /* z16 */    PF_IEEE_FLOAT | PF_ZARCH | PF_LONG_DISPLACEMENT
 		 | PF_EXTIMM | PF_DFP | PF_Z10 | PF_Z196 | PF_ZEC12 | PF_TX
 		 | PF_Z13 | PF_VX | PF_VXE | PF_Z14 | PF_VXE2 | PF_Z15
-		 | PF_NNPA | PF_ARCH14
+		 | PF_NNPA | PF_Z16
   };
 
 /* Change optimizations to be performed, depending on the
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 7b58e13..c5064dd 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -4261,7 +4261,7 @@
 				ext_val=`echo $ext_val | sed -e 's/[a-z0-9]\+//'`
 			  done
 
-			  ext_mask="(("$ext_mask") << 6)"
+			  ext_mask="(("$ext_mask") << TARGET_CPU_NBITS)"
 			  if [ x"$base_id" != x ]; then
 				target_cpu_cname="TARGET_CPU_$base_id | $ext_mask"
 			  fi
@@ -4717,7 +4717,7 @@
 		esac
 		PYTHON=`which python || which python3 || which python2`
 		if test "x${PYTHON}" != x; then
-			with_arch=`${PYTHON} ${srcdir}/config/riscv/arch-canonicalize ${with_arch}`
+			with_arch=`${PYTHON} ${srcdir}/config/riscv/arch-canonicalize -misa-spec=${with_isa_spec} ${with_arch}`
 		fi
 		tm_defines="${tm_defines} TARGET_RISCV_DEFAULT_ARCH=${with_arch}"
 
@@ -4766,6 +4766,7 @@
 			case "${target}" in
 			riscv*-*-elf*)
 				if ${srcdir}/config/riscv/multilib-generator \
+					-misa-spec=${with_isa_spec} \
 					`echo ${with_multilib_generator} | sed 's/;/ /g'`\
 					> t-multilib-config;
 				then
@@ -5531,7 +5532,7 @@
 		for which in arch tune; do
 			eval "val=\$with_$which"
 			case ${val} in
-			"" | native | z900 | z990 | z9-109 | z9-ec | z10 | z196 | zEC12 | z13 | z14 | z15 | arch5 | arch6 | arch7 | arch8 | arch9 | arch10 | arch11 | arch12 | arch13 | arch14 )
+			"" | native | z900 | z990 | z9-109 | z9-ec | z10 | z196 | zEC12 | z13 | z14 | z15 | z16 | arch5 | arch6 | arch7 | arch8 | arch9 | arch10 | arch11 | arch12 | arch13 | arch14 )
 				# OK
 				;;
 			*)
diff --git a/gcc/config/aarch64/aarch64-builtins.cc b/gcc/config/aarch64/aarch64-builtins.cc
index 6ebeee7..c21476d 100644
--- a/gcc/config/aarch64/aarch64-builtins.cc
+++ b/gcc/config/aarch64/aarch64-builtins.cc
@@ -1664,6 +1664,14 @@
       = aarch64_general_add_builtin (data[i].name, data[i].type, data[i].code);
 }
 
+/* Implement #pragma GCC aarch64 "arm_acle.h".  */
+void
+handle_arm_acle_h (void)
+{
+  if (TARGET_LS64)
+    aarch64_init_ls64_builtins ();
+}
+
 /* Initialize fpsr fpcr getters and setters.  */
 
 static void
@@ -1755,9 +1763,6 @@
 
   if (TARGET_MEMTAG)
     aarch64_init_memtag_builtins ();
-
-  if (TARGET_LS64)
-    aarch64_init_ls64_builtins ();
 }
 
 /* Implement TARGET_BUILTIN_DECL for the AARCH64_BUILTIN_GENERAL group.  */
diff --git a/gcc/config/aarch64/aarch64-c.cc b/gcc/config/aarch64/aarch64-c.cc
index caf8e33..767ee0c 100644
--- a/gcc/config/aarch64/aarch64-c.cc
+++ b/gcc/config/aarch64/aarch64-c.cc
@@ -302,6 +302,8 @@
     aarch64_sve::handle_arm_sve_h ();
   else if (strcmp (name, "arm_neon.h") == 0)
     handle_arm_neon_h ();
+  else if (strcmp (name, "arm_acle.h") == 0)
+    handle_arm_acle_h ();
   else
     error ("unknown %<#pragma GCC aarch64%> option %qs", name);
 }
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index c6f13ee..2ac781d 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -995,6 +995,7 @@
 tree aarch64_general_builtin_decl (unsigned, bool);
 tree aarch64_general_builtin_rsqrt (unsigned int);
 tree aarch64_builtin_vectorized_function (unsigned int, tree, tree);
+void handle_arm_acle_h (void);
 void handle_arm_neon_h (void);
 
 namespace aarch64_sve {
diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index 1873342..a00e1c6 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -3385,20 +3385,6 @@
 
 ;; 'across lanes' add.
 
-(define_expand "reduc_plus_scal_<mode>"
-  [(match_operand:<VEL> 0 "register_operand")
-   (unspec:VDQ_I [(match_operand:VDQ_I 1 "register_operand")]
-	       UNSPEC_ADDV)]
-  "TARGET_SIMD"
-  {
-    rtx elt = aarch64_endian_lane_rtx (<MODE>mode, 0);
-    rtx scratch = gen_reg_rtx (<MODE>mode);
-    emit_insn (gen_aarch64_reduc_plus_internal<mode> (scratch, operands[1]));
-    emit_insn (gen_aarch64_get_lane<mode> (operands[0], scratch, elt));
-    DONE;
-  }
-)
-
 (define_insn "aarch64_faddp<mode>"
  [(set (match_operand:VHSDF 0 "register_operand" "=w")
        (unspec:VHSDF [(match_operand:VHSDF 1 "register_operand" "w")
@@ -3409,15 +3395,58 @@
   [(set_attr "type" "neon_fp_reduc_add_<stype><q>")]
 )
 
-(define_insn "aarch64_reduc_plus_internal<mode>"
- [(set (match_operand:VDQV 0 "register_operand" "=w")
-       (unspec:VDQV [(match_operand:VDQV 1 "register_operand" "w")]
+(define_insn "reduc_plus_scal_<mode>"
+ [(set (match_operand:<VEL> 0 "register_operand" "=w")
+       (unspec:<VEL> [(match_operand:VDQV 1 "register_operand" "w")]
 		    UNSPEC_ADDV))]
  "TARGET_SIMD"
  "add<VDQV:vp>\\t%<Vetype>0, %1.<Vtype>"
   [(set_attr "type" "neon_reduc_add<q>")]
 )
 
+(define_insn "reduc_plus_scal_v2si"
+ [(set (match_operand:SI 0 "register_operand" "=w")
+       (unspec:SI [(match_operand:V2SI 1 "register_operand" "w")]
+		    UNSPEC_ADDV))]
+ "TARGET_SIMD"
+ "addp\\t%0.2s, %1.2s, %1.2s"
+  [(set_attr "type" "neon_reduc_add")]
+)
+
+;; ADDV with result zero-extended to SI/DImode (for popcount).
+(define_insn "aarch64_zero_extend<GPI:mode>_reduc_plus_<VDQV_E:mode>"
+ [(set (match_operand:GPI 0 "register_operand" "=w")
+       (zero_extend:GPI
+	(unspec:<VDQV_E:VEL> [(match_operand:VDQV_E 1 "register_operand" "w")]
+			     UNSPEC_ADDV)))]
+ "TARGET_SIMD"
+ "add<VDQV_E:vp>\\t%<VDQV_E:Vetype>0, %1.<VDQV_E:Vtype>"
+  [(set_attr "type" "neon_reduc_add<VDQV_E:q>")]
+)
+
+(define_insn "reduc_plus_scal_<mode>"
+ [(set (match_operand:<VEL> 0 "register_operand" "=w")
+       (unspec:<VEL> [(match_operand:V2F 1 "register_operand" "w")]
+		   UNSPEC_FADDV))]
+ "TARGET_SIMD"
+ "faddp\\t%<Vetype>0, %1.<Vtype>"
+  [(set_attr "type" "neon_fp_reduc_add_<Vetype><q>")]
+)
+
+(define_expand "reduc_plus_scal_v4sf"
+ [(set (match_operand:SF 0 "register_operand")
+       (unspec:SF [(match_operand:V4SF 1 "register_operand")]
+		    UNSPEC_FADDV))]
+ "TARGET_SIMD"
+{
+  rtx elt = aarch64_endian_lane_rtx (V4SFmode, 0);
+  rtx scratch = gen_reg_rtx (V4SFmode);
+  emit_insn (gen_aarch64_faddpv4sf (scratch, operands[1], operands[1]));
+  emit_insn (gen_aarch64_faddpv4sf (scratch, scratch, scratch));
+  emit_insn (gen_aarch64_get_lanev4sf (operands[0], scratch, elt));
+  DONE;
+})
+
 (define_insn "aarch64_<su>addlv<mode>"
  [(set (match_operand:<VWIDE_S> 0 "register_operand" "=w")
        (unspec:<VWIDE_S> [(match_operand:VDQV_L 1 "register_operand" "w")]
@@ -3436,49 +3465,6 @@
   [(set_attr "type" "neon_reduc_add<q>")]
 )
 
-;; ADDV with result zero-extended to SI/DImode (for popcount).
-(define_insn "aarch64_zero_extend<GPI:mode>_reduc_plus_<VDQV_E:mode>"
- [(set (match_operand:GPI 0 "register_operand" "=w")
-       (zero_extend:GPI
-	(unspec:<VDQV_E:VEL> [(match_operand:VDQV_E 1 "register_operand" "w")]
-			     UNSPEC_ADDV)))]
- "TARGET_SIMD"
- "add<VDQV_E:vp>\\t%<VDQV_E:Vetype>0, %1.<VDQV_E:Vtype>"
-  [(set_attr "type" "neon_reduc_add<VDQV_E:q>")]
-)
-
-(define_insn "aarch64_reduc_plus_internalv2si"
- [(set (match_operand:V2SI 0 "register_operand" "=w")
-       (unspec:V2SI [(match_operand:V2SI 1 "register_operand" "w")]
-		    UNSPEC_ADDV))]
- "TARGET_SIMD"
- "addp\\t%0.2s, %1.2s, %1.2s"
-  [(set_attr "type" "neon_reduc_add")]
-)
-
-(define_insn "reduc_plus_scal_<mode>"
- [(set (match_operand:<VEL> 0 "register_operand" "=w")
-       (unspec:<VEL> [(match_operand:V2F 1 "register_operand" "w")]
-		   UNSPEC_FADDV))]
- "TARGET_SIMD"
- "faddp\\t%<Vetype>0, %1.<Vtype>"
-  [(set_attr "type" "neon_fp_reduc_add_<Vetype><q>")]
-)
-
-(define_expand "reduc_plus_scal_v4sf"
- [(set (match_operand:SF 0 "register_operand")
-       (unspec:V4SF [(match_operand:V4SF 1 "register_operand")]
-		    UNSPEC_FADDV))]
- "TARGET_SIMD"
-{
-  rtx elt = aarch64_endian_lane_rtx (V4SFmode, 0);
-  rtx scratch = gen_reg_rtx (V4SFmode);
-  emit_insn (gen_aarch64_faddpv4sf (scratch, operands[1], operands[1]));
-  emit_insn (gen_aarch64_faddpv4sf (scratch, scratch, scratch));
-  emit_insn (gen_aarch64_get_lanev4sf (operands[0], scratch, elt));
-  DONE;
-})
-
 (define_insn "clrsb<mode>2"
   [(set (match_operand:VDQ_BHSI 0 "register_operand" "=w")
         (clrsb:VDQ_BHSI (match_operand:VDQ_BHSI 1 "register_operand" "w")))]
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 3e2a6fb..f650abb 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -15637,7 +15637,7 @@
   unsigned int adjust_body_cost (loop_vec_info, const aarch64_vector_costs *,
 				 unsigned int);
   bool prefer_unrolled_loop () const;
-  unsigned int determine_suggested_unroll_factor ();
+  unsigned int determine_suggested_unroll_factor (loop_vec_info);
 
   /* True if we have performed one-time initialization based on the
      vec_info.  */
@@ -16746,7 +16746,8 @@
 }
 
 unsigned int
-aarch64_vector_costs::determine_suggested_unroll_factor ()
+aarch64_vector_costs::
+determine_suggested_unroll_factor (loop_vec_info loop_vinfo)
 {
   bool sve = m_vec_flags & VEC_ANY_SVE;
   /* If we are trying to unroll an Advanced SIMD main loop that contains
@@ -16760,6 +16761,7 @@
     return 1;
 
   unsigned int max_unroll_factor = 1;
+  auto vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
   for (auto vec_ops : m_ops)
     {
       aarch64_simd_vec_issue_info const *vec_issue
@@ -16768,7 +16770,8 @@
 	return 1;
       /* Limit unroll factor to a value adjustable by the user, the default
 	 value is 4. */
-      unsigned int unroll_factor = aarch64_vect_unroll_limit;
+      unsigned int unroll_factor = MIN (aarch64_vect_unroll_limit,
+					(int) known_alignment (vf));
       unsigned int factor
        = vec_ops.reduction_latency > 1 ? vec_ops.reduction_latency : 1;
       unsigned int temp;
@@ -16946,7 +16949,8 @@
     {
       m_costs[vect_body] = adjust_body_cost (loop_vinfo, scalar_costs,
 					     m_costs[vect_body]);
-      m_suggested_unroll_factor = determine_suggested_unroll_factor ();
+      m_suggested_unroll_factor
+	= determine_suggested_unroll_factor (loop_vinfo);
     }
 
   /* Apply the heuristic described above m_stp_sequence_cost.  Prefer
@@ -18053,6 +18057,9 @@
   return false;
 }
 
+static_assert (TARGET_CPU_generic < TARGET_CPU_MASK,
+	       "TARGET_CPU_NBITS is big enough");
+
 /* Return the CPU corresponding to the enum CPU.
    If it doesn't specify a cpu, return the default.  */
 
@@ -18062,12 +18069,12 @@
   if (cpu != aarch64_none)
     return &all_cores[cpu];
 
-  /* The & 0x3f is to extract the bottom 6 bits that encode the
-     default cpu as selected by the --with-cpu GCC configure option
+  /* The & TARGET_CPU_MASK is to extract the bottom TARGET_CPU_NBITS bits that
+     encode the default cpu as selected by the --with-cpu GCC configure option
      in config.gcc.
      ???: The whole TARGET_CPU_DEFAULT and AARCH64_CPU_DEFAULT_FLAGS
      flags mechanism should be reworked to make it more sane.  */
-  return &all_cores[TARGET_CPU_DEFAULT & 0x3f];
+  return &all_cores[TARGET_CPU_DEFAULT & TARGET_CPU_MASK];
 }
 
 /* Return the architecture corresponding to the enum ARCH.
@@ -18079,7 +18086,8 @@
   if (arch != aarch64_no_arch)
     return &all_architectures[arch];
 
-  const struct processor *cpu = &all_cores[TARGET_CPU_DEFAULT & 0x3f];
+  const struct processor *cpu
+    = &all_cores[TARGET_CPU_DEFAULT & TARGET_CPU_MASK];
 
   return &all_architectures[cpu->arch];
 }
@@ -18166,7 +18174,7 @@
 	{
 	  /* Get default configure-time CPU.  */
 	  selected_cpu = aarch64_get_tune_cpu (aarch64_none);
-	  aarch64_isa_flags = TARGET_CPU_DEFAULT >> 6;
+	  aarch64_isa_flags = TARGET_CPU_DEFAULT >> TARGET_CPU_NBITS;
 	}
 
       if (selected_tune)
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index efa46ac..359b6e85 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -813,10 +813,16 @@
   TARGET_CPU_generic
 };
 
+/* Define how many bits are used to represent the CPU in TARGET_CPU_DEFAULT.
+   This needs to be big enough to fit the value of TARGET_CPU_generic.
+   All bits after this are used to represent the AARCH64_CPU_DEFAULT_FLAGS.  */
+#define TARGET_CPU_NBITS 8
+#define TARGET_CPU_MASK ((1 << TARGET_CPU_NBITS) - 1)
+
 /* If there is no CPU defined at configure, use generic as default.  */
 #ifndef TARGET_CPU_DEFAULT
 #define TARGET_CPU_DEFAULT \
-  (TARGET_CPU_generic | (AARCH64_CPU_DEFAULT_FLAGS << 6))
+  (TARGET_CPU_generic | (AARCH64_CPU_DEFAULT_FLAGS << TARGET_CPU_NBITS))
 #endif
 
 /* If inserting NOP before a mult-accumulate insn remember to adjust the
diff --git a/gcc/config/aarch64/arm_acle.h b/gcc/config/aarch64/arm_acle.h
index ecd852f..9775a48 100644
--- a/gcc/config/aarch64/arm_acle.h
+++ b/gcc/config/aarch64/arm_acle.h
@@ -29,6 +29,8 @@
 
 #include <stdint.h>
 
+#pragma GCC aarch64 "arm_acle.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
diff --git a/gcc/config/arm/t-aprofile b/gcc/config/arm/t-aprofile
index 574951c..fe2ec88 100644
--- a/gcc/config/arm/t-aprofile
+++ b/gcc/config/arm/t-aprofile
@@ -26,8 +26,8 @@
 
 # Arch and FPU variants to build libraries with
 
-MULTI_ARCH_OPTS_A       = march=armv7-a/march=armv7-a+fp/march=armv7-a+simd/march=armv7ve+simd/march=armv8-a/march=armv8-a+simd/march=armv9-a/march=armv9-a+simd
-MULTI_ARCH_DIRS_A       = v7-a v7-a+fp v7-a+simd v7ve+simd v8-a v8-a+simd v9-a v9-a+simd
+MULTI_ARCH_OPTS_A       = march=armv7-a/march=armv7-a+fp/march=armv7-a+simd/march=armv7ve+simd/march=armv8-a/march=armv8-a+simd
+MULTI_ARCH_DIRS_A       = v7-a v7-a+fp v7-a+simd v7ve+simd v8-a v8-a+simd
 
 # ARMv7-A - build nofp, fp-d16 and SIMD variants
 
@@ -46,11 +46,6 @@
 MULTILIB_REQUIRED	+= mthumb/march=armv8-a+simd/mfloat-abi=hard
 MULTILIB_REQUIRED	+= mthumb/march=armv8-a+simd/mfloat-abi=softfp
 
-# Armv9-A - build nofp and SIMD variants.
-MULTILIB_REQUIRED	+= mthumb/march=armv9-a/mfloat-abi=soft
-MULTILIB_REQUIRED	+= mthumb/march=armv9-a+simd/mfloat-abi=hard
-MULTILIB_REQUIRED	+= mthumb/march=armv9-a+simd/mfloat-abi=softfp
-
 # Matches
 
 # Arch Matches
@@ -135,14 +130,12 @@
 			     march?armv8-a+simd=march?armv8.6-a$(ARCH))
 
 # Armv9 without SIMD: map down to base architecture
-MULTILIB_MATCHES	+= $(foreach ARCH, $(v9_a_nosimd_variants), \
-			     march?armv9-a=march?armv9-a$(ARCH))
+MULTILIB_MATCHES    += march?armv8-a=march?armv9-a
+# No variants without SIMD.
 
 # Armv9 with SIMD: map down to base arch + simd
-MULTILIB_MATCHES	+= march?armv9-a+simd=march?armv9-a+crc+simd \
-			   $(foreach ARCH, $(filter-out +simd, $(v9_a_simd_variants)), \
-			     march?armv9-a+simd=march?armv9-a$(ARCH) \
-			     march?armv9-a+simd=march?armv9-a+crc$(ARCH))
+MULTILIB_MATCHES    += $(foreach ARCH, $(v9_a_simd_variants), \
+			     march?armv8-a+simd=march?armv9-a$(ARCH))
 
 # Use Thumb libraries for everything.
 
@@ -150,13 +143,11 @@
 
 MULTILIB_REUSE		+= mthumb/march.armv8-a/mfloat-abi.soft=marm/march.armv8-a/mfloat-abi.soft
 
-MULTILIB_REUSE		+= mthumb/march.armv9-a/mfloat-abi.soft=marm/march.armv9-a/mfloat-abi.soft
-
 MULTILIB_REUSE		+= $(foreach ABI, hard softfp, \
-			     $(foreach ARCH, armv7-a+fp armv7-a+simd armv7ve+simd armv8-a+simd armv9-a+simd, \
+			     $(foreach ARCH, armv7-a+fp armv7-a+simd armv7ve+simd armv8-a+simd, \
 			       mthumb/march.$(ARCH)/mfloat-abi.$(ABI)=marm/march.$(ARCH)/mfloat-abi.$(ABI)))
 
 # Softfp but no FP, use the soft-float libraries.
 MULTILIB_REUSE		+= $(foreach MODE, arm thumb, \
-			     $(foreach ARCH, armv7-a armv8-a armv9-a, \
+			     $(foreach ARCH, armv7-a armv8-a, \
 			       mthumb/march.$(ARCH)/mfloat-abi.soft=m$(MODE)/march.$(ARCH)/mfloat-abi.softfp))
diff --git a/gcc/config/arm/t-multilib b/gcc/config/arm/t-multilib
index ea258b1..6bb58d3 100644
--- a/gcc/config/arm/t-multilib
+++ b/gcc/config/arm/t-multilib
@@ -78,7 +78,6 @@
 v8_5_a_simd_variants	:= $(call all_feat_combs, simd fp16 crypto i8mm bf16)
 v8_6_a_simd_variants	:= $(call all_feat_combs, simd fp16 crypto i8mm bf16)
 v8_r_nosimd_variants	:= +crc
-v9_a_nosimd_variants	:= +crc
 v9_a_simd_variants	:= $(call all_feat_combs, simd fp16 crypto i8mm bf16)
 
 ifneq (,$(HAS_APROFILE))
@@ -206,14 +205,10 @@
 
 # Armv9
 MULTILIB_MATCHES	+= march?armv7=march?armv9-a
-MULTILIB_MATCHES	+= $(foreach ARCH, $(v9_a_nosimd_variants), \
-			     march?armv7=march?armv9-a$(ARCH))
 
 # Armv9 with SIMD
-MULTILIB_MATCHES	+= march?armv7+fp=march?armv9-a+crc+simd \
-			   $(foreach ARCH, $(v9_a_simd_variants), \
-			     march?armv7+fp=march?armv9-a$(ARCH) \
-			     march?armv7+fp=march?armv9-a+crc$(ARCH))
+MULTILIB_MATCHES	+= $(foreach ARCH, $(v9_a_simd_variants), \
+			     march?armv7+fp=march?armv9-a$(ARCH))
 endif		# Not APROFILE.
 
 # Use Thumb libraries for everything.
diff --git a/gcc/config/bfin/bfin.md b/gcc/config/bfin/bfin.md
index 0e44653..56b2472 100644
--- a/gcc/config/bfin/bfin.md
+++ b/gcc/config/bfin/bfin.md
@@ -1741,7 +1741,7 @@
 	(ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d") (const_int 1))
 		(zero_extend:SI (reg:BI REG_CC))))
    (set (reg:BI REG_CC)
-	(zero_extract:BI (match_dup 1) (const_int 31) (const_int 0)))]
+	(zero_extract:BI (match_dup 1) (const_int 1) (const_int 31)))]
   ""
   "%0 = ROT %1 BY 1%!"
   [(set_attr "type" "dsp32shiftimm")])
diff --git a/gcc/config/freebsd.h b/gcc/config/freebsd.h
index 28ebcad..d89ee7d 100644
--- a/gcc/config/freebsd.h
+++ b/gcc/config/freebsd.h
@@ -55,7 +55,7 @@
 #endif
 
 #undef TARGET_LIBC_HAS_FUNCTION
-#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
+#define TARGET_LIBC_HAS_FUNCTION bsd_libc_has_function
 
 /* Use --as-needed -lgcc_s for eh support.  */
 #ifdef HAVE_LD_AS_NEEDED
diff --git a/gcc/config/gcn/gcn.cc b/gcc/config/gcn/gcn.cc
index 402f025..e2e9335 100644
--- a/gcc/config/gcn/gcn.cc
+++ b/gcc/config/gcn/gcn.cc
@@ -5588,8 +5588,9 @@
       fprintf (f, "%u", gang_private_hwm);
       gang_private_hwm += size;
       if (gang_private_hwm > gang_private_size_opt)
-	error ("gang-private data-share memory exhausted (increase with "
-	       "%<-mgang-private-size=<number>%>)");
+	error ("%d bytes of gang-private data-share memory exhausted"
+	       " (increase with %<-mgang-private-size=%d%>, for example)",
+	       gang_private_size_opt, gang_private_hwm);
     }
 }
 
diff --git a/gcc/config/i386/avx512fintrin.h b/gcc/config/i386/avx512fintrin.h
index 29511fd..77d6249 100644
--- a/gcc/config/i386/avx512fintrin.h
+++ b/gcc/config/i386/avx512fintrin.h
@@ -3286,31 +3286,67 @@
 						      (__mmask8) __U, __R);
 }
 #else
-#define _mm512_scalef_round_pd(A, B, C)            \
-    (__m512d)__builtin_ia32_scalefpd512_mask(A, B, (__v8df)_mm512_undefined_pd(), -1, C)
+#define _mm512_scalef_round_pd(A, B, C)					\
+  ((__m512d)								\
+   __builtin_ia32_scalefpd512_mask((A), (B),				\
+				   (__v8df) _mm512_undefined_pd(),	\
+				   -1, (C)))
 
-#define _mm512_mask_scalef_round_pd(W, U, A, B, C) \
-    (__m512d)__builtin_ia32_scalefpd512_mask(A, B, W, U, C)
+#define _mm512_mask_scalef_round_pd(W, U, A, B, C)			\
+  ((__m512d) __builtin_ia32_scalefpd512_mask((A), (B), (W), (U), (C)))
 
-#define _mm512_maskz_scalef_round_pd(U, A, B, C)   \
-    (__m512d)__builtin_ia32_scalefpd512_mask(A, B, (__v8df)_mm512_setzero_pd(), U, C)
+#define _mm512_maskz_scalef_round_pd(U, A, B, C)			\
+  ((__m512d)								\
+   __builtin_ia32_scalefpd512_mask((A), (B),				\
+				   (__v8df) _mm512_setzero_pd(),	\
+				   (U), (C)))
 
-#define _mm512_scalef_round_ps(A, B, C)            \
-    (__m512)__builtin_ia32_scalefps512_mask(A, B, (__v16sf)_mm512_undefined_ps(), -1, C)
+#define _mm512_scalef_round_ps(A, B, C)					\
+  ((__m512)								\
+   __builtin_ia32_scalefps512_mask((A), (B),				\
+				   (__v16sf) _mm512_undefined_ps(),	\
+				   -1, (C)))
 
-#define _mm512_mask_scalef_round_ps(W, U, A, B, C) \
-    (__m512)__builtin_ia32_scalefps512_mask(A, B, W, U, C)
+#define _mm512_mask_scalef_round_ps(W, U, A, B, C)			\
+  ((__m512) __builtin_ia32_scalefps512_mask((A), (B), (W), (U), (C)))
 
-#define _mm512_maskz_scalef_round_ps(U, A, B, C)   \
-    (__m512)__builtin_ia32_scalefps512_mask(A, B, (__v16sf)_mm512_setzero_ps(), U, C)
+#define _mm512_maskz_scalef_round_ps(U, A, B, C)			\
+  ((__m512)								\
+   __builtin_ia32_scalefps512_mask((A), (B),				\
+				   (__v16sf) _mm512_setzero_ps(),	\
+				   (U), (C)))
 
-#define _mm_scalef_round_sd(A, B, C)            \
-    (__m128d)__builtin_ia32_scalefsd_mask_round (A, B, \
-	(__v2df)_mm_setzero_pd (), -1, C)
+#define _mm_scalef_round_sd(A, B, C)					\
+  ((__m128d)								\
+   __builtin_ia32_scalefsd_mask_round ((A), (B),			\
+				       (__v2df) _mm_undefined_pd (),	\
+				       -1, (C)))
 
-#define _mm_scalef_round_ss(A, B, C)            \
-    (__m128)__builtin_ia32_scalefss_mask_round (A, B, \
-	(__v4sf)_mm_setzero_ps (), -1, C)
+#define _mm_scalef_round_ss(A, B, C)					\
+  ((__m128)								\
+   __builtin_ia32_scalefss_mask_round ((A), (B),			\
+				       (__v4sf) _mm_undefined_ps (),	\
+				       -1, (C)))
+
+#define _mm_mask_scalef_round_sd(W, U, A, B, C)				\
+  ((__m128d)								\
+   __builtin_ia32_scalefsd_mask_round ((A), (B), (W), (U), (C)))
+
+#define _mm_mask_scalef_round_ss(W, U, A, B, C)				\
+  ((__m128)								\
+   __builtin_ia32_scalefss_mask_round ((A), (B), (W), (U), (C)))
+
+#define _mm_maskz_scalef_round_sd(U, A, B, C)				\
+  ((__m128d)								\
+   __builtin_ia32_scalefsd_mask_round ((A), (B),			\
+				       (__v2df) _mm_setzero_pd (),	\
+				       (U), (C)))
+
+#define _mm_maskz_scalef_round_ss(U, A, B, C)				\
+  ((__m128)								\
+   __builtin_ia32_scalefss_mask_round ((A), (B),			\
+				       (__v4sf) _mm_setzero_ps (),	\
+				       (U), (C)))
 #endif
 
 #define _mm_mask_scalef_sd(W, U, A, B) \
diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc
index 794315ee..31780b6 100644
--- a/gcc/config/i386/i386-expand.cc
+++ b/gcc/config/i386/i386-expand.cc
@@ -3136,6 +3136,8 @@
   bool sign_bit_compare_p = false;
   rtx op0 = XEXP (operands[1], 0);
   rtx op1 = XEXP (operands[1], 1);
+  rtx op2 = operands[2];
+  rtx op3 = operands[3];
 
   if (GET_MODE (op0) == TImode
       || (GET_MODE (op0) == DImode
@@ -3153,17 +3155,29 @@
       || (op1 == constm1_rtx && (code == GT || code == LE)))
     sign_bit_compare_p = true;
 
+  /* op0 == op1 ? op0 : op3 is equivalent to op0 == op1 ? op1 : op3,
+     but if op1 is a constant, the latter form allows more optimizations,
+     either through the last 2 ops being constant handling, or the one
+     constant and one variable cases.  On the other side, for cmov the
+     former might be better as we don't need to load the constant into
+     another register.  */
+  if (code == EQ && CONST_INT_P (op1) && rtx_equal_p (op0, op2))
+    op2 = op1;
+  /* Similarly for op0 != op1 ? op2 : op0 and op0 != op1 ? op2 : op1.  */
+  else if (code == NE && CONST_INT_P (op1) && rtx_equal_p (op0, op3))
+    op3 = op1;
+
   /* Don't attempt mode expansion here -- if we had to expand 5 or 6
      HImode insns, we'd be swallowed in word prefix ops.  */
 
   if ((mode != HImode || TARGET_FAST_PREFIX)
       && (mode != (TARGET_64BIT ? TImode : DImode))
-      && CONST_INT_P (operands[2])
-      && CONST_INT_P (operands[3]))
+      && CONST_INT_P (op2)
+      && CONST_INT_P (op3))
     {
       rtx out = operands[0];
-      HOST_WIDE_INT ct = INTVAL (operands[2]);
-      HOST_WIDE_INT cf = INTVAL (operands[3]);
+      HOST_WIDE_INT ct = INTVAL (op2);
+      HOST_WIDE_INT cf = INTVAL (op3);
       HOST_WIDE_INT diff;
 
       diff = ct - cf;
@@ -3559,6 +3573,9 @@
       if (BRANCH_COST (optimize_insn_for_speed_p (), false) <= 2)
 	return false;
 
+      operands[2] = op2;
+      operands[3] = op3;
+
       /* If one of the two operands is an interesting constant, load a
 	 constant with the above and mask it in with a logical operation.  */
 
@@ -17036,7 +17053,8 @@
 
 /* Output code to perform an sinh XFmode calculation.  */
 
-void ix86_emit_i387_sinh (rtx op0, rtx op1)
+void
+ix86_emit_i387_sinh (rtx op0, rtx op1)
 {
   rtx e1 = gen_reg_rtx (XFmode);
   rtx e2 = gen_reg_rtx (XFmode);
@@ -17084,7 +17102,8 @@
 
 /* Output code to perform an cosh XFmode calculation.  */
 
-void ix86_emit_i387_cosh (rtx op0, rtx op1)
+void
+ix86_emit_i387_cosh (rtx op0, rtx op1)
 {
   rtx e1 = gen_reg_rtx (XFmode);
   rtx e2 = gen_reg_rtx (XFmode);
@@ -17106,7 +17125,8 @@
 
 /* Output code to perform an tanh XFmode calculation.  */
 
-void ix86_emit_i387_tanh (rtx op0, rtx op1)
+void
+ix86_emit_i387_tanh (rtx op0, rtx op1)
 {
   rtx e1 = gen_reg_rtx (XFmode);
   rtx e2 = gen_reg_rtx (XFmode);
@@ -17152,7 +17172,8 @@
 
 /* Output code to perform an asinh XFmode calculation.  */
 
-void ix86_emit_i387_asinh (rtx op0, rtx op1)
+void
+ix86_emit_i387_asinh (rtx op0, rtx op1)
 {
   rtx e1 = gen_reg_rtx (XFmode);
   rtx e2 = gen_reg_rtx (XFmode);
@@ -17204,7 +17225,8 @@
 
 /* Output code to perform an acosh XFmode calculation.  */
 
-void ix86_emit_i387_acosh (rtx op0, rtx op1)
+void
+ix86_emit_i387_acosh (rtx op0, rtx op1)
 {
   rtx e1 = gen_reg_rtx (XFmode);
   rtx e2 = gen_reg_rtx (XFmode);
@@ -17230,7 +17252,8 @@
 
 /* Output code to perform an atanh XFmode calculation.  */
 
-void ix86_emit_i387_atanh (rtx op0, rtx op1)
+void
+ix86_emit_i387_atanh (rtx op0, rtx op1)
 {
   rtx e1 = gen_reg_rtx (XFmode);
   rtx e2 = gen_reg_rtx (XFmode);
@@ -17281,7 +17304,8 @@
 
 /* Output code to perform a log1p XFmode calculation.  */
 
-void ix86_emit_i387_log1p (rtx op0, rtx op1)
+void
+ix86_emit_i387_log1p (rtx op0, rtx op1)
 {
   rtx_code_label *label1 = gen_label_rtx ();
   rtx_code_label *label2 = gen_label_rtx ();
@@ -17291,6 +17315,11 @@
   rtx cst, cstln2, cst1;
   rtx_insn *insn;
 
+  /* The emit_jump call emits pending stack adjust, make sure it is emitted
+     before the conditional jump, otherwise the stack adjustment will be
+     only conditional.  */
+  do_pending_stack_adjust ();
+
   cst = const_double_from_real_value
     (REAL_VALUE_ATOF ("0.29289321881345247561810596348408353", XFmode), XFmode);
   cstln2 = force_reg (XFmode, standard_80387_constant_rtx (4)); /* fldln2 */
@@ -17320,7 +17349,8 @@
 }
 
 /* Emit code for round calculation.  */
-void ix86_emit_i387_round (rtx op0, rtx op1)
+void
+ix86_emit_i387_round (rtx op0, rtx op1)
 {
   machine_mode inmode = GET_MODE (op1);
   machine_mode outmode = GET_MODE (op0);
@@ -17434,7 +17464,8 @@
 /* Output code to perform a Newton-Rhapson approximation of a single precision
    floating point divide [http://en.wikipedia.org/wiki/N-th_root_algorithm].  */
 
-void ix86_emit_swdivsf (rtx res, rtx a, rtx b, machine_mode mode)
+void
+ix86_emit_swdivsf (rtx res, rtx a, rtx b, machine_mode mode)
 {
   rtx x0, x1, e0, e1;
 
@@ -17485,7 +17516,8 @@
 /* Output code to perform a Newton-Rhapson approximation of a
    single precision floating point [reciprocal] square root.  */
 
-void ix86_emit_swsqrtsf (rtx res, rtx a, machine_mode mode, bool recip)
+void
+ix86_emit_swsqrtsf (rtx res, rtx a, machine_mode mode, bool recip)
 {
   rtx x0, e0, e1, e2, e3, mthree, mhalf;
   REAL_VALUE_TYPE r;
@@ -23240,9 +23272,10 @@
   *rem_p = rem;
 }
 
-void ix86_expand_atomic_fetch_op_loop (rtx target, rtx mem, rtx val,
-				       enum rtx_code code, bool after,
-				       bool doubleword)
+void
+ix86_expand_atomic_fetch_op_loop (rtx target, rtx mem, rtx val,
+				  enum rtx_code code, bool after,
+				  bool doubleword)
 {
   rtx old_reg, new_reg, old_mem, success;
   machine_mode mode = GET_MODE (target);
@@ -23286,10 +23319,11 @@
    it will be relaxed to an atomic load + compare, and skip
    cmpxchg instruction if mem != exp_input.  */
 
-void ix86_expand_cmpxchg_loop (rtx *ptarget_bool, rtx target_val,
-			       rtx mem, rtx exp_input, rtx new_input,
-			       rtx mem_model, bool doubleword,
-			       rtx_code_label *loop_label)
+void
+ix86_expand_cmpxchg_loop (rtx *ptarget_bool, rtx target_val,
+			  rtx mem, rtx exp_input, rtx new_input,
+			  rtx mem_model, bool doubleword,
+			  rtx_code_label *loop_label)
 {
   rtx_code_label *cmp_label = NULL;
   rtx_code_label *done_label = NULL;
@@ -23388,6 +23422,7 @@
 
     /* If mem is not expected, pause and loop back.  */
     emit_label (cmp_label);
+    emit_move_insn (target_val, new_mem);
     emit_insn (gen_pause ());
     emit_jump_insn (gen_jump (loop_label));
     emit_barrier ();
diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index c959b71..b16df5b 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -4891,6 +4891,7 @@
 	{
 	  int i, prev_size = 0;
 	  tree temp = create_tmp_var (type, "va_arg_tmp");
+	  TREE_ADDRESSABLE (temp) = 1;
 
 	  /* addr = &temp; */
 	  t = build1 (ADDR_EXPR, build_pointer_type (type), temp);
@@ -6524,7 +6525,8 @@
 }
 
 /* Emits a warning for unsupported msabi to sysv pro/epilogues.  */
-void warn_once_call_ms2sysv_xlogues (const char *feature)
+void
+warn_once_call_ms2sysv_xlogues (const char *feature)
 {
   static bool warned_once = false;
   if (!warned_once)
@@ -18806,7 +18808,8 @@
       return NULL_TREE;
     }
 
-  tree fndecl = mathfn_built_in (TREE_TYPE (type_in), fn);
+  tree fndecl = mathfn_built_in (el_mode == DFmode
+				 ? double_type_node : float_type_node, fn);
   bname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
 
   if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LOGF)
@@ -18898,7 +18901,8 @@
       return NULL_TREE;
     }
 
-  tree fndecl = mathfn_built_in (TREE_TYPE (type_in), fn);
+  tree fndecl = mathfn_built_in (el_mode == DFmode
+				 ? double_type_node : float_type_node, fn);
   bname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
   sprintf (name + 7, "%s", bname+10);
 
diff --git a/gcc/config/i386/smmintrin.h b/gcc/config/i386/smmintrin.h
index b42b212..eb6a451 100644
--- a/gcc/config/i386/smmintrin.h
+++ b/gcc/config/i386/smmintrin.h
@@ -810,17 +810,11 @@
 
 #include <popcntintrin.h>
 
-#ifndef __SSE4_1__
+#ifndef __CRC32__
 #pragma GCC push_options
-#pragma GCC target("sse4.1")
-#define __DISABLE_SSE4_1__
-#endif /* __SSE4_1__ */
-
-#ifndef __SSE4_2__
-#pragma GCC push_options
-#pragma GCC target("sse4.2")
-#define __DISABLE_SSE4_2__
-#endif /* __SSE4_1__ */
+#pragma GCC target("crc32")
+#define __DISABLE_CRC32__
+#endif /* __CRC32__ */
 
 /* Accumulate CRC32 (polynomial 0x11EDC6F41) value.  */
 extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
@@ -849,14 +843,9 @@
 }
 #endif
 
-#ifdef __DISABLE_SSE4_2__
-#undef __DISABLE_SSE4_2__
+#ifdef __DISABLE_CRC32__
+#undef __DISABLE_CRC32__
 #pragma GCC pop_options
-#endif /* __DISABLE_SSE4_2__ */
-
-#ifdef __DISABLE_SSE4_1__
-#undef __DISABLE_SSE4_1__
-#pragma GCC pop_options
-#endif /* __DISABLE_SSE4_1__ */
+#endif /* __DISABLE_CRC32__ */
 
 #endif /* _SMMINTRIN_H_INCLUDED */
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index a852c16..5e93aa2 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -327,9 +327,7 @@
 
 ;; 128-, 256- and 512-bit float vector modes for bitwise operations
 (define_mode_iterator VFB
-  [(V32HF "TARGET_AVX512FP16")
-   (V16HF "TARGET_AVX512FP16")
-   (V8HF "TARGET_AVX512FP16")
+  [(V32HF "TARGET_AVX512F") (V16HF "TARGET_AVX") (V8HF "TARGET_SSE2")
    (V16SF "TARGET_AVX512F") (V8SF "TARGET_AVX") V4SF
    (V8DF "TARGET_AVX512F") (V4DF "TARGET_AVX") (V2DF "TARGET_SSE2")])
 
@@ -340,8 +338,7 @@
 
 ;; 128- and 256-bit float vector modes for bitwise operations
 (define_mode_iterator VFB_128_256
-  [(V16HF "TARGET_AVX512FP16")
-   (V8HF "TARGET_AVX512FP16")
+  [(V16HF "TARGET_AVX") (V8HF "TARGET_SSE2")
    (V8SF "TARGET_AVX") V4SF
    (V4DF "TARGET_AVX") (V2DF "TARGET_SSE2")])
 
@@ -399,7 +396,7 @@
 
 ;; All 512bit vector float modes for bitwise operations
 (define_mode_iterator VFB_512
-  [(V32HF "TARGET_AVX512FP16") V16SF V8DF])
+  [V32HF V16SF V8DF])
 
 (define_mode_iterator VI48_AVX512VL
   [V16SI (V8SI  "TARGET_AVX512VL") (V4SI  "TARGET_AVX512VL")
@@ -4581,7 +4578,8 @@
 	  (not:VFB_128_256
 	    (match_operand:VFB_128_256 1 "register_operand" "0,x,v,v"))
 	  (match_operand:VFB_128_256 2 "vector_operand" "xBm,xm,vm,vm")))]
-  "TARGET_SSE && <mask_avx512vl_condition>"
+  "TARGET_SSE && <mask_avx512vl_condition>
+   && (!<mask_applied> || <ssescalarmode>mode != HFmode)"
 {
   char buf[128];
   const char *ops;
@@ -4648,7 +4646,7 @@
 	  (not:VFB_512
 	    (match_operand:VFB_512 1 "register_operand" "v"))
 	  (match_operand:VFB_512 2 "nonimmediate_operand" "vm")))]
-  "TARGET_AVX512F"
+  "TARGET_AVX512F && (!<mask_applied> || <ssescalarmode>mode != HFmode)"
 {
   char buf[128];
   const char *ops;
@@ -4683,7 +4681,8 @@
        (any_logic:VFB_128_256
          (match_operand:VFB_128_256 1 "vector_operand")
          (match_operand:VFB_128_256 2 "vector_operand")))]
-  "TARGET_SSE && <mask_avx512vl_condition>"
+  "TARGET_SSE && <mask_avx512vl_condition>
+   && (!<mask_applied> || <ssescalarmode>mode != HFmode)"
   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
 
 (define_expand "<code><mode>3<mask_name>"
@@ -4691,7 +4690,7 @@
        (any_logic:VFB_512
          (match_operand:VFB_512 1 "nonimmediate_operand")
          (match_operand:VFB_512 2 "nonimmediate_operand")))]
-  "TARGET_AVX512F"
+  "TARGET_AVX512F && (!<mask_applied> || <ssescalarmode>mode != HFmode)"
   "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
 
 (define_insn "*<code><mode>3<mask_name>"
@@ -4700,6 +4699,7 @@
 	  (match_operand:VFB_128_256 1 "vector_operand" "%0,x,v,v")
 	  (match_operand:VFB_128_256 2 "vector_operand" "xBm,xm,vm,vm")))]
   "TARGET_SSE && <mask_avx512vl_condition>
+   && (!<mask_applied> || <ssescalarmode>mode != HFmode)
    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
 {
   char buf[128];
@@ -4766,7 +4766,8 @@
 	(any_logic:VFB_512
 	  (match_operand:VFB_512 1 "nonimmediate_operand" "%v")
 	  (match_operand:VFB_512 2 "nonimmediate_operand" "vm")))]
-  "TARGET_AVX512F && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
+  "TARGET_AVX512F && !(MEM_P (operands[1]) && MEM_P (operands[2]))
+   && (!<mask_applied> || <ssescalarmode>mode != HFmode)"
 {
   char buf[128];
   const char *ops;
@@ -16741,17 +16742,6 @@
 	  (match_operand:<avx512fmaskmode> 4 "register_operand")))]
   "TARGET_AVX512F")
 
-(define_expand "<sse2_avx2>_andnot<mode>3_mask"
-  [(set (match_operand:VI12_AVX512VL 0 "register_operand")
-	(vec_merge:VI12_AVX512VL
-	  (and:VI12_AVX512VL
-	    (not:VI12_AVX512VL
-	      (match_operand:VI12_AVX512VL 1 "register_operand"))
-	    (match_operand:VI12_AVX512VL 2 "nonimmediate_operand"))
-	  (match_operand:VI12_AVX512VL 3 "nonimm_or_0_operand")
-	  (match_operand:<avx512fmaskmode> 4 "register_operand")))]
-  "TARGET_AVX512BW")
-
 (define_insn "*andnot<mode>3"
   [(set (match_operand:VI 0 "register_operand" "=x,x,v")
 	(and:VI
diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc
index 6e24111..80046b6 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -329,6 +329,9 @@
 	    if (!TYPE_P (TREE_TYPE (f)))
 	      return -1;
 
+	    if (DECL_SIZE (f) && integer_zerop (DECL_SIZE (f)))
+	      continue;
+
 	    HOST_WIDE_INT pos = offset + int_byte_position (f);
 	    n = loongarch_flatten_aggregate_field (TREE_TYPE (f), fields, n,
 						   pos);
@@ -473,13 +476,14 @@
 
 static rtx
 loongarch_pass_fpr_single (machine_mode type_mode, unsigned regno,
-			   machine_mode value_mode)
+			   machine_mode value_mode,
+			   HOST_WIDE_INT offset)
 {
   rtx x = gen_rtx_REG (value_mode, regno);
 
   if (type_mode != value_mode)
     {
-      x = gen_rtx_EXPR_LIST (VOIDmode, x, const0_rtx);
+      x = gen_rtx_EXPR_LIST (VOIDmode, x, GEN_INT (offset));
       x = gen_rtx_PARALLEL (type_mode, gen_rtvec (1, x));
     }
   return x;
@@ -539,7 +543,8 @@
 	  {
 	  case 1:
 	    return loongarch_pass_fpr_single (mode, fregno,
-					      TYPE_MODE (fields[0].type));
+					      TYPE_MODE (fields[0].type),
+					      fields[0].offset);
 
 	  case 2:
 	    return loongarch_pass_fpr_pair (mode, fregno,
diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md
index 6c57c8b..d3c809e 100644
--- a/gcc/config/loongarch/loongarch.md
+++ b/gcc/config/loongarch/loongarch.md
@@ -713,6 +713,12 @@
 ;;
 
 ;; Float division and modulus.
+(define_expand "div<mode>3"
+  [(set (match_operand:ANYF 0 "register_operand")
+	(div:ANYF (match_operand:ANYF 1 "reg_or_1_operand")
+		  (match_operand:ANYF 2 "register_operand")))]
+  "")
+
 (define_insn "*div<mode>3"
   [(set (match_operand:ANYF 0 "register_operand" "=f")
 	(div:ANYF (match_operand:ANYF 1 "register_operand" "f")
@@ -2047,13 +2053,17 @@
 
 (define_insn "loongarch_ibar"
   [(unspec_volatile:SI
-      [(match_operand 0 "const_uimm15_operand")] UNSPECV_IBAR)]
+      [(match_operand 0 "const_uimm15_operand")]
+       UNSPECV_IBAR)
+   (clobber (mem:BLK (scratch)))]
   ""
   "ibar\t%0")
 
 (define_insn "loongarch_dbar"
   [(unspec_volatile:SI
-      [(match_operand 0 "const_uimm15_operand")] UNSPECV_DBAR)]
+      [(match_operand 0 "const_uimm15_operand")]
+       UNSPECV_DBAR)
+   (clobber (mem:BLK (scratch)))]
   ""
   "dbar\t%0")
 
@@ -2072,13 +2082,17 @@
 
 (define_insn "loongarch_syscall"
   [(unspec_volatile:SI
-      [(match_operand 0 "const_uimm15_operand")] UNSPECV_SYSCALL)]
+      [(match_operand 0 "const_uimm15_operand")]
+       UNSPECV_SYSCALL)
+   (clobber (mem:BLK (scratch)))]
   ""
   "syscall\t%0")
 
 (define_insn "loongarch_break"
   [(unspec_volatile:SI
-      [(match_operand 0 "const_uimm15_operand")] UNSPECV_BREAK)]
+      [(match_operand 0 "const_uimm15_operand")]
+       UNSPECV_BREAK)
+   (clobber (mem:BLK (scratch)))]
   ""
   "break\t%0")
 
@@ -2103,7 +2117,8 @@
 (define_insn "loongarch_csrrd_<d>"
   [(set (match_operand:GPR 0 "register_operand" "=r")
 	(unspec_volatile:GPR [(match_operand  1 "const_uimm14_operand")]
-			      UNSPECV_CSRRD))]
+			      UNSPECV_CSRRD))
+   (clobber (mem:BLK (scratch)))]
   ""
   "csrrd\t%0,%1"
   [(set_attr "type" "load")
@@ -2114,7 +2129,8 @@
 	  (unspec_volatile:GPR
 	    [(match_operand:GPR 1 "register_operand" "0")
 	     (match_operand 2 "const_uimm14_operand")]
-	     UNSPECV_CSRWR))]
+	     UNSPECV_CSRWR))
+   (clobber (mem:BLK (scratch)))]
   ""
   "csrwr\t%0,%2"
   [(set_attr "type" "store")
@@ -2126,7 +2142,8 @@
 	    [(match_operand:GPR 1 "register_operand" "0")
 	     (match_operand:GPR 2 "register_operand" "q")
 	     (match_operand 3 "const_uimm14_operand")]
-	     UNSPECV_CSRXCHG))]
+	     UNSPECV_CSRXCHG))
+   (clobber (mem:BLK (scratch)))]
   ""
   "csrxchg\t%0,%2,%3"
   [(set_attr "type" "load")
@@ -2135,7 +2152,8 @@
 (define_insn "loongarch_iocsrrd_<size>"
   [(set (match_operand:QHWD 0 "register_operand" "=r")
 	(unspec_volatile:QHWD [(match_operand:SI 1 "register_operand" "r")]
-			      UNSPECV_IOCSRRD))]
+			      UNSPECV_IOCSRRD))
+   (clobber (mem:BLK (scratch)))]
   ""
   "iocsrrd.<size>\t%0,%1"
   [(set_attr "type" "load")
@@ -2144,7 +2162,8 @@
 (define_insn "loongarch_iocsrwr_<size>"
   [(unspec_volatile:QHWD [(match_operand:QHWD 0 "register_operand" "r")
 			  (match_operand:SI 1 "register_operand" "r")]
-			  UNSPECV_IOCSRWR)]
+			  UNSPECV_IOCSRWR)
+   (clobber (mem:BLK (scratch)))]
   ""
   "iocsrwr.<size>\t%0,%1"
   [(set_attr "type" "load")
@@ -2154,7 +2173,8 @@
   [(unspec_volatile:X [(match_operand 0 "const_uimm5_operand")
 		       (match_operand:X 1 "register_operand" "r")
 		       (match_operand 2 "const_imm12_operand")]
-		       UNSPECV_CACOP)]
+		       UNSPECV_CACOP)
+   (clobber (mem:BLK (scratch)))]
   ""
   "cacop\t%0,%1,%2"
   [(set_attr "type" "load")
@@ -2164,7 +2184,8 @@
   [(unspec_volatile:X [(match_operand:X 0 "register_operand" "r")
 		       (match_operand:X 1 "register_operand" "r")
 		       (match_operand 2 "const_uimm5_operand")]
-		       UNSPECV_LDDIR)]
+		       UNSPECV_LDDIR)
+   (clobber (mem:BLK (scratch)))]
   ""
   "lddir\t%0,%1,%2"
   [(set_attr "type" "load")
@@ -2173,7 +2194,8 @@
 (define_insn "loongarch_ldpte_<d>"
   [(unspec_volatile:X [(match_operand:X 0 "register_operand" "r")
 		       (match_operand 1 "const_uimm5_operand")]
-		       UNSPECV_LDPTE)]
+		       UNSPECV_LDPTE)
+   (clobber (mem:BLK (scratch)))]
   ""
   "ldpte\t%0,%1"
   [(set_attr "type" "load")
diff --git a/gcc/config/nvptx/nvptx.h b/gcc/config/nvptx/nvptx.h
index 3b06f33..ed72c25 100644
--- a/gcc/config/nvptx/nvptx.h
+++ b/gcc/config/nvptx/nvptx.h
@@ -29,25 +29,6 @@
 
 #define STARTFILE_SPEC "%{mmainkernel:crt0.o}"
 
-/* Newer versions of CUDA no longer support sm_30, and nvptx-tools as
-   currently doesn't handle that gracefully when verifying
-   ( https://github.com/MentorEmbedded/nvptx-tools/issues/30 ).  Work around
-   this by verifying with sm_35 when having misa=sm_30 (either implicitly
-   or explicitly).  */
-#define ASM_SPEC				\
-  "%{"						\
-  /* Explict misa=sm_30.  */			\
-  "misa=sm_30:-m sm_35"				\
-  /* Separator.	 */				\
-  "; "						\
-  /* Catch-all.	 */				\
-  "misa=*:-m %*"				\
-  /* Separator.	 */				\
-  "; "						\
-  /* Implicit misa=sm_30.  */			\
-  ":-m sm_35"					\
-  "}"
-
 #define TARGET_CPU_CPP_BUILTINS() nvptx_cpu_cpp_builtins ()
 
 /* Avoid the default in ../../gcc.cc, which adds "-pthread", which is not
diff --git a/gcc/config/nvptx/nvptx.opt b/gcc/config/nvptx/nvptx.opt
index 55a1057..c5a5668 100644
--- a/gcc/config/nvptx/nvptx.opt
+++ b/gcc/config/nvptx/nvptx.opt
@@ -52,7 +52,6 @@
 Target Mask(GOMP)
 Generate code for OpenMP offloading: enables -msoft-stack and -muniform-simt.
 
-; Default needs to be in sync with default in ASM_SPEC in nvptx.h.
 misa=
 Target RejectNegative ToLower Joined Enum(ptx_isa) Var(ptx_isa_option) Init(PTX_ISA_SM30)
 Specify the PTX ISA target architecture to use.
diff --git a/gcc/config/riscv/arch-canonicalize b/gcc/config/riscv/arch-canonicalize
index 49a6204..f36a2ca 100755
--- a/gcc/config/riscv/arch-canonicalize
+++ b/gcc/config/riscv/arch-canonicalize
@@ -20,14 +20,18 @@
 # along with GCC; see the file COPYING3.  If not see
 # <http://www.gnu.org/licenses/>.
 
+# TODO: Extract riscv_subset_t from riscv-common.cc and make it can be compiled
+#       standalone to replace this script, that also prevents us implementing
+#       that twice and keep sync again and again.
 
 from __future__ import print_function
 import sys
+import argparse
 import collections
 import itertools
 from functools import reduce
 
-
+SUPPORTED_ISA_SPEC = ["2.2", "20190608", "20191213"]
 CANONICAL_ORDER = "imafdgqlcbjktpvn"
 LONG_EXT_PREFIXES = ['z', 's', 'h', 'x']
 
@@ -35,29 +39,42 @@
 # IMPLIED_EXT(ext) -> implied extension list.
 #
 IMPLIED_EXT = {
-  "d" : ["f"],
-  "zk" : ["zkn"],
-  "zk" : ["zkr"],
-  "zk" : ["zkt"],
-  "zkn" : ["zbkb"],
-  "zkn" : ["zbkc"],
-  "zkn" : ["zbkx"],
-  "zkn" : ["zkne"],
-  "zkn" : ["zknd"],
-  "zkn" : ["zknh"],
-  "zks" : ["zbkb"],
-  "zks" : ["zbkc"],
-  "zks" : ["zbkx"],
-  "zks" : ["zksed"],
-  "zks" : ["zksh"],
+  "d" : ["f", "zicsr"],
+  "f" : ["zicsr"],
+  "zk" : ["zkn", "zkr", "zkt"],
+  "zkn" : ["zbkb", "zbkc", "zbkx", "zkne", "zknd", "zknh"],
+  "zks" : ["zbkb", "zbkc", "zbkx", "zksed", "zksh"],
+
+  "v" : ["zvl128b", "zve64d"],
+  "zve32x" : ["zvl32b"],
+  "zve64x" : ["zve32x", "zvl64b"],
+  "zve32f" : ["f", "zve32x"],
+  "zve64f" : ["f", "zve32f", "zve64x"],
+  "zve64d" : ["d", "zve64f"],
+
+  "zvl64b" : ["zvl32b"],
+  "zvl128b" : ["zvl64b"],
+  "zvl256b" : ["zvl128b"],
+  "zvl512b" : ["zvl256b"],
+  "zvl1024b" : ["zvl512b"],
+  "zvl2048b" : ["zvl1024b"],
+  "zvl4096b" : ["zvl2048b"],
+  "zvl8192b" : ["zvl4096b"],
+  "zvl16384b" : ["zvl8192b"],
+  "zvl32768b" : ["zvl16384b"],
+  "zvl65536b" : ["zvl32768b"],
 }
 
-def arch_canonicalize(arch):
+def arch_canonicalize(arch, isa_spec):
   # TODO: Support extension version.
+  is_isa_spec_2p2 = isa_spec == '2.2'
   new_arch = ""
+  extra_long_ext = []
   if arch[:5] in ['rv32e', 'rv32i', 'rv32g', 'rv64i', 'rv64g']:
-    # TODO: We should expand g to imad_zifencei once we support newer spec.
     new_arch = arch[:5].replace("g", "imafd")
+    if arch[:5] in ['rv32g', 'rv64g']:
+      if not is_isa_spec_2p2:
+        extra_long_ext = ['zicsr', 'zifencei']
   else:
     raise Exception("Unexpected arch: `%s`" % arch[:5])
 
@@ -74,15 +91,24 @@
     long_exts = []
     std_exts = list(arch[5:])
 
+  long_exts += extra_long_ext
+
   #
   # Handle implied extensions.
   #
-  for ext in std_exts + long_exts:
-    if ext in IMPLIED_EXT:
-      implied_exts = IMPLIED_EXT[ext]
-      for implied_ext in implied_exts:
-        if implied_ext not in std_exts + long_exts:
-          long_exts.append(implied_ext)
+  any_change = True
+  while any_change:
+    any_change = False
+    for ext in std_exts + long_exts:
+      if ext in IMPLIED_EXT:
+        implied_exts = IMPLIED_EXT[ext]
+        for implied_ext in implied_exts:
+          if implied_ext == 'zicsr' and is_isa_spec_2p2:
+              continue
+
+          if implied_ext not in std_exts + long_exts:
+            long_exts.append(implied_ext)
+            any_change = True
 
   # Single letter extension might appear in the long_exts list,
   # becasue we just append extensions list to the arch string.
@@ -99,6 +125,9 @@
     return (exts.startswith("x"), exts.startswith("zxm"),
             LONG_EXT_PREFIXES.index(exts[0]), canonical_sort, exts[1:])
 
+  # Removing duplicates.
+  long_exts = list(set(long_exts))
+
   # Multi-letter extension must be in lexicographic order.
   long_exts = list(sorted(filter(lambda x:len(x) != 1, long_exts),
                           key=longext_sort))
@@ -118,11 +147,20 @@
   # Concat rest of the multi-char extensions.
   if long_exts:
     new_arch += "_" + "_".join(long_exts)
+
   return new_arch
 
 if len(sys.argv) < 2:
   print ("Usage: %s <arch_str> [<arch_str>*]" % sys.argv)
   sys.exit(1)
 
-for arg in sys.argv[1:]:
-  print (arch_canonicalize(arg))
+parser = argparse.ArgumentParser()
+parser.add_argument('-misa-spec', type=str,
+                    default='20191213',
+                    choices=SUPPORTED_ISA_SPEC)
+parser.add_argument('arch_strs', nargs=argparse.REMAINDER)
+
+args = parser.parse_args()
+
+for arch in args.arch_strs:
+  print (arch_canonicalize(arch, args.misa_spec))
diff --git a/gcc/config/riscv/multilib-generator b/gcc/config/riscv/multilib-generator
index 1ea2fb2..36698d4 100755
--- a/gcc/config/riscv/multilib-generator
+++ b/gcc/config/riscv/multilib-generator
@@ -46,16 +46,18 @@
 # TODO: Add test for this script.
 #
 
+SUPPORTED_ISA_SPEC = ["2.2", "20190608", "20191213"]
 arches = collections.OrderedDict()
 abis = collections.OrderedDict()
 required = []
 reuse = []
 
-def arch_canonicalize(arch):
+def arch_canonicalize(arch, isa_spec):
   this_file = os.path.abspath(os.path.join( __file__))
   arch_can_script = \
     os.path.join(os.path.dirname(this_file), "arch-canonicalize")
-  proc = subprocess.Popen([sys.executable, arch_can_script, arch],
+  proc = subprocess.Popen([sys.executable, arch_can_script,
+                          '-misa-spec=%s' % isa_spec, arch],
                           stdout=subprocess.PIPE)
   out, err = proc.communicate()
   return out.decode().strip()
@@ -133,6 +135,9 @@
 
 parser = argparse.ArgumentParser()
 parser.add_argument("--cmodel", type=str)
+parser.add_argument('-misa-spec', type=str,
+                    default='20191213',
+                    choices=SUPPORTED_ISA_SPEC)
 parser.add_argument("cfgs", type=str, nargs='*')
 args = parser.parse_args()
 
@@ -158,13 +163,14 @@
     if cmodel == "compact" and arch.startswith("rv32"):
       continue
 
-    arch = arch_canonicalize (arch)
+    arch = arch_canonicalize (arch, args.misa_spec)
     arches[arch] = 1
     abis[abi] = 1
     extra = list(filter(None, extra.split(',')))
     ext_combs = expand_combination(ext)
     alts = sum([[x] + [x + y for y in ext_combs] for x in [arch] + extra], [])
-    alts = list(map(arch_canonicalize, alts))
+    alts = filter(lambda x: len(x) != 0, alts)
+    alts = list(map(lambda a : arch_canonicalize(a, args.misa_spec), alts))
 
     # Drop duplicated entry.
     alts = unique(alts)
diff --git a/gcc/config/rs6000/rs6000-builtins.def b/gcc/config/rs6000/rs6000-builtins.def
index 0f527c5..f4a9f24 100644
--- a/gcc/config/rs6000/rs6000-builtins.def
+++ b/gcc/config/rs6000/rs6000-builtins.def
@@ -1190,9 +1190,6 @@
   const vd __builtin_altivec_neg_v2df (vd);
     NEG_V2DF negv2df2 {}
 
-  const vsll __builtin_altivec_neg_v2di (vsll);
-    NEG_V2DI negv2di2 {}
-
   void __builtin_altivec_stvx_v2df (vd, signed long, void *);
     STVX_V2DF altivec_stvx_v2df {stvec}
 
@@ -2136,6 +2133,9 @@
   const vus __builtin_altivec_nand_v8hi_uns (vus, vus);
     NAND_V8HI_UNS nandv8hi3 {}
 
+  const vsll __builtin_altivec_neg_v2di (vsll);
+    NEG_V2DI negv2di2 {}
+
   const vsc __builtin_altivec_orc_v16qi (vsc, vsc);
     ORC_V16QI orcv16qi3 {}
 
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index ceaddaf..bc61959 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -25678,11 +25678,20 @@
   rtx r12 = NULL_RTX;
   rtx func_addr = func_desc;
 
-  gcc_assert (INTVAL (cookie) == 0);
-
   if (global_tlsarg)
     tlsarg = global_tlsarg;
 
+  /* Handle longcall attributes.  */
+  if (INTVAL (cookie) & CALL_LONG && SYMBOL_REF_P (func_desc))
+    {
+      /* PCREL can do a sibling call to a longcall function
+	 because we don't need to restore the TOC register.  */
+      gcc_assert (rs6000_pcrel_p ());
+      func_desc = rs6000_longcall_ref (func_desc, tlsarg);
+    }
+  else
+    gcc_assert (INTVAL (cookie) == 0);
+
   /* For ELFv2, r12 and CTR need to hold the function address
      for an indirect call.  */
   if (GET_CODE (func_desc) != SYMBOL_REF && DEFAULT_ABI == ABI_ELFv2)
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index fdfbc65..64049a6 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -835,8 +835,8 @@
 ;; complex forms.  Basic data transfer is done later.
 
 (define_insn "zero_extendqi<mode>2"
-  [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wa,^v")
-	(zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,v")))]
+  [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,wa,^v")
+	(zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,?Z,v")))]
   ""
   "@
    lbz%U1%X1 %0,%1
@@ -889,8 +889,8 @@
 
 
 (define_insn "zero_extendhi<mode>2"
-  [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wa,^v")
-	(zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,v")))]
+  [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,wa,^v")
+	(zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,?Z,v")))]
   ""
   "@
    lhz%U1%X1 %0,%1
@@ -944,7 +944,7 @@
 
 (define_insn "zero_extendsi<mode>2"
   [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,d,wa,wa,r,wa")
-	(zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wa,wa")))]
+	(zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,?Z,?Z,r,wa,wa")))]
   ""
   "@
    lwz%U1%X1 %0,%1
@@ -7496,7 +7496,7 @@
   [(set (match_operand:SI 0 "nonimmediate_operand"
 	  "=r,         r,
 	   r,          d,          v,
-	   m,          Z,          Z,
+	   m,          ?Z,         ?Z,
 	   r,          r,          r,          r,
 	   wa,         wa,         wa,         v,
 	   wa,         v,          v,
@@ -7504,7 +7504,7 @@
 	   r,          *h,         *h")
 	(match_operand:SI 1 "input_operand"
 	  "r,          U,
-	   m,          Z,          Z,
+	   m,          ?Z,         ?Z,
 	   r,          d,          v,
 	   I,          L,          eI,         n,
 	   wa,         O,          wM,         wB,
@@ -7785,11 +7785,11 @@
 ;;		MTVSRWZ     MF%1       MT%1       NOP
 (define_insn "*mov<mode>_internal"
   [(set (match_operand:QHI 0 "nonimmediate_operand"
-		"=r,        r,         wa,        m,         Z,         r,
+		"=r,        r,         wa,        m,         ?Z,        r,
 		 wa,        wa,        wa,        v,         ?v,        r,
 		 wa,        r,         *c*l,      *h")
 	(match_operand:QHI 1 "input_operand"
-		"r,         m,         Z,         r,         wa,        i,
+		"r,         m,         ?Z,        r,         wa,        i,
 		 wa,        O,         wM,        wB,        wS,        wa,
 		 r,         *h,        r,         0"))]
   "gpc_reg_operand (operands[0], <MODE>mode)
@@ -7973,10 +7973,10 @@
 ;;	FMR          MR         MT%0       MF%1       NOP
 (define_insn "movsd_hardfloat"
   [(set (match_operand:SD 0 "nonimmediate_operand"
-	 "=!r,       d,         m,         Z,         ?d,        ?r,
+	 "=!r,       d,         m,         ?Z,        ?d,        ?r,
 	  f,         !r,        *c*l,      !r,        *h")
 	(match_operand:SD 1 "input_operand"
-	 "m,         Z,         r,         wx,        r,         d,
+	 "m,         ?Z,        r,         wx,        r,         d,
 	  f,         r,         r,         *h,        0"))]
   "(register_operand (operands[0], SDmode)
    || register_operand (operands[1], SDmode))
@@ -14580,10 +14580,10 @@
   [(set_attr "type" "fp,fpstore,mtvsr,mfvsr,store")])
 
 (define_insn_and_split "unpack<mode>_nodm"
-  [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
+  [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,m")
 	(unspec:<FP128_64>
-	 [(match_operand:FMOVE128 1 "register_operand" "d,d")
-	  (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
+	 [(match_operand:FMOVE128 1 "register_operand" "d,d,r")
+	  (match_operand:QI 2 "const_0_to_1_operand" "i,i,i")]
 	 UNSPEC_UNPACK_128BIT))]
   "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
   "#"
@@ -14600,15 +14600,28 @@
 
   operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
 }
-  [(set_attr "type" "fp,fpstore")])
+  [(set_attr "type" "fp,fpstore,store")])
 
-(define_insn_and_split "pack<mode>"
+(define_expand "pack<mode>"
+  [(use (match_operand:FMOVE128 0 "register_operand"))
+   (use (match_operand:<FP128_64> 1 "register_operand"))
+   (use (match_operand:<FP128_64> 2 "register_operand"))]
+  "FLOAT128_2REG_P (<MODE>mode)"
+{
+  if (TARGET_HARD_FLOAT)
+    emit_insn (gen_pack<mode>_hard (operands[0], operands[1], operands[2]));
+  else
+    emit_insn (gen_pack<mode>_soft (operands[0], operands[1], operands[2]));
+  DONE;
+})
+
+(define_insn_and_split "pack<mode>_hard"
   [(set (match_operand:FMOVE128 0 "register_operand" "=&d")
 	(unspec:FMOVE128
 	 [(match_operand:<FP128_64> 1 "register_operand" "d")
 	  (match_operand:<FP128_64> 2 "register_operand" "d")]
 	 UNSPEC_PACK_128BIT))]
-  "FLOAT128_2REG_P (<MODE>mode)"
+  "FLOAT128_2REG_P (<MODE>mode) && TARGET_HARD_FLOAT"
   "#"
   "&& reload_completed"
   [(set (match_dup 3) (match_dup 1))
@@ -14626,6 +14639,34 @@
   [(set_attr "type" "fp")
    (set_attr "length" "8")])
 
+(define_insn_and_split "pack<mode>_soft"
+  [(set (match_operand:FMOVE128 0 "register_operand" "=&r")
+	(unspec:FMOVE128
+	 [(match_operand:<FP128_64> 1 "register_operand" "r")
+	  (match_operand:<FP128_64> 2 "register_operand" "r")]
+	 UNSPEC_PACK_128BIT))]
+  "FLOAT128_2REG_P (<MODE>mode) && TARGET_SOFT_FLOAT"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 3) (match_dup 1))
+   (set (match_dup 4) (match_dup 2))]
+{
+  unsigned dest_hi = REGNO (operands[0]);
+  unsigned dest_lo = dest_hi + (TARGET_POWERPC64 ? 1 : 2);
+
+  gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
+  gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
+
+  operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
+  operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
+}
+  [(set_attr "type" "integer")
+   (set (attr "length")
+	(if_then_else
+	 (match_test "TARGET_POWERPC64")
+	 (const_string "8")
+	 (const_string "16")))])
+
 (define_insn "unpack<mode>"
   [(set (match_operand:DI 0 "register_operand" "=wa,wa")
 	(unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
diff --git a/gcc/config/s390/3931.md b/gcc/config/s390/3931.md
new file mode 100644
index 0000000..bc97bc5
--- /dev/null
+++ b/gcc/config/s390/3931.md
@@ -0,0 +1,2562 @@
+;; Scheduling description for z16.
+;;   Copyright (C) 2022 Free Software Foundation, Inc.
+;;   Contributed by Robin Dapp (rdapp@linux.ibm.com)
+
+;; 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_attr "z16_unit_fpd" ""
+(cond [(eq_attr "mnemonic"
+"ddb,
+ddbr,
+deb,
+debr,
+dxbr,
+sqdb,
+sqdbr,
+sqeb,
+sqebr,
+sqxbr,
+vfddb,
+vfdsb,
+vfsqdb,
+vfsqsb,
+wfddb,
+wfdsb,
+wfdxb,
+wfsqdb,
+wfsqxb"
+)
+ (const_int 1)] (const_int 0)))
+
+(define_attr "z16_unit_fxa" ""
+(cond [(eq_attr "mnemonic"
+"a,
+afi,
+ag,
+agf,
+agfi,
+agfr,
+agh,
+aghi,
+aghik,
+agr,
+agrk,
+ah,
+ahi,
+ahik,
+ahy,
+al,
+alc,
+alcg,
+alcgr,
+alcr,
+alfi,
+alg,
+algf,
+algfi,
+algfr,
+alghsik,
+algr,
+algrk,
+alhsik,
+alr,
+alrk,
+aly,
+ar,
+ark,
+ay,
+bras,
+brasl,
+etnd,
+exrl,
+flogr,
+ic,
+icm,
+icmh,
+icmy,
+icy,
+iihf,
+iilf,
+ipm,
+la,
+larl,
+lay,
+lb,
+lbr,
+lcgr,
+lcr,
+lgb,
+lgbr,
+lgf,
+lgfi,
+lgfr,
+lgfrl,
+lgh,
+lghi,
+lghr,
+lghrl,
+lgr,
+lh,
+lhi,
+lhr,
+lhrl,
+lhy,
+llcr,
+llgcr,
+llgfr,
+llghr,
+llgtr,
+llhr,
+llihf,
+llihh,
+llihl,
+llilf,
+llilh,
+llill,
+lngr,
+lnr,
+loc,
+locg,
+locghi,
+locgr,
+lochi,
+locr,
+lpgr,
+lpr,
+lr,
+lrv,
+lrvg,
+lrvgr,
+lrvh,
+lrvr,
+lt,
+ltg,
+ltgf,
+ltgfr,
+ltgr,
+ltr,
+m,
+mfy,
+mg,
+mgh,
+mghi,
+mgrk,
+mh,
+mhi,
+mhy,
+ml,
+mlg,
+mlgr,
+mlr,
+mr,
+ms,
+msc,
+msfi,
+msg,
+msgc,
+msgf,
+msgfi,
+msgfr,
+msgr,
+msgrkc,
+msr,
+msrkc,
+msy,
+n,
+ncgrk,
+ncrk,
+ng,
+ngr,
+ngrk,
+nihf,
+nihh,
+nihl,
+nilf,
+nilh,
+nill,
+nngrk,
+nnrk,
+nogrk,
+nork,
+nr,
+nrk,
+nxgrk,
+nxrk,
+ny,
+o,
+ocgrk,
+ocrk,
+og,
+ogr,
+ogrk,
+oihf,
+oihh,
+oihl,
+oilf,
+oilh,
+oill,
+or,
+ork,
+oy,
+pfpo,
+popcnt,
+risbg,
+risbgn,
+rll,
+rllg,
+s,
+selgr,
+selr,
+sg,
+sgf,
+sgfr,
+sgh,
+sgr,
+sgrk,
+sh,
+shy,
+sl,
+slb,
+slbg,
+slbgr,
+slbr,
+slfi,
+slg,
+slgf,
+slgfi,
+slgfr,
+slgr,
+slgrk,
+sll,
+sllg,
+sllk,
+slr,
+slrk,
+sly,
+sr,
+sra,
+srag,
+srak,
+srk,
+srl,
+srlg,
+srlk,
+sy,
+x,
+xg,
+xgr,
+xgrk,
+xihf,
+xilf,
+xr,
+xrk,
+xy"
+)
+ (const_int 1)] (const_int 0)))
+
+(define_attr "z16_unit_fxb" ""
+(cond [(eq_attr "mnemonic"
+"agsi,
+algsi,
+alsi,
+asi,
+b,
+bc,
+bcr,
+bi,
+br,
+brcl,
+c,
+cfi,
+cg,
+cgf,
+cgfi,
+cgfr,
+cgfrl,
+cgh,
+cghi,
+cghrl,
+cghsi,
+cgit,
+cgr,
+cgrl,
+cgrt,
+ch,
+chi,
+chrl,
+chsi,
+chy,
+cit,
+cl,
+clfhsi,
+clfi,
+clfit,
+clg,
+clgf,
+clgfi,
+clgfr,
+clgfrl,
+clghrl,
+clghsi,
+clgit,
+clgr,
+clgrl,
+clgrt,
+clgt,
+clhhsi,
+clhrl,
+cli,
+cliy,
+clm,
+clmy,
+clr,
+clrl,
+clrt,
+clt,
+cly,
+cr,
+crl,
+crt,
+cy,
+j,
+jg,
+laa,
+laag,
+lan,
+lang,
+lao,
+laog,
+lat,
+lax,
+laxg,
+lcdfr,
+ldgr,
+ldr,
+lgat,
+lgdr,
+lndfr,
+lpdfr,
+lzdr,
+lzer,
+mvghi,
+mvhhi,
+mvhi,
+mvi,
+mviy,
+ni,
+niy,
+nop,
+nopr,
+ntstg,
+oi,
+oiy,
+ppa,
+st,
+stc,
+stcy,
+std,
+stdy,
+ste,
+stey,
+stg,
+stgrl,
+sth,
+sthrl,
+sthy,
+stoc,
+stocg,
+strl,
+strv,
+strvg,
+strvh,
+sty,
+tend,
+tm,
+tmh,
+tmhh,
+tmhl,
+tml,
+tmlh,
+tmll,
+tmy,
+vlgvb,
+vlgvf,
+vlgvg,
+vlgvh,
+vlr,
+vlvgb,
+vlvgf,
+vlvgg,
+vlvgh,
+vlvgp,
+vst,
+vstbr,
+vstbrf,
+vstbrg,
+vstbrh,
+vstbrq,
+vstebrf,
+vstebrg,
+vstef,
+vsteg,
+vsterf,
+vsterg,
+vsterh,
+vstl,
+vstrl,
+vstrlr,
+xi,
+xiy"
+)
+ (const_int 1)] (const_int 0)))
+
+(define_attr "z16_unit_fxd" ""
+(cond [(eq_attr "mnemonic"
+"dlgr,
+dlr,
+dr,
+dsgfr,
+dsgr"
+)
+ (const_int 1)] (const_int 0)))
+
+(define_attr "z16_unit_lsu" ""
+(cond [(eq_attr "mnemonic"
+"a,
+adb,
+aeb,
+ag,
+agf,
+agh,
+agsi,
+ah,
+ahy,
+al,
+alc,
+alcg,
+alg,
+algf,
+algsi,
+alsi,
+aly,
+asi,
+ay,
+c,
+cdb,
+ceb,
+cg,
+cgf,
+cgfrl,
+cgh,
+cghrl,
+cghsi,
+cgrl,
+ch,
+chrl,
+chsi,
+chy,
+cl,
+clc,
+clfhsi,
+clg,
+clgf,
+clgfrl,
+clghrl,
+clghsi,
+clgrl,
+clgt,
+clhhsi,
+clhrl,
+cli,
+cliy,
+clm,
+clmy,
+clrl,
+clt,
+cly,
+crl,
+cy,
+ddb,
+deb,
+ear,
+ic,
+icm,
+icmh,
+icmy,
+icy,
+kdb,
+keb,
+l,
+laa,
+laag,
+lan,
+lang,
+lao,
+laog,
+lat,
+lax,
+laxg,
+lb,
+lcbb,
+ld,
+lde,
+ldeb,
+ldy,
+le,
+ley,
+lg,
+lgat,
+lgb,
+lgf,
+lgfrl,
+lgh,
+lghrl,
+lgrl,
+lh,
+lhrl,
+lhy,
+llc,
+llgc,
+llgf,
+llgfrl,
+llgh,
+llghrl,
+llgt,
+llh,
+llhrl,
+loc,
+locg,
+lrl,
+lrv,
+lrvg,
+lrvh,
+lt,
+ltg,
+ltgf,
+ly,
+m,
+madb,
+maeb,
+mdb,
+meeb,
+mfy,
+mg,
+mgh,
+mh,
+mhy,
+ml,
+mlg,
+ms,
+msc,
+msdb,
+mseb,
+msg,
+msgc,
+msgf,
+msy,
+mvghi,
+mvhhi,
+mvhi,
+mvi,
+mviy,
+n,
+ng,
+ni,
+niy,
+ntstg,
+ny,
+o,
+og,
+oi,
+oiy,
+oy,
+s,
+sar,
+sdb,
+seb,
+sfpc,
+sg,
+sgf,
+sgh,
+sh,
+shy,
+sl,
+slb,
+slbg,
+slg,
+slgf,
+sly,
+sqdb,
+sqeb,
+st,
+stc,
+stcy,
+std,
+stdy,
+ste,
+stey,
+stg,
+stgrl,
+sth,
+sthrl,
+sthy,
+stoc,
+stocg,
+strl,
+strv,
+strvg,
+strvh,
+sty,
+sy,
+tabort,
+tm,
+tmy,
+vl,
+vlbb,
+vlbr,
+vlbrf,
+vlbrg,
+vlbrh,
+vlbrq,
+vlbrrepf,
+vlbrrepg,
+vlbrreph,
+vleb,
+vlebrf,
+vlebrg,
+vlebrh,
+vlef,
+vleg,
+vleh,
+vlerf,
+vlerg,
+vlerh,
+vll,
+vllebrzf,
+vllebrzg,
+vllebrzh,
+vllezb,
+vllezf,
+vllezg,
+vllezh,
+vllezlf,
+vlrepb,
+vlrepf,
+vlrepg,
+vlreph,
+vlrl,
+vlrlr,
+vst,
+vstbr,
+vstbrf,
+vstbrg,
+vstbrh,
+vstbrq,
+vstebrf,
+vstebrg,
+vstef,
+vsteg,
+vsterf,
+vsterg,
+vsterh,
+vstl,
+vstrl,
+vstrlr,
+x,
+xg,
+xi,
+xiy,
+xy"
+)
+ (const_int 1)] (const_int 0)))
+
+(define_attr "z16_unit_vfu" ""
+(cond [(eq_attr "mnemonic"
+"adb,
+adbr,
+adtr,
+aeb,
+aebr,
+axbr,
+axtr,
+cdb,
+cdbr,
+cdtr,
+ceb,
+cebr,
+cpsdr,
+cxbr,
+cxtr,
+ddtr,
+dxtr,
+fidbr,
+fidbra,
+fidtr,
+fiebr,
+fiebra,
+fixbr,
+fixbra,
+fixtr,
+kdb,
+kdbr,
+kdtr,
+keb,
+kebr,
+kxbr,
+kxtr,
+lcdbr,
+lcebr,
+lcxbr,
+ldeb,
+ldebr,
+ldetr,
+le,
+ledbr,
+ledtr,
+ler,
+ley,
+lndbr,
+lnebr,
+lnxbr,
+lpdbr,
+lpebr,
+lpxbr,
+ltdbr,
+ltdtr,
+ltebr,
+ltxbr,
+ltxtr,
+lxdb,
+lxdbr,
+lxdtr,
+lxeb,
+lxebr,
+madb,
+madbr,
+maeb,
+maebr,
+mdb,
+mdbr,
+mdtr,
+meeb,
+meebr,
+msdb,
+msdbr,
+mseb,
+msebr,
+mxbr,
+mxtr,
+sdb,
+sdbr,
+sdtr,
+seb,
+sebr,
+sxbr,
+sxtr,
+tcdb,
+tceb,
+tcxb,
+tdcdt,
+tdcet,
+tdcxt,
+vab,
+vaccb,
+vacccq,
+vaccf,
+vaccg,
+vacch,
+vaccq,
+vacq,
+vaf,
+vag,
+vah,
+vaq,
+vavgb,
+vavgf,
+vavgg,
+vavgh,
+vavglb,
+vavglf,
+vavglg,
+vavglh,
+vbperm,
+vcdgb,
+vcdlgb,
+vcefb,
+vcelfb,
+vceqb,
+vceqbs,
+vceqf,
+vceqfs,
+vceqg,
+vceqgs,
+vceqh,
+vceqhs,
+vcfeb,
+vcfn,
+vcgdb,
+vchb,
+vchbs,
+vchf,
+vchfs,
+vchg,
+vchgs,
+vchh,
+vchhs,
+vchlb,
+vchlbs,
+vchlf,
+vchlfs,
+vchlg,
+vchlgs,
+vchlh,
+vchlhs,
+vcksm,
+vclfeb,
+vclfnh,
+vclfnl,
+vclgdb,
+vclzb,
+vclzf,
+vclzg,
+vclzh,
+vcnf,
+vcrnf,
+vctzb,
+vctzf,
+vctzg,
+vctzh,
+verimb,
+verimf,
+verimg,
+verimh,
+verllb,
+verllf,
+verllg,
+verllh,
+verllvb,
+verllvf,
+verllvg,
+verllvh,
+veslb,
+veslf,
+veslg,
+veslh,
+veslvb,
+veslvf,
+veslvg,
+veslvh,
+vesrab,
+vesraf,
+vesrag,
+vesrah,
+vesravb,
+vesravf,
+vesravg,
+vesravh,
+vesrlb,
+vesrlf,
+vesrlg,
+vesrlh,
+vesrlvb,
+vesrlvf,
+vesrlvg,
+vesrlvh,
+vfadb,
+vfasb,
+vfcedb,
+vfcedbs,
+vfcesb,
+vfcesbs,
+vfchdb,
+vfchdbs,
+vfchedb,
+vfchedbs,
+vfchesb,
+vfchesbs,
+vfchsb,
+vfchsbs,
+vfeeb,
+vfeef,
+vfeeh,
+vfeezbs,
+vfeezfs,
+vfeezhs,
+vfeneb,
+vfenef,
+vfeneh,
+vfenezb,
+vfenezf,
+vfenezh,
+vfidb,
+vfisb,
+vfkedb,
+vfkesb,
+vfkhdb,
+vfkhedb,
+vfkhesb,
+vfkhsb,
+vflcdb,
+vflcsb,
+vflndb,
+vflnsb,
+vflpdb,
+vflpsb,
+vfmadb,
+vfmasb,
+vfmaxdb,
+vfmaxsb,
+vfmdb,
+vfmindb,
+vfminsb,
+vfmsb,
+vfmsdb,
+vfmssb,
+vfnmadb,
+vfnmasb,
+vfnmsdb,
+vfnmssb,
+vfsdb,
+vfssb,
+vftcidb,
+vftcisb,
+vgbm,
+vgfmab,
+vgfmaf,
+vgfmag,
+vgfmah,
+vgfmb,
+vgfmf,
+vgfmg,
+vgfmh,
+vgm,
+vgmb,
+vgmf,
+vgmg,
+vgmh,
+vistrb,
+vistrbs,
+vistrf,
+vistrfs,
+vistrh,
+vistrhs,
+vlcb,
+vlcf,
+vlcg,
+vlch,
+vldeb,
+vleb,
+vlebrf,
+vlebrg,
+vlebrh,
+vledb,
+vlef,
+vleg,
+vleh,
+vleib,
+vleif,
+vleig,
+vleih,
+vlpb,
+vlpf,
+vlpg,
+vlph,
+vmaeb,
+vmaef,
+vmaeh,
+vmahb,
+vmahf,
+vmahh,
+vmalb,
+vmaleb,
+vmalef,
+vmaleh,
+vmalf,
+vmalhb,
+vmalhf,
+vmalhh,
+vmalhw,
+vmalob,
+vmalof,
+vmaloh,
+vmaob,
+vmaof,
+vmaoh,
+vmeb,
+vmef,
+vmeh,
+vmhb,
+vmhf,
+vmhh,
+vmlb,
+vmleb,
+vmlef,
+vmleh,
+vmlf,
+vmlhb,
+vmlhf,
+vmlhh,
+vmlhw,
+vmlob,
+vmlof,
+vmloh,
+vmnb,
+vmnf,
+vmng,
+vmnh,
+vmnlb,
+vmnlf,
+vmnlg,
+vmnlh,
+vmob,
+vmof,
+vmoh,
+vmrhb,
+vmrhf,
+vmrhg,
+vmrhh,
+vmrlb,
+vmrlf,
+vmrlg,
+vmrlh,
+vmslg,
+vmxb,
+vmxf,
+vmxg,
+vmxh,
+vmxlb,
+vmxlf,
+vmxlg,
+vmxlh,
+vn,
+vnc,
+vnn,
+vno,
+vnot,
+vnx,
+vo,
+voc,
+vone,
+vpdi,
+vperm,
+vpkf,
+vpkg,
+vpkh,
+vpklsf,
+vpklsfs,
+vpklsg,
+vpklsgs,
+vpklsh,
+vpklshs,
+vpksf,
+vpksfs,
+vpksg,
+vpksgs,
+vpksh,
+vpkshs,
+vpopct,
+vpopctb,
+vpopctf,
+vpopctg,
+vpopcth,
+vrepb,
+vrepf,
+vrepg,
+vreph,
+vrepi,
+vrepib,
+vrepif,
+vrepig,
+vrepih,
+vsb,
+vsbcbiq,
+vsbiq,
+vscbib,
+vscbif,
+vscbig,
+vscbih,
+vscbiq,
+vsegb,
+vsegf,
+vsegh,
+vsel,
+vsf,
+vsg,
+vsh,
+vsl,
+vslb,
+vsld,
+vsldb,
+vsq,
+vsra,
+vsrab,
+vsrd,
+vsrl,
+vsrlb,
+vsumb,
+vsumgf,
+vsumgh,
+vsumh,
+vsumqf,
+vsumqg,
+vtm,
+vuphb,
+vuphf,
+vuphh,
+vuplb,
+vuplf,
+vuplhb,
+vuplhf,
+vuplhh,
+vuplhw,
+vupllb,
+vupllf,
+vupllh,
+vx,
+vzero,
+wcdgb,
+wcdlgb,
+wcefb,
+wcelfb,
+wcfeb,
+wcgdb,
+wclfeb,
+wclgdb,
+wfadb,
+wfasb,
+wfaxb,
+wfcdb,
+wfcedb,
+wfcesb,
+wfcexb,
+wfcexbs,
+wfchdb,
+wfchedb,
+wfchesb,
+wfchexb,
+wfchexbs,
+wfchsb,
+wfchxb,
+wfchxbs,
+wfcsb,
+wfcxb,
+wfidb,
+wfisb,
+wfixb,
+wfkdb,
+wfkedb,
+wfkesb,
+wfkexb,
+wfkhdb,
+wfkhedb,
+wfkhesb,
+wfkhexb,
+wfkhsb,
+wfkhxb,
+wfksb,
+wfkxb,
+wflcdb,
+wflcsb,
+wflcxb,
+wflld,
+wflndb,
+wflnsb,
+wflnxb,
+wflpdb,
+wflpsb,
+wflpxb,
+wflrx,
+wfmadb,
+wfmasb,
+wfmaxb,
+wfmaxxb,
+wfmdb,
+wfminxb,
+wfmsb,
+wfmsdb,
+wfmssb,
+wfmsxb,
+wfmxb,
+wfnmaxb,
+wfnmsxb,
+wfsdb,
+wfssb,
+wfsxb,
+wftcixb,
+wldeb,
+wledb"
+)
+ (const_int 1)] (const_int 0)))
+
+(define_attr "z16_cracked" ""
+(cond [(eq_attr "mnemonic"
+"bas,
+basr,
+cdfbr,
+cdftr,
+cdgbr,
+cdgtr,
+cdlfbr,
+cdlftr,
+cdlgbr,
+cdlgtr,
+cefbr,
+cegbr,
+celfbr,
+celgbr,
+cfdbr,
+cfebr,
+cfxbr,
+cgdbr,
+cgdtr,
+cgebr,
+cgxbr,
+cgxtr,
+chhsi,
+clfdbr,
+clfdtr,
+clfebr,
+clfxbr,
+clfxtr,
+clgdbr,
+clgdtr,
+clgebr,
+clgxbr,
+clgxtr,
+cs,
+csg,
+csy,
+d,
+efpc,
+ex,
+lcgfr,
+lngfr,
+lpgfr,
+lpq,
+lxr,
+lzxr,
+rxsbg,
+stpq,
+vgef,
+vgeg,
+vscef,
+vsceg,
+vsteb,
+vstebrh,
+vsteh"
+)
+ (const_int 1)] (const_int 0)))
+
+(define_attr "z16_expanded" ""
+(cond [(eq_attr "mnemonic"
+"cds,
+cdsg,
+cdsy,
+cxfbr,
+cxftr,
+cxgbr,
+cxgtr,
+cxlfbr,
+cxlftr,
+cxlgbr,
+cxlgtr,
+dl,
+dlg,
+dsg,
+dsgf,
+lam,
+lm,
+lmg,
+lmy,
+sldl,
+srda,
+srdl,
+stam,
+stm,
+stmg,
+stmy,
+tbegin,
+tbeginc"
+)
+ (const_int 1)] (const_int 0)))
+
+(define_attr "z16_groupalone" ""
+(cond [(eq_attr "mnemonic"
+"alc,
+alcg,
+alcgr,
+alcr,
+axbr,
+axtr,
+clc,
+cxbr,
+cxtr,
+dlgr,
+dlr,
+dr,
+dsgfr,
+dsgr,
+dxbr,
+dxtr,
+fixbr,
+fixbra,
+fixtr,
+flogr,
+kxbr,
+kxtr,
+lcxbr,
+lnxbr,
+lpxbr,
+ltxbr,
+ltxtr,
+lxdb,
+lxdbr,
+lxdtr,
+lxeb,
+lxebr,
+m,
+madb,
+maeb,
+maebr,
+mfy,
+mg,
+mgrk,
+ml,
+mlg,
+mlgr,
+mlr,
+mr,
+msdb,
+mseb,
+msebr,
+mvc,
+mxbr,
+mxtr,
+nc,
+oc,
+ppa,
+sfpc,
+slb,
+slbg,
+slbgr,
+slbr,
+sqxbr,
+sxbr,
+sxtr,
+tabort,
+tcxb,
+tdcxt,
+tend,
+xc"
+)
+ (const_int 1)] (const_int 0)))
+
+(define_attr "z16_endgroup" ""
+(cond [(eq_attr "mnemonic"
+"bras,
+brasl,
+exrl,
+ipm"
+)
+ (const_int 1)] (const_int 0)))
+
+(define_attr "z16_groupoftwo" ""
+(cond [(eq_attr "mnemonic"
+"vacccq,
+vacq,
+vfmadb,
+vfmasb,
+vfmsdb,
+vfmssb,
+vfnmadb,
+vfnmasb,
+vfnmsdb,
+vfnmssb,
+vgfmab,
+vgfmaf,
+vgfmag,
+vgfmah,
+vmaeb,
+vmaef,
+vmaeh,
+vmahb,
+vmahf,
+vmahh,
+vmalb,
+vmaleb,
+vmalef,
+vmaleh,
+vmalf,
+vmalhb,
+vmalhf,
+vmalhh,
+vmalhw,
+vmalob,
+vmalof,
+vmaloh,
+vmaob,
+vmaof,
+vmaoh,
+vmslg,
+vperm,
+vsbcbiq,
+vsbiq,
+vsel,
+wfmadb,
+wfmasb,
+wfmaxb,
+wfmsdb,
+wfmssb,
+wfmsxb,
+wfnmaxb,
+wfnmsxb"
+)
+ (const_int 1)] (const_int 0)))
+
+(define_insn_reservation "z16_0" 0
+  (and (eq_attr "cpu" "z16")
+(eq_attr "mnemonic"
+"a,
+afi,
+ag,
+agfi,
+aghi,
+aghik,
+agr,
+agrk,
+ahi,
+ahik,
+al,
+alfi,
+alg,
+algf,
+algfi,
+algfr,
+alghsik,
+algr,
+algrk,
+alhsik,
+alr,
+alrk,
+aly,
+ar,
+ark,
+ay,
+b,
+bc,
+bcr,
+bi,
+br,
+bras,
+brasl,
+brcl,
+c,
+cfi,
+cg,
+cgfi,
+cghi,
+cghsi,
+cgit,
+cgr,
+cgrl,
+cgrt,
+chi,
+chsi,
+cit,
+cl,
+clfhsi,
+clfi,
+clfit,
+clg,
+clgf,
+clgfi,
+clgfr,
+clgfrl,
+clghrl,
+clghsi,
+clgit,
+clgr,
+clgrl,
+clgrt,
+clgt,
+clhhsi,
+clhrl,
+cli,
+cliy,
+clr,
+clrl,
+clrt,
+clt,
+cly,
+cr,
+crl,
+crt,
+cy,
+etnd,
+exrl,
+ic,
+icm,
+icmh,
+icmy,
+icy,
+iihf,
+iilf,
+j,
+jg,
+la,
+larl,
+lat,
+lay,
+lb,
+lbr,
+lcdfr,
+lcgr,
+lcr,
+ldgr,
+ldr,
+lgat,
+lgb,
+lgbr,
+lgf,
+lgfi,
+lgfr,
+lgfrl,
+lgh,
+lghi,
+lghr,
+lghrl,
+lgr,
+lh,
+lhi,
+lhr,
+lhrl,
+lhy,
+llcr,
+llgcr,
+llgfr,
+llghr,
+llgtr,
+llhr,
+llihf,
+llihh,
+llihl,
+llilf,
+llilh,
+llill,
+lndfr,
+lngr,
+lnr,
+lpdfr,
+lpgr,
+lpr,
+lr,
+lrv,
+lrvg,
+lrvgr,
+lrvh,
+lrvr,
+lt,
+ltg,
+ltgf,
+ltgfr,
+ltgr,
+ltr,
+lzdr,
+lzer,
+n,
+ncgrk,
+ncrk,
+ng,
+ngr,
+ngrk,
+nihf,
+nihh,
+nihl,
+nilf,
+nilh,
+nill,
+nngrk,
+nnrk,
+nogrk,
+nop,
+nopr,
+nork,
+nr,
+nrk,
+nxgrk,
+nxrk,
+ny,
+o,
+ocgrk,
+ocrk,
+og,
+ogr,
+ogrk,
+oihf,
+oihh,
+oihl,
+oilf,
+oilh,
+oill,
+or,
+ork,
+oy,
+pfpo,
+risbg,
+risbgn,
+rll,
+rllg,
+rnsbg,
+rosbg,
+s,
+sg,
+sgr,
+sgrk,
+sl,
+sldl,
+slfi,
+slg,
+slgf,
+slgfi,
+slgfr,
+slgr,
+slgrk,
+sll,
+sllg,
+sllk,
+slr,
+slrk,
+sly,
+sr,
+sra,
+srag,
+srak,
+srda,
+srdl,
+srk,
+srl,
+srlg,
+srlk,
+sy,
+tm,
+tmh,
+tmhh,
+tmhl,
+tml,
+tmlh,
+tmll,
+tmy,
+vlr,
+vlvgb,
+vlvgf,
+vlvgg,
+vlvgh,
+x,
+xg,
+xgr,
+xgrk,
+xihf,
+xilf,
+xr,
+xrk,
+xy"
+)) "nothing")
+
+(define_insn_reservation "z16_1" 1
+  (and (eq_attr "cpu" "z16")
+(eq_attr "mnemonic"
+"agf,
+agfr,
+agh,
+agsi,
+ah,
+ahy,
+algsi,
+alsi,
+asi,
+cgf,
+cgfr,
+cgfrl,
+cgh,
+cghrl,
+ch,
+chrl,
+chy,
+clm,
+clmy,
+cpsdr,
+laa,
+laag,
+lan,
+lang,
+lao,
+laog,
+lax,
+laxg,
+le,
+ler,
+ley,
+loc,
+locg,
+locghi,
+locgr,
+lochi,
+locr,
+mvghi,
+mvhhi,
+mvhi,
+mvi,
+mviy,
+ni,
+niy,
+ntstg,
+oi,
+oiy,
+selgr,
+selr,
+sgf,
+sgfr,
+sgh,
+sh,
+shy,
+st,
+stc,
+stcy,
+stg,
+stgrl,
+sth,
+sthrl,
+sthy,
+stoc,
+stocg,
+strl,
+strv,
+strvg,
+strvh,
+sty,
+vab,
+vaccb,
+vacccq,
+vaccf,
+vaccg,
+vacch,
+vaccq,
+vacq,
+vaf,
+vag,
+vah,
+vaq,
+vavgb,
+vavgf,
+vavgg,
+vavgh,
+vavglb,
+vavglf,
+vavglg,
+vavglh,
+vbperm,
+vceqb,
+vceqf,
+vceqg,
+vceqh,
+vcfn,
+vchb,
+vchf,
+vchg,
+vchh,
+vchlb,
+vchlf,
+vchlg,
+vchlh,
+vclfnh,
+vclfnl,
+vclzb,
+vclzf,
+vclzg,
+vclzh,
+vcnf,
+vcrnf,
+vctzb,
+vctzf,
+vctzg,
+vctzh,
+verimb,
+verimf,
+verimg,
+verimh,
+verllb,
+verllf,
+verllg,
+verllh,
+verllvb,
+verllvf,
+verllvg,
+verllvh,
+veslb,
+veslf,
+veslg,
+veslh,
+veslvb,
+veslvf,
+veslvg,
+veslvh,
+vesrab,
+vesraf,
+vesrag,
+vesrah,
+vesravb,
+vesravf,
+vesravg,
+vesravh,
+vesrlb,
+vesrlf,
+vesrlg,
+vesrlh,
+vesrlvb,
+vesrlvf,
+vesrlvg,
+vesrlvh,
+vfcedb,
+vfcesb,
+vfchdb,
+vfchedb,
+vfchesb,
+vfchsb,
+vfkedb,
+vfkesb,
+vfkhdb,
+vfkhedb,
+vfkhesb,
+vfkhsb,
+vflcdb,
+vflcsb,
+vflndb,
+vflnsb,
+vflpdb,
+vflpsb,
+vfmaxdb,
+vfmaxsb,
+vfmindb,
+vfminsb,
+vgbm,
+vgm,
+vgmb,
+vgmf,
+vgmg,
+vgmh,
+vlcb,
+vlcf,
+vlcg,
+vlch,
+vleb,
+vlebrf,
+vlebrg,
+vlebrh,
+vlef,
+vleg,
+vleh,
+vleib,
+vleif,
+vleig,
+vleih,
+vlpb,
+vlpf,
+vlpg,
+vlph,
+vmnb,
+vmnf,
+vmng,
+vmnh,
+vmnlb,
+vmnlf,
+vmnlg,
+vmnlh,
+vmrhb,
+vmrhf,
+vmrhg,
+vmrhh,
+vmrlb,
+vmrlf,
+vmrlg,
+vmrlh,
+vmxb,
+vmxf,
+vmxg,
+vmxh,
+vmxlb,
+vmxlf,
+vmxlg,
+vmxlh,
+vn,
+vnc,
+vnn,
+vno,
+vnot,
+vnx,
+vo,
+voc,
+vone,
+vpdi,
+vperm,
+vpkf,
+vpkg,
+vpkh,
+vpklsf,
+vpklsg,
+vpklsh,
+vpksf,
+vpksg,
+vpksh,
+vpopct,
+vpopctb,
+vpopctf,
+vpopctg,
+vpopcth,
+vrepb,
+vrepf,
+vrepg,
+vreph,
+vrepi,
+vrepib,
+vrepif,
+vrepig,
+vrepih,
+vsb,
+vsbcbiq,
+vsbiq,
+vscbib,
+vscbif,
+vscbig,
+vscbih,
+vscbiq,
+vsegb,
+vsegf,
+vsegh,
+vsel,
+vsf,
+vsg,
+vsh,
+vsl,
+vslb,
+vsld,
+vsldb,
+vsq,
+vsra,
+vsrab,
+vsrd,
+vsrl,
+vsrlb,
+vuphb,
+vuphf,
+vuphh,
+vuplb,
+vuplf,
+vuplhb,
+vuplhf,
+vuplhh,
+vuplhw,
+vupllb,
+vupllf,
+vupllh,
+vx,
+vzero,
+wfcedb,
+wfcesb,
+wfcexb,
+wfchdb,
+wfchedb,
+wfchesb,
+wfchexb,
+wfchsb,
+wfchxb,
+wfkedb,
+wfkesb,
+wfkexb,
+wfkhdb,
+wfkhedb,
+wfkhesb,
+wfkhexb,
+wfkhsb,
+wfkhxb,
+wflcdb,
+wflcsb,
+wflcxb,
+wflndb,
+wflnsb,
+wflnxb,
+wflpdb,
+wflpsb,
+wflpxb,
+wfmaxxb,
+wfminxb,
+xi,
+xiy"
+)) "nothing")
+
+(define_insn_reservation "z16_2" 2
+  (and (eq_attr "cpu" "z16")
+(eq_attr "mnemonic"
+"cdb,
+cdbr,
+ceb,
+cebr,
+ear,
+ipm,
+kdb,
+kdbr,
+keb,
+kebr,
+l,
+lcbb,
+lcdbr,
+lcebr,
+ld,
+lde,
+ldy,
+lg,
+lgdr,
+lgrl,
+llc,
+llgc,
+llgf,
+llgfrl,
+llgh,
+llghrl,
+llgt,
+llh,
+llhrl,
+lm,
+lmg,
+lmy,
+lndbr,
+lnebr,
+lpdbr,
+lpebr,
+lrl,
+ltdbr,
+ltebr,
+ly,
+popcnt,
+sar,
+tcdb,
+tceb,
+vceqbs,
+vceqfs,
+vceqgs,
+vceqhs,
+vchbs,
+vchfs,
+vchgs,
+vchhs,
+vchlbs,
+vchlfs,
+vchlgs,
+vchlhs,
+vfcedbs,
+vfcesbs,
+vfchdbs,
+vfchedbs,
+vfchesbs,
+vfchsbs,
+vfeeb,
+vfeef,
+vfeeh,
+vfeneb,
+vfenef,
+vfeneh,
+vfenezb,
+vfenezf,
+vfenezh,
+vftcidb,
+vftcisb,
+vistrb,
+vistrf,
+vistrh,
+vlbrrepf,
+vlbrrepg,
+vlbrreph,
+vlgvb,
+vlgvf,
+vlgvg,
+vlgvh,
+vllebrzf,
+vllebrzg,
+vllebrzh,
+vllezb,
+vllezf,
+vllezg,
+vllezh,
+vllezlf,
+vlrepb,
+vlrepf,
+vlrepg,
+vlreph,
+vlrl,
+vlvgp,
+vpklsfs,
+vpklsgs,
+vpklshs,
+vpksfs,
+vpksgs,
+vpkshs,
+wfcdb,
+wfcexbs,
+wfchexbs,
+wfchxbs,
+wfcsb,
+wfcxb,
+wfkdb,
+wfksb,
+wfkxb,
+wftcixb"
+)) "nothing")
+
+(define_insn_reservation "z16_3" 3
+  (and (eq_attr "cpu" "z16")
+(eq_attr "mnemonic"
+"cds,
+cdsy,
+mgh,
+mghi,
+mh,
+mhi,
+mhy,
+std,
+stdy,
+ste,
+stey,
+vcksm,
+vfeezbs,
+vfeezfs,
+vfeezhs,
+vgfmab,
+vgfmaf,
+vgfmag,
+vgfmah,
+vgfmb,
+vgfmf,
+vgfmg,
+vgfmh,
+vistrbs,
+vistrfs,
+vistrhs,
+vl,
+vlbb,
+vlbr,
+vlbrf,
+vlbrg,
+vlbrh,
+vlbrq,
+vlerf,
+vlerg,
+vlerh,
+vll,
+vlrlr,
+vmaeb,
+vmaef,
+vmaeh,
+vmahb,
+vmahf,
+vmahh,
+vmalb,
+vmaleb,
+vmalef,
+vmaleh,
+vmalf,
+vmalhb,
+vmalhf,
+vmalhh,
+vmalhw,
+vmalob,
+vmalof,
+vmaloh,
+vmaob,
+vmaof,
+vmaoh,
+vmeb,
+vmef,
+vmeh,
+vmhb,
+vmhf,
+vmhh,
+vmlb,
+vmleb,
+vmlef,
+vmleh,
+vmlf,
+vmlhb,
+vmlhf,
+vmlhh,
+vmlhw,
+vmlob,
+vmlof,
+vmloh,
+vmob,
+vmof,
+vmoh,
+vsumb,
+vsumgf,
+vsumgh,
+vsumh,
+vsumqf,
+vsumqg,
+vtm"
+)) "nothing")
+
+(define_insn_reservation "z16_4" 4
+  (and (eq_attr "cpu" "z16")
+(eq_attr "mnemonic"
+"bas,
+basr,
+chhsi,
+clc,
+ex,
+lam,
+lcgfr,
+lngfr,
+lpgfr,
+lxr,
+lzxr,
+ms,
+msfi,
+msgf,
+msgfi,
+msgfr,
+msr,
+msy,
+mvc,
+nc,
+oc,
+ppa,
+rxsbg,
+tabort,
+tbegin,
+tbeginc,
+tend,
+vst,
+vstbr,
+vstbrf,
+vstbrg,
+vstbrh,
+vstbrq,
+vstebrf,
+vstebrg,
+vstef,
+vsteg,
+vsterf,
+vsterg,
+vsterh,
+vstl,
+vstrl,
+vstrlr,
+xc"
+)) "nothing")
+
+(define_insn_reservation "z16_5" 5
+  (and (eq_attr "cpu" "z16")
+(eq_attr "mnemonic"
+"adb,
+adbr,
+aeb,
+aebr,
+alc,
+alcg,
+alcgr,
+alcr,
+cs,
+csg,
+csy,
+fidbr,
+fidbra,
+fiebr,
+fiebra,
+ldeb,
+ldebr,
+ledbr,
+madbr,
+mdb,
+mdbr,
+meeb,
+meebr,
+msc,
+msdbr,
+msrkc,
+sdb,
+sdbr,
+seb,
+sebr,
+slb,
+slbg,
+slbgr,
+slbr,
+stm,
+stmg,
+stmy,
+vcdgb,
+vcdlgb,
+vcefb,
+vcelfb,
+vcfeb,
+vcgdb,
+vclfeb,
+vclgdb,
+vfadb,
+vfasb,
+vfidb,
+vfisb,
+vfmadb,
+vfmasb,
+vfmdb,
+vfmsb,
+vfmsdb,
+vfmssb,
+vfnmadb,
+vfnmasb,
+vfnmsdb,
+vfnmssb,
+vfsdb,
+vfssb,
+vldeb,
+vledb,
+vmslg,
+wcdgb,
+wcdlgb,
+wcefb,
+wcelfb,
+wcfeb,
+wcgdb,
+wclfeb,
+wclgdb,
+wfadb,
+wfasb,
+wfidb,
+wfisb,
+wflld,
+wfmadb,
+wfmasb,
+wfmdb,
+wfmsb,
+wfmsdb,
+wfmssb,
+wfsdb,
+wfssb,
+wldeb,
+wledb"
+)) "nothing")
+
+(define_insn_reservation "z16_6" 6
+  (and (eq_attr "cpu" "z16")
+(eq_attr "mnemonic"
+"msg,
+msgr,
+sfpc"
+)) "nothing")
+
+(define_insn_reservation "z16_7" 7
+  (and (eq_attr "cpu" "z16")
+(eq_attr "mnemonic"
+"adtr,
+cdtr,
+fidtr,
+kdtr,
+ldetr,
+ltdtr,
+msgc,
+msgrkc,
+sdtr,
+tdcdt,
+tdcet,
+vgef,
+vgeg"
+)) "nothing")
+
+(define_insn_reservation "z16_8" 8
+  (and (eq_attr "cpu" "z16")
+(eq_attr "mnemonic"
+"cdsg,
+flogr,
+lpq,
+stpq,
+vsteb,
+vstebrh,
+vsteh"
+)) "nothing")
+
+(define_insn_reservation "z16_9" 9
+  (and (eq_attr "cpu" "z16")
+(eq_attr "mnemonic"
+"cdfbr,
+cdgbr,
+cdlfbr,
+cdlgbr,
+cefbr,
+cegbr,
+celfbr,
+celgbr,
+cxfbr,
+cxgbr,
+cxlfbr,
+cxlgbr,
+m,
+madb,
+maeb,
+maebr,
+mfy,
+ml,
+mlr,
+mr,
+msdb,
+mseb,
+msebr,
+stam,
+wfaxb,
+wfixb,
+wflrx,
+wfsxb"
+)) "nothing")
+
+(define_insn_reservation "z16_10" 10
+  (and (eq_attr "cpu" "z16")
+(eq_attr "mnemonic"
+"lxdb,
+lxdbr,
+lxeb,
+lxebr,
+vscef,
+vsceg"
+)) "nothing")
+
+(define_insn_reservation "z16_11" 11
+  (and (eq_attr "cpu" "z16")
+(eq_attr "mnemonic"
+"cfdbr,
+cfebr,
+cgdbr,
+cgebr,
+clfdbr,
+clfebr,
+clgdbr,
+clgebr,
+mg,
+mgrk,
+mlg,
+mlgr"
+)) "nothing")
+
+(define_insn_reservation "z16_12" 12
+  (and (eq_attr "cpu" "z16")
+(eq_attr "mnemonic"
+"cxbr,
+cxftr,
+cxlftr,
+cxtr,
+kxbr,
+kxtr,
+tcxb,
+tdcxt"
+)) "nothing")
+
+(define_insn_reservation "z16_13" 13
+  (and (eq_attr "cpu" "z16")
+(eq_attr "mnemonic"
+"axbr,
+axtr,
+fixbr,
+fixbra,
+fixtr,
+lcxbr,
+lnxbr,
+lpxbr,
+ltxbr,
+ltxtr,
+lxdtr,
+sxbr,
+sxtr"
+)) "nothing")
+
+(define_insn_reservation "z16_14" 14
+  (and (eq_attr "cpu" "z16")
+(eq_attr "mnemonic"
+"cfxbr,
+cgxbr,
+clfxbr,
+clgxbr,
+ledtr"
+)) "nothing")
+
+(define_insn_reservation "z16_16" 16
+  (and (eq_attr "cpu" "z16")
+(eq_attr "mnemonic"
+"cdftr,
+cdlftr"
+)) "nothing")
+
+(define_insn_reservation "z16_20" 20
+  (and (eq_attr "cpu" "z16")
+(eq_attr "mnemonic"
+"cdgtr,
+cdlgtr,
+cgdtr,
+cgxtr,
+clfdtr,
+clfxtr,
+clgdtr,
+clgxtr,
+cxgtr,
+cxlgtr,
+d,
+ddb,
+ddbr,
+ddtr,
+deb,
+debr,
+dl,
+dlg,
+dlgr,
+dlr,
+dr,
+dsg,
+dsgf,
+dsgfr,
+dsgr,
+dxbr,
+dxtr,
+efpc,
+mdtr,
+mxbr,
+mxtr,
+sqdb,
+sqdbr,
+sqeb,
+sqebr,
+sqxbr,
+vfddb,
+vfdsb,
+vfsqdb,
+vfsqsb,
+wfddb,
+wfdsb,
+wfdxb,
+wfmaxb,
+wfmsxb,
+wfmxb,
+wfnmaxb,
+wfnmsxb,
+wfsqdb,
+wfsqxb"
+)) "nothing")
+
diff --git a/gcc/config/s390/driver-native.cc b/gcc/config/s390/driver-native.cc
index 48524c4..b5eb222 100644
--- a/gcc/config/s390/driver-native.cc
+++ b/gcc/config/s390/driver-native.cc
@@ -123,8 +123,12 @@
 	    case 0x8562:
 	      cpu = "z15";
 	      break;
+	    case 0x3931:
+	    case 0x3932:
+	      cpu = "z16";
+	      break;
 	    default:
-	      cpu = "arch14";
+	      cpu = "z16";
 	      break;
 	    }
 	}
diff --git a/gcc/config/s390/s390-opts.h b/gcc/config/s390/s390-opts.h
index 1ec8463..4ef82ac 100644
--- a/gcc/config/s390/s390-opts.h
+++ b/gcc/config/s390/s390-opts.h
@@ -38,7 +38,7 @@
   PROCESSOR_2964_Z13,
   PROCESSOR_3906_Z14,
   PROCESSOR_8561_Z15,
-  PROCESSOR_ARCH14,
+  PROCESSOR_3931_Z16,
   PROCESSOR_NATIVE,
   PROCESSOR_max
 };
diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h
index e625159..fd4acaa 100644
--- a/gcc/config/s390/s390-protos.h
+++ b/gcc/config/s390/s390-protos.h
@@ -49,7 +49,6 @@
 extern void s390_set_has_landing_pad_p (bool);
 extern bool s390_hard_regno_rename_ok (unsigned int, unsigned int);
 extern int s390_class_max_nregs (enum reg_class, machine_mode);
-extern bool s390_function_arg_vector (machine_mode, const_tree);
 extern bool s390_return_addr_from_memory(void);
 extern bool s390_fma_allowed_p (machine_mode);
 #if S390_USE_TARGET_ATTRIBUTE
diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc
index d2af6d8..7c3bd6c 100644
--- a/gcc/config/s390/s390.cc
+++ b/gcc/config/s390/s390.cc
@@ -337,7 +337,7 @@
   { "z13",    "z13",    PROCESSOR_2964_Z13,    &zEC12_cost,  11 },
   { "z14",    "arch12", PROCESSOR_3906_Z14,    &zEC12_cost,  12 },
   { "z15",    "arch13", PROCESSOR_8561_Z15,    &zEC12_cost,  13 },
-  { "arch14", "arch14", PROCESSOR_ARCH14,      &zEC12_cost,  14 },
+  { "z16",    "arch14", PROCESSOR_3931_Z16,    &zEC12_cost,  14 },
   { "native", "",       PROCESSOR_NATIVE,      NULL,         0  }
 };
 
@@ -853,12 +853,6 @@
 	  error ("Builtin %qF requires z15 or higher", fndecl);
 	  return const0_rtx;
 	}
-
-      if ((bflags & B_NNPA) && !TARGET_NNPA)
-	{
-	  error ("Builtin %qF requires arch14 or higher.", fndecl);
-	  return const0_rtx;
-	}
     }
   if (fcode >= S390_OVERLOADED_BUILTIN_VAR_OFFSET
       && fcode < S390_ALL_BUILTIN_MAX)
@@ -8525,7 +8519,7 @@
     case PROCESSOR_2827_ZEC12:
     case PROCESSOR_2964_Z13:
     case PROCESSOR_3906_Z14:
-    case PROCESSOR_ARCH14:
+    case PROCESSOR_3931_Z16:
     default:
       return 1;
     }
@@ -12148,29 +12142,26 @@
   gcc_unreachable ();
 }
 
-/* Return true if a function argument of type TYPE and mode MODE
-   is to be passed in a vector register, if available.  */
+/* Return true if a variable of TYPE should be passed as single value
+   with type CODE. If STRICT_SIZE_CHECK_P is true the sizes of the
+   record type and the field type must match.
 
-bool
-s390_function_arg_vector (machine_mode mode, const_tree type)
+   The ABI says that record types with a single member are treated
+   just like that member would be.  This function is a helper to
+   detect such cases.  The function also produces the proper
+   diagnostics for cases where the outcome might be different
+   depending on the GCC version.  */
+static bool
+s390_single_field_struct_p (enum tree_code code, const_tree type,
+			    bool strict_size_check_p)
 {
-  if (!TARGET_VX_ABI)
-    return false;
-
-  if (s390_function_arg_size (mode, type) > 16)
-    return false;
-
-  /* No type info available for some library calls ...  */
-  if (!type)
-    return VECTOR_MODE_P (mode);
-
-  /* The ABI says that record types with a single member are treated
-     just like that member would be.  */
   int empty_base_seen = 0;
+  bool zero_width_bf_skipped_p = false;
   const_tree orig_type = type;
+
   while (TREE_CODE (type) == RECORD_TYPE)
     {
-      tree field, single = NULL_TREE;
+      tree field, single_type = NULL_TREE;
 
       for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
 	{
@@ -12187,48 +12178,108 @@
 	      continue;
 	    }
 
-	  if (single == NULL_TREE)
-	    single = TREE_TYPE (field);
+	  if (DECL_FIELD_CXX_ZERO_WIDTH_BIT_FIELD (field))
+	    {
+	      zero_width_bf_skipped_p = true;
+	      continue;
+	    }
+
+	  if (single_type == NULL_TREE)
+	    single_type = TREE_TYPE (field);
 	  else
 	    return false;
 	}
 
-      if (single == NULL_TREE)
+      if (single_type == NULL_TREE)
 	return false;
-      else
-	{
-	  /* If the field declaration adds extra byte due to
-	     e.g. padding this is not accepted as vector type.  */
-	  if (int_size_in_bytes (single) <= 0
-	      || int_size_in_bytes (single) != int_size_in_bytes (type))
-	    return false;
-	  type = single;
-	}
+
+      /* Reaching this point we have a struct with a single member and
+	 zero or more zero-sized bit-fields which have been skipped in the
+	 past.  */
+
+      /* If ZERO_WIDTH_BF_SKIPPED_P then the struct will not be accepted.  In case
+	 we are not supposed to emit a warning exit early.  */
+      if (zero_width_bf_skipped_p && !warn_psabi)
+	return false;
+
+      /* If the field declaration adds extra bytes due to padding this
+	 is not accepted with STRICT_SIZE_CHECK_P.  */
+      if (strict_size_check_p
+	  && (int_size_in_bytes (single_type) <= 0
+	      || int_size_in_bytes (single_type) != int_size_in_bytes (type)))
+	return false;
+
+      type = single_type;
     }
 
-  if (!VECTOR_TYPE_P (type))
+  if (TREE_CODE (type) != code)
     return false;
 
-  if (warn_psabi && empty_base_seen)
+  if (warn_psabi)
     {
-      static unsigned last_reported_type_uid;
       unsigned uid = TYPE_UID (TYPE_MAIN_VARIANT (orig_type));
-      if (uid != last_reported_type_uid)
+
+      if (empty_base_seen)
 	{
-	  const char *url = CHANGES_ROOT_URL "gcc-10/changes.html#empty_base";
-	  last_reported_type_uid = uid;
-	  if (empty_base_seen & 1)
-	    inform (input_location,
-		    "parameter passing for argument of type %qT when C++17 "
-		    "is enabled changed to match C++14 %{in GCC 10.1%}",
-		    orig_type, url);
-	  else
-	    inform (input_location,
-		    "parameter passing for argument of type %qT with "
-		    "%<[[no_unique_address]]%> members changed "
-		    "%{in GCC 10.1%}", orig_type, url);
+	  static unsigned last_reported_type_uid_empty_base;
+	  if (uid != last_reported_type_uid_empty_base)
+	    {
+	      last_reported_type_uid_empty_base = uid;
+	      const char *url = CHANGES_ROOT_URL "gcc-10/changes.html#empty_base";
+	      if (empty_base_seen & 1)
+		inform (input_location,
+			"parameter passing for argument of type %qT when C++17 "
+			"is enabled changed to match C++14 %{in GCC 10.1%}",
+			orig_type, url);
+	      else
+		inform (input_location,
+			"parameter passing for argument of type %qT with "
+			"%<[[no_unique_address]]%> members changed "
+			"%{in GCC 10.1%}", orig_type, url);
+	    }
+	}
+
+      /* For C++ older GCCs ignored zero width bitfields and therefore
+	 passed structs more often as single values than GCC 12 does.
+	 So diagnostics are only required in cases where we do NOT
+	 accept the struct to be passed as single value.  */
+      if (zero_width_bf_skipped_p)
+	{
+	  static unsigned last_reported_type_uid_zero_width;
+	  if (uid != last_reported_type_uid_zero_width)
+	    {
+	      last_reported_type_uid_zero_width = uid;
+	      inform (input_location,
+		      "parameter passing for argument of type %qT with "
+		      "zero-width bit fields members changed in GCC 12",
+		      orig_type);
+	    }
 	}
     }
+
+  return !zero_width_bf_skipped_p;
+}
+
+
+/* Return true if a function argument of type TYPE and mode MODE
+   is to be passed in a vector register, if available.  */
+
+static bool
+s390_function_arg_vector (machine_mode mode, const_tree type)
+{
+  if (!TARGET_VX_ABI)
+    return false;
+
+  if (s390_function_arg_size (mode, type) > 16)
+    return false;
+
+  /* No type info available for some library calls ...  */
+  if (!type)
+    return VECTOR_MODE_P (mode);
+
+  if (!s390_single_field_struct_p (VECTOR_TYPE, type, true))
+    return false;
+
   return true;
 }
 
@@ -12249,64 +12300,9 @@
   if (!type)
     return mode == SFmode || mode == DFmode || mode == SDmode || mode == DDmode;
 
-  /* The ABI says that record types with a single member are treated
-     just like that member would be.  */
-  int empty_base_seen = 0;
-  const_tree orig_type = type;
-  while (TREE_CODE (type) == RECORD_TYPE)
-    {
-      tree field, single = NULL_TREE;
-
-      for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
-	{
-	  if (TREE_CODE (field) != FIELD_DECL)
-	    continue;
-	  if (DECL_FIELD_ABI_IGNORED (field))
-	    {
-	      if (lookup_attribute ("no_unique_address",
-				    DECL_ATTRIBUTES (field)))
-		empty_base_seen |= 2;
-	      else
-		empty_base_seen |= 1;
-	      continue;
-	    }
-
-	  if (single == NULL_TREE)
-	    single = TREE_TYPE (field);
-	  else
-	    return false;
-	}
-
-      if (single == NULL_TREE)
-	return false;
-      else
-	type = single;
-    }
-
-  if (TREE_CODE (type) != REAL_TYPE)
+  if (!s390_single_field_struct_p (REAL_TYPE, type, false))
     return false;
 
-  if (warn_psabi && empty_base_seen)
-    {
-      static unsigned last_reported_type_uid;
-      unsigned uid = TYPE_UID (TYPE_MAIN_VARIANT (orig_type));
-      if (uid != last_reported_type_uid)
-	{
-	  const char *url = CHANGES_ROOT_URL "gcc-10/changes.html#empty_base";
-	  last_reported_type_uid = uid;
-	  if (empty_base_seen & 1)
-	    inform (input_location,
-		    "parameter passing for argument of type %qT when C++17 "
-		    "is enabled changed to match C++14 %{in GCC 10.1%}",
-		    orig_type, url);
-	  else
-	    inform (input_location,
-		    "parameter passing for argument of type %qT with "
-		    "%<[[no_unique_address]]%> members changed "
-		    "%{in GCC 10.1%}", orig_type, url);
-	}
-    }
-
   return true;
 }
 
@@ -14879,7 +14875,6 @@
 	mask |= S390_SCHED_ATTR_MASK_GROUPOFTWO;
       break;
     case PROCESSOR_8561_Z15:
-    case PROCESSOR_ARCH14:
       if (get_attr_z15_cracked (insn))
 	mask |= S390_SCHED_ATTR_MASK_CRACKED;
       if (get_attr_z15_expanded (insn))
@@ -14891,6 +14886,18 @@
       if (get_attr_z15_groupoftwo (insn))
 	mask |= S390_SCHED_ATTR_MASK_GROUPOFTWO;
       break;
+    case PROCESSOR_3931_Z16:
+      if (get_attr_z16_cracked (insn))
+	mask |= S390_SCHED_ATTR_MASK_CRACKED;
+      if (get_attr_z16_expanded (insn))
+	mask |= S390_SCHED_ATTR_MASK_EXPANDED;
+      if (get_attr_z16_endgroup (insn))
+	mask |= S390_SCHED_ATTR_MASK_ENDGROUP;
+      if (get_attr_z16_groupalone (insn))
+	mask |= S390_SCHED_ATTR_MASK_GROUPALONE;
+      if (get_attr_z16_groupoftwo (insn))
+	mask |= S390_SCHED_ATTR_MASK_GROUPOFTWO;
+      break;
     default:
       gcc_unreachable ();
     }
@@ -14927,7 +14934,6 @@
 	mask |= 1 << 3;
       break;
     case PROCESSOR_8561_Z15:
-    case PROCESSOR_ARCH14:
       *units = 4;
       if (get_attr_z15_unit_lsu (insn))
 	mask |= 1 << 0;
@@ -14938,6 +14944,17 @@
       if (get_attr_z15_unit_vfu (insn))
 	mask |= 1 << 3;
       break;
+    case PROCESSOR_3931_Z16:
+      *units = 4;
+      if (get_attr_z16_unit_lsu (insn))
+	mask |= 1 << 0;
+      if (get_attr_z16_unit_fxa (insn))
+	mask |= 1 << 1;
+      if (get_attr_z16_unit_fxb (insn))
+	mask |= 1 << 2;
+      if (get_attr_z16_unit_vfu (insn))
+	mask |= 1 << 3;
+      break;
     default:
       gcc_unreachable ();
     }
@@ -14951,7 +14968,7 @@
     return false;
 
   return get_attr_z13_unit_fpd (insn) || get_attr_z14_unit_fpd (insn)
-    || get_attr_z15_unit_fpd (insn);
+    || get_attr_z15_unit_fpd (insn) || get_attr_z16_unit_fpd (insn);
 }
 
 static bool
@@ -14961,7 +14978,7 @@
     return false;
 
   return get_attr_z13_unit_fxd (insn) || get_attr_z14_unit_fxd (insn)
-    || get_attr_z15_unit_fxd (insn);
+    || get_attr_z15_unit_fxd (insn) || get_attr_z16_unit_fxd (insn);
 }
 
 /* Returns TRUE if INSN is a long-running instruction.  */
diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h
index 5a64048..2e1bc71 100644
--- a/gcc/config/s390/s390.h
+++ b/gcc/config/s390/s390.h
@@ -43,12 +43,12 @@
   PF_VXE2 = 8192,
   PF_Z15 = 16384,
   PF_NNPA = 32768,
-  PF_ARCH14 = 65536
+  PF_Z16 = 65536
 };
 
 /* This is necessary to avoid a warning about comparing different enum
    types.  */
-#define s390_tune_attr ((enum attr_cpu)(s390_tune > PROCESSOR_8561_Z15 ? PROCESSOR_8561_Z15 : s390_tune ))
+#define s390_tune_attr ((enum attr_cpu)(s390_tune > PROCESSOR_3931_Z16 ? PROCESSOR_3931_Z16 : s390_tune ))
 
 /* These flags indicate that the generated code should run on a cpu
    providing the respective hardware facility regardless of the
@@ -110,10 +110,10 @@
 	(s390_arch_flags & PF_VXE2)
 #define TARGET_CPU_VXE2_P(opts) \
 	(opts->x_s390_arch_flags & PF_VXE2)
-#define TARGET_CPU_ARCH14 \
-	(s390_arch_flags & PF_ARCH14)
-#define TARGET_CPU_ARCH14_P(opts) \
-	(opts->x_s390_arch_flags & PF_ARCH14)
+#define TARGET_CPU_Z16 \
+	(s390_arch_flags & PF_Z16)
+#define TARGET_CPU_Z16_P(opts) \
+	(opts->x_s390_arch_flags & PF_Z16)
 #define TARGET_CPU_NNPA \
 	(s390_arch_flags & PF_NNPA)
 #define TARGET_CPU_NNPA_P(opts) \
@@ -177,9 +177,9 @@
 	(TARGET_VX && TARGET_CPU_VXE2)
 #define TARGET_VXE2_P(opts)						\
 	(TARGET_VX_P (opts) && TARGET_CPU_VXE2_P (opts))
-#define TARGET_ARCH14 (TARGET_ZARCH && TARGET_CPU_ARCH14)
-#define TARGET_ARCH14_P(opts)						\
-	(TARGET_ZARCH_P (opts->x_target_flags) && TARGET_CPU_ARCH14_P (opts))
+#define TARGET_Z16 (TARGET_ZARCH && TARGET_CPU_Z16)
+#define TARGET_Z16_P(opts)						\
+	(TARGET_ZARCH_P (opts->x_target_flags) && TARGET_CPU_Z16_P (opts))
 #define TARGET_NNPA					\
 	(TARGET_ZARCH && TARGET_CPU_NNPA)
 #define TARGET_NNPA_P(opts)						\
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index d0f233e..55c0064 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -518,11 +518,11 @@
 ;; Processor type.  This attribute must exactly match the processor_type
 ;; enumeration in s390.h.
 
-(define_attr "cpu" "z900,z990,z9_109,z9_ec,z10,z196,zEC12,z13,z14,z15"
+(define_attr "cpu" "z900,z990,z9_109,z9_ec,z10,z196,zEC12,z13,z14,z15,z16"
   (const (symbol_ref "s390_tune_attr")))
 
 (define_attr "cpu_facility"
-  "standard,ieee,zarch,cpu_zarch,longdisp,extimm,dfp,z10,z196,zEC12,vx,z13,z14,vxe,z15,vxe2,arch14,nnpa"
+  "standard,ieee,zarch,cpu_zarch,longdisp,extimm,dfp,z10,z196,zEC12,vx,z13,z14,vxe,z15,vxe2,z16,nnpa"
   (const_string "standard"))
 
 (define_attr "enabled" ""
@@ -588,8 +588,8 @@
 	      (match_test "TARGET_VXE2"))
 	 (const_int 1)
 
-	 (and (eq_attr "cpu_facility" "arch14")
-	      (match_test "TARGET_ARCH14"))
+	 (and (eq_attr "cpu_facility" "z16")
+	      (match_test "TARGET_Z16"))
 	 (const_int 1)
 
          (and (eq_attr "cpu_facility" "nnpa")
@@ -629,6 +629,9 @@
 ;; Pipeline description for z15
 (include "8561.md")
 
+;; Pipeline description for z16
+(include "3931.md")
+
 ;; Predicates
 (include "predicates.md")
 
diff --git a/gcc/config/s390/s390.opt b/gcc/config/s390/s390.opt
index 5068486..9e8d3bf 100644
--- a/gcc/config/s390/s390.opt
+++ b/gcc/config/s390/s390.opt
@@ -116,7 +116,10 @@
 Enum(processor_type) String(arch13) Value(PROCESSOR_8561_Z15)
 
 EnumValue
-Enum(processor_type) String(arch14) Value(PROCESSOR_ARCH14)
+Enum(processor_type) String(arch14) Value(PROCESSOR_3931_Z16)
+
+EnumValue
+Enum(processor_type) String(z16) Value(PROCESSOR_3931_Z16)
 
 EnumValue
 Enum(processor_type) String(native) Value(PROCESSOR_NATIVE) DriverOnly
diff --git a/gcc/config/sparc/sparc.cc b/gcc/config/sparc/sparc.cc
index bb4ce88..467a9f1 100644
--- a/gcc/config/sparc/sparc.cc
+++ b/gcc/config/sparc/sparc.cc
@@ -8884,8 +8884,20 @@
       if (REGNO (*where) >= 8 && REGNO (*where) < 24)      /* oX or lX */
 	return 1;
       if (! test && REGNO (*where) >= 24 && REGNO (*where) < 32)
-	*where = gen_rtx_REG (GET_MODE (*where), OUTGOING_REGNO (REGNO(*where)));
-      /* fallthrough */
+	{
+	  if (ORIGINAL_REGNO (*where))
+	    {
+	      rtx n = gen_raw_REG (GET_MODE (*where),
+				   OUTGOING_REGNO (REGNO (*where)));
+	      ORIGINAL_REGNO (n) = ORIGINAL_REGNO (*where);
+	      *where = n;
+	    }
+	  else
+	    *where = gen_rtx_REG (GET_MODE (*where),
+				  OUTGOING_REGNO (REGNO (*where)));
+	}
+      return 0;
+
     case SCRATCH:
     case PC:
     case CONST_INT:
diff --git a/gcc/configure b/gcc/configure
index 7717863..8e685ff 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -30625,7 +30625,10 @@
 # In binutils 2.26, gld gained support for the ELF gABI format.
 if test $in_tree_ld = yes ; then
   gcc_cv_ld_compress_debug=0
-  if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 19 -o "$gcc_cv_gld_major_version" -gt 2 \
+  if test $ld_is_mold = yes; then
+    gcc_cv_ld_compress_debug=3
+    gcc_cv_ld_compress_debug_option="--compress-debug-sections"
+  elif test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 19 -o "$gcc_cv_gld_major_version" -gt 2 \
      && test $in_tree_ld_is_elf = yes && test $ld_is_gold = yes; then
     gcc_cv_ld_compress_debug=2
     gcc_cv_ld_compress_debug_option="--compress-debug-sections"
@@ -30638,7 +30641,10 @@
     gcc_cv_ld_compress_debug=1
   fi
 elif echo "$ld_ver" | grep GNU > /dev/null; then
-  if test "$ld_vers_major" -lt 2 \
+  if test $ld_is_mold = yes; then
+    gcc_cv_ld_compress_debug=3
+    gcc_cv_ld_compress_debug_option="--compress-debug-sections"
+  elif test "$ld_vers_major" -lt 2 \
      || test "$ld_vers_major" -eq 2 -a "$ld_vers_minor" -lt 21; then
     gcc_cv_ld_compress_debug=0
   elif test "$ld_vers_major" -eq 2 -a "$ld_vers_minor" -lt 26; then
diff --git a/gcc/configure.ac b/gcc/configure.ac
index 54c8445..d3b07c0 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -6266,7 +6266,10 @@
 # In binutils 2.26, gld gained support for the ELF gABI format.
 if test $in_tree_ld = yes ; then
   gcc_cv_ld_compress_debug=0
-  if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 19 -o "$gcc_cv_gld_major_version" -gt 2 \
+  if test $ld_is_mold = yes; then
+    gcc_cv_ld_compress_debug=3
+    gcc_cv_ld_compress_debug_option="--compress-debug-sections"
+  elif test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 19 -o "$gcc_cv_gld_major_version" -gt 2 \
      && test $in_tree_ld_is_elf = yes && test $ld_is_gold = yes; then
     gcc_cv_ld_compress_debug=2
     gcc_cv_ld_compress_debug_option="--compress-debug-sections"
@@ -6279,7 +6282,10 @@
     gcc_cv_ld_compress_debug=1
   fi
 elif echo "$ld_ver" | grep GNU > /dev/null; then
-  if test "$ld_vers_major" -lt 2 \
+  if test $ld_is_mold = yes; then
+    gcc_cv_ld_compress_debug=3
+    gcc_cv_ld_compress_debug_option="--compress-debug-sections"
+  elif test "$ld_vers_major" -lt 2 \
      || test "$ld_vers_major" -eq 2 -a "$ld_vers_minor" -lt 21; then
     gcc_cv_ld_compress_debug=0
   elif test "$ld_vers_major" -eq 2 -a "$ld_vers_minor" -lt 26; then
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 5db636a..3ef9e89 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,280 @@
+2022-04-27  Jason Merrill  <jason@redhat.com>
+
+	* tree.cc (strip_typedefs): Add default argument comments.
+
+2022-04-27  Marek Polacek  <polacek@redhat.com>
+
+	PR c++/105398
+	* pt.cc (uses_template_parms): Return false for any NAMESPACE_DECL.
+
+2022-04-26  Jason Merrill  <jason@redhat.com>
+
+	PR c++/102629
+	* pt.cc (gen_elem_of_pack_expansion_instantiation): Clear
+	TEMPLATE_TYPE_PARAMETER_PACK on auto.
+
+2022-04-26  Patrick Palka  <ppalka@redhat.com>
+
+	PR c++/105386
+	* semantics.cc (finish_decltype_type): Pass tf_decltype to
+	instantiate_non_dependent_expr_sfinae.
+
+2022-04-26  Jason Merrill  <jason@redhat.com>
+
+	PR c++/104624
+	* pt.cc (check_for_bare_parameter_packs): Check for lambda
+	function parameter pack.
+
+2022-04-26  Patrick Palka  <ppalka@redhat.com>
+
+	PR c++/105289
+	PR c++/86193
+	* pt.cc (process_partial_specialization): Downgrade "partial
+	specialization isn't more specialized" diagnostic from permerror
+	to an on-by-default pedwarn.
+	(unify) <case TEMPLATE_PARM_INDEX>: When substituting into the
+	NTTP type a second time, use the original type not the
+	substituted type.
+
+2022-04-25  Marek Polacek  <polacek@redhat.com>
+
+	PR c++/105353
+	* typeck.cc (build_x_shufflevector): Use
+	instantiation_dependent_expression_p except for the first two
+	arguments.
+
+2022-04-21  Marek Polacek  <polacek@redhat.com>
+
+	* constexpr.cc (cxx_eval_logical_expression): Remove unused
+	parameter.
+	(cxx_eval_constant_expression) <case TRUTH_ANDIF_EXPR>,
+	<case TRUTH_OR_EXPR>: Adjust calls to cxx_eval_logical_expression.
+
+2022-04-21  Marek Polacek  <polacek@redhat.com>
+
+	PR c++/105321
+	* constexpr.cc (cxx_eval_logical_expression): Always pass false for lval
+	to cxx_eval_constant_expression.
+
+2022-04-20  Ed Catmur  <ed@catmur.uk>
+
+	PR c++/104996
+	* call.cc (compare_ics): When comparing list-initialization
+	sequences, do not return early.
+
+2022-04-19  Jakub Jelinek  <jakub@redhat.com>
+
+	PR c++/105256
+	* typeck2.cc (process_init_constructor_array,
+	process_init_constructor_record, process_init_constructor_union): Move
+	CONSTRUCTOR_PLACEHOLDER_BOUNDARY flag from CONSTRUCTOR elements to the
+	containing CONSTRUCTOR.
+
+2022-04-15  Marek Polacek  <polacek@redhat.com>
+
+	PR c++/105268
+	* parser.cc (cp_parser_placeholder_type_specifier): Return
+	error_mark_node when trying to build up a constrained parameter in
+	a default argument.
+
+2022-04-15  Jason Merrill  <jason@redhat.com>
+
+	PR c++/102804
+	* decl.cc (grokdeclarator): Drop typedef used with 'unsigned'.
+
+2022-04-15  Jason Merrill  <jason@redhat.com>
+
+	PR c++/102987
+	* error.cc (dump_expr): Handle USING_DECL.
+	[VIEW_CONVERT_EXPR]: Just look through location wrapper.
+
+2022-04-14  Jason Merrill  <jason@redhat.com>
+
+	PR c++/104646
+	* constexpr.cc (maybe_save_constexpr_fundef): Don't do extra
+	checks for defaulted ctors.
+
+2022-04-14  Jason Merrill  <jason@redhat.com>
+
+	PR c++/82980
+	* lambda.cc (type_deducible_expression_p): New.
+	(lambda_capture_field_type): Check it.
+
+2022-04-14  Jason Merrill  <jason@redhat.com>
+
+	PR c++/65211
+	* pt.cc (tsubst_decl) [TYPE_DECL]: Copy TYPE_ALIGN.
+
+2022-04-14  Jason Merrill  <jason@redhat.com>
+
+	PR c++/97219
+	* name-lookup.cc (dependent_local_decl_p): New.
+	* cp-tree.h (dependent_local_decl_p): Declare.
+	* semantics.cc (finish_call_expr): Use it.
+	* pt.cc (tsubst_arg_types): Also substitute default args
+	for local externs.
+
+2022-04-14  Jason Merrill  <jason@redhat.com>
+
+	PR c++/101698
+	* pt.cc (tsubst_baselink): Also check dependent optype.
+
+2022-04-14  Jason Merrill  <jason@redhat.com>
+
+	PR c++/101442
+	* decl.cc (cp_finish_decl): Don't pass decl to push_cleanup.
+	* init.cc (perform_member_init): Likewise.
+	* semantics.cc (push_cleanup): Adjust comment.
+
+2022-04-13  Jason Merrill  <jason@redhat.com>
+
+	PR c++/105245
+	PR c++/100111
+	* constexpr.cc (cxx_eval_store_expression): Build a CONSTRUCTOR
+	as needed in empty base handling.
+
+2022-04-13  Jakub Jelinek  <jakub@redhat.com>
+
+	PR c++/105233
+	* decl2.cc (cp_check_const_attributes): For aligned attribute
+	pass manifestly_const_eval=true to fold_non_dependent_expr.
+
+2022-04-13  Marek Polacek  <polacek@redhat.com>
+
+	PR c++/97296
+	* call.cc (direct_reference_binding): strip_top_quals when creating
+	a ck_qual.
+
+2022-04-12  Jason Merrill  <jason@redhat.com>
+
+	PR c++/104669
+	* decl.cc (decls_match): Compare versions even if not recording.
+	(duplicate_decls): Propagate attributes to alias.
+	* decl2.cc (find_last_decl): Give up if versioned.
+
+2022-04-12  Jason Merrill  <jason@redhat.com>
+
+	PR c++/102071
+	* init.cc (build_new_1): Check array_p for alignment.
+
+2022-04-12  Patrick Palka  <ppalka@redhat.com>
+
+	PR c++/103105
+	* pt.cc (build_extra_args): Call preserve_args.
+
+2022-04-12  Jason Merrill  <jason@redhat.com>
+
+	PR c++/104142
+	* decl.cc (check_initializer): Check TREE_SIDE_EFFECTS.
+
+2022-04-12  Jason Merrill  <jason@redhat.com>
+
+	PR c++/105223
+	PR c++/92918
+	* class.cc (finish_struct): Always using op=.
+
+2022-04-11  Jason Merrill  <jason@redhat.com>
+
+	PR c++/98249
+	* call.cc (build_operator_new_call): Just look in ::.
+
+2022-04-11  Alexandre Oliva  <oliva@adacore.com>
+
+	* constexpr.cc (cxx_eval_call_expression): Disregard dtor
+	result.
+
+2022-04-11  Alexandre Oliva  <oliva@adacore.com>
+
+	* semantics.cc (set_cleanup_locs): Propagate locus to call
+	wrapped in cast-to-void.
+
+2022-04-11  Jason Merrill  <jason@redhat.com>
+
+	PR c++/100370
+	* init.cc (warn_placement_new_too_small): Check deref.
+
+2022-04-09  Jason Merrill  <jason@redhat.com>
+
+	PR c++/105191
+	PR c++/92385
+	* tree.cc (build_vec_init_elt): Do {}-init for aggregates.
+	* constexpr.cc (cxx_eval_vec_init): Only treat {} as value-init
+	for non-aggregate types.
+	(build_vec_init_expr): Also check constancy of explicit
+	initializer elements.
+
+2022-04-09  Jason Merrill  <jason@redhat.com>
+
+	PR c++/91618
+	PR c++/96604
+	* name-lookup.cc (set_decl_namespace): Set
+	DECL_IMPLICIT_INSTANTIATION if no non-template match.
+	* pt.cc (check_explicit_specialization): Check it.
+	* decl2.cc (check_classfn): Call it.
+
+2022-04-07  Patrick Palka  <ppalka@redhat.com>
+
+	PR c++/99479
+	* name-lookup.cc (name_lookup::using_queue): Change to an
+	auto_vec (with 16 elements of internal storage).
+	(name_lookup::queue_namespace): Change return type to void,
+	take queue parameter by reference and adjust function body
+	accordingly.
+	(name_lookup::do_queue_usings): Inline into ...
+	(name_lookup::queue_usings): ... here.  As in queue_namespace.
+	(name_lookup::search_unqualified): Don't make queue static,
+	remove length variable, and adjust function body accordingly.
+
+2022-04-07  Jakub Jelinek  <jakub@redhat.com>
+
+	PR tree-optimization/102586
+	* cp-objcp-common.h (cp_classtype_as_base): Declare.
+	(LANG_HOOKS_CLASSTYPE_AS_BASE): Redefine.
+	* cp-objcp-common.cc (cp_classtype_as_base): New function.
+
+2022-04-07  Jason Merrill  <jason@redhat.com>
+
+	PR c++/101051
+	* decl.cc (grokdeclarator): Reject conversion with trailing return
+	sooner.
+
+2022-04-07  Jason Merrill  <jason@redhat.com>
+
+	PR c++/101717
+	* lambda.cc (lambda_expr_this_capture): Check all enclosing
+	lambdas for completeness.
+
+2022-04-07  Jason Merrill  <jason@redhat.com>
+
+	PR c++/105187
+	* typeck2.cc (store_init_value): Allow TREE_HAS_CONSTRUCTOR for
+	vectors.
+
+2022-04-06  Jakub Jelinek  <jakub@redhat.com>
+
+	PR c++/104668
+	* decl2.cc (splice_template_attributes): Return NULL if *p is
+	error_mark_node.
+	(cplus_decl_attributes): Return early if attributes is
+	error_mark_node.  Don't check that later.
+
+2022-04-06  Patrick Palka  <ppalka@redhat.com>
+
+	PR c++/105143
+	* pt.cc (do_class_deduction): Check complain before attempting
+	to issue a -Wctad-maybe-unsupported warning.
+
+2022-04-06  Jason Merrill  <jason@redhat.com>
+
+	PR c++/104702
+	* init.cc (build_vec_init): Use a reference for the result.
+
+2022-04-06  Jason Merrill  <jason@redhat.com>
+
+	PR c++/100608
+	* name-lookup.cc (check_local_shadow): Use -Wshadow=local
+	if exactly one of 'old' and 'decl' is a type.
+
 2022-04-05  Jason Merrill  <jason@redhat.com>
 
 	PR c++/103852
diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index 73fede5..fa18d7f 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -1680,8 +1680,19 @@
        because the types "int *" and "const int *const" are
        reference-related and we were binding both directly and they
        had the same rank.  To break it up, we add a ck_qual under the
-       ck_ref_bind so that conversion sequence ranking chooses #1.  */
-    conv = build_conv (ck_qual, t, conv);
+       ck_ref_bind so that conversion sequence ranking chooses #1.
+
+       We strip_top_quals here which is also what standard_conversion
+       does.  Failure to do so would confuse comp_cv_qual_signature
+       into thinking that in
+
+	 void f(const int * const &); // #1
+	 void f(const int *); // #2
+	 int *x;
+	 f(x);
+
+       #2 is a better match than #1 even though they're ambiguous (97296).  */
+    conv = build_conv (ck_qual, strip_top_quals (t), conv);
 
   return build_conv (ck_ref_bind, type, conv);
 }
@@ -4899,8 +4910,7 @@
        up in the global scope.
 
      we disregard block-scope declarations of "operator new".  */
-  fns = lookup_name (fnname, LOOK_where::NAMESPACE);
-  fns = lookup_arg_dependent (fnname, fns, *args);
+  fns = lookup_qualified_name (global_namespace, fnname);
 
   if (align_arg)
     {
@@ -11536,12 +11546,9 @@
 	 P0388R4.)  */
       else if (t1->kind == ck_aggr
 	       && TREE_CODE (t1->type) == ARRAY_TYPE
-	       && TREE_CODE (t2->type) == ARRAY_TYPE)
+	       && TREE_CODE (t2->type) == ARRAY_TYPE
+	       && same_type_p (TREE_TYPE (t1->type), TREE_TYPE (t2->type)))
 	{
-	  /* The type of the array elements must be the same.  */
-	  if (!same_type_p (TREE_TYPE (t1->type), TREE_TYPE (t2->type)))
-	    return 0;
-
 	  tree n1 = nelts_initialized_by_list_init (t1);
 	  tree n2 = nelts_initialized_by_list_init (t2);
 	  if (tree_int_cst_lt (n1, n2))
diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc
index 40e1714..bfda006 100644
--- a/gcc/cp/class.cc
+++ b/gcc/cp/class.cc
@@ -7723,17 +7723,14 @@
 	 lookup not to fail or recurse into bases.  This isn't added
 	 to the template decl list so we drop this at instantiation
 	 time.  */
-      if (!get_class_binding_direct (t, assign_op_identifier, false))
-	{
-	  tree ass_op = build_lang_decl (USING_DECL, assign_op_identifier,
-					 NULL_TREE);
-	  DECL_CONTEXT (ass_op) = t;
-	  USING_DECL_SCOPE (ass_op) = t;
-	  DECL_DEPENDENT_P (ass_op) = true;
-	  DECL_ARTIFICIAL (ass_op) = true;
-	  DECL_CHAIN (ass_op) = TYPE_FIELDS (t);
-	  TYPE_FIELDS (t) = ass_op;
-	}
+      tree ass_op = build_lang_decl (USING_DECL, assign_op_identifier,
+				     NULL_TREE);
+      DECL_CONTEXT (ass_op) = t;
+      USING_DECL_SCOPE (ass_op) = t;
+      DECL_DEPENDENT_P (ass_op) = true;
+      DECL_ARTIFICIAL (ass_op) = true;
+      DECL_CHAIN (ass_op) = TYPE_FIELDS (t);
+      TYPE_FIELDS (t) = ass_op;
 
       TYPE_SIZE (t) = bitsize_zero_node;
       TYPE_SIZE_UNIT (t) = size_zero_node;
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index 9c40b05..47d5113 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -920,7 +920,8 @@
   if (!potential && complain)
     require_potential_rvalue_constant_expression (massaged);
 
-  if (DECL_CONSTRUCTOR_P (fun) && potential)
+  if (DECL_CONSTRUCTOR_P (fun) && potential
+      && !DECL_DEFAULTED_FN (fun))
     {
       if (cx_check_missing_mem_inits (DECL_CONTEXT (fun),
 				      massaged, complain))
@@ -2889,7 +2890,8 @@
 	  else
 	    {
 	      result = *ctx->global->values.get (res);
-	      if (result == NULL_TREE && !*non_constant_p)
+	      if (result == NULL_TREE && !*non_constant_p
+		  && !DECL_DESTRUCTOR_P (fun))
 		{
 		  if (!ctx->quiet)
 		    error ("%<constexpr%> call flows off the end "
@@ -4564,19 +4566,18 @@
 static tree
 cxx_eval_logical_expression (const constexpr_ctx *ctx, tree t,
                              tree bailout_value, tree continue_value,
-			     bool lval,
 			     bool *non_constant_p, bool *overflow_p)
 {
   tree r;
   tree lhs = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
-					   lval,
-					   non_constant_p, overflow_p);
+					   /*lval*/false, non_constant_p,
+					   overflow_p);
   VERIFY_CONSTANT (lhs);
   if (tree_int_cst_equal (lhs, bailout_value))
     return lhs;
   gcc_assert (tree_int_cst_equal (lhs, continue_value));
   r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
-				    lval, non_constant_p,
+				    /*lval*/false, non_constant_p,
 				    overflow_p);
   VERIFY_CONSTANT (r);
   return r;
@@ -5008,7 +5009,8 @@
   bool value_init = VEC_INIT_EXPR_VALUE_INIT (t);
   if (!init || !BRACE_ENCLOSED_INITIALIZER_P (init))
     ;
-  else if (CONSTRUCTOR_NELTS (init) == 0)
+  else if (CONSTRUCTOR_NELTS (init) == 0
+	   && !CP_AGGREGATE_TYPE_P (strip_array_types (atype)))
     {
       /* Handle {} as value-init.  */
       init = NULL_TREE;
@@ -5931,6 +5933,12 @@
     {
       /* See above on initialization of empty bases.  */
       gcc_assert (is_empty_class (TREE_TYPE (init)) && !lval);
+      if (!*valp)
+	{
+	  /* But do make sure we have something in *valp.  */
+	  *valp = build_constructor (type, nullptr);
+	  CONSTRUCTOR_NO_CLEARING (*valp) = no_zero_init;
+	}
       return init;
     }
   else
@@ -7097,7 +7105,6 @@
     case TRUTH_ANDIF_EXPR:
       r = cxx_eval_logical_expression (ctx, t, boolean_false_node,
 				       boolean_true_node,
-				       lval,
 				       non_constant_p, overflow_p);
       break;
 
@@ -7105,7 +7112,6 @@
     case TRUTH_ORIF_EXPR:
       r = cxx_eval_logical_expression (ctx, t, boolean_true_node,
 				       boolean_false_node,
-				       lval,
 				       non_constant_p, overflow_p);
       break;
 
diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index cdf6503..551ddc9 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -513,8 +513,14 @@
 		      coro_info->promise_type);
 	  inform (DECL_SOURCE_LOCATION (BASELINK_FUNCTIONS (has_ret_void)),
 		  "%<return_void%> declared here");
-	  inform (DECL_SOURCE_LOCATION (BASELINK_FUNCTIONS (has_ret_val)),
-		  "%<return_value%> declared here");
+	  has_ret_val = BASELINK_FUNCTIONS (has_ret_val);
+	  const char *message = "%<return_value%> declared here";
+	  if (TREE_CODE (has_ret_val) == OVERLOAD)
+	    {
+	      has_ret_val = OVL_FIRST (has_ret_val);
+	      message = "%<return_value%> first declared here";
+	    }
+	  inform (DECL_SOURCE_LOCATION (has_ret_val), message);
 	  coro_info->coro_co_return_error_emitted = true;
 	  return false;
 	}
@@ -877,13 +883,14 @@
 static bool
 coro_diagnose_throwing_final_aw_expr (tree expr)
 {
-  tree t = TARGET_EXPR_INITIAL (expr);
+  if (TREE_CODE (expr) == TARGET_EXPR)
+    expr = TARGET_EXPR_INITIAL (expr);
   tree fn = NULL_TREE;
-  if (TREE_CODE (t) == CALL_EXPR)
-    fn = CALL_EXPR_FN(t);
-  else if (TREE_CODE (t) == AGGR_INIT_EXPR)
-    fn = AGGR_INIT_EXPR_FN (t);
-  else if (TREE_CODE (t) == CONSTRUCTOR)
+  if (TREE_CODE (expr) == CALL_EXPR)
+    fn = CALL_EXPR_FN (expr);
+  else if (TREE_CODE (expr) == AGGR_INIT_EXPR)
+    fn = AGGR_INIT_EXPR_FN (expr);
+  else if (TREE_CODE (expr) == CONSTRUCTOR)
     return false;
   else
     {
@@ -1148,10 +1155,13 @@
      extraneous warnings during substitution.  */
   suppress_warning (current_function_decl, OPT_Wreturn_type);
 
-  /* If we don't know the promise type, we can't proceed, build the
-     co_await with the expression unchanged.  */
-  tree functype = TREE_TYPE (current_function_decl);
-  if (dependent_type_p (functype) || type_dependent_expression_p (expr))
+  /* Defer expansion when we are processing a template.
+     FIXME: If the coroutine function's type is not dependent, and the operand
+     is not dependent, we should determine the type of the co_await expression
+     using the DEPENDENT_EXPR wrapper machinery.  That allows us to determine
+     the subexpression type, but leave its operand unchanged and then
+     instantiate it later.  */
+  if (processing_template_decl)
     {
       tree aw_expr = build5_loc (kw, CO_AWAIT_EXPR, unknown_type_node, expr,
 				 NULL_TREE, NULL_TREE, NULL_TREE,
@@ -1222,10 +1232,9 @@
      extraneous warnings during substitution.  */
   suppress_warning (current_function_decl, OPT_Wreturn_type);
 
-  /* If we don't know the promise type, we can't proceed, build the
-     co_await with the expression unchanged.  */
-  tree functype = TREE_TYPE (current_function_decl);
-  if (dependent_type_p (functype) || type_dependent_expression_p (expr))
+  /* Defer expansion when we are processing a template; see FIXME in the
+     co_await code.  */
+  if (processing_template_decl)
     return build2_loc (kw, CO_YIELD_EXPR, unknown_type_node, expr, NULL_TREE);
 
   if (!coro_promise_type_found_p (current_function_decl, kw))
@@ -1307,10 +1316,9 @@
       && check_for_bare_parameter_packs (expr))
     return error_mark_node;
 
-  /* If we don't know the promise type, we can't proceed, build the
-     co_return with the expression unchanged.  */
-  tree functype = TREE_TYPE (current_function_decl);
-  if (dependent_type_p (functype) || type_dependent_expression_p (expr))
+  /* Defer expansion when we are processing a template; see FIXME in the
+     co_await code.  */
+  if (processing_template_decl)
     {
       /* co_return expressions are always void type, regardless of the
 	 expression type.  */
@@ -3109,7 +3117,7 @@
 	 If the initializer is a conditional expression, we need to collect
 	 and declare any promoted variables nested within it.  DTORs for such
 	 variables must be run conditionally too.  */
-      if (t->var && DECL_NAME (t->var))
+      if (t->var)
 	{
 	  tree var = t->var;
 	  DECL_CHAIN (var) = vlist;
@@ -3310,7 +3318,7 @@
   tree b_vars = BIND_EXPR_VARS (bind);
   /* Build a variable to hold the condition, this will be included in the
      frame as a local var.  */
-  char *nam = xasprintf ("%s.%d", nam_root, nam_vers);
+  char *nam = xasprintf ("__%s_%d", nam_root, nam_vers);
   tree newvar = build_lang_decl (VAR_DECL, get_identifier (nam), var_type);
   free (nam);
   DECL_CHAIN (newvar) = b_vars;
@@ -3955,7 +3963,7 @@
 	     scopes with identically named locals and still be able to
 	     identify them in the coroutine frame.  */
 	  tree lvname = DECL_NAME (lvar);
-	  char *buf;
+	  char *buf = NULL;
 
 	  /* The outermost bind scope contains the artificial variables that
 	     we inject to implement the coro state machine.  We want to be able
@@ -3965,14 +3973,14 @@
 	  else if (lvname != NULL_TREE)
 	    buf = xasprintf ("%s_%u_%u", IDENTIFIER_POINTER (lvname),
 			     lvd->nest_depth, lvd->bind_indx);
-	  else
-	    buf = xasprintf ("_D%u_%u_%u", DECL_UID (lvar), lvd->nest_depth,
-			     lvd->bind_indx);
 	  /* TODO: Figure out if we should build a local type that has any
 	     excess alignment or size from the original decl.  */
-	  local_var.field_id
-	    = coro_make_frame_entry (lvd->field_list, buf, lvtype, lvd->loc);
-	  free (buf);
+	  if (buf)
+	    {
+	      local_var.field_id = coro_make_frame_entry (lvd->field_list, buf,
+							  lvtype, lvd->loc);
+	      free (buf);
+	    }
 	  /* We don't walk any of the local var sub-trees, they won't contain
 	     any bind exprs.  */
 	}
diff --git a/gcc/cp/cp-objcp-common.cc b/gcc/cp/cp-objcp-common.cc
index 8f74802..0b70d55 100644
--- a/gcc/cp/cp-objcp-common.cc
+++ b/gcc/cp/cp-objcp-common.cc
@@ -280,6 +280,22 @@
   return TYPE_SIZE_UNIT (type);
 }
 
+/* Returns type corresponding to FIELD's type when FIELD is a C++ base class
+   i.e., type without virtual base classes or tail padding.  Returns
+   NULL_TREE otherwise.  */
+
+tree
+cp_classtype_as_base (const_tree field)
+{
+  if (DECL_FIELD_IS_BASE (field))
+    {
+      tree type = TREE_TYPE (field);
+      if (TYPE_LANG_SPECIFIC (type))
+	return CLASSTYPE_AS_BASE (type);
+    }
+  return NULL_TREE;
+}
+
 /* Stubs to keep c-opts.cc happy.  */
 void
 push_file_scope (void)
diff --git a/gcc/cp/cp-objcp-common.h b/gcc/cp/cp-objcp-common.h
index 4c13731..3c04e5c 100644
--- a/gcc/cp/cp-objcp-common.h
+++ b/gcc/cp/cp-objcp-common.h
@@ -31,6 +31,7 @@
 extern int cp_type_dwarf_attribute (const_tree, int);
 extern void cp_common_init_ts (void);
 extern tree cp_unit_size_without_reusable_padding (tree);
+extern tree cp_classtype_as_base (const_tree);
 extern tree cp_get_global_decls ();
 extern tree cp_pushdecl (tree);
 extern void cp_register_dumps (gcc::dump_manager *);
@@ -167,6 +168,8 @@
 #define LANG_HOOKS_TYPE_DWARF_ATTRIBUTE cp_type_dwarf_attribute
 #undef LANG_HOOKS_UNIT_SIZE_WITHOUT_REUSABLE_PADDING
 #define LANG_HOOKS_UNIT_SIZE_WITHOUT_REUSABLE_PADDING cp_unit_size_without_reusable_padding
+#undef LANG_HOOKS_CLASSTYPE_AS_BASE
+#define LANG_HOOKS_CLASSTYPE_AS_BASE cp_classtype_as_base
 
 #undef LANG_HOOKS_OMP_PREDETERMINED_SHARING
 #define LANG_HOOKS_OMP_PREDETERMINED_SHARING cxx_omp_predetermined_sharing
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 2f71885..e9a3d09 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -8243,6 +8243,7 @@
 /* in name-lookup.cc */
 extern tree strip_using_decl                    (tree);
 extern void diagnose_name_conflict		(tree, tree);
+extern bool dependent_local_decl_p		(tree);
 
 /* Tell the binding oracle what kind of binding we are looking for.  */
 
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 0ff13e9..2852093 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -1069,11 +1069,14 @@
       if (types_match
 	  && !DECL_EXTERN_C_P (newdecl)
 	  && !DECL_EXTERN_C_P (olddecl)
-	  && record_versions
-	  && maybe_version_functions (newdecl, olddecl,
-				      (!DECL_FUNCTION_VERSIONED (newdecl)
-				       || !DECL_FUNCTION_VERSIONED (olddecl))))
-	return 0;
+	  && targetm.target_option.function_versions (newdecl, olddecl))
+	{
+	  if (record_versions)
+	    maybe_version_functions (newdecl, olddecl,
+				     (!DECL_FUNCTION_VERSIONED (newdecl)
+				      || !DECL_FUNCTION_VERSIONED (olddecl)));
+	  return 0;
+	}
     }
   else if (TREE_CODE (newdecl) == TEMPLATE_DECL)
     {
@@ -2598,7 +2601,12 @@
       else
 	{
 	  retrofit_lang_decl (newdecl);
-	  DECL_LOCAL_DECL_ALIAS (newdecl) = DECL_LOCAL_DECL_ALIAS (olddecl);
+	  tree alias = DECL_LOCAL_DECL_ALIAS (newdecl)
+	    = DECL_LOCAL_DECL_ALIAS (olddecl);
+	  DECL_ATTRIBUTES (alias)
+	    = (*targetm.merge_decl_attributes) (alias, newdecl);
+	  if (TREE_CODE (newdecl) == FUNCTION_DECL)
+	    merge_attribute_bits (newdecl, alias);
 	}
     }
 
@@ -7444,6 +7452,10 @@
   if (init && init != error_mark_node)
     init_code = build2 (INIT_EXPR, type, decl, init);
 
+  if (init_code && !TREE_SIDE_EFFECTS (init_code)
+      && init_code != error_mark_node)
+    init_code = NULL_TREE;
+
   if (init_code)
     {
       /* We might have set these in cp_finish_decl.  */
@@ -8542,7 +8554,7 @@
     {
       for (tree t : *cleanups)
 	{
-	  push_cleanup (decl, t, false);
+	  push_cleanup (NULL_TREE, t, false);
 	  /* As in initialize_local_var.  */
 	  wrap_temporary_cleanups (init, t);
 	}
@@ -12231,6 +12243,8 @@
 	      pedwarn (loc, OPT_Wpedantic, "%qs specified with %qT",
 		       key, type);
 	      ok = !flag_pedantic_errors;
+	      type = DECL_ORIGINAL_TYPE (typedef_decl);
+	      typedef_decl = NULL_TREE;
 	    }
 	  else if (declspecs->decltype_p)
 	    error_at (loc, "%qs specified with %<decltype%>", key);
@@ -12866,6 +12880,11 @@
 			    "type specifier", name);
 		return error_mark_node;
 	      }
+	    if (late_return_type && sfk == sfk_conversion)
+	      {
+		error ("a conversion function cannot have a trailing return type");
+		return error_mark_node;
+	      }
 	    type = splice_late_return_type (type, late_return_type);
 	    if (type == error_mark_node)
 	      return error_mark_node;
@@ -13030,8 +13049,6 @@
 		    maybe_warn_cpp0x (CPP0X_EXPLICIT_CONVERSION);
 		    explicitp = 2;
 		  }
-		if (late_return_type_p)
-		  error ("a conversion function cannot have a trailing return type");
 	      }
 	    else if (sfk == sfk_deduction_guide)
 	      {
diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc
index dc2c924..d2b2920 100644
--- a/gcc/cp/decl2.cc
+++ b/gcc/cp/decl2.cc
@@ -734,11 +734,15 @@
   tree pushed_scope = push_scope (ctype);
   tree matched = NULL_TREE;
   tree fns = get_class_binding (ctype, DECL_NAME (function));
-  
+  bool saw_template = false;
+
   for (ovl_iterator iter (fns); !matched && iter; ++iter)
     {
       tree fndecl = *iter;
 
+      if (TREE_CODE (fndecl) == TEMPLATE_DECL)
+	saw_template = true;
+
       /* A member template definition only matches a member template
 	 declaration.  */
       if (is_template != (TREE_CODE (fndecl) == TEMPLATE_DECL))
@@ -788,6 +792,23 @@
 	matched = fndecl;
     }
 
+  if (!matched && !is_template && saw_template
+      && !processing_template_decl && DECL_UNIQUE_FRIEND_P (function))
+    {
+      /* "[if no non-template match is found,] each remaining function template
+	 is replaced with the specialization chosen by deduction from the
+	 friend declaration or discarded if deduction fails."
+
+	 So ask check_explicit_specialization to find a matching template.  */
+      SET_DECL_IMPLICIT_INSTANTIATION (function);
+      tree spec = check_explicit_specialization (DECL_NAME (function),
+						 function, /* tcount */0,
+						 /* friend flag */4,
+						 /* attrlist */NULL_TREE);
+      if (spec != error_mark_node)
+	matched = spec;
+    }
+
   if (!matched)
     {
       if (!COMPLETE_TYPE_P (ctype))
@@ -1513,12 +1534,19 @@
   for (attr = attributes; attr; attr = TREE_CHAIN (attr))
     {
       tree arg;
+      /* As we implement alignas using gnu::aligned attribute and
+	 alignas argument is a constant expression, force manifestly
+	 constant evaluation of aligned attribute argument.  */
+      bool manifestly_const_eval
+	= is_attribute_p ("aligned", get_attribute_name (attr));
       for (arg = TREE_VALUE (attr); arg && TREE_CODE (arg) == TREE_LIST;
 	   arg = TREE_CHAIN (arg))
 	{
 	  tree expr = TREE_VALUE (arg);
 	  if (EXPR_P (expr))
-	    TREE_VALUE (arg) = fold_non_dependent_expr (expr);
+	    TREE_VALUE (arg)
+	      = fold_non_dependent_expr (expr, tf_warning_or_error,
+					 manifestly_const_eval);
 	}
     }
 }
@@ -1616,8 +1644,16 @@
 	  if (TREE_CODE (*iter) == OVERLOAD)
 	    continue;
 
-	  if (decls_match (decl, *iter, /*record_decls=*/false))
-	    return *iter;
+	  tree d = *iter;
+
+	  /* We can't compare versions in the middle of processing the
+	     attribute that has the version.  */
+	  if (TREE_CODE (d) == FUNCTION_DECL
+	      && DECL_FUNCTION_VERSIONED (d))
+	    return NULL_TREE;
+
+	  if (decls_match (decl, d, /*record_decls=*/false))
+	    return d;
 	}
       return NULL_TREE;
     }
diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc
index e76842e..1e944ca 100644
--- a/gcc/cp/error.cc
+++ b/gcc/cp/error.cc
@@ -2203,6 +2203,7 @@
     case WILDCARD_DECL:
     case OVERLOAD:
     case TYPE_DECL:
+    case USING_DECL:
     case IDENTIFIER_NODE:
       dump_decl (pp, t, ((flags & ~(TFF_DECL_SPECIFIERS|TFF_RETURN_TYPE
                                     |TFF_TEMPLATE_HEADER))
@@ -2584,6 +2585,13 @@
     case VIEW_CONVERT_EXPR:
       {
 	tree op = TREE_OPERAND (t, 0);
+
+	if (location_wrapper_p (t))
+	  {
+	    dump_expr (pp, op, flags);
+	    break;
+	  }
+
 	tree ttype = TREE_TYPE (t);
 	tree optype = TREE_TYPE (op);
 
diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc
index c20ed21..75ab965 100644
--- a/gcc/cp/init.cc
+++ b/gcc/cp/init.cc
@@ -1066,7 +1066,7 @@
       init = build2 (INIT_EXPR, type, decl, init);
       finish_expr_stmt (init);
       FOR_EACH_VEC_ELT (*cleanups, i, t)
-	push_cleanup (decl, t, false);
+	push_cleanup (NULL_TREE, t, false);
     }
   else if (type_build_ctor_call (type)
 	   || (init && CLASS_TYPE_P (strip_array_types (type))))
@@ -2811,6 +2811,11 @@
   if (!objsize)
     return;
 
+  /* We can only draw conclusions if ref.deref == -1,
+     i.e. oper is the address of the object.  */
+  if (ref.deref != -1)
+    return;
+
   offset_int bytes_avail = wi::to_offset (objsize);
   offset_int bytes_need;
 
@@ -3287,7 +3292,7 @@
     {
       unsigned align = TYPE_ALIGN_UNIT (elt_type);
       /* Also consider the alignment of the cookie, if any.  */
-      if (TYPE_VEC_NEW_USES_COOKIE (elt_type))
+      if (array_p && TYPE_VEC_NEW_USES_COOKIE (elt_type))
 	align = MAX (align, TYPE_ALIGN_UNIT (size_type_node));
       align_arg = build_int_cst (align_type_node, align);
     }
diff --git a/gcc/cp/lambda.cc b/gcc/cp/lambda.cc
index 4cc3a47..65579ed 100644
--- a/gcc/cp/lambda.cc
+++ b/gcc/cp/lambda.cc
@@ -183,6 +183,24 @@
   return lambda;
 }
 
+/* True if EXPR is an expression whose type can be used directly in lambda
+   capture.  Not to be used for 'auto'.  */
+
+static bool
+type_deducible_expression_p (tree expr)
+{
+  if (!type_dependent_expression_p (expr))
+    return true;
+  if (BRACE_ENCLOSED_INITIALIZER_P (expr)
+      || TREE_CODE (expr) == EXPR_PACK_EXPANSION)
+    return false;
+  tree t = non_reference (TREE_TYPE (expr));
+  if (!t) return false;
+  while (TREE_CODE (t) == POINTER_TYPE)
+    t = TREE_TYPE (t);
+  return currently_open_class (t);
+}
+
 /* Returns the type to use for the FIELD_DECL corresponding to the
    capture of EXPR.  EXPLICIT_INIT_P indicates whether this is a
    C++14 init capture, and BY_REFERENCE_P indicates whether we're
@@ -211,7 +229,7 @@
       else
 	type = do_auto_deduction (type, expr, auto_node);
     }
-  else if (type_dependent_expression_p (expr))
+  else if (!type_deducible_expression_p (expr))
     {
       type = cxx_make_type (DECLTYPE_TYPE);
       DECLTYPE_TYPE_EXPR (type) = expr;
@@ -741,6 +759,7 @@
     {
       tree lambda_stack = NULL_TREE;
       tree init = NULL_TREE;
+      bool saw_complete = false;
 
       /* If we are in a lambda function, we can move out until we hit:
            1. a non-lambda function or NSDMI,
@@ -759,6 +778,11 @@
 				      lambda_stack);
 
 	  tree closure = LAMBDA_EXPR_CLOSURE (tlambda);
+	  if (COMPLETE_TYPE_P (closure))
+	    /* We're instantiating a generic lambda op(), the containing
+	       scope may be gone.  */
+	    saw_complete = true;
+
 	  tree containing_function
 	    = decl_function_context (TYPE_NAME (closure));
 
@@ -768,7 +792,7 @@
 	      /* Lambda in an NSDMI.  We don't have a function to look up
 		 'this' in, but we can find (or rebuild) the fake one from
 		 inject_this_parameter.  */
-	      if (!containing_function && !COMPLETE_TYPE_P (closure))
+	      if (!containing_function && !saw_complete)
 		/* If we're parsing a lambda in a non-local class,
 		   we can find the fake 'this' in scope_chain.  */
 		init = scope_chain->x_current_class_ptr;
diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc
index d16c577..7b0638d 100644
--- a/gcc/cp/name-lookup.cc
+++ b/gcc/cp/name-lookup.cc
@@ -429,7 +429,7 @@
 {
 public:
   typedef std::pair<tree, tree> using_pair;
-  typedef vec<using_pair, va_heap, vl_embed> using_queue;
+  typedef auto_vec<using_pair, 16> using_queue;
 
 public:
   tree name;	/* The identifier being looked for.  */
@@ -528,16 +528,8 @@
   bool search_usings (tree scope);
 
 private:
-  using_queue *queue_namespace (using_queue *queue, int depth, tree scope);
-  using_queue *do_queue_usings (using_queue *queue, int depth,
-				vec<tree, va_gc> *usings);
-  using_queue *queue_usings (using_queue *queue, int depth,
-			     vec<tree, va_gc> *usings)
-  {
-    if (usings)
-      queue = do_queue_usings (queue, depth, usings);
-    return queue;
-  }
+  void queue_namespace (using_queue& queue, int depth, tree scope);
+  void queue_usings (using_queue& queue, int depth, vec<tree, va_gc> *usings);
 
 private:
   void add_fns (tree);
@@ -1084,39 +1076,35 @@
 /* Add SCOPE to the unqualified search queue, recursively add its
    inlines and those via using directives.  */
 
-name_lookup::using_queue *
-name_lookup::queue_namespace (using_queue *queue, int depth, tree scope)
+void
+name_lookup::queue_namespace (using_queue& queue, int depth, tree scope)
 {
   if (see_and_mark (scope))
-    return queue;
+    return;
 
   /* Record it.  */
   tree common = scope;
   while (SCOPE_DEPTH (common) > depth)
     common = CP_DECL_CONTEXT (common);
-  vec_safe_push (queue, using_pair (common, scope));
+  queue.safe_push (using_pair (common, scope));
 
   /* Queue its inline children.  */
   if (vec<tree, va_gc> *inlinees = DECL_NAMESPACE_INLINEES (scope))
     for (unsigned ix = inlinees->length (); ix--;)
-      queue = queue_namespace (queue, depth, (*inlinees)[ix]);
+      queue_namespace (queue, depth, (*inlinees)[ix]);
 
   /* Queue its using targets.  */
-  queue = queue_usings (queue, depth, NAMESPACE_LEVEL (scope)->using_directives);
-
-  return queue;
+  queue_usings (queue, depth, NAMESPACE_LEVEL (scope)->using_directives);
 }
 
 /* Add the namespaces in USINGS to the unqualified search queue.  */
 
-name_lookup::using_queue *
-name_lookup::do_queue_usings (using_queue *queue, int depth,
-			      vec<tree, va_gc> *usings)
+void
+name_lookup::queue_usings (using_queue& queue, int depth, vec<tree, va_gc> *usings)
 {
-  for (unsigned ix = usings->length (); ix--;)
-    queue = queue_namespace (queue, depth, (*usings)[ix]);
-
-  return queue;
+  if (usings)
+    for (unsigned ix = usings->length (); ix--;)
+      queue_namespace (queue, depth, (*usings)[ix]);
 }
 
 /* Unqualified namespace lookup in SCOPE.
@@ -1128,15 +1116,12 @@
 bool
 name_lookup::search_unqualified (tree scope, cp_binding_level *level)
 {
-  /* Make static to avoid continual reallocation.  We're not
-     recursive.  */
-  static using_queue *queue = NULL;
+  using_queue queue;
   bool found = false;
-  int length = vec_safe_length (queue);
 
   /* Queue local using-directives.  */
   for (; level->kind != sk_namespace; level = level->level_chain)
-    queue = queue_usings (queue, SCOPE_DEPTH (scope), level->using_directives);
+    queue_usings (queue, SCOPE_DEPTH (scope), level->using_directives);
 
   for (; !found; scope = CP_DECL_CONTEXT (scope))
     {
@@ -1144,19 +1129,19 @@
       int depth = SCOPE_DEPTH (scope);
 
       /* Queue namespaces reachable from SCOPE. */
-      queue = queue_namespace (queue, depth, scope);
+      queue_namespace (queue, depth, scope);
 
       /* Search every queued namespace where SCOPE is the common
 	 ancestor.  Adjust the others.  */
-      unsigned ix = length;
+      unsigned ix = 0;
       do
 	{
-	  using_pair &pair = (*queue)[ix];
+	  using_pair &pair = queue[ix];
 	  while (pair.first == scope)
 	    {
 	      found |= search_namespace_only (pair.second);
-	      pair = queue->pop ();
-	      if (ix == queue->length ())
+	      pair = queue.pop ();
+	      if (ix == queue.length ())
 		goto done;
 	    }
 	  /* The depth is the same as SCOPE, find the parent scope.  */
@@ -1164,7 +1149,7 @@
 	    pair.first = CP_DECL_CONTEXT (pair.first);
 	  ix++;
 	}
-      while (ix < queue->length ());
+      while (ix < queue.length ());
     done:;
       if (scope == global_namespace)
 	break;
@@ -1181,9 +1166,6 @@
 
   dedup (false);
 
-  /* Restore to incoming length.  */
-  vec_safe_truncate (queue, length);
-
   return found;
 }
 
@@ -5916,6 +5898,7 @@
 
   tree found = NULL_TREE;
   bool hidden_p = false;
+  bool saw_template = false;
 
   for (lkp_iterator iter (old); iter; ++iter)
     {
@@ -5940,6 +5923,20 @@
 	  found = ofn;
 	  hidden_p = iter.hidden_p ();
 	}
+      else if (TREE_CODE (decl) == FUNCTION_DECL
+	       && TREE_CODE (ofn) == TEMPLATE_DECL)
+	saw_template = true;
+    }
+
+  if (!found && friendp && saw_template)
+    {
+      /* "[if no non-template match is found,] each remaining function template
+	 is replaced with the specialization chosen by deduction from the
+	 friend declaration or discarded if deduction fails."
+
+	 So tell check_explicit_specialization to look for a match.  */
+      SET_DECL_IMPLICIT_INSTANTIATION (decl);
+      return;
     }
 
   if (found)
@@ -8979,4 +8976,22 @@
     }
 }
 
+/* True if D is a local declaration in dependent scope.  Assumes that it is
+   (part of) the current lookup result for its name.  */
+
+bool
+dependent_local_decl_p (tree d)
+{
+  if (!DECL_LOCAL_DECL_P (d))
+    return false;
+
+  cxx_binding *b = IDENTIFIER_BINDING (DECL_NAME (d));
+  cp_binding_level *l = b->scope;
+  while (!l->this_entity)
+    l = l->level_chain;
+  return uses_template_parms (l->this_entity);
+}
+
+
+
 #include "gt-cp-name-lookup.h"
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index bfd16e1..2235da1 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -20041,7 +20041,16 @@
   /* In a template parameter list, a type-parameter can be introduced
      by type-constraints alone.  */
   if (processing_template_parmlist && !placeholder)
-    return build_constrained_parameter (con, proto, args);
+    {
+      /* In a default argument we may not be creating new parameters.  */
+      if (parser->local_variables_forbidden_p & LOCAL_VARS_FORBIDDEN)
+	{
+	  /* If this assert turns out to be false, do error() instead.  */
+	  gcc_assert (tentative);
+	  return error_mark_node;
+	}
+      return build_constrained_parameter (con, proto, args);
+    }
 
   /* Diagnose issues placeholder issues.  */
   if (!flag_concepts_ts
@@ -25924,6 +25933,7 @@
       case CPP_OPEN_PAREN:
       case CPP_CLOSE_PAREN:
       case CPP_COMMA:
+      case CPP_SCOPE:
         want_semicolon = false;
         break;
 
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 63794a4..e785c5d 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -2863,7 +2863,9 @@
 	  specialization = 1;
 	  SET_DECL_TEMPLATE_SPECIALIZATION (decl);
 	}
-      else if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR)
+      else if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR
+	       || (DECL_LANG_SPECIFIC (decl)
+		   && DECL_IMPLICIT_INSTANTIATION (decl)))
 	{
 	  if (is_friend)
 	    /* This could be something like:
@@ -4339,7 +4341,9 @@
 	 parameter_packs = TREE_CHAIN (parameter_packs))
       {
 	tree pack = TREE_VALUE (parameter_packs);
-	if (is_capture_proxy (pack))
+	if (is_capture_proxy (pack)
+	    || (TREE_CODE (pack) == PARM_DECL
+		&& DECL_CONTEXT (DECL_CONTEXT (pack)) == lam))
 	  break;
       }
 
@@ -5225,8 +5229,9 @@
 	   && !get_partial_spec_bindings (maintmpl, maintmpl, specargs))
     {
       auto_diagnostic_group d;
-      if (permerror (input_location, "partial specialization %qD is not "
-		     "more specialized than", decl))
+      if (pedwarn (input_location, 0,
+		   "partial specialization %qD is not more specialized than",
+		   decl))
 	inform (DECL_SOURCE_LOCATION (maintmpl), "primary template %qD",
 		maintmpl);
     }
@@ -10900,7 +10905,7 @@
 		   || uses_template_parms (TREE_CHAIN (t)));
   else if (TREE_CODE (t) == TYPE_DECL)
     dependent_p = dependent_type_p (TREE_TYPE (t));
-  else if (t == error_mark_node)
+  else if (t == error_mark_node || TREE_CODE (t) == NAMESPACE_DECL)
     dependent_p = false;
   else
     dependent_p = instantiation_dependent_expression_p (t);
@@ -12677,7 +12682,13 @@
     t = tsubst_expr (pattern, args, complain, in_decl,
 		     /*integral_constant_expression_p=*/false);
   else
-    t = tsubst (pattern, args, complain, in_decl);
+    {
+      t = tsubst (pattern, args, complain, in_decl);
+      if (is_auto (t) && !ith_elem_is_expansion)
+	/* When expanding the fake auto... pack expansion from add_capture, we
+	   need to mark that the expansion is no longer a pack.  */
+	TEMPLATE_TYPE_PARAMETER_PACK (t) = false;
+    }
 
   /*  If the Ith argument pack element is a pack expansion, then
       the Ith element resulting from the substituting is going to
@@ -13046,7 +13057,7 @@
 {
   /* Make a copy of the extra arguments so that they won't get changed
      out from under us.  */
-  tree extra = copy_template_args (args);
+  tree extra = preserve_args (copy_template_args (args), /*cow_p=*/false);
   if (local_specializations)
     if (tree locals = extract_local_specs (pattern, complain))
       extra = tree_cons (NULL_TREE, extra, locals);
@@ -15082,6 +15093,12 @@
 	  {
 	    DECL_ORIGINAL_TYPE (r) = NULL_TREE;
 	    set_underlying_type (r);
+
+	    /* common_handle_aligned_attribute doesn't apply the alignment
+	       to DECL_ORIGINAL_TYPE.  */
+	    if (TYPE_USER_ALIGN (TREE_TYPE (t)))
+	      TREE_TYPE (r) = build_aligned_type (TREE_TYPE (r),
+						  TYPE_ALIGN (TREE_TYPE (t)));
 	  }
 
 	layout_decl (r, 0);
@@ -15180,7 +15197,9 @@
   /* Except that we do substitute default arguments under tsubst_lambda_expr,
      since the new op() won't have any associated template arguments for us
      to refer to later.  */
-  if (lambda_fn_in_template_p (in_decl))
+  if (lambda_fn_in_template_p (in_decl)
+      || (in_decl && TREE_CODE (in_decl) == FUNCTION_DECL
+	  && DECL_LOCAL_DECL_P (in_decl)))
     default_arg = tsubst_copy_and_build (default_arg, args, complain, in_decl,
 					 false/*fn*/, false/*constexpr*/);
 
@@ -16468,7 +16487,8 @@
 
   tree binfo_type = BINFO_TYPE (BASELINK_BINFO (baselink));
   binfo_type = tsubst (binfo_type, args, complain, in_decl);
-  bool dependent_p = binfo_type != BINFO_TYPE (BASELINK_BINFO (baselink));
+  bool dependent_p = (binfo_type != BINFO_TYPE (BASELINK_BINFO (baselink))
+		      || optype != BASELINK_OPTYPE (baselink));
 
   if (dependent_p)
     {
@@ -24288,7 +24308,7 @@
 	      /* Now check whether the type of this parameter is still
 		 dependent, and give up if so.  */
 	      ++processing_template_decl;
-	      tparm = tsubst (tparm, targs, tf_none, NULL_TREE);
+	      tparm = tsubst (TREE_TYPE (parm), targs, tf_none, NULL_TREE);
 	      --processing_template_decl;
 	      if (uses_template_parms (tparm))
 		return unify_success (explain_p);
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index a7f6449..ab48f11 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -609,7 +609,17 @@
 {
   if (TREE_CODE (stmts) == CLEANUP_STMT)
     {
-      protected_set_expr_location (CLEANUP_EXPR (stmts), loc);
+      tree t = CLEANUP_EXPR (stmts);
+      protected_set_expr_location (t, loc);
+      /* Avoid locus differences for C++ cdtor calls depending on whether
+	 cdtor_returns_this: a conversion to void is added to discard the return
+	 value, and this conversion ends up carrying the location, and when it
+	 gets discarded, the location is lost.  So hold it in the call as
+	 well.  */
+      if (TREE_CODE (t) == NOP_EXPR
+	  && TREE_TYPE (t) == void_type_node
+	  && TREE_CODE (TREE_OPERAND (t, 0)) == CALL_EXPR)
+	protected_set_expr_location (TREE_OPERAND (t, 0), loc);
       set_cleanup_locs (CLEANUP_BODY (stmts), loc);
     }
   else if (TREE_CODE (stmts) == STATEMENT_LIST)
@@ -656,7 +666,8 @@
 
 /* Queue a cleanup.  CLEANUP is an expression/statement to be executed
    when the current scope is exited.  EH_ONLY is true when this is not
-   meant to apply to normal control flow transfer.  */
+   meant to apply to normal control flow transfer.  DECL is the VAR_DECL
+   being cleaned up, if any, or null for temporaries or subobjects.  */
 
 void
 push_cleanup (tree decl, tree cleanup, bool eh_only)
@@ -2679,13 +2690,13 @@
 
   if (processing_template_decl)
     {
-      /* If FN is a local extern declaration or set thereof, look them up
-	 again at instantiation time.  */
+      /* If FN is a local extern declaration (or set thereof) in a template,
+	 look it up again at instantiation time.  */
       if (is_overloaded_fn (fn))
 	{
 	  tree ifn = get_first_fn (fn);
 	  if (TREE_CODE (ifn) == FUNCTION_DECL
-	      && DECL_LOCAL_DECL_P (ifn))
+	      && dependent_local_decl_p (ifn))
 	    orig_fn = DECL_NAME (ifn);
 	}
 
@@ -11241,7 +11252,7 @@
     }
   else if (processing_template_decl)
     {
-      expr = instantiate_non_dependent_expr_sfinae (expr, complain);
+      expr = instantiate_non_dependent_expr_sfinae (expr, complain|tf_decltype);
       if (expr == error_mark_node)
 	return error_mark_node;
       /* Keep processing_template_decl cleared for the rest of the function
diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
index 780a8d8..ed0d0d2 100644
--- a/gcc/cp/tree.cc
+++ b/gcc/cp/tree.cc
@@ -740,7 +740,7 @@
    constructor calls until gimplification time; now we only do it to set
    VEC_INIT_EXPR_IS_CONSTEXPR.
 
-   We assume that init is either NULL_TREE, void_type_node (indicating
+   We assume that init is either NULL_TREE, {}, void_type_node (indicating
    value-initialization), or another array to copy.  */
 
 static tree
@@ -752,7 +752,20 @@
       || !CLASS_TYPE_P (inner_type))
     /* No interesting initialization to do.  */
     return integer_zero_node;
-  else if (init == void_type_node)
+  if (init && BRACE_ENCLOSED_INITIALIZER_P (init))
+    {
+      /* Even if init has initializers for some array elements,
+	 we're interested in the {}-init of trailing elements.	*/
+      if (CP_AGGREGATE_TYPE_P (inner_type))
+	{
+	  tree empty = build_constructor (init_list_type_node, nullptr);
+	  return digest_init (inner_type, empty, complain);
+	}
+      else
+	/* It's equivalent to value-init.  */
+	init = void_type_node;
+    }
+  if (init == void_type_node)
     return build_value_init (inner_type, complain);
 
   releasing_vec argvec;
@@ -808,9 +821,13 @@
   TREE_SIDE_EFFECTS (init) = true;
   SET_EXPR_LOCATION (init, input_location);
 
-  if (cxx_dialect >= cxx11
-      && potential_constant_expression (elt_init))
-    VEC_INIT_EXPR_IS_CONSTEXPR (init) = true;
+  if (cxx_dialect >= cxx11)
+    {
+      bool cx = potential_constant_expression (elt_init);
+      if (BRACE_ENCLOSED_INITIALIZER_P (init))
+	cx &= potential_constant_expression (init);
+      VEC_INIT_EXPR_IS_CONSTEXPR (init) = cx;
+    }
   VEC_INIT_EXPR_VALUE_INIT (init) = value_init;
 
   return init;
@@ -1566,7 +1583,8 @@
    stripped.  */
 
 tree
-strip_typedefs (tree t, bool *remove_attributes, unsigned int flags)
+strip_typedefs (tree t, bool *remove_attributes /* = NULL */,
+		unsigned int flags /* = 0 */)
 {
   tree result = NULL, type = NULL, t0 = NULL;
 
diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index 26a7cb4..0da6f24 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -6315,7 +6315,9 @@
   if (processing_template_decl)
     {
       for (unsigned i = 0; i < args->length (); ++i)
-	if (type_dependent_expression_p ((*args)[i]))
+	if (i <= 1
+	    ? type_dependent_expression_p ((*args)[i])
+	    : instantiation_dependent_expression_p ((*args)[i]))
 	  {
 	    tree exp = build_min_nt_call_vec (NULL, args);
 	    CALL_EXPR_IFN (exp) = IFN_SHUFFLEVECTOR;
diff --git a/gcc/cp/typeck2.cc b/gcc/cp/typeck2.cc
index cebe6ac..63d95c1 100644
--- a/gcc/cp/typeck2.cc
+++ b/gcc/cp/typeck2.cc
@@ -922,6 +922,7 @@
      here it should have been digested into an actual value for the type.  */
   gcc_checking_assert (TREE_CODE (value) != CONSTRUCTOR
 		       || processing_template_decl
+		       || TREE_CODE (type) == VECTOR_TYPE
 		       || !TREE_HAS_CONSTRUCTOR (value));
 
   /* If the initializer is not a constant, fill in DECL_INITIAL with
@@ -1514,6 +1515,14 @@
 	      strip_array_types (TREE_TYPE (ce->value)))));
 
       picflags |= picflag_from_initializer (ce->value);
+      /* Propagate CONSTRUCTOR_PLACEHOLDER_BOUNDARY to outer
+	 CONSTRUCTOR.  */
+      if (TREE_CODE (ce->value) == CONSTRUCTOR
+	  && CONSTRUCTOR_PLACEHOLDER_BOUNDARY (ce->value))
+	{
+	  CONSTRUCTOR_PLACEHOLDER_BOUNDARY (init) = 1;
+	  CONSTRUCTOR_PLACEHOLDER_BOUNDARY (ce->value) = 0;
+	}
     }
 
   /* No more initializers. If the array is unbounded, we are done. Otherwise,
@@ -1559,6 +1568,14 @@
 	      }
 
 	    picflags |= picflag_from_initializer (next);
+	    /* Propagate CONSTRUCTOR_PLACEHOLDER_BOUNDARY to outer
+	       CONSTRUCTOR.  */
+	    if (TREE_CODE (next) == CONSTRUCTOR
+		&& CONSTRUCTOR_PLACEHOLDER_BOUNDARY (next))
+	      {
+		CONSTRUCTOR_PLACEHOLDER_BOUNDARY (init) = 1;
+		CONSTRUCTOR_PLACEHOLDER_BOUNDARY (next) = 0;
+	      }
 	    if (len > i+1)
 	      {
 		tree range = build2 (RANGE_EXPR, size_type_node,
@@ -1753,6 +1770,13 @@
       if (fldtype != TREE_TYPE (field))
 	next = cp_convert_and_check (TREE_TYPE (field), next, complain);
       picflags |= picflag_from_initializer (next);
+      /* Propagate CONSTRUCTOR_PLACEHOLDER_BOUNDARY to outer CONSTRUCTOR.  */
+      if (TREE_CODE (next) == CONSTRUCTOR
+	  && CONSTRUCTOR_PLACEHOLDER_BOUNDARY (next))
+	{
+	  CONSTRUCTOR_PLACEHOLDER_BOUNDARY (init) = 1;
+	  CONSTRUCTOR_PLACEHOLDER_BOUNDARY (next) = 0;
+	}
       CONSTRUCTOR_APPEND_ELT (v, field, next);
     }
 
@@ -1893,6 +1917,14 @@
     ce->value = massage_init_elt (TREE_TYPE (ce->index), ce->value, nested,
 				  flags, complain);
 
+  /* Propagate CONSTRUCTOR_PLACEHOLDER_BOUNDARY to outer CONSTRUCTOR.  */
+  if (ce->value
+      && TREE_CODE (ce->value) == CONSTRUCTOR
+      && CONSTRUCTOR_PLACEHOLDER_BOUNDARY (ce->value))
+    {
+      CONSTRUCTOR_PLACEHOLDER_BOUNDARY (init) = 1;
+      CONSTRUCTOR_PLACEHOLDER_BOUNDARY (ce->value) = 0;
+    }
   return picflag_from_initializer (ce->value);
 }
 
diff --git a/gcc/ctfc.cc b/gcc/ctfc.cc
index 6fe44d2..f24e7bf 100644
--- a/gcc/ctfc.cc
+++ b/gcc/ctfc.cc
@@ -179,6 +179,40 @@
   return NULL;
 }
 
+/* Insert a dummy CTF variable into the list of variables to be ignored.  */
+
+static void
+ctf_dvd_ignore_insert (ctf_container_ref ctfc, ctf_dvdef_ref dvd)
+{
+  bool existed = false;
+  ctf_dvdef_ref entry = dvd;
+
+  ctf_dvdef_ref * item = ctfc->ctfc_ignore_vars->find_slot (entry, INSERT);
+  if (*item == NULL)
+     *item = dvd;
+  else
+    existed = true;
+  /* Duplicate variable records not expected to be inserted.  */
+  gcc_assert (!existed);
+}
+
+/* Lookup the dummy CTF variable given the DWARF die for the non-defining
+   decl to be ignored.  */
+
+bool
+ctf_dvd_ignore_lookup (const ctf_container_ref ctfc, dw_die_ref die)
+{
+  ctf_dvdef_t entry;
+  entry.dvd_key = die;
+
+  ctf_dvdef_ref * slot = ctfc->ctfc_ignore_vars->find_slot (&entry, NO_INSERT);
+
+  if (slot)
+    return true;
+
+  return false;
+}
+
 /* Append member definition to the list.  Member list is a singly-linked list
    with list start pointing to the head.  */
 
@@ -666,9 +700,10 @@
 
 int
 ctf_add_variable (ctf_container_ref ctfc, const char * name, ctf_id_t ref,
-		  dw_die_ref die, unsigned int external_vis)
+		  dw_die_ref die, unsigned int external_vis,
+		  dw_die_ref die_var_decl)
 {
-  ctf_dvdef_ref dvd;
+  ctf_dvdef_ref dvd, dvd_ignore;
 
   gcc_assert (name);
 
@@ -680,6 +715,24 @@
       dvd->dvd_name = ctf_add_string (ctfc, name, &(dvd->dvd_name_offset));
       dvd->dvd_visibility = external_vis;
       dvd->dvd_type = ref;
+
+      /* If DW_AT_specification attribute exists, keep track of it as this is
+	 the non-defining declaration corresponding to the variable.  We will
+	 skip emitting CTF variable for such incomplete, non-defining
+	 declarations.
+	 There could be some non-defining declarations, however, for which a
+	 defining declaration does not show up in the same CU.  For such
+	 cases, the compiler continues to emit CTF variable record as
+	 usual.  */
+      if (die_var_decl)
+	{
+	  dvd_ignore = ggc_cleared_alloc<ctf_dvdef_t> ();
+	  dvd_ignore->dvd_key = die_var_decl;
+	  /* It's alright to leave other fields as zero.  No valid CTF
+	     variable will be added for these DW_TAG_variable DIEs.  */
+	  ctf_dvd_ignore_insert (ctfc, dvd_ignore);
+	}
+
       ctf_dvd_insert (ctfc, dvd);
 
       if (strcmp (name, ""))
@@ -900,6 +953,8 @@
     = hash_table<ctfc_dtd_hasher>::create_ggc (100);
   tu_ctfc->ctfc_vars
     = hash_table<ctfc_dvd_hasher>::create_ggc (100);
+  tu_ctfc->ctfc_ignore_vars
+    = hash_table<ctfc_dvd_hasher>::create_ggc (10);
 
   return tu_ctfc;
 }
@@ -952,6 +1007,9 @@
       ctfc->ctfc_vars->empty ();
       ctfc->ctfc_types = NULL;
 
+      ctfc->ctfc_ignore_vars->empty ();
+      ctfc->ctfc_ignore_vars = NULL;
+
       ctfc_delete_strtab (&ctfc->ctfc_strtable);
       ctfc_delete_strtab (&ctfc->ctfc_aux_strtable);
       if (ctfc->ctfc_vars_list)
diff --git a/gcc/ctfc.h b/gcc/ctfc.h
index 18c93c8..001e544 100644
--- a/gcc/ctfc.h
+++ b/gcc/ctfc.h
@@ -274,6 +274,8 @@
   hash_table <ctfc_dtd_hasher> * GTY (()) ctfc_types;
   /* CTF variables.  */
   hash_table <ctfc_dvd_hasher> * GTY (()) ctfc_vars;
+  /* CTF variables to be ignored.  */
+  hash_table <ctfc_dvd_hasher> * GTY (()) ctfc_ignore_vars;
 
   /* CTF string table.  */
   ctf_strtable_t ctfc_strtable;
@@ -301,6 +303,8 @@
   /* List of pre-processed CTF Variables.  CTF requires that the variables
      appear in the sorted order of their names.  */
   ctf_dvdef_t ** GTY ((length ("0"))) ctfc_vars_list;
+  /* Count of pre-processed CTF Variables in the list.  */
+  uint64_t ctfc_vars_list_count;
   /* List of pre-processed CTF types.  CTF requires that a shared type must
      appear before the type that uses it.  For the compiler, this means types
      are emitted in sorted order of their type IDs.  */
@@ -392,6 +396,8 @@
 				     dw_die_ref die);
 extern ctf_dvdef_ref ctf_dvd_lookup (const ctf_container_ref ctfc,
 				     dw_die_ref die);
+extern bool ctf_dvd_ignore_lookup (const ctf_container_ref ctfc,
+				   dw_die_ref die);
 
 extern const char * ctf_add_string (ctf_container_ref, const char *,
 				    uint32_t *, int);
@@ -428,7 +434,7 @@
 extern int ctf_add_function_arg (ctf_container_ref, dw_die_ref,
 				 const char *, ctf_id_t);
 extern int ctf_add_variable (ctf_container_ref, const char *, ctf_id_t,
-			     dw_die_ref, unsigned int);
+			     dw_die_ref, unsigned int, dw_die_ref);
 
 extern ctf_id_t ctf_lookup_tree_type (ctf_container_ref, const tree);
 extern ctf_id_t get_btf_id (ctf_id_t);
diff --git a/gcc/ctfout.cc b/gcc/ctfout.cc
index a23d377..3cf89b9 100644
--- a/gcc/ctfout.cc
+++ b/gcc/ctfout.cc
@@ -173,9 +173,7 @@
 static void
 ctf_list_add_ctf_vars (ctf_container_ref ctfc, ctf_dvdef_ref var)
 {
-  /* FIXME - static may not fly with multiple CUs.  */
-  static int num_vars_added = 0;
-  ctfc->ctfc_vars_list[num_vars_added++] = var;
+  ctfc->ctfc_vars_list[ctfc->ctfc_vars_list_count++] = var;
 }
 
 /* Initialize the various sections and labels for CTF output.  */
@@ -214,6 +212,13 @@
   ctf_dvdef_ref var = (ctf_dvdef_ref) *slot;
   ctf_container_ref arg_ctfc = dvd_arg->dvd_arg_ctfc;
 
+  /* If the CTF variable corresponds to an extern variable declaration with
+     a defining declaration later on, skip it.  Only CTF variable
+     corresponding to the defining declaration for the extern variable is
+     desirable.  */
+  if (ctf_dvd_ignore_lookup (arg_ctfc, var->dvd_key))
+    return 1;
+
   ctf_preprocess_var (arg_ctfc, var);
 
   /* Keep track of global objts.  */
@@ -278,16 +283,16 @@
 ctf_preprocess (ctf_container_ref ctfc)
 {
   size_t num_ctf_types = ctfc->ctfc_types->elements ();
+  size_t num_ctf_vars = ctfc_get_num_ctf_vars (ctfc);
 
   /* Initialize an array to keep track of the CTF variables at global
-     scope.  */
-  size_t num_global_objts = ctfc->ctfc_num_global_objts;
+     scope.  At this time, size it conservatively.  */
+  size_t num_global_objts = num_ctf_vars;
   if (num_global_objts)
     {
       ctfc->ctfc_gobjts_list = ggc_vec_alloc<ctf_dvdef_t*>(num_global_objts);
     }
 
-  size_t num_ctf_vars = ctfc_get_num_ctf_vars (ctfc);
   if (num_ctf_vars)
     {
       ctf_dvd_preprocess_arg_t dvd_arg;
@@ -301,8 +306,11 @@
 	 list for sorting.  */
       ctfc->ctfc_vars->traverse<void *, ctf_dvd_preprocess_cb> (&dvd_arg);
       /* Sort the list.  */
-      qsort (ctfc->ctfc_vars_list, num_ctf_vars, sizeof (ctf_dvdef_ref),
-	     ctf_varent_compare);
+      qsort (ctfc->ctfc_vars_list, ctfc->ctfc_vars_list_count,
+	     sizeof (ctf_dvdef_ref), ctf_varent_compare);
+      /* Update the actual number of the generated CTF variables at global
+	 scope.  */
+      ctfc->ctfc_num_global_objts = dvd_arg.dvd_global_obj_idx;
     }
 
   /* Initialize an array to keep track of the CTF functions types for global
@@ -478,7 +486,7 @@
       /* Vars appear after function index.  */
       varoff = funcidxoff + ctfc->ctfc_num_global_funcs * sizeof (uint32_t);
       /* CTF types appear after vars.  */
-      typeoff = varoff + ctfc_get_num_ctf_vars (ctfc) * sizeof (ctf_varent_t);
+      typeoff = varoff + (ctfc->ctfc_vars_list_count) * sizeof (ctf_varent_t);
       /* The total number of bytes for CTF types is the sum of the number of
 	 times struct ctf_type_t, struct ctf_stype_t are written, plus the
 	 amount of variable length data after each one of these.  */
@@ -597,7 +605,7 @@
 output_ctf_vars (ctf_container_ref ctfc)
 {
   size_t i;
-  size_t num_ctf_vars = ctfc_get_num_ctf_vars (ctfc);
+  unsigned int num_ctf_vars = ctfc->ctfc_vars_list_count;
   if (num_ctf_vars)
     {
       /* Iterate over the list of sorted vars and output the asm.  */
diff --git a/gcc/d/ChangeLog b/gcc/d/ChangeLog
index f1afaf2..bb179bc 100644
--- a/gcc/d/ChangeLog
+++ b/gcc/d/ChangeLog
@@ -1,3 +1,19 @@
+2022-04-21  Iain Buclaw  <ibuclaw@gdcproject.org>
+
+	* dmd/MERGE: Merge upstream dmd eb7bee331.
+	* dmd/VERSION: Update version to v2.100.0-beta.1.
+	* d-lang.cc (d_handle_option): Handle OPT_frevert_dip1000.
+	* lang.opt (frevert=dip1000): New option.
+
+2022-04-13  Iain Buclaw  <ibuclaw@gdcproject.org>
+
+	* Make-lang.in (D_FRONTEND_OBJS): Add d/common-bitfields.o,
+	d/mustuse.o.
+	* d-ctfloat.cc (CTFloat::isIdentical): Don't treat NaN values as
+	identical.
+	* dmd/MERGE: Merge upstream dmd 4d1bfcf14.
+	* expr.cc (ExprVisitor::visit (VoidInitExp *)): New.
+
 2022-04-03  Iain Buclaw  <ibuclaw@gdcproject.org>
 
 	* d-lang.cc: Include dmd/template.h.
diff --git a/gcc/d/Make-lang.in b/gcc/d/Make-lang.in
index 6c90657..f3e34c5 100644
--- a/gcc/d/Make-lang.in
+++ b/gcc/d/Make-lang.in
@@ -89,6 +89,7 @@
 	d/canthrow.o \
 	d/chkformat.o \
 	d/clone.o \
+	d/common-bitfields.o \
 	d/common-file.o \
 	d/common-outbuffer.o \
 	d/common-string.o \
@@ -143,6 +144,7 @@
 	d/lambdacomp.o \
 	d/lexer.o \
 	d/mtype.o \
+	d/mustuse.o \
 	d/nogc.o \
 	d/nspace.o \
 	d/ob.o \
diff --git a/gcc/d/d-ctfloat.cc b/gcc/d/d-ctfloat.cc
index 6e6d10f..c4d9a44 100644
--- a/gcc/d/d-ctfloat.cc
+++ b/gcc/d/d-ctfloat.cc
@@ -55,8 +55,7 @@
 {
   real_value rx = x.rv ();
   real_value ry = y.rv ();
-  return (REAL_VALUE_ISNAN (rx) && REAL_VALUE_ISNAN (ry))
-    || real_identical (&rx, &ry);
+  return real_identical (&rx, &ry);
 }
 
 /* Return true if real_t value R is NaN.  */
diff --git a/gcc/d/d-lang.cc b/gcc/d/d-lang.cc
index 6957162..9adcabd 100644
--- a/gcc/d/d-lang.cc
+++ b/gcc/d/d-lang.cc
@@ -637,12 +637,17 @@
       break;
 
     case OPT_frevert_all:
+      global.params.useDIP1000 = FeatureState::disabled;
       global.params.useDIP25 = FeatureState::disabled;
       global.params.dtorFields = FeatureState::disabled;
       global.params.fix16997 = !value;
       global.params.markdown = !value;
       break;
 
+    case OPT_frevert_dip1000:
+      global.params.useDIP1000 = FeatureState::disabled;
+      break;
+
     case OPT_frevert_dip25:
       global.params.useDIP25 = FeatureState::disabled;
       break;
diff --git a/gcc/d/d-port.cc b/gcc/d/d-port.cc
index a0e06b3..a908cc8 100644
--- a/gcc/d/d-port.cc
+++ b/gcc/d/d-port.cc
@@ -31,11 +31,11 @@
 /* Compare the first N bytes of S1 and S2 without regard to the case.  */
 
 int
-Port::memicmp (const char *s1, const char *s2, size_t n)
+Port::memicmp (const char *s1, const char *s2, d_size_t n)
 {
   int result = 0;
 
-  for (size_t i = 0; i < n; i++)
+  for (d_size_t i = 0; i < n; i++)
     {
       char c1 = s1[i];
       char c2 = s2[i];
@@ -143,9 +143,9 @@
 /* Write an SZ-byte sized VALUE to BUFFER, ignoring endian-ness.  */
 
 void
-Port::valcpy (void *buffer, uint64_t value, size_t sz)
+Port::valcpy (void *buffer, uint64_t value, d_size_t sz)
 {
-  gcc_assert (((size_t) buffer) % sz == 0);
+  gcc_assert (((d_size_t) buffer) % sz == 0);
 
   switch (sz)
     {
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index ca409df..d181191 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-47871363d804f54b29ccfd444b082c19716c2301
+313d28b3db7523e67880ae3baf8ef28ce9abe9bd
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/dmd repository.
diff --git a/gcc/d/dmd/README.md b/gcc/d/dmd/README.md
index f613ab2..b143103 100644
--- a/gcc/d/dmd/README.md
+++ b/gcc/d/dmd/README.md
@@ -130,6 +130,8 @@
 | [impcnvtab.d](https://github.com/dlang/dmd/blob/master/src/dmd/impcnvtab.d)   | Define an implicit conversion table for basic types                                        |
 | [importc.d](https://github.com/dlang/dmd/blob/master/src/dmd/importc.d)       | Helpers specific to ImportC                                                                |
 | [sideeffect.d](https://github.com/dlang/dmd/blob/master/src/dmd/sideeffect.d) | Extract side-effects of expressions for certain lowerings.                                 |
+| [mustuse.d](https://github.com/dlang/dmd/blob/master/src/dmd/mustuse.d)       | Helpers related to the `@mustuse` attribute                                                |
+
 
 **Compile Time Function Execution (CTFE)**
 
diff --git a/gcc/d/dmd/VERSION b/gcc/d/dmd/VERSION
index 16f49a7..2450fd5 100644
--- a/gcc/d/dmd/VERSION
+++ b/gcc/d/dmd/VERSION
@@ -1 +1 @@
-v2.099.1-beta.1
+v2.100.0-beta.1
diff --git a/gcc/d/dmd/aggregate.d b/gcc/d/dmd/aggregate.d
index 8895aa5..f4b5e8a 100644
--- a/gcc/d/dmd/aggregate.d
+++ b/gcc/d/dmd/aggregate.d
@@ -58,6 +58,28 @@
 }
 
 /**
+ * Give a nice string for a class kind for error messages
+ * Params:
+ *     c = class kind
+ * Returns:
+ *     0-terminated string for `c`
+ */
+const(char)* toChars(ClassKind c)
+{
+    final switch (c)
+    {
+        case ClassKind.d:
+            return "D";
+        case ClassKind.cpp:
+            return "C++";
+        case ClassKind.objc:
+            return "Objective-C";
+        case ClassKind.c:
+            return "C";
+    }
+}
+
+/**
  * If an aggregate has a pargma(mangle, ...) this holds the information
  * to mangle.
  */
diff --git a/gcc/d/dmd/arrayop.d b/gcc/d/dmd/arrayop.d
index 52f39d3..16cbe62 100644
--- a/gcc/d/dmd/arrayop.d
+++ b/gcc/d/dmd/arrayop.d
@@ -158,7 +158,7 @@
 /// ditto
 Expression arrayOp(BinAssignExp e, Scope* sc)
 {
-    //printf("BinAssignExp.arrayOp() %s\n", toChars());
+    //printf("BinAssignExp.arrayOp() %s\n", e.toChars());
 
     /* Check that the elements of e1 can be assigned to
      */
diff --git a/gcc/d/dmd/astenums.d b/gcc/d/dmd/astenums.d
index 1a2cf8b..bf19693 100644
--- a/gcc/d/dmd/astenums.d
+++ b/gcc/d/dmd/astenums.d
@@ -28,6 +28,7 @@
 
 enum MODFlags : int
 {
+    none         = 0,    // default (mutable)
     const_       = 1,    // type is const
     immutable_   = 4,    // type is immutable
     shared_      = 2,    // type is shared
diff --git a/gcc/d/dmd/attrib.d b/gcc/d/dmd/attrib.d
index 9c2bbd6..1e84b55 100644
--- a/gcc/d/dmd/attrib.d
+++ b/gcc/d/dmd/attrib.d
@@ -44,7 +44,6 @@
 import dmd.objc; // for objc.addSymbols
 import dmd.common.outbuffer;
 import dmd.root.array; // for each
-import dmd.target; // for target.systemLinkage
 import dmd.tokens;
 import dmd.visitor;
 
@@ -399,7 +398,7 @@
     {
         super(loc, null, decl);
         //printf("LinkDeclaration(linkage = %d, decl = %p)\n", linkage, decl);
-        this.linkage = (linkage == LINK.system) ? target.systemLinkage() : linkage;
+        this.linkage = linkage;
     }
 
     static LinkDeclaration create(const ref Loc loc, LINK p, Dsymbols* decl)
@@ -994,7 +993,7 @@
     // Decide if 'then' or 'else' code should be included
     override Dsymbols* include(Scope* sc)
     {
-        //printf("ConditionalDeclaration::include(sc = %p) scope = %p\n", sc, scope);
+        //printf("ConditionalDeclaration::include(sc = %p) scope = %p\n", sc, _scope);
 
         if (errors)
             return null;
@@ -1057,7 +1056,7 @@
      */
     override Dsymbols* include(Scope* sc)
     {
-        //printf("StaticIfDeclaration::include(sc = %p) scope = %p\n", sc, scope);
+        //printf("StaticIfDeclaration::include(sc = %p) scope = %p\n", sc, _scope);
 
         if (errors || onStack)
             return null;
@@ -1496,12 +1495,7 @@
         if (global.params.cplusplus < CppStdRevision.cpp11)
             return;
 
-        // Avoid `if` at the call site
-        if (sym.userAttribDecl is null || sym.userAttribDecl.atts is null)
-            return;
-
-        foreach (exp; *sym.userAttribDecl.atts)
-        {
+        foreachUdaNoSemantic(sym, (exp) {
             if (isGNUABITag(exp))
             {
                 if (sym.isCPPNamespaceDeclaration() || sym.isNspace())
@@ -1515,9 +1509,10 @@
                     sym.errors = true;
                 }
                 // Only one `@gnuAbiTag` is allowed by semantic2
-                return;
+                return 1; // break
             }
-        }
+            return 0; // continue
+        });
     }
 }
 
@@ -1544,14 +1539,14 @@
 /**
  * Iterates the UDAs attached to the given symbol.
  *
- * If `dg` returns `!= 0`, it will stop the iteration and return that
- * value, otherwise it will return 0.
- *
  * Params:
  *  sym = the symbol to get the UDAs from
  *  sc = scope to use for semantic analysis of UDAs
- *  dg = called once for each UDA. If `dg` returns `!= 0`, it will stop the
- *      iteration and return that value, otherwise it will return `0`.
+ *  dg = called once for each UDA
+ *
+ * Returns:
+ *  If `dg` returns `!= 0`, stops the iteration and returns that value.
+ *  Otherwise, returns 0.
  */
 int foreachUda(Dsymbol sym, Scope* sc, int delegate(Expression) dg)
 {
@@ -1577,3 +1572,32 @@
         });
     });
 }
+
+/**
+ * Iterates the UDAs attached to the given symbol, without performing semantic
+ * analysis.
+ *
+ * Use this function instead of `foreachUda` if semantic analysis of `sym` is
+ * still in progress.
+ *
+ * Params:
+ *  sym = the symbol to get the UDAs from
+ *  dg = called once for each UDA
+ *
+ * Returns:
+ *  If `dg` returns `!= 0`, stops the iteration and returns that value.
+ *  Otherwise, returns 0.
+ */
+int foreachUdaNoSemantic(Dsymbol sym, int delegate(Expression) dg)
+{
+    if (sym.userAttribDecl is null || sym.userAttribDecl.atts is null)
+        return 0;
+
+    foreach (exp; *sym.userAttribDecl.atts)
+    {
+        if (auto result = dg(exp))
+            return result;
+    }
+
+    return 0;
+}
diff --git a/gcc/d/dmd/blockexit.d b/gcc/d/dmd/blockexit.d
index afd7ac0..22c9dde 100644
--- a/gcc/d/dmd/blockexit.d
+++ b/gcc/d/dmd/blockexit.d
@@ -139,16 +139,21 @@
                             // Allow if last case/default was empty
                             CaseStatement sc = slast.isCaseStatement();
                             DefaultStatement sd = slast.isDefaultStatement();
-                            if (sc && (!sc.statement.hasCode() || sc.statement.isCaseStatement() || sc.statement.isErrorStatement()))
-                            {
-                            }
-                            else if (sd && (!sd.statement.hasCode() || sd.statement.isCaseStatement() || sd.statement.isErrorStatement()))
+                            auto sl = (sc ? sc.statement : (sd ? sd.statement : null));
+
+                            if (sl && (!sl.hasCode() || sl.isErrorStatement()))
                             {
                             }
                             else if (func.getModule().filetype != FileType.c)
                             {
                                 const(char)* gototype = s.isCaseStatement() ? "case" : "default";
-                                s.error("switch case fallthrough - use 'goto %s;' if intended", gototype);
+                                // @@@DEPRECATED_2.110@@@ https://issues.dlang.org/show_bug.cgi?id=22999
+                                // Deprecated in 2.100
+                                // Make an error in 2.110
+                                if (sl && sl.isCaseStatement())
+                                    s.deprecation("switch case fallthrough - use 'goto %s;' if intended", gototype);
+                                else
+                                    s.error("switch case fallthrough - use 'goto %s;' if intended", gototype);
                             }
                         }
                     }
diff --git a/gcc/d/dmd/clone.d b/gcc/d/dmd/clone.d
index 2ed0dc7..9c8c1c3 100644
--- a/gcc/d/dmd/clone.d
+++ b/gcc/d/dmd/clone.d
@@ -912,8 +912,8 @@
                 ex = new DotVarExp(loc, ex, v);
 
                 // This is a hack so we can call destructors on const/immutable objects.
-                // Do it as a type 'paint'.
-                ex = new CastExp(loc, ex, v.type.mutableOf());
+                // Do it as a type 'paint', `cast()`
+                ex = new CastExp(loc, ex, MODFlags.none);
                 if (stc & STC.safe)
                     stc = (stc & ~STC.safe) | STC.trusted;
 
@@ -1588,7 +1588,7 @@
 
         auto tf = ctorDecl.type.toTypeFunction();
         const dim = tf.parameterList.length;
-        if (dim == 1)
+        if (dim == 1 || (dim > 1 && tf.parameterList[1].defaultArg))
         {
             auto param = tf.parameterList[0];
             if (param.type.mutableOf().unSharedOf() == sd.type.mutableOf().unSharedOf())
diff --git a/gcc/d/dmd/common/README.md b/gcc/d/dmd/common/README.md
index a9b65c3..fb282dc 100644
--- a/gcc/d/dmd/common/README.md
+++ b/gcc/d/dmd/common/README.md
@@ -2,6 +2,7 @@
 
 | File                                                                               | Purpose                                                         |
 |------------------------------------------------------------------------------------|-----------------------------------------------------------------|
+| [bitfields.d](https://github.com/dlang/dmd/blob/master/src/dmd/common/bitfields.d) | Pack multiple boolean fields into bit fields                    |
 | [file.d](https://github.com/dlang/dmd/blob/master/src/dmd/common/file.d)           | Functions and objects dedicated to file I/O and management      |
 | [outbuffer.d](https://github.com/dlang/dmd/blob/master/src/dmd/common/outbuffer.d) | An expandable buffer in which you can write text or binary data |
 | [string.d](https://github.com/dlang/dmd/blob/master/src/dmd/common/string.d)       | Common string functions including filename manipulation         |
diff --git a/gcc/d/dmd/common/bitfields.d b/gcc/d/dmd/common/bitfields.d
new file mode 100644
index 0000000..d17983d
--- /dev/null
+++ b/gcc/d/dmd/common/bitfields.d
@@ -0,0 +1,70 @@
+/**
+ * A library bitfields utility
+ *
+ * Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
+ * Authors:   Dennis Korpel
+ * License:   $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
+ * Source:    $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/common/bitfields.d, common/bitfields.d)
+ * Documentation: https://dlang.org/phobos/dmd_common_bitfields.html
+ * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/common/bitfields.d
+ */
+module dmd.common.bitfields;
+
+/**
+ * Generate code for bit fields inside a struct/class body
+ * Params:
+ *   S = type of a struct with only boolean fields, which should become bit fields
+ *   T = type of bit fields variable, must have enough bits to store all booleans
+ * Returns: D code with a bit fields variable and getter / setter functions
+ */
+extern (D) string generateBitFields(S, T)()
+if (__traits(isUnsigned, T))
+{
+    string result = "extern (C++) pure nothrow @nogc @safe final {";
+    enum structName = __traits(identifier, S);
+
+    foreach (size_t i, mem; __traits(allMembers, S))
+    {
+        static assert(is(typeof(__traits(getMember, S, mem)) == bool));
+        static assert(i < T.sizeof * 8, "too many fields for bit field storage of type `"~T.stringof~"`");
+        enum mask = "(1 << "~i.stringof~")";
+        result ~= "
+        /// set or get the corresponding "~structName~" member
+        bool "~mem~"() const { return !!(bitFields & "~mask~"); }
+        /// ditto
+        bool "~mem~"(bool v)
+        {
+            v ? (bitFields |= "~mask~") : (bitFields &= ~"~mask~");
+            return v;
+        }";
+    }
+    return result ~ "}\n private "~T.stringof~" bitFields;\n";
+}
+
+///
+unittest
+{
+    static struct B
+    {
+        bool x;
+        bool y;
+        bool z;
+    }
+
+    static struct S
+    {
+        mixin(generateBitFields!(B, ubyte));
+    }
+
+    S s;
+    assert(!s.x);
+    s.x = true;
+    assert(s.x);
+    s.x = false;
+    assert(!s.x);
+
+    s.y = true;
+    assert(s.y);
+    assert(!s.x);
+    assert(!s.z);
+}
diff --git a/gcc/d/dmd/common/file.d b/gcc/d/dmd/common/file.d
index e4483d5..8f34b53 100644
--- a/gcc/d/dmd/common/file.d
+++ b/gcc/d/dmd/common/file.d
@@ -25,6 +25,8 @@
 
 import dmd.common.string;
 
+nothrow:
+
 /**
 Encapsulated management of a memory-mapped file.
 
@@ -52,6 +54,8 @@
     private const(char)* name;
     // state }
 
+  nothrow:
+
     /**
     Open `filename` and map it in memory. If `Datum` is `const`, opens for
     read-only and maps the content in memory; no error is issued if the file
diff --git a/gcc/d/dmd/common/outbuffer.d b/gcc/d/dmd/common/outbuffer.d
index 0705c18..7e46d29 100644
--- a/gcc/d/dmd/common/outbuffer.d
+++ b/gcc/d/dmd/common/outbuffer.d
@@ -16,6 +16,8 @@
 import core.stdc.string;
 import core.stdc.stdlib;
 
+nothrow:
+
 // In theory these functions should also restore errno, but we don't care because
 // we abort application on error anyway.
 extern (C) private pure @system @nogc nothrow
@@ -54,6 +56,8 @@
     int level;
     // state }
 
+  nothrow:
+
     /**
     Construct given size.
     */
diff --git a/gcc/d/dmd/common/string.d b/gcc/d/dmd/common/string.d
index d3bc24f..48bf9bb 100644
--- a/gcc/d/dmd/common/string.d
+++ b/gcc/d/dmd/common/string.d
@@ -10,6 +10,8 @@
  */
 module dmd.common.string;
 
+nothrow:
+
 /**
 Defines a temporary array using a fixed-length buffer as back store. If the length
 of the buffer suffices, it is readily used. Otherwise, `malloc` is used to
@@ -26,6 +28,8 @@
     private T[] _extent;
     private bool needsFree;
 
+  nothrow:
+
     @disable this(); // no default ctor
     @disable this(ref const SmallBuffer!T); // noncopyable, nonassignable
 
diff --git a/gcc/d/dmd/constfold.d b/gcc/d/dmd/constfold.d
index 75ba9ea..bf66408 100644
--- a/gcc/d/dmd/constfold.d
+++ b/gcc/d/dmd/constfold.d
@@ -936,7 +936,7 @@
     {
         if (e1.type.isreal())
         {
-            cmp = RealIdentical(e1.toReal(), e2.toReal());
+            cmp = CTFloat.isIdentical(e1.toReal(), e2.toReal());
         }
         else if (e1.type.isimaginary())
         {
diff --git a/gcc/d/dmd/cparse.d b/gcc/d/dmd/cparse.d
index bb12aa7..2b2046f 100644
--- a/gcc/d/dmd/cparse.d
+++ b/gcc/d/dmd/cparse.d
@@ -213,16 +213,12 @@
                     goto Lexp;
 
                 case TOK.leftParenthesis:
-                {
-                    /* If tokens look like a function call, assume it is one,
-                     * As any type-name won't be resolved until semantic, this
-                     * could be rewritten later.
-                     */
-                    auto tk = &token;
-                    if (isFunctionCall(tk))
-                        goto Lexp;
-                    goto default;
-                }
+                    if (auto pt = lookupTypedef(token.ident))
+                    {
+                        if (*pt)
+                            goto Ldeclaration;
+                    }
+                    goto Lexp;  // function call
 
                 default:
                 {
@@ -259,6 +255,7 @@
         case TOK.plusPlus:
         case TOK.minusMinus:
         case TOK.sizeof_:
+        case TOK._Generic:
         Lexp:
             auto exp = cparseExpression();
             if (token.value == TOK.identifier && exp.op == EXP.identifier)
@@ -1625,10 +1622,21 @@
          */
         if (token.value == TOK.semicolon)
         {
-            nextToken();
             if (!tspec)
+            {
+                nextToken();
                 return;         // accept empty declaration as an extension
+            }
 
+            if (auto ti = tspec.isTypeIdentifier())
+            {
+                // C11 6.7.2-2
+                error("type-specifier missing for declaration of `%s`", ti.ident.toChars());
+                nextToken();
+                return;
+            }
+
+            nextToken();
             auto tt = tspec.isTypeTag();
             if (!tt ||
                 !tt.id && (tt.tok == TOK.struct_ || tt.tok == TOK.union_))
@@ -1660,6 +1668,22 @@
             specifier.mod &= ~MOD.xnone;          // 'used' it
         }
 
+        void scanPastSemicolon()
+        {
+            while (token.value != TOK.semicolon && token.value != TOK.endOfFile)
+                nextToken();
+            nextToken();
+        }
+
+        if (token.value == TOK.assign && tspec && tspec.isTypeIdentifier())
+        {
+            /* C11 6.7.2-2
+             * Special check for `const b = 1;` because some compilers allow it
+             */
+            error("type-specifier omitted for declaration of `%s`", tspec.isTypeIdentifier().ident.toChars());
+            return scanPastSemicolon();
+        }
+
         bool first = true;
         while (1)
         {
@@ -1879,10 +1903,7 @@
                 default:
                     error("`=`, `;` or `,` expected to end declaration instead of `%s`", token.toChars());
                 Lend:
-                    while (token.value != TOK.semicolon && token.value != TOK.endOfFile)
-                        nextToken();
-                    nextToken();
-                    return;
+                    return scanPastSemicolon();
             }
         }
     }
@@ -2399,15 +2420,13 @@
                 if (idx.length > 2 && idx[0] == '_' && idx[1] == '_')  // leading double underscore
                     importBuiltins = true;  // probably one of those compiler extensions
                 t = null;
-                if (scw & SCW.xtypedef)
-                {
-                    /* Punch through to what the typedef is, to support things like:
-                     *  typedef T* T;
-                     */
-                    auto pt = lookupTypedef(previd);
-                    if (pt && *pt)      // if previd is a known typedef
-                        t = *pt;
-                }
+
+                /* Punch through to what the typedef is, to support things like:
+                 *  typedef T* T;
+                 */
+                auto pt = lookupTypedef(previd);
+                if (pt && *pt)      // if previd is a known typedef
+                    t = *pt;
 
                 if (!t)
                     t = new AST.TypeIdentifier(loc, previd);
@@ -2529,7 +2548,14 @@
                 default:
                     if (declarator == DTR.xdirect)
                     {
-                        error("identifier or `(` expected"); // )
+                        if (!t || t.isTypeIdentifier())
+                        {
+                            // const arr[1];
+                            error("no type-specifier for declarator");
+                            t = AST.Type.tint32;
+                        }
+                        else
+                            error("identifier or `(` expected"); // )
                         panic();
                     }
                     ts = t;
@@ -2745,6 +2771,16 @@
         Specifier specifier;
         specifier.packalign.setDefault();
         auto tspec = cparseSpecifierQualifierList(LVL.global, specifier);
+        if (!tspec)
+        {
+            error("type-specifier is missing");
+            tspec = AST.Type.tint32;
+        }
+        if (tspec && specifier.mod & MOD.xconst)
+        {
+            tspec = toConst(tspec);
+            specifier.mod = MOD.xnone;      // 'used' it
+        }
         Identifier id;
         return cparseDeclarator(DTR.xabstract, tspec, id, specifier);
     }
@@ -2825,8 +2861,18 @@
             Specifier specifier;
             specifier.packalign.setDefault();
             auto tspec = cparseDeclarationSpecifiers(LVL.prototype, specifier);
-            if (tspec && specifier.mod & MOD.xconst)
+            if (!tspec)
             {
+                error("no type-specifier for parameter");
+                tspec = AST.Type.tint32;
+            }
+
+            if (specifier.mod & MOD.xconst)
+            {
+                if ((token.value == TOK.rightParenthesis || token.value == TOK.comma) &&
+                    tspec.isTypeIdentifier())
+                    error("type-specifier omitted for parameter `%s`", tspec.isTypeIdentifier().ident.toChars());
+
                 tspec = toConst(tspec);
                 specifier.mod = MOD.xnone;      // 'used' it
             }
@@ -3396,7 +3442,12 @@
         Specifier specifier;
         specifier.packalign = this.packalign;
         auto tspec = cparseSpecifierQualifierList(LVL.member, specifier);
-        if (tspec && specifier.mod & MOD.xconst)
+        if (!tspec)
+        {
+            error("no type-specifier for struct member");
+            tspec = AST.Type.tint32;
+        }
+        if (specifier.mod & MOD.xconst)
         {
             tspec = toConst(tspec);
             specifier.mod = MOD.xnone;          // 'used' it
@@ -3409,7 +3460,13 @@
             nextToken();
             auto tt = tspec.isTypeTag();
             if (!tt)
+            {
+                if (auto ti = tspec.isTypeIdentifier())
+                {
+                    error("type-specifier omitted before declaration of `%s`", ti.ident.toChars());
+                }
                 return; // legal but meaningless empty declaration
+            }
 
             /* If anonymous struct declaration
              *   struct { ... members ... };
@@ -3449,6 +3506,12 @@
             AST.Type dt;
             if (token.value == TOK.colon)
             {
+                if (auto ti = tspec.isTypeIdentifier())
+                {
+                    error("type-specifier omitted before bit field declaration of `%s`", ti.ident.toChars());
+                    tspec = AST.Type.tint32;
+                }
+
                 // C11 6.7.2.1-12 unnamed bit-field
                 id = Identifier.generateAnonymousId("BitField");
                 dt = tspec;
diff --git a/gcc/d/dmd/ctfeexpr.d b/gcc/d/dmd/ctfeexpr.d
index 32aed16..11229d4 100644
--- a/gcc/d/dmd/ctfeexpr.d
+++ b/gcc/d/dmd/ctfeexpr.d
@@ -1269,7 +1269,7 @@
         real_t r1 = e1.type.isreal() ? e1.toReal() : e1.toImaginary();
         real_t r2 = e1.type.isreal() ? e2.toReal() : e2.toImaginary();
         if (identity)
-            return !RealIdentical(r1, r2);
+            return !CTFloat.isIdentical(r1, r2);
         if (CTFloat.isNaN(r1) || CTFloat.isNaN(r2)) // if unordered
         {
             return 1;   // they are not equal
@@ -1399,7 +1399,7 @@
         cmp = (es1.var == es2.var && es1.offset == es2.offset);
     }
     else if (e1.type.isreal())
-        cmp = RealIdentical(e1.toReal(), e2.toReal());
+        cmp = CTFloat.isIdentical(e1.toReal(), e2.toReal());
     else if (e1.type.isimaginary())
         cmp = RealIdentical(e1.toImaginary(), e2.toImaginary());
     else if (e1.type.iscomplex())
diff --git a/gcc/d/dmd/dcast.d b/gcc/d/dmd/dcast.d
index 685987b..8397839 100644
--- a/gcc/d/dmd/dcast.d
+++ b/gcc/d/dmd/dcast.d
@@ -432,7 +432,7 @@
                 return MATCH.nomatch;
             goto case Tuns8;
         case Tuns8:
-            //printf("value = %llu %llu\n", (dinteger_t)(unsigned char)value, value);
+            //printf("value = %llu %llu\n", cast(dinteger_t)cast(ubyte)value, value);
             if (cast(ubyte)value != value)
                 return MATCH.nomatch;
             break;
@@ -492,8 +492,8 @@
             break;
 
         case Tpointer:
-            //printf("type = %s\n", type.toBasetype()->toChars());
-            //printf("t = %s\n", t.toBasetype()->toChars());
+            //printf("type = %s\n", type.toBasetype().toChars());
+            //printf("t = %s\n", t.toBasetype().toChars());
             if (ty == Tpointer && e.type.toBasetype().nextOf().ty == t.toBasetype().nextOf().ty)
             {
                 /* Allow things like:
@@ -1107,6 +1107,10 @@
 
     MATCH visitCond(CondExp e)
     {
+        auto result = visit(e);
+        if (result != MATCH.nomatch)
+            return result;
+
         MATCH m1 = e.e1.implicitConvTo(t);
         MATCH m2 = e.e2.implicitConvTo(t);
         //printf("CondExp: m1 %d m2 %d\n", m1, m2);
@@ -2077,7 +2081,7 @@
         if (auto tsa = tb.isTypeSArray())
         {
             size_t dim2 = cast(size_t)tsa.dim.toInteger();
-            //printf("dim from = %d, to = %d\n", (int)se.len, (int)dim2);
+            //printf("dim from = %d, to = %d\n", cast(int)se.len, cast(int)dim2);
 
             // Changing dimensions
             if (dim2 != se.len)
diff --git a/gcc/d/dmd/declaration.d b/gcc/d/dmd/declaration.d
index c0e40a5..a533d30 100644
--- a/gcc/d/dmd/declaration.d
+++ b/gcc/d/dmd/declaration.d
@@ -379,7 +379,7 @@
 
         if (e1 && e1.op == EXP.this_ && isField())
         {
-            VarDeclaration vthis = (cast(ThisExp)e1).var;
+            VarDeclaration vthis = e1.isThisExp().var;
             for (Scope* scx = sc; scx; scx = scx.enclosing)
             {
                 if (scx.func == vthis.parent && (scx.flags & SCOPE.contract))
@@ -656,9 +656,8 @@
             if (o.dyncast() == DYNCAST.expression)
             {
                 Expression e = cast(Expression)o;
-                if (e.op == EXP.dSymbol)
+                if (DsymbolExp ve = e.isDsymbolExp())
                 {
-                    DsymbolExp ve = cast(DsymbolExp)e;
                     Declaration d = ve.s.isDeclaration();
                     if (d && d.needThis())
                     {
@@ -1083,29 +1082,12 @@
         bool isArgDtorVar;      /// temporary created to handle scope destruction of a function argument
     }
 
-    private ushort bitFields;       // stores multiple booleans for BitFields
+    import dmd.common.bitfields : generateBitFields;
+    mixin(generateBitFields!(BitFields, ushort));
+
     byte canassign;                 // it can be assigned to
     ubyte isdataseg;                // private data for isDataseg 0 unset, 1 true, 2 false
 
-    // Generate getter and setter functions for `bitFields`
-    extern (D) mixin(() {
-        string result = "extern (C++) pure nothrow @nogc @safe final {";
-        foreach (size_t i, mem; __traits(allMembers, BitFields))
-        {
-            result ~= "
-            /// set or get the corresponding BitFields member
-            bool "~mem~"() const { return !!(bitFields & (1 << "~i.stringof~")); }
-            /// ditto
-            bool "~mem~"(bool v)
-            {
-                v ? (bitFields |= (1 << "~i.stringof~")) : (bitFields &= ~(1 << "~i.stringof~"));
-                return v;
-            }";
-        }
-        return result ~ "}";
-    }());
-
-
     final extern (D) this(const ref Loc loc, Type type, Identifier ident, Initializer _init, StorageClass storage_class = STC.undefined_)
     in
     {
@@ -1160,7 +1142,7 @@
                 assert(o.dyncast() == DYNCAST.expression);
                 Expression e = cast(Expression)o;
                 assert(e.op == EXP.dSymbol);
-                DsymbolExp se = cast(DsymbolExp)e;
+                DsymbolExp se = e.isDsymbolExp();
                 se.s.setFieldOffset(ad, fieldState, isunion);
             }
             return;
@@ -1458,16 +1440,17 @@
                 const sdsz = sd.type.size();
                 assert(sdsz != SIZE_INVALID && sdsz != 0);
                 const n = sz / sdsz;
-                e = new SliceExp(loc, e, new IntegerExp(loc, 0, Type.tsize_t), new IntegerExp(loc, n, Type.tsize_t));
+                SliceExp se = new SliceExp(loc, e, new IntegerExp(loc, 0, Type.tsize_t),
+                    new IntegerExp(loc, n, Type.tsize_t));
 
                 // Prevent redundant bounds check
-                (cast(SliceExp)e).upperIsInBounds = true;
-                (cast(SliceExp)e).lowerIsLessThanUpper = true;
+                se.upperIsInBounds = true;
+                se.lowerIsLessThanUpper = true;
 
                 // This is a hack so we can call destructors on const/immutable objects.
-                e.type = sd.type.arrayOf();
+                se.type = sd.type.arrayOf();
 
-                e = new CallExp(loc, new IdentifierExp(loc, Id.__ArrayDtor), e);
+                e = new CallExp(loc, new IdentifierExp(loc, Id.__ArrayDtor), se);
             }
             return e;
         }
diff --git a/gcc/d/dmd/dmangle.d b/gcc/d/dmd/dmangle.d
index c3662a7..1f895e0 100644
--- a/gcc/d/dmd/dmangle.d
+++ b/gcc/d/dmd/dmangle.d
@@ -340,7 +340,6 @@
         final switch (t.linkage)
         {
         case LINK.default_:
-        case LINK.system:
         case LINK.d:
             mc = 'F';
             break;
@@ -356,6 +355,8 @@
         case LINK.objc:
             mc = 'Y';
             break;
+        case LINK.system:
+            assert(0);
         }
         buf.writeByte(mc);
 
@@ -1340,7 +1341,9 @@
     {
         if (d.linkage != LINK.d && d.localNum)
             d.error("the same declaration cannot be in multiple scopes with non-D linkage");
-        final switch (d.linkage)
+
+        const l = d.linkage == LINK.system ? target.systemLinkage() : d.linkage;
+        final switch (l)
         {
             case LINK.d:
                 break;
@@ -1354,9 +1357,10 @@
                 return p.toDString();
             }
             case LINK.default_:
-            case LINK.system:
                 d.error("forward declaration");
                 return d.ident.toString();
+            case LINK.system:
+                assert(0);
         }
     }
     return null;
diff --git a/gcc/d/dmd/dmodule.d b/gcc/d/dmd/dmodule.d
index c7e6418..2d9f651 100644
--- a/gcc/d/dmd/dmodule.d
+++ b/gcc/d/dmd/dmodule.d
@@ -69,7 +69,7 @@
 /**
  * Remove generated .di files on error and exit
  */
-void removeHdrFilesAndFail(ref Param params, ref Modules modules)
+void removeHdrFilesAndFail(ref Param params, ref Modules modules) nothrow
 {
     if (params.doHdrGeneration)
     {
@@ -94,7 +94,7 @@
  * Returns:
  *  the filename of the child package or module
  */
-private const(char)[] getFilename(Identifier[] packages, Identifier ident)
+private const(char)[] getFilename(Identifier[] packages, Identifier ident) nothrow
 {
     const(char)[] filename = ident.toString();
 
@@ -157,14 +157,14 @@
     uint tag;        // auto incremented tag, used to mask package tree in scopes
     Module mod;     // !=null if isPkgMod == PKG.module_
 
-    final extern (D) this(const ref Loc loc, Identifier ident)
+    final extern (D) this(const ref Loc loc, Identifier ident) nothrow
     {
         super(loc, ident);
         __gshared uint packageTag;
         this.tag = packageTag++;
     }
 
-    override const(char)* kind() const
+    override const(char)* kind() const nothrow
     {
         return "package";
     }
@@ -664,7 +664,7 @@
         //printf("Module::read('%s') file '%s'\n", toChars(), srcfile.toChars());
         if (auto result = global.fileManager.lookup(srcfile))
         {
-            this.src = result.data;
+            this.src = result;
             if (global.params.emitMakeDeps)
                 global.params.makeDeps.push(srcfile.toChars());
             return true;
@@ -1133,8 +1133,10 @@
         // If it isn't there, some compiler rewrites, like
         //    classinst == classinst -> .object.opEquals(classinst, classinst)
         // would fail inside object.d.
-        if (members.dim == 0 || (*members)[0].ident != Id.object ||
-            (*members)[0].isImport() is null)
+        if (filetype != FileType.c &&
+            (members.dim == 0 ||
+             (*members)[0].ident != Id.object ||
+             (*members)[0].isImport() is null))
         {
             auto im = new Import(Loc.initial, null, Id.object, null, 0);
             members.shift(im);
@@ -1380,7 +1382,7 @@
         a.setDim(0);
     }
 
-    extern (D) static void clearCache()
+    extern (D) static void clearCache() nothrow
     {
         foreach (Module m; amodules)
             m.searchCacheIdent = null;
@@ -1391,7 +1393,7 @@
      * return true if it imports m.
      * Can be used to detect circular imports.
      */
-    int imports(Module m)
+    int imports(Module m) nothrow
     {
         //printf("%s Module::imports(%s)\n", toChars(), m.toChars());
         version (none)
@@ -1414,14 +1416,14 @@
         return false;
     }
 
-    bool isRoot()
+    bool isRoot() nothrow
     {
         return this.importedFrom == this;
     }
 
     // true if the module source file is directly
     // listed in command line.
-    bool isCoreModule(Identifier ident)
+    bool isCoreModule(Identifier ident) nothrow
     {
         return this.ident == ident && parent && parent.ident == Id.core && !parent.parent;
     }
@@ -1440,7 +1442,7 @@
 
     uint[uint] ctfe_cov; /// coverage information from ctfe execution_count[line]
 
-    override inout(Module) isModule() inout
+    override inout(Module) isModule() inout nothrow
     {
         return this;
     }
@@ -1455,7 +1457,7 @@
      * Params:
      *    buf = The buffer to write to
      */
-    void fullyQualifiedName(ref OutBuffer buf)
+    void fullyQualifiedName(ref OutBuffer buf) nothrow
     {
         buf.writestring(ident.toString());
 
@@ -1469,7 +1471,7 @@
     /** Lazily initializes and returns the escape table.
     Turns out it eats a lot of memory.
     */
-    extern(D) Escape* escapetable()
+    extern(D) Escape* escapetable() nothrow
     {
         if (!_escapetable)
             _escapetable = new Escape();
diff --git a/gcc/d/dmd/dscope.d b/gcc/d/dmd/dscope.d
index c3a1d05..6339a9e 100644
--- a/gcc/d/dmd/dscope.d
+++ b/gcc/d/dmd/dscope.d
@@ -457,6 +457,8 @@
 
                 if (sc.scopesym.isModule())
                     flags |= SearchUnqualifiedModule;        // tell Module.search() that SearchLocalsOnly is to be obeyed
+                else if (sc.flags & SCOPE.Cfile && sc.scopesym.isStructDeclaration())
+                    continue;                                // C doesn't have struct scope
 
                 if (Dsymbol s = sc.scopesym.search(loc, ident, flags))
                 {
diff --git a/gcc/d/dmd/dsymbol.d b/gcc/d/dmd/dsymbol.d
index cb6c278..74eaa1d 100644
--- a/gcc/d/dmd/dsymbol.d
+++ b/gcc/d/dmd/dsymbol.d
@@ -112,12 +112,12 @@
 {
     uint oldgag;
 
-    extern (D) this(uint old)
+    extern (D) this(uint old) nothrow
     {
         this.oldgag = old;
     }
 
-    extern (C++) ~this()
+    extern (C++) ~this() nothrow
     {
         global.gag = oldgag;
     }
@@ -255,27 +255,27 @@
     DeprecatedDeclaration depdecl;           // customized deprecation message
     UserAttributeDeclaration userAttribDecl;    // user defined attributes
 
-    final extern (D) this()
+    final extern (D) this() nothrow
     {
         //printf("Dsymbol::Dsymbol(%p)\n", this);
         loc = Loc(null, 0, 0);
     }
 
-    final extern (D) this(Identifier ident)
+    final extern (D) this(Identifier ident) nothrow
     {
         //printf("Dsymbol::Dsymbol(%p, ident)\n", this);
         this.loc = Loc(null, 0, 0);
         this.ident = ident;
     }
 
-    final extern (D) this(const ref Loc loc, Identifier ident)
+    final extern (D) this(const ref Loc loc, Identifier ident) nothrow
     {
         //printf("Dsymbol::Dsymbol(%p, ident)\n", this);
         this.loc = loc;
         this.ident = ident;
     }
 
-    static Dsymbol create(Identifier ident)
+    static Dsymbol create(Identifier ident) nothrow
     {
         return new Dsymbol(ident);
     }
@@ -800,6 +800,22 @@
             if (isAliasDeclaration() && !_scope)
                 setScope(sc);
             Dsymbol s2 = sds.symtabLookup(this,ident);
+            /* https://issues.dlang.org/show_bug.cgi?id=17434
+             *
+             * If we are trying to add an import to the symbol table
+             * that has already been introduced, then keep the one with
+             * larger visibility. This is fine for imports because if
+             * we have multiple imports of the same file, if a single one
+             * is public then the symbol is reachable.
+             */
+            if (auto i1 = isImport())
+            {
+                if (auto i2 = s2.isImport())
+                {
+                    if (sc.explicitVisibility && sc.visibility > i2.visibility)
+                        sds.symtab.update(this);
+                }
+            }
 
             // If using C tag/prototype/forward declaration rules
             if (sc.flags & SCOPE.Cfile && !this.isImport())
@@ -822,7 +838,8 @@
         }
         if (sds.isAggregateDeclaration() || sds.isEnumDeclaration())
         {
-            if (ident == Id.__sizeof || ident == Id.__xalignof || ident == Id._mangleof)
+            if (ident == Id.__sizeof ||
+                !(sc && sc.flags & SCOPE.Cfile) && (ident == Id.__xalignof || ident == Id._mangleof))
             {
                 error("`.%s` property cannot be redefined", ident.toChars());
                 errors = true;
@@ -933,14 +950,7 @@
                 TemplateInstance ti = st.isTemplateInstance();
                 sm = s.search(loc, ti.name);
                 if (!sm)
-                {
-                    sm = s.search_correct(ti.name);
-                    if (sm)
-                        .error(loc, "template identifier `%s` is not a member of %s `%s`, did you mean %s `%s`?", ti.name.toChars(), s.kind(), s.toPrettyChars(), sm.kind(), sm.toChars());
-                    else
-                        .error(loc, "template identifier `%s` is not a member of %s `%s`", ti.name.toChars(), s.kind(), s.toPrettyChars());
                     return null;
-                }
                 sm = sm.toAlias();
                 TemplateDeclaration td = sm.isTemplateDeclaration();
                 if (!td)
@@ -1381,16 +1391,16 @@
     BitArray accessiblePackages, privateAccessiblePackages;// whitelists of accessible (imported) packages
 
 public:
-    final extern (D) this()
+    final extern (D) this() nothrow
     {
     }
 
-    final extern (D) this(Identifier ident)
+    final extern (D) this(Identifier ident) nothrow
     {
         super(ident);
     }
 
-    final extern (D) this(const ref Loc loc, Identifier ident)
+    final extern (D) this(const ref Loc loc, Identifier ident) nothrow
     {
         super(loc, ident);
     }
@@ -1604,7 +1614,7 @@
         return os;
     }
 
-    void importScope(Dsymbol s, Visibility visibility)
+    void importScope(Dsymbol s, Visibility visibility) nothrow
     {
         //printf("%s.ScopeDsymbol::importScope(%s, %d)\n", toChars(), s.toChars(), visibility);
         // No circular or redundant import's
@@ -1631,7 +1641,7 @@
         }
     }
 
-    extern (D) final void addAccessiblePackage(Package p, Visibility visibility)
+    extern (D) final void addAccessiblePackage(Package p, Visibility visibility) nothrow
     {
         auto pary = visibility.kind == Visibility.Kind.private_ ? &privateAccessiblePackages : &accessiblePackages;
         if (pary.length <= p.tag)
@@ -1639,7 +1649,7 @@
         (*pary)[p.tag] = true;
     }
 
-    bool isPackageAccessible(Package p, Visibility visibility, int flags = 0)
+    bool isPackageAccessible(Package p, Visibility visibility, int flags = 0) nothrow
     {
         if (p.tag < accessiblePackages.length && accessiblePackages[p.tag] ||
             visibility.kind == Visibility.Kind.private_ && p.tag < privateAccessiblePackages.length && privateAccessiblePackages[p.tag])
@@ -1654,7 +1664,7 @@
         return false;
     }
 
-    override final bool isforwardRef()
+    override final bool isforwardRef() nothrow
     {
         return (members is null);
     }
@@ -1742,7 +1752,7 @@
      * Returns:
      *   null if already in table, `s` if inserted
      */
-    Dsymbol symtabInsert(Dsymbol s)
+    Dsymbol symtabInsert(Dsymbol s) nothrow
     {
         return symtab.insert(s);
     }
@@ -1755,7 +1765,7 @@
      * Returns:
      *   Dsymbol if found, null if not
      */
-    Dsymbol symtabLookup(Dsymbol s, Identifier id)
+    Dsymbol symtabLookup(Dsymbol s, Identifier id) nothrow
     {
         return symtab.lookup(id);
     }
@@ -1838,7 +1848,7 @@
 {
     WithStatement withstate;
 
-    extern (D) this(WithStatement withstate)
+    extern (D) this(WithStatement withstate) nothrow
     {
         this.withstate = withstate;
     }
@@ -1898,7 +1908,7 @@
     private RootObject arrayContent;
     Scope* sc;
 
-    extern (D) this(Scope* sc, Expression exp)
+    extern (D) this(Scope* sc, Expression exp) nothrow
     {
         super(exp.loc, null);
         assert(exp.op == EXP.index || exp.op == EXP.slice || exp.op == EXP.array);
@@ -1906,13 +1916,13 @@
         this.arrayContent = exp;
     }
 
-    extern (D) this(Scope* sc, TypeTuple type)
+    extern (D) this(Scope* sc, TypeTuple type) nothrow
     {
         this.sc = sc;
         this.arrayContent = type;
     }
 
-    extern (D) this(Scope* sc, TupleDeclaration td)
+    extern (D) this(Scope* sc, TupleDeclaration td) nothrow
     {
         this.sc = sc;
         this.arrayContent = td;
@@ -2109,7 +2119,7 @@
 {
     Dsymbols a;     // array of Dsymbols
 
-    extern (D) this(Identifier ident, OverloadSet os = null)
+    extern (D) this(Identifier ident, OverloadSet os = null) nothrow
     {
         super(ident);
         if (os)
@@ -2118,7 +2128,7 @@
         }
     }
 
-    void push(Dsymbol s)
+    void push(Dsymbol s) nothrow
     {
         a.push(s);
     }
@@ -2152,12 +2162,13 @@
      * Can be `null` before being lazily initialized.
      */
     ScopeDsymbol forward;
-    extern (D) this(ScopeDsymbol forward)
+    extern (D) this(ScopeDsymbol forward) nothrow
     {
         super(null);
         this.forward = forward;
     }
-    override Dsymbol symtabInsert(Dsymbol s)
+
+    override Dsymbol symtabInsert(Dsymbol s) nothrow
     {
         assert(forward);
         if (auto d = s.isDeclaration())
@@ -2188,7 +2199,7 @@
      * and
      *     static foreach (i; [0]) { enum i = 2; }
      */
-    override Dsymbol symtabLookup(Dsymbol s, Identifier id)
+    override Dsymbol symtabLookup(Dsymbol s, Identifier id) nothrow
     {
         assert(forward);
         // correctly diagnose clashing foreach loop variables.
@@ -2219,7 +2230,7 @@
 
     override const(char)* kind()const{ return "local scope"; }
 
-    override inout(ForwardingScopeDsymbol) isForwardingScopeDsymbol() inout
+    override inout(ForwardingScopeDsymbol) isForwardingScopeDsymbol() inout nothrow
     {
         return this;
     }
@@ -2234,13 +2245,13 @@
 extern (C++) final class ExpressionDsymbol : Dsymbol
 {
     Expression exp;
-    this(Expression exp)
+    this(Expression exp) nothrow
     {
         super();
         this.exp = exp;
     }
 
-    override inout(ExpressionDsymbol) isExpressionDsymbol() inout
+    override inout(ExpressionDsymbol) isExpressionDsymbol() inout nothrow
     {
         return this;
     }
@@ -2259,7 +2270,7 @@
     Dsymbol aliassym; /// replace previous RHS of AliasDeclaration with `aliassym`
                       /// only one of type and aliassym can be != null
 
-    extern (D) this(const ref Loc loc, Identifier ident, Type type, Dsymbol aliassym)
+    extern (D) this(const ref Loc loc, Identifier ident, Type type, Dsymbol aliassym) nothrow
     {
         super(loc, null);
         this.ident = ident;
@@ -2299,6 +2310,8 @@
 {
     AssocArray!(Identifier, Dsymbol) tab;
 
+  nothrow:
+
    /***************************
     * Look up Identifier in symbol table
     * Params:
@@ -2511,6 +2524,7 @@
 
         if (i1)                         // vd is the definition
         {
+            vd2.storage_class |= STC.extern_;  // so toObjFile() won't emit it
             sds.symtab.update(vd);      // replace vd2 with the definition
             return vd;
         }
diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d
index c990636..5415401 100644
--- a/gcc/d/dmd/dsymbolsem.d
+++ b/gcc/d/dmd/dsymbolsem.d
@@ -51,6 +51,7 @@
 import dmd.initsem;
 import dmd.hdrgen;
 import dmd.mtype;
+import dmd.mustuse;
 import dmd.nogc;
 import dmd.nspace;
 import dmd.objc;
@@ -542,7 +543,7 @@
                     Parameter arg = Parameter.getNth(tt.arguments, pos);
                     arg.type = arg.type.typeSemantic(dsym.loc, sc);
                     //printf("[%d] iexps.dim = %d, ", pos, iexps.dim);
-                    //printf("e = (%s %s, %s), ", Token::tochars[e.op], e.toChars(), e.type.toChars());
+                    //printf("e = (%s %s, %s), ", Token.tochars[e.op], e.toChars(), e.type.toChars());
                     //printf("arg = (%s, %s)\n", arg.toChars(), arg.type.toChars());
 
                     if (e != ie)
@@ -581,7 +582,7 @@
                             arg = Parameter.getNth(tt.arguments, pos + u);
                             arg.type = arg.type.typeSemantic(dsym.loc, sc);
                             //printf("[%d+%d] exps.dim = %d, ", pos, u, exps.dim);
-                            //printf("ee = (%s %s, %s), ", Token::tochars[ee.op], ee.toChars(), ee.type.toChars());
+                            //printf("ee = (%s %s, %s), ", Token.tochars[ee.op], ee.toChars(), ee.type.toChars());
                             //printf("arg = (%s, %s)\n", arg.toChars(), arg.type.toChars());
 
                             size_t iexps_dim = iexps.dim - 1 + exps.dim;
@@ -2046,6 +2047,7 @@
 
         ed.semanticRun = PASS.semantic;
         UserAttributeDeclaration.checkGNUABITag(ed, sc.linkage);
+        checkMustUseReserved(ed);
 
         if (!ed.members && !ed.memtype) // enum ident;
         {
@@ -2872,7 +2874,7 @@
             sc = sc.endCTFE();
             resolved = resolved.ctfeInterpret();
             StringExp name = resolved.toStringExp();
-            TupleExp tup = name ? null : resolved.toTupleExp();
+            TupleExp tup = name ? null : resolved.isTupleExp();
             if (!tup && !name)
             {
                 error(ns.loc, "expected string expression for namespace name, got `%s`", ns.identExp.toChars());
@@ -3017,7 +3019,7 @@
         if ((funcdecl.storage_class & STC.TYPECTOR) && !(ad || funcdecl.isNested()))
             funcdecl.storage_class &= ~STC.TYPECTOR;
 
-        //printf("function storage_class = x%llx, sc.stc = x%llx, %x\n", storage_class, sc.stc, Declaration::isFinal());
+        //printf("function storage_class = x%llx, sc.stc = x%llx, %x\n", storage_class, sc.stc, Declaration.isFinal());
 
         if (sc.flags & SCOPE.compile)
             funcdecl.flags |= FUNCFLAG.compileTimeOnly; // don't emit code for this function
@@ -3056,6 +3058,7 @@
         funcdecl.visibility = sc.visibility;
         funcdecl.userAttribDecl = sc.userAttribDecl;
         UserAttributeDeclaration.checkGNUABITag(funcdecl, funcdecl.linkage);
+        checkMustUseReserved(funcdecl);
 
         if (!funcdecl.originalType)
             funcdecl.originalType = funcdecl.type.syntaxCopy();
@@ -4092,7 +4095,7 @@
     override void visit(PostBlitDeclaration pbd)
     {
         //printf("PostBlitDeclaration::semantic() %s\n", toChars());
-        //printf("ident: %s, %s, %p, %p\n", ident.toChars(), Id::dtor.toChars(), ident, Id::dtor);
+        //printf("ident: %s, %s, %p, %p\n", ident.toChars(), Id.dtor.toChars(), ident, Id.dtor);
         //printf("stc = x%llx\n", sc.stc);
         if (pbd.semanticRun >= PASS.semanticdone)
             return;
@@ -4129,7 +4132,7 @@
     override void visit(DtorDeclaration dd)
     {
         //printf("DtorDeclaration::semantic() %s\n", toChars());
-        //printf("ident: %s, %s, %p, %p\n", ident.toChars(), Id::dtor.toChars(), ident, Id::dtor);
+        //printf("ident: %s, %s, %p, %p\n", ident.toChars(), Id.dtor.toChars(), ident, Id.dtor);
         if (dd.semanticRun >= PASS.semanticdone)
             return;
         if (dd._scope)
@@ -4618,7 +4621,8 @@
         buildOpAssign(sd, sc2);
         buildOpEquals(sd, sc2);
 
-        if (global.params.useTypeInfo && Type.dtypeinfo)  // these functions are used for TypeInfo
+        if (!(sc2.flags & SCOPE.Cfile) &&
+            global.params.useTypeInfo && Type.dtypeinfo)  // these functions are used for TypeInfo
         {
             sd.xeq = buildXopEquals(sd, sc2);
             sd.xcmp = buildXopCmp(sd, sc2);
@@ -4770,6 +4774,7 @@
         }
         cldec.semanticRun = PASS.semantic;
         UserAttributeDeclaration.checkGNUABITag(cldec, sc.linkage);
+        checkMustUseReserved(cldec);
 
         if (cldec.baseok < Baseok.done)
         {
@@ -5019,6 +5024,10 @@
                     cldec.com = true;
                 if (cldec.baseClass.isCPPclass())
                     cldec.classKind = ClassKind.cpp;
+                if (cldec.classKind != cldec.baseClass.classKind)
+                    cldec.error("with %s linkage cannot inherit from class `%s` with %s linkage",
+                        cldec.classKind.toChars(), cldec.baseClass.toChars(), cldec.baseClass.classKind.toChars());
+
                 if (cldec.baseClass.stack)
                     cldec.stack = true;
                 cldec.enclosing = cldec.baseClass.enclosing;
@@ -5475,6 +5484,7 @@
                 idec.classKind = ClassKind.cpp;
             idec.cppnamespace = sc.namespace;
             UserAttributeDeclaration.checkGNUABITag(idec, sc.linkage);
+            checkMustUseReserved(idec);
 
             if (sc.linkage == LINK.objc)
                 objc.setObjc(idec);
diff --git a/gcc/d/dmd/dtemplate.d b/gcc/d/dmd/dtemplate.d
index a5ec63c..fb41e2b 100644
--- a/gcc/d/dmd/dtemplate.d
+++ b/gcc/d/dmd/dtemplate.d
@@ -2626,7 +2626,7 @@
             printf("\t%s %s\n", arg.type.toChars(), arg.toChars());
             //printf("\tty = %d\n", arg.type.ty);
         }
-        //printf("stc = %llx\n", dstart.scope.stc);
+        //printf("stc = %llx\n", dstart._scope.stc);
         //printf("match:t/f = %d/%d\n", ta_last, m.last);
     }
 
@@ -4332,7 +4332,7 @@
             {
                 TypeStruct tp = cast(TypeStruct)tparam;
 
-                //printf("\t%d\n", (MATCH) t.implicitConvTo(tp));
+                //printf("\t%d\n", cast(MATCH) t.implicitConvTo(tp));
                 if (wm && t.deduceWild(tparam, false))
                 {
                     result = MATCH.constant;
@@ -4513,7 +4513,7 @@
             {
                 TypeClass tp = cast(TypeClass)tparam;
 
-                //printf("\t%d\n", (MATCH) t.implicitConvTo(tp));
+                //printf("\t%d\n", cast(MATCH) t.implicitConvTo(tp));
                 if (wm && t.deduceWild(tparam, false))
                 {
                     result = MATCH.constant;
diff --git a/gcc/d/dmd/errors.d b/gcc/d/dmd/errors.d
index 114bd44..62e86a1 100644
--- a/gcc/d/dmd/errors.d
+++ b/gcc/d/dmd/errors.d
@@ -434,8 +434,20 @@
     pragma(printf) extern (C++) void vdeprecationSupplemental(const ref Loc loc, const(char)* format, va_list ap);
 
 /**
- * Call this after printing out fatal error messages to clean up and exit
- * the compiler.
+ * The type of the fatal error handler
+ * Returns: true if error handling is done, false to do exit(EXIT_FAILURE)
+ */
+alias FatalErrorHandler = bool delegate();
+
+/**
+ * The fatal error handler.
+ * If non-null it will be called for every fatal() call issued by the compiler.
+ */
+__gshared FatalErrorHandler fatalErrorHandler;
+
+/**
+ * Call this after printing out fatal error messages to clean up and exit the
+ * compiler. You can also set a fatalErrorHandler to override this behaviour.
  */
 extern (C++) void fatal();
 
diff --git a/gcc/d/dmd/escape.d b/gcc/d/dmd/escape.d
index 4196c05..44c3757 100644
--- a/gcc/d/dmd/escape.d
+++ b/gcc/d/dmd/escape.d
@@ -316,24 +316,27 @@
      */
     void unsafeAssign(VarDeclaration v, const char* desc)
     {
-        if (global.params.useDIP1000 == FeatureState.enabled && sc.func.setUnsafe())
+        if (setUnsafeDIP1000(sc.func))
         {
             if (!gag)
             {
                 if (assertmsg)
                 {
-                    error(arg.loc, "%s `%s` assigned to non-scope parameter calling `assert()`",
+                    previewErrorFunc(sc.isDeprecated(), global.params.useDIP1000)
+                                    (arg.loc, "%s `%s` assigned to non-scope parameter calling `assert()`",
                         desc, v.toChars());
                 }
                 else
                 {
-                    error(arg.loc, "%s `%s` assigned to non-scope parameter `%s` calling %s",
+                    previewErrorFunc(sc.isDeprecated(), global.params.useDIP1000)
+                                    (arg.loc, "%s `%s` assigned to non-scope parameter `%s` calling %s",
                         desc, v.toChars(),
                         par ? par.toChars() : "this",
                         fdc ? fdc.toPrettyChars() : "indirectly");
                 }
             }
-            result = true;
+            if (global.params.useDIP1000 == FeatureState.enabled)
+                result = true;
         }
     }
 
@@ -440,22 +443,33 @@
  *      sc = used to determine current function and module
  *      firstArg = `ref` argument through which `arg` may be assigned
  *      arg = initializer for parameter
+ *      param = parameter declaration corresponding to `arg`
  *      gag = do not print error messages
  * Returns:
  *      `true` if assignment to `firstArg` would cause an error
  */
-bool checkParamArgumentReturn(Scope* sc, Expression firstArg, Expression arg, bool gag)
+bool checkParamArgumentReturn(Scope* sc, Expression firstArg, Expression arg, Parameter param, bool gag)
 {
     enum log = false;
     if (log) printf("checkParamArgumentReturn(firstArg: %s arg: %s)\n",
         firstArg.toChars(), arg.toChars());
     //printf("type = %s, %d\n", arg.type.toChars(), arg.type.hasPointers());
 
-    if (!arg.type.hasPointers())
+    if (!(param.storageClass & STC.return_))
         return false;
 
+    if (!arg.type.hasPointers() && !param.isReference())
+        return false;
+
+    // `byRef` needed for `assign(ref int* x, ref int i) {x = &i};`
+    // Note: taking address of scope pointer is not allowed
+    // `assign(ref int** x, return ref scope int* i) {x = &i};`
+    // Thus no return ref/return scope ambiguity here
+    const byRef = param.isReference() && !(param.storageClass & STC.scope_)
+        && !(param.storageClass & STC.returnScope); // fixme: it's possible to infer returnScope without scope with vaIsFirstRef
+
     scope e = new AssignExp(arg.loc, firstArg, arg);
-    return checkAssignEscape(sc, e, gag);
+    return checkAssignEscape(sc, e, gag, byRef);
 }
 
 /*****************************************************
@@ -496,23 +510,13 @@
     foreach (const i; 0 .. n)
     {
         Expression arg = (*ce.arguments)[i];
-        if (!arg.type.hasPointers())
-            continue;
-
         //printf("\targ[%d]: %s\n", i, arg.toChars());
 
         if (i - j < nparams && i >= j)
         {
             Parameter p = tf.parameterList[i - j];
-
-            if (p.storageClass & STC.return_)
-            {
-                /* Fake `dve.e1 = arg;` and look for scope violations
-                 */
-                scope e = new AssignExp(arg.loc, dve.e1, arg);
-                if (checkAssignEscape(sc, e, gag))
-                    return true;
-            }
+            if (checkParamArgumentReturn(sc, dve.e1, arg, p, gag))
+                return true;
         }
     }
 
@@ -529,13 +533,14 @@
  *      sc = used to determine current function and module
  *      e = `AssignExp` or `CatAssignExp` to check for any pointers to the stack
  *      gag = do not print error messages
+ *      byRef = set to `true` if `e1` of `e` gets assigned a reference to `e2`
  * Returns:
  *      `true` if pointers to the stack can escape via assignment
  */
-bool checkAssignEscape(Scope* sc, Expression e, bool gag)
+bool checkAssignEscape(Scope* sc, Expression e, bool gag, bool byRef)
 {
     enum log = false;
-    if (log) printf("checkAssignEscape(e: %s)\n", e.toChars());
+    if (log) printf("checkAssignEscape(e: %s, byRef: %d)\n", e.toChars(), byRef);
     if (e.op != EXP.assign && e.op != EXP.blit && e.op != EXP.construct &&
         e.op != EXP.concatenateAssign && e.op != EXP.concatenateElemAssign && e.op != EXP.concatenateDcharAssign)
         return false;
@@ -561,7 +566,10 @@
 
     EscapeByResults er;
 
-    escapeByValue(e2, &er);
+    if (byRef)
+        escapeByRef(e2, &er);
+    else
+        escapeByValue(e2, &er);
 
     if (!er.byref.dim && !er.byvalue.dim && !er.byfunc.dim && !er.byexp.dim)
         return false;
@@ -769,7 +777,7 @@
         if (v.isDataseg())
             continue;
 
-        if (global.params.useDIP1000 == FeatureState.enabled)
+        if (global.params.useDIP1000 != FeatureState.disabled)
         {
             if (va && va.isScope() && !v.isReference())
             {
@@ -777,20 +785,36 @@
                 {
                     va.doNotInferReturn = true;
                 }
-                else if (fd.setUnsafe())
+                else if (setUnsafeDIP1000(fd))
                 {
                     if (!gag)
-                        error(ae.loc, "address of local variable `%s` assigned to return scope `%s`", v.toChars(), va.toChars());
-                    result = true;
-                    continue;
+                        previewErrorFunc(sc.isDeprecated(), global.params.useDIP1000)
+                            (ae.loc, "address of local variable `%s` assigned to return scope `%s`", v.toChars(), va.toChars());
+
+
+                    if (global.params.useDIP1000 == FeatureState.enabled)
+                    {
+                        result = true;
+                        continue;
+                    }
                 }
             }
         }
 
         Dsymbol p = v.toParent2();
 
+        if (vaIsFirstRef && v.isParameter() &&
+            !(v.storage_class & STC.return_) &&
+            fd.flags & FUNCFLAG.returnInprocess &&
+            p == fd)
+        {
+            //if (log) printf("inferring 'return' for parameter %s in function %s\n", v.toChars(), fd.toChars());
+            inferReturn(fd, v, /*returnScope:*/ false);
+        }
+
         // If va's lifetime encloses v's, then error
         if (va &&
+            !(vaIsFirstRef && (v.storage_class & STC.return_)) &&
             (va.enclosesLifetimeOf(v) || (va.isReference() && !(va.storage_class & STC.temp)) || va.isDataseg()) &&
             fd.setUnsafe())
         {
@@ -961,12 +985,11 @@
         if (v.isScope() && !v.iscatchvar)       // special case: allow catch var to be rethrown
                                                 // despite being `scope`
         {
+            if (!gag)
+                previewErrorFunc(sc.isDeprecated(), global.params.useDIP1000)
+                                (e.loc, "scope variable `%s` may not be thrown", v.toChars());
             if (global.params.useDIP1000 == FeatureState.enabled) // https://issues.dlang.org/show_bug.cgi?id=17029
-            {
-                if (!gag)
-                    error(e.loc, "scope variable `%s` may not be thrown", v.toChars());
                 result = true;
-            }
             continue;
         }
         else
@@ -1027,13 +1050,16 @@
                  */
                 !(p.parent == sc.func))
             {
-                if (global.params.useDIP1000 == FeatureState.enabled   // https://issues.dlang.org/show_bug.cgi?id=17029
-                    && sc.func.setUnsafe())     // https://issues.dlang.org/show_bug.cgi?id=20868
+                if (setUnsafeDIP1000(sc.func))     // https://issues.dlang.org/show_bug.cgi?id=20868
                 {
+                    // Only look for errors if in module listed on command line
                     if (!gag)
-                        error(e.loc, "scope variable `%s` may not be copied into allocated memory", v.toChars());
-                    result = true;
+                        previewErrorFunc(sc.isDeprecated(), global.params.useDIP1000)
+                                        (e.loc, "scope variable `%s` may not be copied into allocated memory", v.toChars());
+                    if (global.params.useDIP1000 == FeatureState.enabled)
+                        result = true;
                 }
+
                 continue;
             }
         }
@@ -1243,11 +1269,13 @@
                )
             {
                 // https://issues.dlang.org/show_bug.cgi?id=17029
-                if (global.params.useDIP1000 == FeatureState.enabled && sc.func.setUnsafe())
+                if (setUnsafeDIP1000(sc.func))
                 {
                     if (!gag)
-                        error(e.loc, "scope variable `%s` may not be returned", v.toChars());
-                    result = true;
+                        previewErrorFunc(sc.isDeprecated(), global.params.useDIP1000)
+                                        (e.loc, "scope variable `%s` may not be returned", v.toChars());
+                    if (global.params.useDIP1000 == FeatureState.enabled)
+                        result = true;
                 }
                 continue;
             }
@@ -2326,3 +2354,11 @@
         va.maybes = new VarDeclarations();
     va.maybes.push(v);
 }
+
+
+private bool setUnsafeDIP1000(FuncDeclaration f)
+{
+    return global.params.useDIP1000 == FeatureState.enabled
+        ? f.setUnsafe()
+        : f.isSafeBypassingInference();
+}
diff --git a/gcc/d/dmd/expression.d b/gcc/d/dmd/expression.d
index 07d885b..107e85b 100644
--- a/gcc/d/dmd/expression.d
+++ b/gcc/d/dmd/expression.d
@@ -967,11 +967,6 @@
         return null;
     }
 
-    TupleExp toTupleExp()
-    {
-        return null;
-    }
-
     /***************************************
      * Return !=0 if expression is an lvalue.
      */
@@ -1660,6 +1655,7 @@
         inout(MixinExp)     isMixinExp() { return op == EXP.mixin_ ? cast(typeof(return))this : null; }
         inout(ImportExp)    isImportExp() { return op == EXP.import_ ? cast(typeof(return))this : null; }
         inout(AssertExp)    isAssertExp() { return op == EXP.assert_ ? cast(typeof(return))this : null; }
+        inout(ThrowExp)     isThrowExp() { return op == EXP.throw_ ? cast(typeof(return))this : null; }
         inout(DotIdExp)     isDotIdExp() { return op == EXP.dotIdentifier ? cast(typeof(return))this : null; }
         inout(DotTemplateExp) isDotTemplateExp() { return op == EXP.dotTemplateDeclaration ? cast(typeof(return))this : null; }
         inout(DotVarExp)    isDotVarExp() { return op == EXP.dotVariable ? cast(typeof(return))this : null; }
@@ -1745,6 +1741,7 @@
         inout(ModuleInitExp)     isModuleInitExp() { return op == EXP.moduleString ? cast(typeof(return))this : null; }
         inout(FuncInitExp)       isFuncInitExp() { return op == EXP.functionString ? cast(typeof(return))this : null; }
         inout(PrettyFuncInitExp) isPrettyFuncInitExp() { return op == EXP.prettyFunction ? cast(typeof(return))this : null; }
+        inout(ObjcClassReferenceExp) isObjcClassReferenceExp() { return op == EXP.objcClassReference ? cast(typeof(return))this : null; }
         inout(ClassReferenceExp) isClassReferenceExp() { return op == EXP.classReference ? cast(typeof(return))this : null; }
         inout(ThrownExceptionExp) isThrownExceptionExp() { return op == EXP.thrownException ? cast(typeof(return))this : null; }
 
@@ -2684,7 +2681,7 @@
         const len2 = se2.len;
 
         assert(this.sz == se2.sz, "Comparing string expressions of different sizes");
-        //printf("sz = %d, len1 = %d, len2 = %d\n", sz, (int)len1, (int)len2);
+        //printf("sz = %d, len1 = %d, len2 = %d\n", sz, cast(int)len1, cast(int)len2);
         if (len1 == len2)
         {
             switch (sz)
@@ -2887,11 +2884,6 @@
         return new TupleExp(loc, exps);
     }
 
-    override TupleExp toTupleExp()
-    {
-        return this;
-    }
-
     override TupleExp syntaxCopy()
     {
         return new TupleExp(loc, e0 ? e0.syntaxCopy() : null, arraySyntaxCopy(exps));
diff --git a/gcc/d/dmd/expression.h b/gcc/d/dmd/expression.h
index 9522b23..330dcdb 100644
--- a/gcc/d/dmd/expression.h
+++ b/gcc/d/dmd/expression.h
@@ -103,7 +103,6 @@
     virtual real_t toImaginary();
     virtual complex_t toComplex();
     virtual StringExp *toStringExp();
-    virtual TupleExp *toTupleExp();
     virtual bool isLvalue();
     virtual Expression *toLvalue(Scope *sc, Expression *e);
     virtual Expression *modifiableLvalue(Scope *sc, Expression *e);
@@ -374,11 +373,11 @@
     OwnedBy ownedByCtfe;
 
     static StringExp *create(const Loc &loc, const char *s);
-    static StringExp *create(const Loc &loc, const void *s, size_t len);
+    static StringExp *create(const Loc &loc, const void *s, d_size_t len);
     static void emplace(UnionExp *pue, const Loc &loc, const char *s);
     bool equals(const RootObject *o) const;
-    char32_t getCodeUnit(size_t i) const;
-    void setCodeUnit(size_t i, char32_t c);
+    char32_t getCodeUnit(d_size_t i) const;
+    void setCodeUnit(d_size_t i, char32_t c);
     StringExp *toStringExp();
     StringExp *toUTF8(Scope *sc);
     Optional<bool> toBool();
@@ -406,7 +405,6 @@
     Expressions *exps;
 
     static TupleExp *create(const Loc &loc, Expressions *exps);
-    TupleExp *toTupleExp();
     TupleExp *syntaxCopy();
     bool equals(const RootObject *o) const;
 
diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d
index 7b7c489..d4e96bb 100644
--- a/gcc/d/dmd/expressionsem.d
+++ b/gcc/d/dmd/expressionsem.d
@@ -56,6 +56,7 @@
 import dmd.inline;
 import dmd.intrange;
 import dmd.mtype;
+import dmd.mustuse;
 import dmd.nspace;
 import dmd.opover;
 import dmd.optimize;
@@ -713,7 +714,7 @@
  */
 Expression resolvePropertiesOnly(Scope* sc, Expression e1)
 {
-    //printf("e1 = %s %s\n", Token::toChars(e1.op), e1.toChars());
+    //printf("e1 = %s %s\n", Token.toChars(e1.op), e1.toChars());
 
     Expression handleOverloadSet(OverloadSet os)
     {
@@ -2027,15 +2028,19 @@
             //printf("type: %s\n", arg.type.toChars());
             //printf("param: %s\n", p.toChars());
 
-            if (firstArg && p.storageClass & STC.return_)
+            const pStc = tf.parameterStorageClass(tthis, p);
+
+            if (firstArg && (pStc & STC.return_))
             {
                 /* Argument value can be assigned to firstArg.
                  * Check arg to see if it matters.
                  */
                 if (global.params.useDIP1000 == FeatureState.enabled)
-                    err |= checkParamArgumentReturn(sc, firstArg, arg, false);
+                    err |= checkParamArgumentReturn(sc, firstArg, arg, p, false);
             }
-            else if (tf.parameterEscapes(tthis, p))
+            // Allow 'lazy' to imply 'scope' - lazy parameters can be passed along
+            // as lazy parameters to the next function, but that isn't escaping.
+            else if (!(pStc & (STC.scope_ | STC.lazy_)))
             {
                 /* Argument value can escape from the called function.
                  * Check arg to see if it matters.
@@ -2043,7 +2048,7 @@
                 if (global.params.useDIP1000 == FeatureState.enabled)
                     err |= checkParamArgumentEscape(sc, fd, p, arg, false, false);
             }
-            else if (!(p.storageClass & STC.return_))
+            else if (!(pStc & STC.return_))
             {
                 /* Argument value cannot escape from the called function.
                  */
@@ -3228,7 +3233,7 @@
         }
         Type t = cle.type.typeSemantic(cle.loc, sc);
         auto init = initializerSemantic(cle.initializer, sc, t, INITnointerpret);
-        auto e = initializerToExpression(init, t);
+        auto e = initializerToExpression(init, t, (sc.flags & SCOPE.Cfile) != 0);
         if (!e)
         {
             error(cle.loc, "cannot convert initializer `%s` to expression", init.toChars());
@@ -3261,7 +3266,7 @@
                 // printf("apply fix for issue 9490: add `this.` to `%s`...\n", e.toChars());
                 e = new DotVarExp(exp.loc, new ThisExp(exp.loc), ve.var, false);
             }
-            //printf("e = %s %s\n", Token::toChars(e.op), e.toChars());
+            //printf("e = %s %s\n", Token.toChars(e.op), e.toChars());
             e = e.expressionSemantic(sc);
         }
         else if (t)
@@ -5211,13 +5216,30 @@
         if (s.ident)
         {
             VarDeclaration v = s.isVarDeclaration();
-            if (v && !(sc.flags & SCOPE.Cfile))
+            if (v)
             {
-                /* Do semantic() on initializer first so this will be illegal:
-                 *      int a = a;
-                 */
-                e.declaration.dsymbolSemantic(sc);
-                s.parent = sc.parent;
+                if (sc.flags & SCOPE.Cfile)
+                {
+                    /* Do semantic() on the type before inserting v into the symbol table
+                     */
+                    if (!v.originalType)
+                        v.originalType = v.type.syntaxCopy();
+                    Scope* sc2 = sc.push();
+                    sc2.stc |= v.storage_class & STC.FUNCATTR;
+                    sc2.linkage = LINK.c;       // account for the extern(C) in front of the declaration
+                    v.inuse++;
+                    v.type = v.type.typeSemantic(v.loc, sc2);
+                    v.inuse--;
+                    sc2.pop();
+                }
+                else
+                {
+                    /* Do semantic() on initializer first so this will be illegal:
+                     *      int a = a;
+                     */
+                    e.declaration.dsymbolSemantic(sc);
+                    s.parent = sc.parent;
+                }
             }
 
             if (!sc.insert(s))
@@ -6032,7 +6054,7 @@
             auto fileName = FileName(name.toDString);
             if (auto fmResult = global.fileManager.lookup(fileName))
             {
-                se = new StringExp(e.loc, fmResult.data);
+                se = new StringExp(e.loc, fmResult);
             }
             else
             {
@@ -6047,9 +6069,7 @@
                     // take ownership of buffer (probably leaking)
                     auto data = readResult.extractSlice();
                     se = new StringExp(e.loc, data);
-
-                    FileBuffer* fileBuffer = new FileBuffer(data);
-                    global.fileManager.add(fileName, fileBuffer);
+                    global.fileManager.add(fileName, data);
                 }
             }
         }
@@ -6388,7 +6408,7 @@
         static if (LOGSEMANTIC)
         {
             printf("DotIdExp::semantic(this = %p, '%s')\n", exp, exp.toChars());
-            //printf("e1.op = %d, '%s'\n", e1.op, Token::toChars(e1.op));
+            //printf("e1.op = %d, '%s'\n", e1.op, Token.toChars(e1.op));
         }
 
         if (sc.flags & SCOPE.Cfile)
@@ -8177,7 +8197,10 @@
             return;
 
         if (e.type is Type.tvoid)
+        {
+            checkMustUse(e.e1, sc);
             discardValue(e.e1);
+        }
         else if (!e.allowCommaExp && !e.isGenerated)
             e.error("Using the result of a comma expression is not allowed");
     }
@@ -8956,7 +8979,7 @@
 
                     Parameter arg = Parameter.getNth(tt.arguments, u);
                     //printf("[%d] iexps.dim = %d, ", u, iexps.dim);
-                    //printf("e = (%s %s, %s), ", Token::tochars[e.op], e.toChars(), e.type.toChars());
+                    //printf("e = (%s %s, %s), ", Token.toChars[e.op], e.toChars(), e.type.toChars());
                     //printf("arg = (%s, %s)\n", arg.toChars(), arg.type.toChars());
 
                     if (!arg || !e.type.implicitConvTo(arg.type))
@@ -9849,7 +9872,7 @@
          * `reorderSettingAAElem` creates a tree of comma expressions, however,
          * `checkAssignExp` expects only AssignExps.
          */
-        checkAssignEscape(sc, Expression.extractLast(res, tmp), false);
+        checkAssignEscape(sc, Expression.extractLast(res, tmp), false, false);
 
         if (auto ae = res.isConstructExp())
         {
@@ -10124,7 +10147,7 @@
                  */
                 if (isRecursiveAliasThis(exp.att1, exp.e1.type))
                     return null;
-                //printf("att %s e1 = %s\n", Token::toChars(e.op), e.e1.type.toChars());
+                //printf("att %s e1 = %s\n", Token.toChars(e.op), e.e1.type.toChars());
                 Expression e1 = new DotIdExp(exp.loc, exp.e1, ad1.aliasthis.ident);
                 BinExp be = cast(BinExp)exp.copy();
                 be.e1 = e1;
@@ -10142,7 +10165,7 @@
                  */
                 if (isRecursiveAliasThis(exp.att2, exp.e2.type))
                     return null;
-                //printf("att %s e2 = %s\n", Token::toChars(e.op), e.e2.type.toChars());
+                //printf("att %s e2 = %s\n", Token.toChars(e.op), e.e2.type.toChars());
                 Expression e2 = new DotIdExp(exp.loc, exp.e2, ad2.aliasthis.ident);
                 BinExp be = cast(BinExp)exp.copy();
                 be.e2 = e2;
@@ -10169,7 +10192,7 @@
         auto res = exp.reorderSettingAAElem(sc);
         if ((exp.op == EXP.concatenateElemAssign || exp.op == EXP.concatenateDcharAssign) &&
             global.params.useDIP1000 == FeatureState.enabled)
-            checkAssignEscape(sc, res, false);
+            checkAssignEscape(sc, res, false, false);
         result = res;
     }
 
@@ -12193,7 +12216,7 @@
     if (Expression ex = unaSemantic(exp, sc))
         return ex;
 
-    if (exp.ident == Id._mangleof)
+    if (!(sc.flags & SCOPE.Cfile) && exp.ident == Id._mangleof)
     {
         // symbol.mangleof
 
@@ -12302,6 +12325,8 @@
 
     //{ static int z; fflush(stdout); if (++z == 10) *(char*)0=0; }
 
+    const cfile = (sc.flags & SCOPE.Cfile) != 0;
+
     /* Special case: rewrite this.id and super.id
      * to be classtype.id and baseclasstype.id
      * if we have no this pointer.
@@ -12553,7 +12578,16 @@
             exp.error("undefined identifier `%s` in %s `%s`", exp.ident.toChars(), ie.sds.kind(), ie.sds.toPrettyChars());
         return ErrorExp.get();
     }
-    else if (t1b.ty == Tpointer && exp.e1.type.ty != Tenum && exp.ident != Id._init && exp.ident != Id.__sizeof && exp.ident != Id.__xalignof && exp.ident != Id.offsetof && exp.ident != Id._mangleof && exp.ident != Id.stringof)
+    else if (t1b.ty == Tpointer && exp.e1.type.ty != Tenum &&
+             !(
+               exp.ident == Id.__sizeof ||
+               exp.ident == Id.__xalignof ||
+               !cfile &&
+                (exp.ident == Id._mangleof ||
+                 exp.ident == Id.offsetof ||
+                 exp.ident == Id._init ||
+                 exp.ident == Id.stringof)
+              ))
     {
         Type t1bn = t1b.nextOf();
         if (flag)
@@ -12588,7 +12622,7 @@
         Expression e = new IntegerExp(exp.loc, actualAlignment, Type.tsize_t);
         return e;
     }
-    else if (sc.flags & SCOPE.Cfile && exp.ident == Id.__sizeof && exp.e1.isStringExp())
+    else if (cfile && exp.ident == Id.__sizeof && exp.e1.isStringExp())
     {
         // Sizeof string literal includes the terminating 0
         auto se = exp.e1.isStringExp();
@@ -12803,129 +12837,125 @@
         return false;
     }
 
-    //printf("checkSharedAccess() %s\n", e.toChars());
+    //printf("checkSharedAccess() `%s` returnRef: %d\n", e.toChars(), returnRef);
 
-    static extern(C++) final class SharedCheckVisitor : SemanticTimeTransitiveVisitor
+    /* In case we don't know which expression triggered it,
+     * e.g. for `visit(Type)` overload
+     */
+    Expression original = e;
+
+    bool check(Expression e, bool allowRef)
     {
-        /// In case we don't know which expression triggered it,
-        /// e.g. for `visit(Type)` overload
-        Expression original;
-        /// Where the result is stored (`true` == error)
-        bool result;
-        /// Whether we should allow one level of dereferencing
-        bool allowRef;
-
-        /// Ctor
-        this(Expression oe, bool allowRef_)
-        {
-            this.original = oe;
-            this.allowRef = allowRef_;
-        }
-
-        void sharedError(Expression e)
+        bool sharedError(Expression e)
         {
             // https://dlang.org/phobos/core_atomic.html
             e.error("direct access to shared `%s` is not allowed, see `core.atomic`", e.toChars());
-            this.result = true;
+            return true;
         }
 
-        /// Introduce base class overrides
-        alias visit = SemanticTimeTransitiveVisitor.visit;
-
         // Error by default
-        override void visit(Expression e)
+        bool visit(Expression e)
         {
             if (e.type.isShared())
-                this.sharedError(e);
+                return sharedError(e);
+            return false;
         }
 
-        /// Ditto
-        override void visit(Type t)
+        bool visitNew(NewExp e)
         {
+            if (e.thisexp)
+                check(e.thisexp, false);
             // Note: This handles things like `new shared(Throwable).msg`,
             // where accessing `msg` would violate `shared`.
-            if (t.isShared())
-                this.sharedError(this.original);
+            if (e.newtype.isShared())
+                return sharedError(original);
+            return false;
         }
 
-        // Those have no indirections / can be ignored
-        override void visit(ErrorExp e) {}
-        override void visit(ComplexExp e) {}
-        override void visit(IntegerExp e) {}
-        override void visit(NullExp e) {}
-
-        override void visit(VarExp e)
+        bool visitVar(VarExp e)
         {
-            if (!this.allowRef && e.var.type.isShared())
-                this.sharedError(e);
+            if (!allowRef && e.var.type.isShared())
+                return sharedError(e);
+            return false;
         }
 
-        override void visit(AddrExp e)
+        bool visitAddr(AddrExp e)
         {
-            this.allowRef = true;
-            e.e1.accept(this);
+            return check(e.e1, true);
         }
 
-        override void visit(PtrExp e)
+        bool visitPtr(PtrExp e)
         {
-            if (!this.allowRef && e.type.isShared())
-                return this.sharedError(e);
+            if (!allowRef && e.type.isShared())
+                return sharedError(e);
 
             if (e.e1.type.isShared())
-                return this.sharedError(e);
+                return sharedError(e);
 
-            this.allowRef = false;
-            e.e1.accept(this);
+            return check(e.e1, false);
         }
 
-        override void visit(DotVarExp e)
+        bool visitDotVar(DotVarExp e)
         {
             auto fd = e.var.isFuncDeclaration();
             const sharedFunc = fd && fd.type.isShared;
 
-            if (!this.allowRef && e.type.isShared() && !sharedFunc)
-                return this.sharedError(e);
+            if (!allowRef && e.type.isShared() && !sharedFunc)
+                return sharedError(e);
 
-            // Allow to use `DotVarExp` within value types
-            if (e.e1.type.ty == Tsarray || e.e1.type.ty == Tstruct)
-                return e.e1.accept(this);
+            // Allow using `DotVarExp` within value types
+            if (e.e1.type.isTypeSArray() || e.e1.type.isTypeStruct())
+                return check(e.e1, allowRef);
 
             // If we end up with a single `VarExp`, it might be a `ref` param
             // `shared ref T` param == `shared(T)*`.
             if (auto ve = e.e1.isVarExp())
             {
-                this.allowRef = this.allowRef && (ve.var.storage_class & STC.ref_);
-                return e.e1.accept(this);
+                return check(e.e1, allowRef && (ve.var.storage_class & STC.ref_));
             }
 
-            this.allowRef = false;
-            return e.e1.accept(this);
+            return check(e.e1, false);
         }
 
-        override void visit(IndexExp e)
+        bool visitIndex(IndexExp e)
         {
-            if (!this.allowRef && e.type.isShared())
-                return this.sharedError(e);
+            if (!allowRef && e.type.isShared())
+                return sharedError(e);
 
             if (e.e1.type.isShared())
-                return this.sharedError(e);
+                return sharedError(e);
 
-            this.allowRef = false;
-            e.e1.accept(this);
+            return check(e.e1, false);
         }
 
-        override void visit(CommaExp e)
+        bool visitComma(CommaExp e)
         {
             // Cannot be `return ref` since we can't use the return,
             // but it's better to show that error than an unrelated `shared` one
-            this.allowRef = true;
-            e.e2.accept(this);
+            return check(e.e2, true);
+        }
+
+        switch (e.op)
+        {
+            default:              return visit(e);
+
+            // Those have no indirections / can be ignored
+            case EXP.call:
+            case EXP.error:
+            case EXP.complex80:
+            case EXP.int64:
+            case EXP.null_:       return false;
+
+            case EXP.variable:    return visitVar(e.isVarExp());
+            case EXP.new_:        return visitNew(e.isNewExp());
+            case EXP.address:     return visitAddr(e.isAddrExp());
+            case EXP.star:        return visitPtr(e.isPtrExp());
+            case EXP.dotVariable: return visitDotVar(e.isDotVarExp());
+            case EXP.index:       return visitIndex(e.isIndexExp());
         }
     }
 
-    scope visitor = new SharedCheckVisitor(e, returnRef);
-    e.accept(visitor);
-    return visitor.result;
+    return check(e, returnRef);
 }
 
 
diff --git a/gcc/d/dmd/file_manager.d b/gcc/d/dmd/file_manager.d
index b86c799..9fe40bf 100644
--- a/gcc/d/dmd/file_manager.d
+++ b/gcc/d/dmd/file_manager.d
@@ -11,7 +11,7 @@
 module dmd.file_manager;
 
 import dmd.root.stringtable : StringTable;
-import dmd.root.file : File, FileBuffer;
+import dmd.root.file : File, Buffer;
 import dmd.root.filename : FileName;
 import dmd.root.string : toDString;
 import dmd.globals;
@@ -22,7 +22,7 @@
 
 final class FileManager
 {
-    private StringTable!(FileBuffer*) files;
+    private StringTable!(const(ubyte)[]) files;
 
     ///
     public this () nothrow
@@ -146,7 +146,7 @@
      * Returns: the loaded source file if it was found in memory,
      *      otherwise `null`
      */
-    const(FileBuffer)* lookup(FileName filename)
+    const(ubyte)[] lookup(FileName filename)
     {
         const name = filename.toString;
         if (auto val = files.lookup(name))
@@ -154,7 +154,7 @@
 
         if (name == "__stdin.d")
         {
-            auto buffer = new FileBuffer(readFromStdin().extractSlice());
+            auto buffer = readFromStdin().extractSlice();
             if (this.files.insert(name, buffer) is null)
                 assert(0, "stdin: Insert after lookup failure should never return `null`");
             return buffer;
@@ -167,7 +167,7 @@
         if (!readResult.success)
             return null;
 
-        FileBuffer* fb = new FileBuffer(readResult.extractSlice());
+        auto fb = readResult.extractSlice();
         if (files.insert(name, fb) is null)
             assert(0, "Insert after lookup failure should never return `null`");
 
@@ -187,17 +187,17 @@
         const(char)[][] lines;
         if (const buffer = lookup(file))
         {
-            const slice = buffer.data[0 .. buffer.data.length];
+            const slice = buffer;
             size_t start, end;
-            ubyte c;
             for (auto i = 0; i < slice.length; i++)
             {
-                c = slice[i];
+                const c = slice[i];
                 if (c == '\n' || c == '\r')
                 {
                     if (i != 0)
                     {
                         end = i;
+                        // Appending lines one at a time will certainly be slow
                         lines ~= cast(const(char)[])slice[start .. end];
                     }
                     // Check for Windows-style CRLF newlines
@@ -234,18 +234,21 @@
     }
 
     /**
-     * Adds a FileBuffer to the table.
-     *
-     * Returns: The FileBuffer added, or null
+     * Adds the contents of a file to the table.
+     * Params:
+     *  filename = name of the file
+     *  buffer = contents of the file
+     * Returns:
+     *  the buffer added, or null
      */
-    FileBuffer* add(FileName filename, FileBuffer* filebuffer)
+    const(ubyte)[] add(FileName filename, const(ubyte)[] buffer)
     {
-        auto val = files.insert(filename.toString, filebuffer);
+        auto val = files.insert(filename.toString, buffer);
         return val == null ? null : val.value;
     }
 }
 
-private FileBuffer readFromStdin() nothrow
+private Buffer readFromStdin() nothrow
 {
     import core.stdc.stdio;
     import dmd.errors;
@@ -277,7 +280,7 @@
                 // We're done
                 assert(pos < sz + 2);
                 buffer[pos .. pos + 4] = '\0';
-                return FileBuffer(buffer[0 .. pos]);
+                return Buffer(buffer[0 .. pos]);
             }
         } while (pos < sz);
 
diff --git a/gcc/d/dmd/hdrgen.d b/gcc/d/dmd/hdrgen.d
index a3afbe5..69fdf27 100644
--- a/gcc/d/dmd/hdrgen.d
+++ b/gcc/d/dmd/hdrgen.d
@@ -1538,6 +1538,13 @@
             }
             else if (hgs.tpltMember == 0 && global.params.hdrStripPlainFunctions)
             {
+                if (!f.fbody)
+                {
+                    // this can happen on interfaces / abstract functions, see `allowsContractWithoutBody`
+                    if (f.fensures || f.frequires)
+                        buf.writenl();
+                    contractsToBuffer(f);
+                }
                 buf.writeByte(';');
                 buf.writenl();
             }
@@ -1548,19 +1555,9 @@
             bodyToBuffer(f);
     }
 
-    void bodyToBuffer(FuncDeclaration f)
+    /// Returns: whether `do` is needed to write the function body
+    bool contractsToBuffer(FuncDeclaration f)
     {
-        if (!f.fbody || (hgs.hdrgen && global.params.hdrStripPlainFunctions && !hgs.autoMember && !hgs.tpltMember))
-        {
-            buf.writeByte(';');
-            buf.writenl();
-            return;
-        }
-        const savetlpt = hgs.tpltMember;
-        const saveauto = hgs.autoMember;
-        hgs.tpltMember = 0;
-        hgs.autoMember = 0;
-        buf.writenl();
         bool requireDo = false;
         // in{}
         if (f.frequires)
@@ -1619,6 +1616,29 @@
                 }
             }
         }
+        return requireDo;
+    }
+
+    void bodyToBuffer(FuncDeclaration f)
+    {
+        if (!f.fbody || (hgs.hdrgen && global.params.hdrStripPlainFunctions && !hgs.autoMember && !hgs.tpltMember))
+        {
+            if (!f.fbody && (f.fensures || f.frequires))
+            {
+                buf.writenl();
+                contractsToBuffer(f);
+            }
+            buf.writeByte(';');
+            buf.writenl();
+            return;
+        }
+        const savetlpt = hgs.tpltMember;
+        const saveauto = hgs.autoMember;
+        hgs.tpltMember = 0;
+        hgs.autoMember = 0;
+        buf.writenl();
+        bool requireDo = contractsToBuffer(f);
+
         if (requireDo)
         {
             buf.writestring("do");
@@ -1788,26 +1808,17 @@
     }
 }
 
-private extern (C++) final class ExpressionPrettyPrintVisitor : Visitor
+/*********************************************
+ * Print expression to buffer.
+ */
+private void expressionPrettyPrint(Expression e, OutBuffer* buf, HdrGenState* hgs)
 {
-    alias visit = Visitor.visit;
-public:
-    OutBuffer* buf;
-    HdrGenState* hgs;
-
-    extern (D) this(OutBuffer* buf, HdrGenState* hgs)
-    {
-        this.buf = buf;
-        this.hgs = hgs;
-    }
-
-    ////////////////////////////////////////////////////////////////////////////
-    override void visit(Expression e)
+    void visit(Expression e)
     {
         buf.writestring(EXPtoString(e.op));
     }
 
-    override void visit(IntegerExp e)
+    void visitInteger(IntegerExp e)
     {
         const dinteger_t v = e.toInteger();
         if (e.type)
@@ -1907,12 +1918,12 @@
             buf.print(v);
     }
 
-    override void visit(ErrorExp e)
+    void visitError(ErrorExp e)
     {
         buf.writestring("__error");
     }
 
-    override void visit(VoidInitExp e)
+    void visitVoidInit(VoidInitExp e)
     {
         buf.writestring("__void");
     }
@@ -1922,12 +1933,12 @@
         .floatToBuffer(type, value, buf, hgs.hdrgen);
     }
 
-    override void visit(RealExp e)
+    void visitReal(RealExp e)
     {
         floatToBuffer(e.type, e.value);
     }
 
-    override void visit(ComplexExp e)
+    void visitComplex(ComplexExp e)
     {
         /* Print as:
          *  (re+imi)
@@ -1939,7 +1950,7 @@
         buf.writestring("i)");
     }
 
-    override void visit(IdentifierExp e)
+    void visitIdentifier(IdentifierExp e)
     {
         if (hgs.hdrgen || hgs.ddoc)
             buf.writestring(e.ident.toHChars2());
@@ -1947,27 +1958,27 @@
             buf.writestring(e.ident.toString());
     }
 
-    override void visit(DsymbolExp e)
+    void visitDsymbol(DsymbolExp e)
     {
         buf.writestring(e.s.toChars());
     }
 
-    override void visit(ThisExp e)
+    void visitThis(ThisExp e)
     {
         buf.writestring("this");
     }
 
-    override void visit(SuperExp e)
+    void visitSuper(SuperExp e)
     {
         buf.writestring("super");
     }
 
-    override void visit(NullExp e)
+    void visitNull(NullExp e)
     {
         buf.writestring("null");
     }
 
-    override void visit(StringExp e)
+    void visitString(StringExp e)
     {
         buf.writeByte('"');
         const o = buf.length;
@@ -1982,14 +1993,14 @@
             buf.writeByte(e.postfix);
     }
 
-    override void visit(ArrayLiteralExp e)
+    void visitArrayLiteral(ArrayLiteralExp e)
     {
         buf.writeByte('[');
         argsToBuffer(e.elements, buf, hgs, e.basis);
         buf.writeByte(']');
     }
 
-    override void visit(AssocArrayLiteralExp e)
+    void visitAssocArrayLiteral(AssocArrayLiteralExp e)
     {
         buf.writeByte('[');
         foreach (i, key; *e.keys)
@@ -2004,7 +2015,7 @@
         buf.writeByte(']');
     }
 
-    override void visit(StructLiteralExp e)
+    void visitStructLiteral(StructLiteralExp e)
     {
         buf.writestring(e.sd.toChars());
         buf.writeByte('(');
@@ -2024,7 +2035,7 @@
         buf.writeByte(')');
     }
 
-    override void visit(CompoundLiteralExp e)
+    void visitCompoundLiteral(CompoundLiteralExp e)
     {
         buf.writeByte('(');
         typeToBuffer(e.type, null, buf, hgs);
@@ -2032,12 +2043,12 @@
         e.initializer.initializerToBuffer(buf, hgs);
     }
 
-    override void visit(TypeExp e)
+    void visitType(TypeExp e)
     {
         typeToBuffer(e.type, null, buf, hgs);
     }
 
-    override void visit(ScopeExp e)
+    void visitScope(ScopeExp e)
     {
         if (e.sds.isTemplateInstance())
         {
@@ -2059,12 +2070,12 @@
         }
     }
 
-    override void visit(TemplateExp e)
+    void visitTemplate(TemplateExp e)
     {
         buf.writestring(e.td.toChars());
     }
 
-    override void visit(NewExp e)
+    void visitNew(NewExp e)
     {
         if (e.thisexp)
         {
@@ -2081,7 +2092,7 @@
         }
     }
 
-    override void visit(NewAnonClassExp e)
+    void visitNewAnonClass(NewAnonClassExp e)
     {
         if (e.thisexp)
         {
@@ -2100,7 +2111,7 @@
             e.cd.dsymbolToBuffer(buf, hgs);
     }
 
-    override void visit(SymOffExp e)
+    void visitSymOff(SymOffExp e)
     {
         if (e.offset)
             buf.printf("(& %s%+lld)", e.var.toChars(), e.offset);
@@ -2110,22 +2121,22 @@
             buf.printf("& %s", e.var.toChars());
     }
 
-    override void visit(VarExp e)
+    void visitVar(VarExp e)
     {
         buf.writestring(e.var.toChars());
     }
 
-    override void visit(OverExp e)
+    void visitOver(OverExp e)
     {
         buf.writestring(e.vars.ident.toString());
     }
 
-    override void visit(TupleExp e)
+    void visitTuple(TupleExp e)
     {
         if (e.e0)
         {
             buf.writeByte('(');
-            e.e0.accept(this);
+            e.e0.expressionPrettyPrint(buf, hgs);
             buf.writestring(", tuple(");
             argsToBuffer(e.exps, buf, hgs);
             buf.writestring("))");
@@ -2138,13 +2149,13 @@
         }
     }
 
-    override void visit(FuncExp e)
+    void visitFunc(FuncExp e)
     {
         e.fd.dsymbolToBuffer(buf, hgs);
         //buf.writestring(e.fd.toChars());
     }
 
-    override void visit(DeclarationExp e)
+    void visitDeclaration(DeclarationExp e)
     {
         /* Normal dmd execution won't reach here - regular variable declarations
          * are handled in visit(ExpStatement), so here would be used only when
@@ -2170,14 +2181,14 @@
         }
     }
 
-    override void visit(TypeidExp e)
+    void visitTypeid(TypeidExp e)
     {
         buf.writestring("typeid(");
         objectToBuffer(e.obj, buf, hgs);
         buf.writeByte(')');
     }
 
-    override void visit(TraitsExp e)
+    void visitTraits(TraitsExp e)
     {
         buf.writestring("__traits(");
         if (e.ident)
@@ -2193,12 +2204,12 @@
         buf.writeByte(')');
     }
 
-    override void visit(HaltExp e)
+    void visitHalt(HaltExp e)
     {
         buf.writestring("halt");
     }
 
-    override void visit(IsExp e)
+    void visitIs(IsExp e)
     {
         buf.writestring("is(");
         typeToBuffer(e.targ, e.id, buf, hgs);
@@ -2223,13 +2234,13 @@
         buf.writeByte(')');
     }
 
-    override void visit(UnaExp e)
+    void visitUna(UnaExp e)
     {
         buf.writestring(EXPtoString(e.op));
         expToBuffer(e.e1, precedence[e.op], buf, hgs);
     }
 
-    override void visit(BinExp e)
+    void visitBin(BinExp e)
     {
         expToBuffer(e.e1, precedence[e.op], buf, hgs);
         buf.writeByte(' ');
@@ -2238,7 +2249,7 @@
         expToBuffer(e.e2, cast(PREC)(precedence[e.op] + 1), buf, hgs);
     }
 
-    override void visit(CommaExp e)
+    void visitComma(CommaExp e)
     {
         // CommaExp is generated by the compiler so it shouldn't
         // appear in error messages or header files.
@@ -2251,7 +2262,7 @@
         // the old path
         if (!ve || !(ve.var.storage_class & STC.temp))
         {
-            visit(cast(BinExp)e);
+            visitBin(cast(BinExp)e);
             return;
         }
 
@@ -2281,25 +2292,25 @@
         }
 
         // not one of the known cases, go on the old path
-        visit(cast(BinExp)e);
+        visitBin(cast(BinExp)e);
         return;
     }
 
-    override void visit(MixinExp e)
+    void visitMixin(MixinExp e)
     {
         buf.writestring("mixin(");
         argsToBuffer(e.exps, buf, hgs, null);
         buf.writeByte(')');
     }
 
-    override void visit(ImportExp e)
+    void visitImport(ImportExp e)
     {
         buf.writestring("import(");
         expToBuffer(e.e1, PREC.assign, buf, hgs);
         buf.writeByte(')');
     }
 
-    override void visit(AssertExp e)
+    void visitAssert(AssertExp e)
     {
         buf.writestring("assert(");
         expToBuffer(e.e1, PREC.assign, buf, hgs);
@@ -2311,13 +2322,13 @@
         buf.writeByte(')');
     }
 
-    override void visit(ThrowExp e)
+    void visitThrow(ThrowExp e)
     {
         buf.writestring("throw ");
         expToBuffer(e.e1, PREC.unary, buf, hgs);
     }
 
-    override void visit(DotIdExp e)
+    void visitDotId(DotIdExp e)
     {
         expToBuffer(e.e1, PREC.primary, buf, hgs);
         if (e.arrow)
@@ -2327,28 +2338,28 @@
         buf.writestring(e.ident.toString());
     }
 
-    override void visit(DotTemplateExp e)
+    void visitDotTemplate(DotTemplateExp e)
     {
         expToBuffer(e.e1, PREC.primary, buf, hgs);
         buf.writeByte('.');
         buf.writestring(e.td.toChars());
     }
 
-    override void visit(DotVarExp e)
+    void visitDotVar(DotVarExp e)
     {
         expToBuffer(e.e1, PREC.primary, buf, hgs);
         buf.writeByte('.');
         buf.writestring(e.var.toChars());
     }
 
-    override void visit(DotTemplateInstanceExp e)
+    void visitDotTemplateInstance(DotTemplateInstanceExp e)
     {
         expToBuffer(e.e1, PREC.primary, buf, hgs);
         buf.writeByte('.');
         e.ti.dsymbolToBuffer(buf, hgs);
     }
 
-    override void visit(DelegateExp e)
+    void visitDelegate(DelegateExp e)
     {
         buf.writeByte('&');
         if (!e.func.isNested() || e.func.needThis())
@@ -2359,14 +2370,14 @@
         buf.writestring(e.func.toChars());
     }
 
-    override void visit(DotTypeExp e)
+    void visitDotType(DotTypeExp e)
     {
         expToBuffer(e.e1, PREC.primary, buf, hgs);
         buf.writeByte('.');
         buf.writestring(e.sym.toChars());
     }
 
-    override void visit(CallExp e)
+    void visitCall(CallExp e)
     {
         if (e.e1.op == EXP.type)
         {
@@ -2375,7 +2386,7 @@
              * This is ok since types in constructor calls
              * can never depend on parens anyway
              */
-            e.e1.accept(this);
+            e.e1.expressionPrettyPrint(buf, hgs);
         }
         else
             expToBuffer(e.e1, precedence[e.op], buf, hgs);
@@ -2384,19 +2395,19 @@
         buf.writeByte(')');
     }
 
-    override void visit(PtrExp e)
+    void visitPtr(PtrExp e)
     {
         buf.writeByte('*');
         expToBuffer(e.e1, precedence[e.op], buf, hgs);
     }
 
-    override void visit(DeleteExp e)
+    void visitDelete(DeleteExp e)
     {
         buf.writestring("delete ");
         expToBuffer(e.e1, precedence[e.op], buf, hgs);
     }
 
-    override void visit(CastExp e)
+    void visitCast(CastExp e)
     {
         buf.writestring("cast(");
         if (e.to)
@@ -2409,7 +2420,7 @@
         expToBuffer(e.e1, precedence[e.op], buf, hgs);
     }
 
-    override void visit(VectorExp e)
+    void visitVector(VectorExp e)
     {
         buf.writestring("cast(");
         typeToBuffer(e.to, null, buf, hgs);
@@ -2417,13 +2428,13 @@
         expToBuffer(e.e1, precedence[e.op], buf, hgs);
     }
 
-    override void visit(VectorArrayExp e)
+    void visitVectorArray(VectorArrayExp e)
     {
         expToBuffer(e.e1, PREC.primary, buf, hgs);
         buf.writestring(".array");
     }
 
-    override void visit(SliceExp e)
+    void visitSlice(SliceExp e)
     {
         expToBuffer(e.e1, precedence[e.op], buf, hgs);
         buf.writeByte('[');
@@ -2442,32 +2453,32 @@
         buf.writeByte(']');
     }
 
-    override void visit(ArrayLengthExp e)
+    void visitArrayLength(ArrayLengthExp e)
     {
         expToBuffer(e.e1, PREC.primary, buf, hgs);
         buf.writestring(".length");
     }
 
-    override void visit(IntervalExp e)
+    void visitInterval(IntervalExp e)
     {
         expToBuffer(e.lwr, PREC.assign, buf, hgs);
         buf.writestring("..");
         expToBuffer(e.upr, PREC.assign, buf, hgs);
     }
 
-    override void visit(DelegatePtrExp e)
+    void visitDelegatePtr(DelegatePtrExp e)
     {
         expToBuffer(e.e1, PREC.primary, buf, hgs);
         buf.writestring(".ptr");
     }
 
-    override void visit(DelegateFuncptrExp e)
+    void visitDelegateFuncptr(DelegateFuncptrExp e)
     {
         expToBuffer(e.e1, PREC.primary, buf, hgs);
         buf.writestring(".funcptr");
     }
 
-    override void visit(ArrayExp e)
+    void visitArray(ArrayExp e)
     {
         expToBuffer(e.e1, PREC.primary, buf, hgs);
         buf.writeByte('[');
@@ -2475,14 +2486,14 @@
         buf.writeByte(']');
     }
 
-    override void visit(DotExp e)
+    void visitDot(DotExp e)
     {
         expToBuffer(e.e1, PREC.primary, buf, hgs);
         buf.writeByte('.');
         expToBuffer(e.e2, PREC.primary, buf, hgs);
     }
 
-    override void visit(IndexExp e)
+    void visitIndex(IndexExp e)
     {
         expToBuffer(e.e1, PREC.primary, buf, hgs);
         buf.writeByte('[');
@@ -2490,19 +2501,19 @@
         buf.writeByte(']');
     }
 
-    override void visit(PostExp e)
+    void visitPost(PostExp e)
     {
         expToBuffer(e.e1, precedence[e.op], buf, hgs);
         buf.writestring(EXPtoString(e.op));
     }
 
-    override void visit(PreExp e)
+    void visitPre(PreExp e)
     {
         buf.writestring(EXPtoString(e.op));
         expToBuffer(e.e1, precedence[e.op], buf, hgs);
     }
 
-    override void visit(RemoveExp e)
+    void visitRemove(RemoveExp e)
     {
         expToBuffer(e.e1, PREC.primary, buf, hgs);
         buf.writestring(".remove(");
@@ -2510,7 +2521,7 @@
         buf.writeByte(')');
     }
 
-    override void visit(CondExp e)
+    void visitCond(CondExp e)
     {
         expToBuffer(e.econd, PREC.oror, buf, hgs);
         buf.writestring(" ? ");
@@ -2519,15 +2530,90 @@
         expToBuffer(e.e2, PREC.cond, buf, hgs);
     }
 
-    override void visit(DefaultInitExp e)
+    void visitDefaultInit(DefaultInitExp e)
     {
         buf.writestring(EXPtoString(e.op));
     }
 
-    override void visit(ClassReferenceExp e)
+    void visitClassReference(ClassReferenceExp e)
     {
         buf.writestring(e.value.toChars());
     }
+
+    switch (e.op)
+    {
+        default:
+            if (auto be = e.isBinExp())
+                return visitBin(be);
+            else if (auto ue = e.isUnaExp())
+                return visitUna(ue);
+            else if (auto de = e.isDefaultInitExp())
+                return visitDefaultInit(e.isDefaultInitExp());
+            return visit(e);
+
+        case EXP.int64:         return visitInteger(e.isIntegerExp());
+        case EXP.error:         return visitError(e.isErrorExp());
+        case EXP.void_:         return visitVoidInit(e.isVoidInitExp());
+        case EXP.float64:       return visitReal(e.isRealExp());
+        case EXP.complex80:     return visitComplex(e.isComplexExp());
+        case EXP.identifier:    return visitIdentifier(e.isIdentifierExp());
+        case EXP.dSymbol:       return visitDsymbol(e.isDsymbolExp());
+        case EXP.this_:         return visitThis(e.isThisExp());
+        case EXP.super_:        return visitSuper(e.isSuperExp());
+        case EXP.null_:         return visitNull(e.isNullExp());
+        case EXP.string_:       return visitString(e.isStringExp());
+        case EXP.arrayLiteral:  return visitArrayLiteral(e.isArrayLiteralExp());
+        case EXP.assocArrayLiteral:     return visitAssocArrayLiteral(e.isAssocArrayLiteralExp());
+        case EXP.structLiteral: return visitStructLiteral(e.isStructLiteralExp());
+        case EXP.compoundLiteral:       return visitCompoundLiteral(e.isCompoundLiteralExp());
+        case EXP.type:          return visitType(e.isTypeExp());
+        case EXP.scope_:        return visitScope(e.isScopeExp());
+        case EXP.template_:     return visitTemplate(e.isTemplateExp());
+        case EXP.new_:          return visitNew(e.isNewExp());
+        case EXP.newAnonymousClass:     return visitNewAnonClass(e.isNewAnonClassExp());
+        case EXP.symbolOffset:  return visitSymOff(e.isSymOffExp());
+        case EXP.variable:      return visitVar(e.isVarExp());
+        case EXP.overloadSet:   return visitOver(e.isOverExp());
+        case EXP.tuple:         return visitTuple(e.isTupleExp());
+        case EXP.function_:     return visitFunc(e.isFuncExp());
+        case EXP.declaration:   return visitDeclaration(e.isDeclarationExp());
+        case EXP.typeid_:       return visitTypeid(e.isTypeidExp());
+        case EXP.traits:        return visitTraits(e.isTraitsExp());
+        case EXP.halt:          return visitHalt(e.isHaltExp());
+        case EXP.is_:           return visitIs(e.isExp());
+        case EXP.comma:         return visitComma(e.isCommaExp());
+        case EXP.mixin_:        return visitMixin(e.isMixinExp());
+        case EXP.import_:       return visitImport(e.isImportExp());
+        case EXP.assert_:       return visitAssert(e.isAssertExp());
+        case EXP.throw_:        return visitThrow(e.isThrowExp());
+        case EXP.dotIdentifier: return visitDotId(e.isDotIdExp());
+        case EXP.dotTemplateDeclaration:        return visitDotTemplate(e.isDotTemplateExp());
+        case EXP.dotVariable:   return visitDotVar(e.isDotVarExp());
+        case EXP.dotTemplateInstance:   return visitDotTemplateInstance(e.isDotTemplateInstanceExp());
+        case EXP.delegate_:     return visitDelegate(e.isDelegateExp());
+        case EXP.dotType:       return visitDotType(e.isDotTypeExp());
+        case EXP.call:          return visitCall(e.isCallExp());
+        case EXP.star:          return visitPtr(e.isPtrExp());
+        case EXP.delete_:       return visitDelete(e.isDeleteExp());
+        case EXP.cast_:         return visitCast(e.isCastExp());
+        case EXP.vector:        return visitVector(e.isVectorExp());
+        case EXP.vectorArray:   return visitVectorArray(e.isVectorArrayExp());
+        case EXP.slice:         return visitSlice(e.isSliceExp());
+        case EXP.arrayLength:   return visitArrayLength(e.isArrayLengthExp());
+        case EXP.interval:      return visitInterval(e.isIntervalExp());
+        case EXP.delegatePointer:       return visitDelegatePtr(e.isDelegatePtrExp());
+        case EXP.delegateFunctionPointer:       return visitDelegateFuncptr(e.isDelegateFuncptrExp());
+        case EXP.array:         return visitArray(e.isArrayExp());
+        case EXP.dot:           return visitDot(e.isDotExp());
+        case EXP.index:         return visitIndex(e.isIndexExp());
+        case EXP.minusMinus:
+        case EXP.plusPlus:      return visitPost(e.isPostExp());
+        case EXP.preMinusMinus:
+        case EXP.prePlusPlus:   return visitPre(e.isPreExp());
+        case EXP.remove:        return visitRemove(e.isRemoveExp());
+        case EXP.question:      return visitCond(e.isCondExp());
+        case EXP.classReference:        return visitClassReference(e.isClassReferenceExp());
+    }
 }
 
 /**
@@ -2547,7 +2633,7 @@
         (ie, 8 chars more than mantissa). Plus one for trailing \0.
         Plus one for rounding. */
     const(size_t) BUFFER_LEN = value.sizeof * 3 + 8 + 1 + 1;
-    char[BUFFER_LEN] buffer;
+    char[BUFFER_LEN] buffer = void;
     CTFloat.sprint(buffer.ptr, 'g', value);
     assert(strlen(buffer.ptr) < BUFFER_LEN);
     if (allowHex)
@@ -2754,7 +2840,7 @@
     }
     if (stc & STC.returninferred)
     {
-        //buf.writestring("return-inferred ");
+        //buf.writestring((stc & STC.returnScope) ? "return-scope-inferred " : "return-ref-inferred ");
         stc &= ~(STC.return_ | STC.returninferred);
     }
 
@@ -2958,8 +3044,7 @@
 
 void toCBuffer(const Expression e, OutBuffer* buf, HdrGenState* hgs)
 {
-    scope v = new ExpressionPrettyPrintVisitor(buf, hgs);
-    (cast() e).accept(v);
+    expressionPrettyPrint(cast()e, buf, hgs);
 }
 
 /**************************************************
@@ -3221,8 +3306,7 @@
 
 private void expressionToBuffer(Expression e, OutBuffer* buf, HdrGenState* hgs)
 {
-    scope v = new ExpressionPrettyPrintVisitor(buf, hgs);
-    e.accept(v);
+    expressionPrettyPrint(e, buf, hgs);
 }
 
 /**************************************************
diff --git a/gcc/d/dmd/id.d b/gcc/d/dmd/id.d
index 2ec75ab..11455af 100644
--- a/gcc/d/dmd/id.d
+++ b/gcc/d/dmd/id.d
@@ -491,6 +491,7 @@
     { "udaGNUAbiTag", "gnuAbiTag" },
     { "udaSelector", "selector" },
     { "udaOptional", "optional"},
+    { "udaMustUse", "mustuse" },
 
     // C names, for undefined identifier error messages
     { "NULL" },
diff --git a/gcc/d/dmd/initsem.d b/gcc/d/dmd/initsem.d
index 649d88e..c84a9f6 100644
--- a/gcc/d/dmd/initsem.d
+++ b/gcc/d/dmd/initsem.d
@@ -554,26 +554,39 @@
                     i.exp = e.optimize(WANTvalue);
             }
         }
+        {
         // Look for the case of statically initializing an array
         // with a single member.
-        if (tb.ty == Tsarray && !tb.nextOf().equals(ti.toBasetype().nextOf()) && i.exp.implicitConvTo(tb.nextOf()))
+        auto tba = tb.isTypeSArray();
+        if (tba && !tba.next.equals(ti.toBasetype().nextOf()) && i.exp.implicitConvTo(tba.next))
         {
             /* If the variable is not actually used in compile time, array creation is
              * redundant. So delay it until invocation of toExpression() or toDt().
              */
             t = tb.nextOf();
         }
+
+        auto tta = t.isTypeSArray();
         if (i.exp.implicitConvTo(t))
         {
             i.exp = i.exp.implicitCastTo(sc, t);
         }
+        else if (sc.flags & SCOPE.Cfile && i.exp.isStringExp() &&
+            tta && (tta.next.ty == Tint8 || tta.next.ty == Tuns8) &&
+            ti.ty == Tpointer && ti.nextOf().ty == Tchar)
+        {
+            /* unsigned char bbb[1] = "";
+             *   signed char ccc[1] = "";
+             */
+            i.exp = i.exp.castTo(sc, t);
+        }
         else
         {
             // Look for mismatch of compile-time known length to emit
             // better diagnostic message, as same as AssignExp::semantic.
-            if (tb.ty == Tsarray && i.exp.implicitConvTo(tb.nextOf().arrayOf()) > MATCH.nomatch)
+            if (tba && i.exp.implicitConvTo(tba.next.arrayOf()) > MATCH.nomatch)
             {
-                uinteger_t dim1 = tb.isTypeSArray().dim.toInteger();
+                uinteger_t dim1 = tba.dim.toInteger();
                 uinteger_t dim2 = dim1;
                 if (auto ale = i.exp.isArrayLiteralExp())
                 {
@@ -596,6 +609,7 @@
             if (global.endGagging(errors))
                 currExp.error("cannot implicitly convert expression `%s` of type `%s` to `%s`", currExp.toChars(), et.toChars(), t.toChars());
         }
+        }
     L1:
         if (i.exp.op == EXP.error)
         {
@@ -681,7 +695,7 @@
                 assert(sc);
                 auto tm = vd.type.addMod(ts.mod);
                 auto iz = di.initializer.initializerSemantic(sc, tm, needInterpret);
-                auto ex = iz.initializerToExpression();
+                auto ex = iz.initializerToExpression(null, true);
                 if (ex.op == EXP.error)
                 {
                     errors = true;
@@ -1059,7 +1073,7 @@
 
     Initializer visitC(CInitializer i)
     {
-        //printf(CInitializer::inferType()\n");
+        //printf("CInitializer.inferType()\n");
         error(i.loc, "TODO C inferType initializers not supported yet");
         return new ErrorInitializer();
     }
@@ -1086,6 +1100,8 @@
  */
 extern (C++) Expression initializerToExpression(Initializer init, Type itype = null, const bool isCfile = false)
 {
+    //printf("initializerToExpression() isCfile: %d\n", isCfile);
+
     Expression visitVoid(VoidInitializer)
     {
         return null;
@@ -1183,7 +1199,7 @@
             assert(j < edim);
             if (Initializer iz = init.value[i])
             {
-                if (Expression ex = iz.initializerToExpression())
+                if (Expression ex = iz.initializerToExpression(null, isCfile))
                 {
                     (*elements)[j] = ex;
                     ++j;
@@ -1271,7 +1287,7 @@
 
     Expression visitC(CInitializer i)
     {
-        //printf("CInitializer.initializerToExpression()\n");
+        //printf("CInitializer.initializerToExpression(null, true)\n");
         return null;
     }
 
@@ -1331,6 +1347,10 @@
     }
     if (auto ae = e.isAddrExp())
     {
+        if (ae.type.nextOf().isImmutable() || ae.type.nextOf().isConst())
+        {
+            return false;
+        }
         if (auto se = ae.e1.isStructLiteralExp())
         {
             if (!(se.stageflags & stageSearchPointers))
diff --git a/gcc/d/dmd/json.d b/gcc/d/dmd/json.d
index 3183c8d..fc27039 100644
--- a/gcc/d/dmd/json.d
+++ b/gcc/d/dmd/json.d
@@ -319,10 +319,7 @@
             // Should not be printed
             //property(name, "d");
             break;
-        case LINK.system:
-            // Should not be printed
-            //property(name, "system");
-            break;
+        case LINK.system:   return property(name, "system");
         case LINK.c:        return property(name, "c");
         case LINK.cpp:      return property(name, "cpp");
         case LINK.windows:  return property(name, "windows");
diff --git a/gcc/d/dmd/lexer.d b/gcc/d/dmd/lexer.d
index 7cd4bfd..5945da3 100644
--- a/gcc/d/dmd/lexer.d
+++ b/gcc/d/dmd/lexer.d
@@ -108,8 +108,8 @@
         size_t endoffset, bool doDocComment, bool commentToken) pure
     {
         scanloc = Loc(filename, 1, 1);
-        //printf("Lexer::Lexer(%p,%d)\n",base,length);
-        //printf("lexer.filename = %s\n", filename);
+        // debug printf("Lexer::Lexer(%p)\n", base);
+        // debug printf("lexer.filename = %s\n", filename);
         token = Token.init;
         this.base = base;
         this.end = base + endoffset;
@@ -1236,28 +1236,47 @@
             {
                 uint v = 0;
                 int n = 0;
-                while (1)
+                if (Ccompile && ndigits == 2)
                 {
-                    if (isdigit(cast(char)c))
-                        c -= '0';
-                    else if (islower(c))
-                        c -= 'a' - 10;
-                    else
-                        c -= 'A' - 10;
-                    v = v * 16 + c;
-                    c = *++p;
-                    if (++n == ndigits)
-                        break;
-                    if (!ishex(cast(char)c))
+                    /* C11 6.4.4.4-7 one to infinity hex digits
+                     */
+                    do
                     {
-                        .error(loc, "escape hex sequence has %d hex digits instead of %d", n, ndigits);
-                        break;
-                    }
+                        if (isdigit(cast(char)c))
+                            c -= '0';
+                        else if (islower(c))
+                            c -= 'a' - 10;
+                        else
+                            c -= 'A' - 10;
+                        v = v * 16 + c;
+                        c = *++p;
+                    } while (ishex(cast(char)c));
                 }
-                if (ndigits != 2 && !utf_isValidDchar(v))
+                else
                 {
-                    .error(loc, "invalid UTF character \\U%08x", v);
-                    v = '?'; // recover with valid UTF character
+                    while (1)
+                    {
+                        if (isdigit(cast(char)c))
+                            c -= '0';
+                        else if (islower(c))
+                            c -= 'a' - 10;
+                        else
+                            c -= 'A' - 10;
+                        v = v * 16 + c;
+                        c = *++p;
+                        if (++n == ndigits)
+                            break;
+                        if (!ishex(cast(char)c))
+                        {
+                            .error(loc, "escape hex sequence has %d hex digits instead of %d", n, ndigits);
+                            break;
+                        }
+                    }
+                    if (ndigits != 2 && !utf_isValidDchar(v))
+                    {
+                        .error(loc, "invalid UTF character \\U%08x", v);
+                        v = '?'; // recover with valid UTF character
+                    }
                 }
                 c = v;
             }
@@ -2122,7 +2141,7 @@
                 // can't translate invalid octal value, just show a generic message
                 error("octal literals larger than 7 are no longer supported");
             else
-                error("octal literals `0%llo%.*s` are no longer supported, use `std.conv.octal!%llo%.*s` instead",
+                error("octal literals `0%llo%.*s` are no longer supported, use `std.conv.octal!\"%llo%.*s\"` instead",
                     n, cast(int)(p - psuffix), psuffix, n, cast(int)(p - psuffix), psuffix);
         }
         TOK result;
@@ -2926,7 +2945,7 @@
      */
     static const(char)* combineComments(const(char)[] c1, const(char)[] c2, bool newParagraph) pure
     {
-        //printf("Lexer::combineComments('%s', '%s', '%i')\n", c1, c2, newParagraph);
+        //debug printf("Lexer::combineComments('%*.s', '%*.s', '%i')\n", cast(int) c1.length, c1.ptr, cast(int) c2.length, c2.ptr, newParagraph);
         const(int) newParagraphSize = newParagraph ? 1 : 0; // Size of the combining '\n'
         if (!c1)
             return c2.ptr;
diff --git a/gcc/d/dmd/mtype.d b/gcc/d/dmd/mtype.d
index b2c7aa4..13df0d7 100644
--- a/gcc/d/dmd/mtype.d
+++ b/gcc/d/dmd/mtype.d
@@ -4200,27 +4200,28 @@
 
     // These flags can be accessed like `bool` properties,
     // getters and setters are generated for them
-    private enum FunctionFlag : uint
+    private extern (D) static struct BitFields
     {
-        none            = 0,
-        isnothrow       = 0x0001, // nothrow
-        isnogc          = 0x0002, // is @nogc
-        isproperty      = 0x0004, // can be called without parentheses
-        isref           = 0x0008, // returns a reference
-        isreturn        = 0x0010, // 'this' is returned by ref
-        isScopeQual     = 0x0020, // 'this' is scope
-        isreturninferred= 0x0040, // 'this' is return from inference
-        isscopeinferred = 0x0080, // 'this' is scope from inference
-        islive          = 0x0100, // is @live
-        incomplete      = 0x0200, // return type or default arguments removed
-        isInOutParam    = 0x0400, // inout on the parameters
-        isInOutQual     = 0x0800, // inout on the qualifier
-        isctor          = 0x1000, // the function is a constructor
-        isreturnscope   = 0x2000, // `this` is returned by value
+        bool isnothrow;        /// nothrow
+        bool isnogc;           /// is @nogc
+        bool isproperty;       /// can be called without parentheses
+        bool isref;            /// returns a reference
+        bool isreturn;         /// 'this' is returned by ref
+        bool isScopeQual;      /// 'this' is scope
+        bool isreturninferred; /// 'this' is return from inference
+        bool isscopeinferred;  /// 'this' is scope from inference
+        bool islive;           /// is @live
+        bool incomplete;       /// return type or default arguments removed
+        bool isInOutParam;     /// inout on the parameters
+        bool isInOutQual;      /// inout on the qualifier
+        bool isctor;           /// the function is a constructor
+        bool isreturnscope;    /// `this` is returned by value
     }
 
+    import dmd.common.bitfields : generateBitFields;
+    mixin(generateBitFields!(BitFields, ushort));
+
     LINK linkage;               // calling convention
-    FunctionFlag funcFlags;
     TRUST trust;                // level of trust
     PURE purity = PURE.impure;
     byte inuse;
@@ -4359,29 +4360,6 @@
         return linkage == LINK.d && parameterList.varargs == VarArg.variadic;
     }
 
-    /***************************
-     * Examine function signature for parameter p and see if
-     * the value of p can 'escape' the scope of the function.
-     * This is useful to minimize the needed annotations for the parameters.
-     * Params:
-     *  tthis = type of `this` parameter, null if none
-     *  p = parameter to this function
-     * Returns:
-     *  true if escapes via assignment to global or through a parameter
-     */
-    bool parameterEscapes(Type tthis, Parameter p)
-    {
-        /* Scope parameters do not escape.
-         * Allow 'lazy' to imply 'scope' -
-         * lazy parameters can be passed along
-         * as lazy parameters to the next function, but that isn't
-         * escaping.
-         */
-        if (parameterStorageClass(tthis, p) & (STC.scope_ | STC.lazy_))
-            return false;
-        return true;
-    }
-
     /************************************
      * Take the specified storage class for p,
      * and use the function signature to infer whether
@@ -4409,7 +4387,7 @@
 
         /* If haven't inferred the return type yet, can't infer storage classes
          */
-        if (!nextOf())
+        if (!nextOf() || !isnothrow())
             return stc;
 
         purityLevel();
@@ -4460,37 +4438,12 @@
             }
         }
 
-        /* Inferring STC.return_ here has false positives
-         * for pure functions, producing spurious error messages
-         * about escaping references.
-         * Give up on it for now.
-         */
-        version (none)
-        {
-            stc |= STC.scope_;
-
-            Type tret = nextOf().toBasetype();
-            if (isref || tret.hasPointers())
-            {
-                /* The result has references, so p could be escaping
-                 * that way.
-                 */
-                stc |= STC.return_;
-            }
-        }
+        // Check escaping through return value
+        Type tret = nextOf().toBasetype();
+        if (isref || tret.hasPointers())
+            return stc | STC.scope_ | STC.return_ | STC.returnScope;
         else
-        {
-            // Check escaping through return value
-            Type tret = nextOf().toBasetype();
-            if (isref || tret.hasPointers() || !isnothrow())
-            {
-                return stc;
-            }
-
-            stc |= STC.scope_;
-        }
-
-        return stc;
+            return stc | STC.scope_;
     }
 
     override Type addStorageClass(StorageClass stc)
@@ -4684,6 +4637,16 @@
             match = MATCH.convert; // match ... with a "conversion" match level
         }
 
+        // https://issues.dlang.org/show_bug.cgi?id=22997
+        if (parameterList.varargs == VarArg.none && nparams > nargs && !parameterList[nargs].defaultArg)
+        {
+            OutBuffer buf;
+            buf.printf("too few arguments, expected `%d`, got `%d`", cast(int)nparams, cast(int)nargs);
+            if (pMessage)
+                *pMessage = buf.extractChars();
+            goto Nomatch;
+        }
+
         foreach (u, p; parameterList)
         {
             if (u == nargs)
@@ -4780,14 +4743,40 @@
                                 m = MATCH.exact;
                             else
                             {
-                                m = MATCH.nomatch;
                                 if (pMessage)
                                 {
+                                    /* https://issues.dlang.org/show_bug.cgi?id=22202
+                                     *
+                                     * If a function was deduced by semantic on the CallExp,
+                                     * it means that resolveFuncCall completed succesfully.
+                                     * Therefore, there exists a callable copy constructor,
+                                     * however, it cannot be called because scope constraints
+                                     * such as purity, safety or nogc.
+                                     */
                                     OutBuffer buf;
-                                    buf.printf("`struct %s` does not define a copy constructor for `%s` to `%s` copies",
-                                           argStruct.toChars(), targ.toChars(), tprm.toChars());
+                                    auto callExp = e.isCallExp();
+                                    if (auto f = callExp.f)
+                                    {
+                                        char[] s;
+                                        if (!f.isPure && sc.func.setImpure())
+                                            s ~= "pure ";
+                                        if (!f.isSafe() && !f.isTrusted() && sc.func.setUnsafe())
+                                            s ~= "@safe ";
+                                        if (!f.isNogc && sc.func.setGC())
+                                            s ~= "nogc ";
+                                        s[$-1] = '\0';
+                                        buf.printf("`%s` copy constructor cannot be called from a `%s` context", f.type.toChars(), s.ptr);
+
+                                    }
+                                    else
+                                    {
+                                        buf.printf("`struct %s` does not define a copy constructor for `%s` to `%s` copies",
+                                               argStruct.toChars(), targ.toChars(), tprm.toChars());
+                                    }
+
                                     *pMessage = buf.extractChars();
                                 }
+                                m = MATCH.nomatch;
                                 goto Nomatch;
                             }
                         }
@@ -5086,41 +5075,21 @@
         return false;
     }
 
-    // Generate getter / setter functions for `FunctionFlag` members so they can be
-    // treated like regular `bool` fields, instead of requiring bit twiddling to read/write
-    extern (D) mixin(() {
-        string result = "extern(C++) pure nothrow @safe @nogc {";
-        foreach (string mem; __traits(allMembers, FunctionFlag))
-        {
-            result ~= "
-            /// set or get if the function has the FunctionFlag attribute of the same name
-            bool "~mem~"() const { return (funcFlags & FunctionFlag."~mem~") != 0; }
-            /// ditto
-            void "~mem~"(bool v)
-            {
-                if (v) funcFlags |= FunctionFlag."~mem~";
-                else funcFlags &= ~FunctionFlag."~mem~";
-            }";
-        }
-        return result ~ "}\n";
-    }());
 
     /// Returns: `true` the function is `isInOutQual` or `isInOutParam` ,`false` otherwise.
     bool iswild() const pure nothrow @safe @nogc
     {
-        return (funcFlags & (FunctionFlag.isInOutParam | FunctionFlag.isInOutQual)) != 0;
+        return isInOutParam || isInOutQual;
     }
 
     /// Returns: whether `this` function type has the same attributes (`@safe`,...) as `other`
     bool attributesEqual(const scope TypeFunction other) const pure nothrow @safe @nogc
     {
-        enum attributes = FunctionFlag.isnothrow
-                        | FunctionFlag.isnogc
-                        | FunctionFlag.islive;
-
         return this.trust == other.trust &&
                 this.purity == other.purity &&
-                (this.funcFlags & attributes) == (other.funcFlags & attributes);
+                this.isnothrow == other.isnothrow &&
+                this.isnogc == other.isnogc &&
+                this.islive == other.islive;
     }
 
     override void accept(Visitor v)
diff --git a/gcc/d/dmd/mtype.h b/gcc/d/dmd/mtype.h
index 07c574d..6ba47df 100644
--- a/gcc/d/dmd/mtype.h
+++ b/gcc/d/dmd/mtype.h
@@ -109,6 +109,7 @@
  */
 enum MODFlags
 {
+    MODnone      = 0, // default (mutable)
     MODconst     = 1, // type is const
     MODimmutable = 4, // type is immutable
     MODshared    = 2, // type is shared
@@ -595,8 +596,8 @@
     // .next is the return type
 
     ParameterList parameterList; // function parameters
+    uint16_t bitFields;
     LINK linkage;                // calling convention
-    unsigned funcFlags;
     TRUST trust;                 // level of trust
     PURE purity;                 // PURExxxx
     char inuse;
@@ -608,7 +609,6 @@
     void purityLevel();
     bool hasLazyParameters();
     bool isDstyleVariadic() const;
-    bool parameterEscapes(Parameter *p);
     StorageClass parameterStorageClass(Parameter *p);
     Type *addStorageClass(StorageClass stc);
 
diff --git a/gcc/d/dmd/mustuse.d b/gcc/d/dmd/mustuse.d
new file mode 100644
index 0000000..4eb4228
--- /dev/null
+++ b/gcc/d/dmd/mustuse.d
@@ -0,0 +1,244 @@
+/**
+ * Compile-time checks associated with the @mustuse attribute.
+ *
+ * Copyright: Copyright (C) 2022 by The D Language Foundation, All Rights Reserved
+ * License:   $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
+ * Source:    $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/mustuse.d, _mustuse.d)
+ * Documentation:  https://dlang.org/phobos/dmd_mustuse.html
+ * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/mustuse.d
+ */
+
+module dmd.mustuse;
+
+import dmd.dscope;
+import dmd.dsymbol;
+import dmd.expression;
+import dmd.globals;
+import dmd.identifier;
+
+// Used in isIncrementOrDecrement
+private static const StringExp plusPlus, minusMinus;
+
+// Loc.initial cannot be used in static initializers, so
+// these need a static constructor.
+static this()
+{
+    plusPlus = new StringExp(Loc.initial, "++");
+    minusMinus = new StringExp(Loc.initial, "--");
+}
+
+/**
+ * Check whether discarding an expression would violate the requirements of
+ * @mustuse. If so, emit an error.
+ *
+ * Params:
+ *   e = the expression to check
+ *   sc = scope in which `e` was semantically analyzed
+ *
+ * Returns: true on error, false on success.
+ */
+bool checkMustUse(Expression e, Scope* sc)
+{
+    import dmd.id : Id;
+
+    assert(e.type);
+    if (auto sym = e.type.toDsymbol(sc))
+    {
+        auto sd = sym.isStructDeclaration();
+        // isStructDeclaration returns non-null for both structs and unions
+        if (sd && hasMustUseAttribute(sd, sc) && !isAssignment(e) && !isIncrementOrDecrement(e))
+        {
+            e.error("ignored value of `@%s` type `%s`; prepend a `cast(void)` if intentional",
+                Id.udaMustUse.toChars(), e.type.toPrettyChars(true));
+            return true;
+        }
+    }
+    return false;
+}
+
+/**
+ * Called from a symbol's semantic to check for reserved usage of @mustuse.
+ *
+ * If such usage is found, emits an errror.
+ *
+ * Params:
+ *   sym = symbol to check
+ */
+void checkMustUseReserved(Dsymbol sym)
+{
+    import dmd.attrib : foreachUdaNoSemantic;
+    import dmd.errors : error;
+    import dmd.id : Id;
+
+    // Can't use foreachUda (and by extension hasMustUseAttribute) while
+    // semantic analysis of `sym` is still in progress
+    foreachUdaNoSemantic(sym, (exp) {
+        if (isMustUseAttribute(exp))
+        {
+            if (sym.isFuncDeclaration())
+            {
+                error(sym.loc, "`@%s` on functions is reserved for future use",
+                    Id.udaMustUse.toChars());
+                sym.errors = true;
+            }
+            else if (sym.isClassDeclaration() || sym.isEnumDeclaration())
+            {
+                error(sym.loc, "`@%s` on `%s` types is reserved for future use",
+                    Id.udaMustUse.toChars(), sym.kind());
+                sym.errors = true;
+            }
+        }
+        return 0; // continue
+    });
+}
+
+/**
+ * Returns: true if the given expression is an assignment, either simple (a = b)
+ * or compound (a += b, etc).
+ */
+private bool isAssignment(Expression e)
+{
+    if (e.isAssignExp || e.isBinAssignExp)
+        return true;
+    if (auto ce = e.isCallExp())
+    {
+        if (auto fd = ce.f)
+        {
+            auto id = fd.ident;
+            if (id && isAssignmentOpId(id))
+                return true;
+        }
+    }
+    return false;
+}
+
+/**
+ * Returns: true if id is the identifier of an assignment operator overload.
+ */
+private bool isAssignmentOpId(Identifier id)
+{
+    import dmd.id : Id;
+
+    return id == Id.assign
+        || id == Id.addass
+        || id == Id.subass
+        || id == Id.mulass
+        || id == Id.divass
+        || id == Id.modass
+        || id == Id.andass
+        || id == Id.orass
+        || id == Id.xorass
+        || id == Id.shlass
+        || id == Id.shrass
+        || id == Id.ushrass
+        || id == Id.catass
+        || id == Id.indexass
+        || id == Id.slice
+        || id == Id.sliceass
+        || id == Id.opOpAssign
+        || id == Id.opIndexOpAssign
+        || id == Id.opSliceOpAssign
+        || id == Id.powass;
+}
+
+/**
+ * Returns: true if the given expression is an increment (++) or decrement (--).
+ */
+private bool isIncrementOrDecrement(Expression e)
+{
+    import dmd.dtemplate : isExpression;
+    import dmd.globals : Loc;
+    import dmd.id : Id;
+    import dmd.tokens : EXP;
+
+    if (e.op == EXP.plusPlus
+        || e.op == EXP.minusMinus
+        || e.op == EXP.prePlusPlus
+        || e.op == EXP.preMinusMinus)
+        return true;
+    if (auto call = e.isCallExp())
+    {
+        // Check for overloaded preincrement
+        // e.g., a.opUnary!"++"
+        if (auto fd = call.f)
+        {
+            if (fd.ident == Id.opUnary && fd.parent)
+            {
+                if (auto ti = fd.parent.isTemplateInstance())
+                {
+                    auto tiargs = ti.tiargs;
+                    if (tiargs && tiargs.length >= 1)
+                    {
+                        if (auto argExp = (*tiargs)[0].isExpression())
+                        {
+                            auto op = argExp.isStringExp();
+                            if (op && (op.compare(plusPlus) == 0 || op.compare(minusMinus) == 0))
+                                return true;
+                        }
+                    }
+                }
+            }
+        }
+    }
+    else if (auto comma = e.isCommaExp())
+    {
+        // Check for overloaded postincrement
+        // e.g., (auto tmp = a, ++a, tmp)
+        if (comma.e1)
+        {
+            if (auto left = comma.e1.isCommaExp())
+            {
+                if (auto middle = left.e2)
+                {
+                    if (middle && isIncrementOrDecrement(middle))
+                        return true;
+                }
+            }
+        }
+    }
+    return false;
+}
+
+/**
+ * Returns: true if the given symbol has the @mustuse attribute.
+ */
+private bool hasMustUseAttribute(Dsymbol sym, Scope* sc)
+{
+    import dmd.attrib : foreachUda;
+
+    bool result = false;
+
+    foreachUda(sym, sc, (Expression uda) {
+        if (isMustUseAttribute(uda))
+        {
+            result = true;
+            return 1; // break
+        }
+        return 0; // continue
+    });
+
+    return result;
+}
+
+/**
+ * Returns: true if the given expression is core.attribute.mustuse.
+ */
+private bool isMustUseAttribute(Expression e)
+{
+    import dmd.attrib : isCoreUda;
+    import dmd.id : Id;
+
+    // Logic based on dmd.objc.Supported.declaredAsOptionalCount
+    auto typeExp = e.isTypeExp;
+    if (!typeExp)
+        return false;
+
+    auto typeEnum = typeExp.type.isTypeEnum();
+    if (!typeEnum)
+        return false;
+
+    if (isCoreUda(typeEnum.sym, Id.udaMustUse))
+        return true;
+
+    return false;
+}
diff --git a/gcc/d/dmd/opover.d b/gcc/d/dmd/opover.d
index dbd761f..4f6903c 100644
--- a/gcc/d/dmd/opover.d
+++ b/gcc/d/dmd/opover.d
@@ -213,7 +213,7 @@
      */
     if (isRecursiveAliasThis(e.att1, e.e1.type))
         return null;
-    //printf("att %s e1 = %s\n", Token::toChars(e.op), e.e1.type.toChars());
+    //printf("att %s e1 = %s\n", Token.toChars(e.op), e.e1.type.toChars());
     BinExp be = cast(BinExp)e.copy();
     // Resolve 'alias this' but in case of assigment don't resolve properties yet
     // because 'e1 = e2' could mean 'e1(e2)' or 'e1() = e2'
@@ -241,7 +241,7 @@
      */
     if (isRecursiveAliasThis(e.att2, e.e2.type))
         return null;
-    //printf("att %s e2 = %s\n", Token::toChars(e.op), e.e2.type.toChars());
+    //printf("att %s e2 = %s\n", Token.toChars(e.op), e.e2.type.toChars());
     BinExp be = cast(BinExp)e.copy();
     be.e2 = resolveAliasThis(sc, e.e2, true);
     if (!be.e2)
diff --git a/gcc/d/dmd/optimize.d b/gcc/d/dmd/optimize.d
index 3745a15d..3cc36b4 100644
--- a/gcc/d/dmd/optimize.d
+++ b/gcc/d/dmd/optimize.d
@@ -271,7 +271,7 @@
  */
 Expression Expression_optimize(Expression e, int result, bool keepLvalue)
 {
-    //printf("Expression_optimize() %s\n", e.toChars());
+    //printf("Expression_optimize() e: %s result: %d keepLvalue %d\n", e.toChars(), result, keepLvalue);
     Expression ret = e;
 
     void error()
@@ -426,7 +426,7 @@
 
     void visitAddr(AddrExp e)
     {
-        //printf("AddrExp::optimize(result = %d) %s\n", result, e.toChars());
+        //printf("AddrExp::optimize(result = %d, keepLvalue = %d) %s\n", result, keepLvalue, e.toChars());
         /* Rewrite &(a,b) as (a,&b)
          */
         if (auto ce = e.e1.isCommaExp())
@@ -438,7 +438,8 @@
         }
         // Keep lvalue-ness
         if (expOptimize(e.e1, result, true))
-            return;
+            return;                     // error return
+
         // Convert &*ex to ex
         if (auto pe = e.e1.isPtrExp())
         {
@@ -515,6 +516,23 @@
                         }
                     }
                 }
+                else if (auto ei = e.isIndexExp())
+                {
+                    if (auto ve = ei.e1.isVarExp())
+                    {
+                        if (!ve.var.isReference() &&
+                            !ve.var.isImportedSymbol() &&
+                            ve.var.isDataseg() &&
+                            ve.var.isCsymbol())
+                        {
+                            if (auto ie = ei.e2.isIntegerExp())
+                            {
+                                var = ve.var.isVarDeclaration();
+                                offset += ie.toInteger() * ve.type.toBasetype().nextOf().size();
+                            }
+                        }
+                    }
+                }
                 return false;
             }
 
@@ -538,7 +556,7 @@
                 return;
             }
         }
-        if (auto ae = e.e1.isIndexExp())
+        else if (auto ae = e.e1.isIndexExp())
         {
             // Convert &array[n] to &array+n
             if (ae.e2.isIntegerExp() && ae.e1.isVarExp())
@@ -551,9 +569,10 @@
                     sinteger_t dim = ts.dim.toInteger();
                     if (index < 0 || index >= dim)
                     {
-                        /* 0 for C static arrays means size is unknown, no need to check
+                        /* 0 for C static arrays means size is unknown, no need to check,
+                         * and address one past the end is OK, too
                          */
-                        if (!(dim == 0 && ve.var.isCsymbol()))
+                        if (!((dim == 0 || dim == index) && ve.var.isCsymbol()))
                         {
                             e.error("array index %lld is out of bounds `[0..%lld]`", index, dim);
                             return error();
@@ -574,7 +593,7 @@
                     return;
                 }
             }
-            // Convert &((a.b)[n]) to (&a.b)+n
+            // Convert &((a.b)[index]) to (&a.b)+index*elementsize
             else if (ae.e2.isIntegerExp() && ae.e1.isDotVarExp())
             {
                 sinteger_t index = ae.e2.toInteger();
@@ -585,18 +604,28 @@
                     sinteger_t dim = ts.dim.toInteger();
                     if (index < 0 || index >= dim)
                     {
-                        /* 0 for C static arrays means size is unknown, no need to check
+                        /* 0 for C static arrays means size is unknown, no need to check,
+                         * and address one past the end is OK, too
                          */
-                        if (!(dim == 0 && ve.var.isCsymbol()))
+                        if (!((dim == 0 || dim == index) && ve.var.isCsymbol()))
                         {
                             e.error("array index %lld is out of bounds `[0..%lld]`", index, dim);
                             return error();
                         }
                     }
 
+                    import core.checkedint : mulu;
+                    bool overflow;
+                    const offset = mulu(index, ts.nextOf().size(e.loc), overflow); // index*elementsize
+                    if (overflow)
+                    {
+                        e.error("array offset overflow");
+                        return error();
+                    }
+
                     auto pe = new AddrExp(e.loc, ve);
                     pe.type = e.type;
-                    ret = new AddExp(e.loc, pe, ae.e2);
+                    ret = new AddExp(e.loc, pe, new IntegerExp(e.loc, offset, Type.tsize_t));
                     ret.type = e.type;
                     return;
                 }
diff --git a/gcc/d/dmd/parse.d b/gcc/d/dmd/parse.d
index 7b1b63c..4b9c0f2 100644
--- a/gcc/d/dmd/parse.d
+++ b/gcc/d/dmd/parse.d
@@ -987,23 +987,9 @@
                 nextToken();
                 if (token.value == TOK.assign)
                 {
-                    nextToken();
-                    if (token.value == TOK.identifier)
-                        s = new AST.DebugSymbol(token.loc, token.ident);
-                    else if (token.value == TOK.int32Literal || token.value == TOK.int64Literal)
-                        s = new AST.DebugSymbol(token.loc, cast(uint)token.unsvalue);
-                    else
-                    {
-                        error("identifier or integer expected, not `%s`", token.toChars());
-                        s = null;
-                    }
-                    nextToken();
-                    if (token.value != TOK.semicolon)
-                        error("semicolon expected");
-                    nextToken();
+                    s = parseDebugSpecification();
                     break;
                 }
-
                 condition = parseDebugCondition();
                 goto Lcondition;
 
@@ -1012,20 +998,7 @@
                 nextToken();
                 if (token.value == TOK.assign)
                 {
-                    nextToken();
-                    if (token.value == TOK.identifier)
-                        s = new AST.VersionSymbol(token.loc, token.ident);
-                    else if (token.value == TOK.int32Literal || token.value == TOK.int64Literal)
-                        s = new AST.VersionSymbol(token.loc, cast(uint)token.unsvalue);
-                    else
-                    {
-                        error("identifier or integer expected, not `%s`", token.toChars());
-                        s = null;
-                    }
-                    nextToken();
-                    if (token.value != TOK.semicolon)
-                        error("semicolon expected");
-                    nextToken();
+                    s = parseVersionSpecification();
                     break;
                 }
                 condition = parseVersionCondition();
@@ -2197,6 +2170,26 @@
         return qualified;
     }
 
+    private AST.DebugSymbol parseDebugSpecification()
+    {
+        AST.DebugSymbol s;
+        nextToken();
+        if (token.value == TOK.identifier)
+            s = new AST.DebugSymbol(token.loc, token.ident);
+        else if (token.value == TOK.int32Literal || token.value == TOK.int64Literal)
+            s = new AST.DebugSymbol(token.loc, cast(uint)token.unsvalue);
+        else
+        {
+            error("identifier or integer expected, not `%s`", token.toChars());
+            s = null;
+        }
+        nextToken();
+        if (token.value != TOK.semicolon)
+            error("semicolon expected");
+        nextToken();
+        return s;
+    }
+
     /**************************************
      * Parse a debug conditional
      */
@@ -2224,6 +2217,29 @@
     }
 
     /**************************************
+     * Parse a version specification
+     */
+    private AST.VersionSymbol parseVersionSpecification()
+    {
+        AST.VersionSymbol s;
+        nextToken();
+        if (token.value == TOK.identifier)
+            s = new AST.VersionSymbol(token.loc, token.ident);
+        else if (token.value == TOK.int32Literal || token.value == TOK.int64Literal)
+            s = new AST.VersionSymbol(token.loc, cast(uint)token.unsvalue);
+        else
+        {
+            error("identifier or integer expected, not `%s`", token.toChars());
+            s = null;
+        }
+        nextToken();
+        if (token.value != TOK.semicolon)
+            error("semicolon expected");
+        nextToken();
+        return s;
+    }
+
+    /**************************************
      * Parse a version conditional
      */
     private AST.Condition parseVersionCondition()
@@ -6053,10 +6069,14 @@
             nextToken();
             if (token.value == TOK.assign)
             {
-                error("debug conditions can only be declared at module scope");
-                nextToken();
-                nextToken();
-                goto Lerror;
+                if (auto ds = parseDebugSpecification())
+                {
+                    if (ds.ident)
+                        ds.error("declaration must be at module level");
+                    else
+                        ds.error("level declaration must be at module level");
+                }
+                break;
             }
             cond = parseDebugCondition();
             goto Lcondition;
@@ -6065,10 +6085,14 @@
             nextToken();
             if (token.value == TOK.assign)
             {
-                error("version conditions can only be declared at module scope");
-                nextToken();
-                nextToken();
-                goto Lerror;
+                if (auto vs = parseVersionSpecification())
+                {
+                    if (vs.ident)
+                        vs.error("declaration must be at module level");
+                    else
+                        vs.error("level declaration must be at module level");
+                }
+                break;
             }
             cond = parseVersionCondition();
             goto Lcondition;
diff --git a/gcc/d/dmd/root/aav.d b/gcc/d/dmd/root/aav.d
index ba5d331..beceb0f0 100644
--- a/gcc/d/dmd/root/aav.d
+++ b/gcc/d/dmd/root/aav.d
@@ -14,6 +14,8 @@
 import core.stdc.string;
 import dmd.root.rmem;
 
+nothrow:
+
 private size_t hash(size_t a) pure nothrow @nogc @safe
 {
     a ^= (a >> 20) ^ (a >> 12);
diff --git a/gcc/d/dmd/root/array.d b/gcc/d/dmd/root/array.d
index cd2d709..c2eb3e1 100644
--- a/gcc/d/dmd/root/array.d
+++ b/gcc/d/dmd/root/array.d
@@ -137,7 +137,7 @@
 
     void reserve(size_t nentries) pure nothrow
     {
-        //printf("Array::reserve: length = %d, data.length = %d, nentries = %d\n", (int)length, (int)data.length, (int)nentries);
+        //printf("Array::reserve: length = %d, data.length = %d, nentries = %d\n", cast(int)length, cast(int)data.length, cast(int)nentries);
 
         // Cold path
         void enlarge(size_t nentries)
diff --git a/gcc/d/dmd/root/complex.d b/gcc/d/dmd/root/complex.d
index d9a396d..a7a7438 100644
--- a/gcc/d/dmd/root/complex.d
+++ b/gcc/d/dmd/root/complex.d
@@ -13,11 +13,15 @@
 
 import dmd.root.ctfloat;
 
+nothrow:
+
 extern (C++) struct complex_t
 {
     real_t re;
     real_t im;
 
+  nothrow:
+
     this() @disable;
 
     this(real_t re)
diff --git a/gcc/d/dmd/root/file.d b/gcc/d/dmd/root/file.d
index a01cfdc..b40413c 100644
--- a/gcc/d/dmd/root/file.d
+++ b/gcc/d/dmd/root/file.d
@@ -26,11 +26,15 @@
 import dmd.common.file;
 import dmd.common.string;
 
-/// Owns a (rmem-managed) file buffer.
-struct FileBuffer
+nothrow:
+
+/// Owns a (rmem-managed) buffer.
+struct Buffer
 {
     ubyte[] data;
 
+  nothrow:
+
     this(this) @disable;
 
     ~this() pure nothrow
@@ -54,7 +58,7 @@
     static struct ReadResult
     {
         bool success;
-        FileBuffer buffer;
+        Buffer buffer;
 
         /// Transfers ownership of the buffer to the caller.
         ubyte[] extractSlice() pure nothrow @nogc @safe
diff --git a/gcc/d/dmd/root/longdouble.d b/gcc/d/dmd/root/longdouble.d
index 27fcf9c..d6753aa 100644
--- a/gcc/d/dmd/root/longdouble.d
+++ b/gcc/d/dmd/root/longdouble.d
@@ -29,6 +29,8 @@
 // Type used by the front-end for compile-time reals
 struct longdouble
 {
+nothrow:
+@nogc:
     extern (D) this(T)(T r)
     {
         this.set(cast(SetType!T)r);
diff --git a/gcc/d/dmd/root/optional.d b/gcc/d/dmd/root/optional.d
index f2f7389..266846b 100644
--- a/gcc/d/dmd/root/optional.d
+++ b/gcc/d/dmd/root/optional.d
@@ -10,6 +10,8 @@
  */
 module dmd.root.optional;
 
+nothrow:
+
 ///
 unittest
 {
@@ -45,6 +47,8 @@
     /// whether `value` is set
     private bool present;
 
+  nothrow:
+
     /// Creates an `Optional` with the given value
     this(T value)
     {
diff --git a/gcc/d/dmd/root/port.h b/gcc/d/dmd/root/port.h
index 069a365..66a6760 100644
--- a/gcc/d/dmd/root/port.h
+++ b/gcc/d/dmd/root/port.h
@@ -13,12 +13,13 @@
 // The idea is to minimize #ifdef's in the app code.
 
 #include "dsystem.h"
+#include "dcompat.h"
 
 typedef unsigned char utf8_t;
 
 struct Port
 {
-    static int memicmp(const char *s1, const char *s2, size_t n);
+    static int memicmp(const char *s1, const char *s2, d_size_t n);
     static char *strupr(char *s);
 
     static bool isFloat32LiteralOutOfRange(const char *s);
@@ -30,5 +31,5 @@
     static unsigned readlongBE(const void *buffer);
     static unsigned readwordLE(const void *buffer);
     static unsigned readwordBE(const void *buffer);
-    static void valcpy(void *dst, uint64_t val, size_t size);
+    static void valcpy(void *dst, uint64_t val, d_size_t size);
 };
diff --git a/gcc/d/dmd/semantic2.d b/gcc/d/dmd/semantic2.d
index b9029a1..cd65920 100644
--- a/gcc/d/dmd/semantic2.d
+++ b/gcc/d/dmd/semantic2.d
@@ -478,7 +478,7 @@
         i.mod.semantic2(null);
         if (i.mod.needmoduleinfo)
         {
-            //printf("module5 %s because of %s\n", sc.module.toChars(), mod.toChars());
+            //printf("module5 %s because of %s\n", sc._module.toChars(), mod.toChars());
             if (sc)
                 sc._module.needmoduleinfo = 1;
         }
diff --git a/gcc/d/dmd/statement.d b/gcc/d/dmd/statement.d
index ae03b8a..7171324 100644
--- a/gcc/d/dmd/statement.d
+++ b/gcc/d/dmd/statement.d
@@ -315,6 +315,14 @@
             override void visit(ImportStatement s)
             {
             }
+
+            override void visit(CaseStatement s)
+            {
+            }
+
+            override void visit(DefaultStatement s)
+            {
+            }
         }
 
         scope HasCode hc = new HasCode();
diff --git a/gcc/d/dmd/statementsem.d b/gcc/d/dmd/statementsem.d
index c2967d6..2916bbc 100644
--- a/gcc/d/dmd/statementsem.d
+++ b/gcc/d/dmd/statementsem.d
@@ -51,6 +51,7 @@
 import dmd.init;
 import dmd.intrange;
 import dmd.mtype;
+import dmd.mustuse;
 import dmd.nogc;
 import dmd.opover;
 import dmd.parse;
@@ -211,7 +212,8 @@
             if (f.checkForwardRef(s.exp.loc))
                 s.exp = ErrorExp.get();
         }
-
+        if (checkMustUse(s.exp, sc))
+            s.exp = ErrorExp.get();
         if (!(sc.flags & SCOPE.Cfile) && discardValue(s.exp))
             s.exp = ErrorExp.get();
 
diff --git a/gcc/d/dmd/tokens.d b/gcc/d/dmd/tokens.d
index 43feab1..03e8024 100644
--- a/gcc/d/dmd/tokens.d
+++ b/gcc/d/dmd/tokens.d
@@ -591,7 +591,7 @@
     Identifier.initTable();
     foreach (kw; keywords)
     {
-        //printf("keyword[%d] = '%s'\n",kw, tochars[kw].ptr);
+        //printf("keyword[%d] = '%s'\n",kw, Token.tochars[kw].ptr);
         Identifier.idPool(Token.tochars[kw].ptr, Token.tochars[kw].length, cast(uint)kw);
     }
 }
diff --git a/gcc/d/dmd/traits.d b/gcc/d/dmd/traits.d
index 4b15e8c..04e1c47 100644
--- a/gcc/d/dmd/traits.d
+++ b/gcc/d/dmd/traits.d
@@ -1278,7 +1278,7 @@
             {
                 s = s.isImport().mod;
             }
-            //printf("getAttributes %s, attrs = %p, scope = %p\n", s.toChars(), s.userAttribDecl, s.scope);
+            //printf("getAttributes %s, attrs = %p, scope = %p\n", s.toChars(), s.userAttribDecl, s._scope);
             udad = s.userAttribDecl;
         }
         else
@@ -1514,7 +1514,9 @@
         TypeFunction tf = toTypeFunction(o, fd);
 
         if (tf)
-            link = tf.linkage;
+        {
+            link = fd ? fd.linkage : tf.linkage;
+        }
         else
         {
             auto s = getDsymbol(o);
@@ -1730,69 +1732,33 @@
             bool err = false;
 
             auto t = isType(o);
-            while (t)
+            auto ex = isExpression(o);
+            if (t)
             {
-                if (auto tm = t.isTypeMixin())
+                Dsymbol s;
+                t.resolve(e.loc, sc2, ex, t, s);
+                if (t)
                 {
-                    /* The mixin string could be a type or an expression.
-                     * Have to try compiling it to see.
-                     */
-                    OutBuffer buf;
-                    if (expressionsToString(buf, sc, tm.exps))
-                    {
+                    t.typeSemantic(e.loc, sc2);
+                    if (t.ty == Terror)
                         err = true;
-                        break;
-                    }
-                    const olderrors = global.errors;
-                    const len = buf.length;
-                    buf.writeByte(0);
-                    const str = buf.extractSlice()[0 .. len];
-                    scope p = new Parser!ASTCodegen(e.loc, sc._module, str, false);
-                    p.nextToken();
-                    //printf("p.loc.linnum = %d\n", p.loc.linnum);
-
-                    o = p.parseTypeOrAssignExp(TOK.endOfFile);
-                    if (olderrors != global.errors || p.token.value != TOK.endOfFile)
-                    {
-                        err = true;
-                        break;
-                    }
-                    t = o.isType();
                 }
-                else
-                    break;
+                else if (s && s.errors)
+                    err = true;
             }
-
-            if (!err)
+            if (ex)
             {
-                auto ex = t ? t.typeToExpression() : isExpression(o);
-                if (!ex && t)
+                ex = ex.expressionSemantic(sc2);
+                ex = resolvePropertiesOnly(sc2, ex);
+                ex = ex.optimize(WANTvalue);
+                if (sc2.func && sc2.func.type.ty == Tfunction)
                 {
-                    Dsymbol s;
-                    t.resolve(e.loc, sc2, ex, t, s);
-                    if (t)
-                    {
-                        t.typeSemantic(e.loc, sc2);
-                        if (t.ty == Terror)
-                            err = true;
-                    }
-                    else if (s && s.errors)
-                        err = true;
+                    const tf = cast(TypeFunction)sc2.func.type;
+                    err |= tf.isnothrow && canThrow(ex, sc2.func, false);
                 }
-                if (ex)
-                {
-                    ex = ex.expressionSemantic(sc2);
-                    ex = resolvePropertiesOnly(sc2, ex);
-                    ex = ex.optimize(WANTvalue);
-                    if (sc2.func && sc2.func.type.ty == Tfunction)
-                    {
-                        const tf = cast(TypeFunction)sc2.func.type;
-                        err |= tf.isnothrow && canThrow(ex, sc2.func, false);
-                    }
-                    ex = checkGC(sc2, ex);
-                    if (ex.op == EXP.error)
-                        err = true;
-                }
+                ex = checkGC(sc2, ex);
+                if (ex.op == EXP.error)
+                    err = true;
             }
 
             // Carefully detach the scope from the parent and throw it away as
diff --git a/gcc/d/dmd/transitivevisitor.d b/gcc/d/dmd/transitivevisitor.d
index 615c49f..0acad6a 100644
--- a/gcc/d/dmd/transitivevisitor.d
+++ b/gcc/d/dmd/transitivevisitor.d
@@ -17,7 +17,9 @@
 extern(C++) class ParseTimeTransitiveVisitor(AST) : PermissiveVisitor!AST
 {
     alias visit = PermissiveVisitor!AST.visit;
-    mixin ParseVisitMethods!AST;
+
+    mixin ParseVisitMethods!AST __methods;
+    alias visit = __methods.visit;
 }
 
 /* This mixin implements the AST traversal logic for parse time AST nodes. The same code
diff --git a/gcc/d/dmd/typesem.d b/gcc/d/dmd/typesem.d
index bcdbec5..f63b177 100644
--- a/gcc/d/dmd/typesem.d
+++ b/gcc/d/dmd/typesem.d
@@ -1220,6 +1220,9 @@
             tf.islive = true;
 
         tf.linkage = sc.linkage;
+        if (tf.linkage == LINK.system)
+            tf.linkage = target.systemLinkage();
+
         version (none)
         {
             /* If the parent is @safe, then this function defaults to safe
@@ -1840,7 +1843,7 @@
                 mtype.sym = e.isScopeExp().sds;
                 break;
             case EXP.tuple:
-                TupleExp te = e.toTupleExp();
+                TupleExp te = e.isTupleExp();
                 Objects* elems = new Objects(te.exps.dim);
                 foreach (i; 0 .. elems.dim)
                 {
@@ -2281,10 +2284,7 @@
         return null;
     }
 
-    Type t = o.isType();
-    Expression e = t ? t.typeToExpression() : o.isExpression();
-
-    return (!e && t) ? t : e;
+    return o;
 }
 
 
@@ -2306,7 +2306,8 @@
         case Tident:
         case Tinstance:
         case Tmixin:
-            return type;
+        case Ttag:
+            return type;        // don't merge placeholder types
 
         case Tsarray:
             // prevents generating the mangle if the array dim is not yet known
@@ -3619,12 +3620,31 @@
                 e.error("`%s` is not an expression", e.toChars());
                 return ErrorExp.get();
             }
-            else if (checkUnsafeDotExp(sc, e, ident, flag))
+            else if (mt.dim.toUInteger() < 1 && checkUnsafeDotExp(sc, e, ident, flag))
             {
+                // .ptr on static array is @safe unless size is 0
+                // https://issues.dlang.org/show_bug.cgi?id=20853
                 return ErrorExp.get();
             }
             e = e.castTo(sc, e.type.nextOf().pointerTo());
         }
+        else if (ident == Id._tupleof)
+        {
+            if (e.isTypeExp())
+            {
+                e.error("`.tupleof` cannot be used on type `%s`", mt.toChars);
+                return ErrorExp.get();
+            }
+            else
+            {
+                const length = cast(size_t)mt.dim.toUInteger();
+                auto exps = new Expressions();
+                exps.reserve(length);
+                foreach (i; 0 .. length)
+                    exps.push(new IndexExp(e.loc, e, new IntegerExp(e.loc, i, Type.tsize_t)));
+                e = new TupleExp(e.loc, exps);
+            }
+        }
         else
         {
             e = visitArray(mt);
@@ -3885,7 +3905,7 @@
         assert(e.op != EXP.dot);
 
         // https://issues.dlang.org/show_bug.cgi?id=14010
-        if (ident == Id._mangleof)
+        if (!(sc.flags & SCOPE.Cfile) && ident == Id._mangleof)
         {
             return mt.getProperty(sc, e.loc, ident, flag & 1);
         }
@@ -4637,7 +4657,7 @@
     {
         static if (LOGDEFAULTINIT)
         {
-            printf("TypeBasic::defaultInit() '%s'\n", mt.toChars());
+            printf("TypeBasic::defaultInit() '%s' isCfile: %d\n", mt.toChars(), isCfile);
         }
         dinteger_t value = 0;
 
@@ -4695,7 +4715,7 @@
     {
         static if (LOGDEFAULTINIT)
         {
-            printf("TypeSArray::defaultInit() '%s'\n", mt.toChars());
+            printf("TypeSArray::defaultInit() '%s' isCfile %d\n", mt.toChars(), isCfile);
         }
         if (mt.next.ty == Tvoid)
             return mt.tuns8.defaultInit(loc, isCfile);
diff --git a/gcc/d/dmd/utils.d b/gcc/d/dmd/utils.d
index 67e4d86..7f3fb64 100644
--- a/gcc/d/dmd/utils.d
+++ b/gcc/d/dmd/utils.d
@@ -19,6 +19,7 @@
 import dmd.common.outbuffer;
 import dmd.root.string;
 
+nothrow:
 
 /**
  * Normalize path by turning forward slashes into backslashes
@@ -52,13 +53,13 @@
  *   loc = The line number information from where the call originates
  *   filename = Path to file
  */
-FileBuffer readFile(Loc loc, const(char)* filename)
+Buffer readFile(Loc loc, const(char)* filename)
 {
     return readFile(loc, filename.toDString());
 }
 
 /// Ditto
-FileBuffer readFile(Loc loc, const(char)[] filename)
+Buffer readFile(Loc loc, const(char)[] filename)
 {
     auto result = File.read(filename);
     if (!result.success)
@@ -66,7 +67,7 @@
         error(loc, "error reading file `%.*s`", cast(int)filename.length, filename.ptr);
         fatal();
     }
-    return FileBuffer(result.extractSlice());
+    return Buffer(result.extractSlice());
 }
 
 
@@ -83,7 +84,7 @@
     ensurePathToNameExists(Loc.initial, filename);
     if (!File.update(filename, data))
     {
-        error(loc, "Error writing file '%*.s'", cast(int) filename.length, filename.ptr);
+        error(loc, "Error writing file '%.*s'", cast(int) filename.length, filename.ptr);
         fatal();
     }
 }
diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc
index 61a2b50..c683d9d 100644
--- a/gcc/d/expr.cc
+++ b/gcc/d/expr.cc
@@ -3006,6 +3006,16 @@
     this->result_ = var;
   }
 
+  /* Build an uninitialized value, generated from void initializers.  */
+
+  void visit (VoidInitExp *e)
+  {
+    /* The front-end only generates these for the initializer of globals.
+       Represent `void' as zeroes, regardless of the type's default value.  */
+    gcc_assert (this->constp_);
+    this->result_ = build_zero_cst (build_ctype (e->type));
+  }
+
   /* These expressions are mainly just a placeholders in the frontend.
      We shouldn't see them here.  */
 
diff --git a/gcc/d/lang.opt b/gcc/d/lang.opt
index 51e8e5c..b4b8152 100644
--- a/gcc/d/lang.opt
+++ b/gcc/d/lang.opt
@@ -396,6 +396,10 @@
 D RejectNegative
 Turn off all revertable D language features.
 
+frevert=dip1000
+D RejectNegative
+Revert DIP1000: Scoped pointers.
+
 frevert=dip25
 D RejectNegative
 Revert DIP25: Sealed references.
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index e10b10b..84e6f66 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -13460,7 +13460,7 @@
 @code{expl}, @code{fabsf}, @code{fabsl}, @code{floorf}, @code{floorl},
 @code{fmodf}, @code{fmodl}, @code{frexpf}, @code{frexpl}, @code{ldexpf},
 @code{ldexpl}, @code{log10f}, @code{log10l}, @code{logf}, @code{logl},
-@code{modfl}, @code{modf}, @code{powf}, @code{powl}, @code{sinf},
+@code{modfl}, @code{modff}, @code{powf}, @code{powl}, @code{sinf},
 @code{sinhf}, @code{sinhl}, @code{sinl}, @code{sqrtf}, @code{sqrtl},
 @code{tanf}, @code{tanhf}, @code{tanhl} and @code{tanl}
 that are recognized in any mode since ISO C90 reserves these names for
@@ -13525,7 +13525,7 @@
 @code{feraiseexcept}.  They may not be available for all targets, and because
 they need close interaction with libc internal values, they may not be available
 for all target libcs, but in all cases they will gracefully fallback to libc
-calls.  This built-in functions appear both with and without the
+calls.  These built-in functions appear both with and without the
 @code{__builtin_} prefix.
 
 @deftypefn {Built-in Function} void *__builtin_alloca (size_t size)
diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index ab67a63..10bfcef 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -287,7 +287,8 @@
 @item @anchor{GDC-prerequisite}GDC
 
 In order to build GDC, the D compiler, you need a working GDC
-compiler (GCC version 9.1 or later), as the D front end is written in D.
+compiler (GCC version 9.1 or later) and D runtime library,
+@samp{libphobos}, as the D front end is written in D.
 
 Versions of GDC prior to 12 can be built with an ISO C++11 compiler, which can
 then be installed and used to bootstrap newer versions of the D front end.
@@ -303,6 +304,10 @@
 of the D language, if too old a GDC version is installed and
 @option{--enable-languages=d} is used, the build will fail.
 
+On some targets, @samp{libphobos} isn't enabled by default, but compiles
+and works if @option{--enable-libphobos} is used.  Specifics are
+documented for affected targets.
+
 @item A ``working'' POSIX compatible shell, or GNU bash
 
 Necessary when running @command{configure} because some
@@ -2134,17 +2139,6 @@
 point, it is not recommended to use
 @option{--with-long-double-format=ieee}.
 
-On little endian PowerPC Linux systems, if you explicitly set the
-@code{long double} type, it will build multilibs to allow you to
-select either @code{long double} format, unless you disable multilibs
-with the @code{--disable-multilib} option.  At present,
-@code{long double} multilibs are not built on big endian PowerPC Linux
-systems.  If you are building multilibs, you will need to configure
-the compiler using the @option{--with-system-zlib} option.
-
-If you do not set the @code{long double} type explicitly, no multilibs
-will be generated.
-
 @item --enable-fdpic
 On SH Linux systems, generate ELF FDPIC code.
 
@@ -3901,8 +3895,8 @@
 @end html
 @anchor{cris}
 @heading CRIS
-CRIS is the CPU architecture in Axis Communications ETRAX system-on-a-chip
-series.  These are used in embedded applications.
+CRIS is a CPU architecture in Axis Communications systems-on-a-chip, for
+example the ETRAX series.  These are used in embedded applications.
 
 @ifnothtml
 @xref{CRIS Options,, CRIS Options, gcc, Using the GNU Compiler
@@ -3913,21 +3907,8 @@
 @end ifhtml
 for a list of CRIS-specific options.
 
-There are a few different CRIS targets:
-@table @code
-@item cris-axis-elf
-Mainly for monolithic embedded systems.  Includes a multilib for the
-@samp{v10} core used in @samp{ETRAX 100 LX}.
-@item cris-axis-linux-gnu
-A GNU/Linux port for the CRIS architecture, currently targeting
-@samp{ETRAX 100 LX} by default.
-@end table
-
-Pre-packaged tools can be obtained from
-@uref{ftp://ftp.axis.com/@/pub/@/axis/@/tools/@/cris/@/compiler-kit/}.  More
-information about this platform is available at
-@uref{http://developer.axis.com/}.
-
+Use @samp{configure --target=cris-elf} to configure GCC@ for building
+a cross-compiler for CRIS.
 @html
 <hr />
 @end html
@@ -4888,6 +4869,12 @@
 appropriate version is found.  Solaris @command{c++filt} from the Solaris
 Studio compilers does @emph{not} work.
 
+In order to build the GNU D compiler, GDC, a working @samp{libphobos} is
+needed.  That library wasn't built by default in GCC 9--11 on SPARC, or
+on x86 when the Solaris assembler is used, but can be enabled by
+configuring with @option{--enable-libphobos}.  Also, GDC 9.4.0 is
+required on x86, while GDC 9.3.0 is known to work on SPARC.
+
 The versions of the GNU Multiple Precision Library (GMP), the MPFR
 library and the MPC library bundled with Solaris 11.3 and later are
 usually recent enough to match GCC's requirements.  There are two
@@ -4901,6 +4888,7 @@
 @item
 The version of the MPFR libary included in Solaris 11.3 is too old; you
 need to provide a more recent one.
+
 @end itemize
 
 @html
@@ -5141,7 +5129,7 @@
 
 @subheading Intel 64-bit versions
 GCC contains support for x86-64 using the mingw-w64
-runtime library, available from @uref{https://mingw-w64.org/doku.php}.
+runtime library, available from @uref{https://www.mingw-w64.org/downloads/}.
 This library should be used with the target triple x86_64-pc-mingw32.
 
 @subheading Windows CE
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 1a51759..07b4401 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -854,12 +854,12 @@
 -msim  -msdata=@var{sdata-type}}
 
 @emph{CRIS Options}
-@gccoptlist{-mcpu=@var{cpu}  -march=@var{cpu}  -mtune=@var{cpu} @gol
--mmax-stack-frame=@var{n}  -melinux-stacksize=@var{n} @gol
+@gccoptlist{-mcpu=@var{cpu}  -march=@var{cpu}
+-mtune=@var{cpu} -mmax-stack-frame=@var{n} @gol
 -metrax4  -metrax100  -mpdebug  -mcc-init  -mno-side-effects @gol
 -mstack-align  -mdata-align  -mconst-align @gol
--m32-bit  -m16-bit  -m8-bit  -mno-prologue-epilogue  -mno-gotplt @gol
--melf  -maout  -melinux  -mlinux  -sim  -sim2 @gol
+-m32-bit  -m16-bit  -m8-bit  -mno-prologue-epilogue @gol
+-melf  -maout  -sim  -sim2 @gol
 -mmul-bug-workaround  -mno-mul-bug-workaround}
 
 @emph{CR16 Options}
@@ -22365,8 +22365,7 @@
 Generate code for the specified architecture.  The choices for
 @var{architecture-type} are @samp{v3}, @samp{v8} and @samp{v10} for
 respectively ETRAX@w{ }4, ETRAX@w{ }100, and ETRAX@w{ }100@w{ }LX@.
-Default is @samp{v0} except for cris-axis-linux-gnu, where the default is
-@samp{v10}.
+Default is @samp{v0}.
 
 @item -mtune=@var{architecture-type}
 @opindex mtune
@@ -22450,27 +22449,13 @@
 warnings or errors are generated when call-saved registers must be saved,
 or storage for local variables needs to be allocated.
 
-@item -mno-gotplt
-@itemx -mgotplt
-@opindex mno-gotplt
-@opindex mgotplt
-With @option{-fpic} and @option{-fPIC}, don't generate (do generate)
-instruction sequences that load addresses for functions from the PLT part
-of the GOT rather than (traditional on other architectures) calls to the
-PLT@.  The default is @option{-mgotplt}.
-
 @item -melf
 @opindex melf
-Legacy no-op option only recognized with the cris-axis-elf and
-cris-axis-linux-gnu targets.
-
-@item -mlinux
-@opindex mlinux
-Legacy no-op option only recognized with the cris-axis-linux-gnu target.
+Legacy no-op option.
 
 @item -sim
 @opindex sim
-This option, recognized for the cris-axis-elf, arranges
+This option arranges
 to link with input-output functions from a simulator library.  Code,
 initialized data and zero-initialized data are allocated consecutively.
 
@@ -29776,7 +29761,8 @@
 @var{cpu-type} are @samp{z900}/@samp{arch5}, @samp{z990}/@samp{arch6},
 @samp{z9-109}, @samp{z9-ec}/@samp{arch7}, @samp{z10}/@samp{arch8},
 @samp{z196}/@samp{arch9}, @samp{zEC12}, @samp{z13}/@samp{arch11},
-@samp{z14}/@samp{arch12}, @samp{z15}/@samp{arch13}, and @samp{native}.
+@samp{z14}/@samp{arch12}, @samp{z15}/@samp{arch13},
+@samp{z16}/@samp{arch14}, and @samp{native}.
 
 The default is @option{-march=z900}.
 
diff --git a/gcc/dwarf2ctf.cc b/gcc/dwarf2ctf.cc
index 747b2f6..a6329ab 100644
--- a/gcc/dwarf2ctf.cc
+++ b/gcc/dwarf2ctf.cc
@@ -808,12 +808,26 @@
   if (ctf_dvd_lookup (ctfc, die))
     return;
 
+  /* Do not generate CTF variable records for non-defining incomplete
+     declarations.  Such declarations can be known via the DWARF
+     DW_AT_specification attribute.  */
+  if (ctf_dvd_ignore_lookup (ctfc, die))
+    return;
+
+  /* The value of the DW_AT_specification attribute, if present, is a
+     reference to the debugging information entry representing the
+     non-defining declaration.  */
+  dw_die_ref decl = get_AT_ref (die, DW_AT_specification);
+
   /* Add the type of the variable.  */
   var_type_id = gen_ctf_type (ctfc, var_type);
 
   /* Generate the new CTF variable and update global counter.  */
-  (void) ctf_add_variable (ctfc, var_name, var_type_id, die, external_vis);
-  ctfc->ctfc_num_global_objts += 1;
+  (void) ctf_add_variable (ctfc, var_name, var_type_id, die, external_vis,
+			   decl);
+  /* Skip updating the number of global objects at this time.  This is updated
+     later after pre-processing as some CTF variable records although
+     generated now, will not be emitted later.  [PR105089].  */
 }
 
 /* Add a CTF function record for the given input DWARF DIE.  */
diff --git a/gcc/emit-rtl.cc b/gcc/emit-rtl.cc
index f4404d7..1e02ae2 100644
--- a/gcc/emit-rtl.cc
+++ b/gcc/emit-rtl.cc
@@ -6440,7 +6440,8 @@
     }
 
   /* Update LABEL_NUSES.  */
-  mark_jump_label (PATTERN (new_rtx), new_rtx, 0);
+  if (NONDEBUG_INSN_P (insn))
+    mark_jump_label (PATTERN (new_rtx), new_rtx, 0);
 
   INSN_LOCATION (new_rtx) = INSN_LOCATION (insn);
 
diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc
index fb08fa1..a57ad07 100644
--- a/gcc/fold-const.cc
+++ b/gcc/fold-const.cc
@@ -2379,13 +2379,12 @@
   return build_vector_from_val (type, t);
 }
 
-/* Returns true, if ARG, an operand or a type, is convertible to TYPE
-   using a NOP_EXPR.  */
+/* Returns true, if ARG is convertible to TYPE using a NOP_EXPR.  */
 
 bool
 fold_convertible_p (const_tree type, const_tree arg)
 {
-  const_tree orig = TYPE_P (arg) ? arg : TREE_TYPE (arg);
+  const_tree orig = TREE_TYPE (arg);
 
   if (type == orig)
     return true;
@@ -2417,7 +2416,7 @@
       return (VECTOR_TYPE_P (orig)
 	      && known_eq (TYPE_VECTOR_SUBPARTS (type),
 			   TYPE_VECTOR_SUBPARTS (orig))
-	      && fold_convertible_p (TREE_TYPE (type), TREE_TYPE (orig)));
+	      && tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (orig)));
 
     default:
       return false;
@@ -5212,7 +5211,7 @@
 	n_high = fold_convert_loc (loc, arg0_type, n_high);
 
       /* If we're converting arg0 from an unsigned type, to exp,
-	 a signed type,  we will be doing the comparison as unsigned.
+	 a signed type, we will be doing the comparison as unsigned.
 	 The tests above have already verified that LOW and HIGH
 	 are both positive.
 
@@ -5274,6 +5273,32 @@
 	    }
 	}
 
+      /* Otherwise, if we are converting arg0 from signed type, to exp,
+	 an unsigned type, we will do the comparison as signed.  If
+	 high is non-NULL, we punt above if it doesn't fit in the signed
+	 type, so if we get through here, +[-, high] or +[low, high] are
+	 equivalent to +[-, n_high] or +[n_low, n_high].  Similarly,
+	 +[-, -] or -[-, -] are equivalent too.  But if low is specified and
+	 high is not, the +[low, -] range is equivalent to union of
+	 +[n_low, -] and +[-, -1] ranges, so +[low, -] is equivalent to
+	 -[0, n_low-1] and similarly -[low, -] to +[0, n_low-1], except for
+	 low being 0, which should be treated as [-, -].  */
+      else if (TYPE_UNSIGNED (exp_type)
+	       && !TYPE_UNSIGNED (arg0_type)
+	       && low
+	       && !high)
+	{
+	  if (integer_zerop (low))
+	    n_low = NULL_TREE;
+	  else
+	    {
+	      n_high = fold_build2_loc (loc, PLUS_EXPR, arg0_type,
+					n_low, build_int_cst (arg0_type, -1));
+	      n_low = build_zero_cst (arg0_type);
+	      in_p = !in_p;
+	    }
+	}
+
       *p_low = n_low;
       *p_high = n_high;
       *p_in_p = in_p;
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 0328328..9b6e55a 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,92 @@
+2022-04-27  Mikael Morin  <mikael@gcc.gnu.org>
+
+	PR fortran/103662
+	PR fortran/105379
+	* array.cc (compare_bounds): Use bool as return type.
+	Support non-constant expressions.
+	(gfc_compare_array_spec): Update call to compare_bounds.
+
+2022-04-27  Mikael Morin  <mikael@gcc.gnu.org>
+
+	PR fortran/102043
+	PR fortran/105381
+	* trans-array.cc (non_negative_strides_array_p): Inline variable
+	orig_decl and merge nested if conditions.  Add condition to not
+	recurse if the next argument is the same as the current.
+
+2022-04-25  Jakub Jelinek  <jakub@redhat.com>
+	    Thomas Schwinge  <thomas@codesourcery.com>
+
+	PR fortran/104717
+	* trans-openmp.cc (gfc_trans_oacc_construct): Wrap construct body
+	in an extra BIND_EXPR.
+
+2022-04-24  Mikael Morin  <mikael@gcc.gnu.org>
+	    Jakub Jelinek  <jakub@redhat.com>
+
+	PR fortran/103662
+	* interface.cc (gfc_compare_derived_types): Support comparing
+	unlimited polymorphic fake symbols.  Recursively compare class
+	descriptor types and virtual table types.
+	* resolve.cc (resolve_fl_derived): Add type to the types list
+	on unlimited polymorphic short-circuit return.
+
+2022-04-22  Mikael Morin  <mikael@gcc.gnu.org>
+	    Richard Biener  <rguenther@suse.de>
+
+	PR fortran/102043
+	* trans.h (gfc_build_array_ref): Add non_negative_offset
+	argument.
+	* trans.cc (gfc_build_array_ref): Ditto. Use pointer arithmetic
+	if non_negative_offset is false.
+	* trans-expr.cc (gfc_conv_substring): Set flag in the call to
+	gfc_build_array_ref.
+	* trans-array.cc (gfc_get_cfi_dim_item,
+	gfc_conv_descriptor_dimension): Same.
+	(build_array_ref): Decide on whether to set the flag and update
+	the call.
+	(gfc_conv_scalarized_array_ref): Same.  New argument tmp_array.
+	(gfc_conv_tmp_array_ref): Update call to
+	gfc_conv_scalarized_ref.
+	(non_negative_strides_array_p): New function.
+
+2022-04-22  Mikael Morin  <mikael@gcc.gnu.org>
+
+	PR fortran/102043
+	* trans-array.cc (gfc_conv_expr_descriptor): Use
+	gfc_conv_tmp_array_ref.
+
+2022-04-22  Mikael Morin  <mikael@gcc.gnu.org>
+
+	PR fortran/102043
+	* trans-io.cc: Add handling for the case where the array
+	is referenced using pointer arithmetic.
+
+2022-04-22  Mikael Morin  <mikael@gcc.gnu.org>
+
+	PR fortran/102043
+	* trans-expr.cc: Pre-evaluate src and dest to variables
+	before using them.
+
+2022-04-21  Fritz Reese  <foreese@gcc.gnu.org>
+
+	PR fortran/105310
+	* trans-expr.cc (gfc_conv_union_initializer): Pass vec* by reference.
+
+2022-04-13  Tobias Burnus  <tobias@codesourcery.com>
+
+	PR fortran/105242
+	* match.cc (match_exit_cycle): Handle missing OMP LOOP, DO and SIMD
+	directives in the EXIT/CYCLE diagnostic.
+
+2022-04-10  Harald Anlauf  <anlauf@gmx.de>
+
+	PR fortran/105184
+	* array.cc (match_subscript): Reject assumed size coarray
+	specification with missing lower bound.
+	* resolve.cc (resolve_allocate_expr): Fix logic for checking
+	allocate-coshape-spec in ALLOCATE statement.
+
 2022-04-05  Sandra Loosemore  <sandra@codesourcery.com>
 
 	* trans-openmp.cc (gfc_split_omp_clauses): Fix mask for
diff --git a/gcc/fortran/array.cc b/gcc/fortran/array.cc
index eb9ed85..bbdb5b3 100644
--- a/gcc/fortran/array.cc
+++ b/gcc/fortran/array.cc
@@ -134,6 +134,13 @@
   if (m == MATCH_ERROR)
     return MATCH_ERROR;
 
+  if (star && ar->start[i] == NULL)
+    {
+      gfc_error ("Missing lower bound in assumed size "
+		 "coarray specification at %C");
+      return MATCH_ERROR;
+    }
+
   /* See if we have an optional stride.  */
   if (gfc_match_char (':') == MATCH_YES)
     {
@@ -950,23 +957,28 @@
 }
 
 
-/* Returns nonzero if the two expressions are equal.  Only handles integer
-   constants.  */
+/* Returns nonzero if the two expressions are equal.
+   We should not need to support more than constant values, as that’s what is
+   allowed in derived type component array spec.  However, we may create types
+   with non-constant array spec for dummy variable class container types, for
+   which the _data component holds the array spec of the variable declaration.
+   So we have to support non-constant bounds as well.  */
 
-static int
+static bool
 compare_bounds (gfc_expr *bound1, gfc_expr *bound2)
 {
   if (bound1 == NULL || bound2 == NULL
-      || bound1->expr_type != EXPR_CONSTANT
-      || bound2->expr_type != EXPR_CONSTANT
       || bound1->ts.type != BT_INTEGER
       || bound2->ts.type != BT_INTEGER)
     gfc_internal_error ("gfc_compare_array_spec(): Array spec clobbered");
 
-  if (mpz_cmp (bound1->value.integer, bound2->value.integer) == 0)
-    return 1;
-  else
-    return 0;
+  /* What qualifies as identical bounds?  We could probably just check that the
+     expressions are exact clones.  We avoid rewriting a specific comparison
+     function and re-use instead the rather involved gfc_dep_compare_expr which
+     is just a bit more permissive, as it can also detect identical values for
+     some mismatching expressions (extra parenthesis, swapped operands, unary
+     plus, etc).  It probably only makes a difference in corner cases.  */
+  return gfc_dep_compare_expr (bound1, bound2) == 0;
 }
 
 
@@ -999,10 +1011,10 @@
   if (as1->type == AS_EXPLICIT)
     for (i = 0; i < as1->rank + as1->corank; i++)
       {
-	if (compare_bounds (as1->lower[i], as2->lower[i]) == 0)
+	if (!compare_bounds (as1->lower[i], as2->lower[i]))
 	  return 0;
 
-	if (compare_bounds (as1->upper[i], as2->upper[i]) == 0)
+	if (!compare_bounds (as1->upper[i], as2->upper[i]))
 	  return 0;
       }
 
diff --git a/gcc/fortran/interface.cc b/gcc/fortran/interface.cc
index 000a530..7ed6e13 100644
--- a/gcc/fortran/interface.cc
+++ b/gcc/fortran/interface.cc
@@ -618,6 +618,14 @@
   if (!derived1 || !derived2)
     gfc_internal_error ("gfc_compare_derived_types: invalid derived type");
 
+  if (derived1->attr.unlimited_polymorphic
+      && derived2->attr.unlimited_polymorphic)
+    return true;
+
+  if (derived1->attr.unlimited_polymorphic
+      != derived2->attr.unlimited_polymorphic)
+    return false;
+
   /* Compare UNION types specially.  */
   if (derived1->attr.flavor == FL_UNION || derived2->attr.flavor == FL_UNION)
     return compare_union_types (derived1, derived2);
@@ -630,10 +638,11 @@
       && strcmp (derived1->module, derived2->module) == 0)
     return true;
 
-  /* Compare type via the rules of the standard.  Both types must have
-     the SEQUENCE or BIND(C) attribute to be equal. STRUCTUREs are special
-     because they can be anonymous; therefore two structures with different
-     names may be equal.  */
+  /* Compare type via the rules of the standard.  Both types must have the
+     SEQUENCE or BIND(C) attribute to be equal.  We also compare types
+     recursively if they are class descriptors types or virtual tables types.
+     STRUCTUREs are special because they can be anonymous; therefore two
+     structures with different names may be equal.  */
 
   /* Compare names, but not for anonymous types such as UNION or MAP.  */
   if (!is_anonymous_dt (derived1) && !is_anonymous_dt (derived2)
@@ -646,6 +655,8 @@
 
   if (!(derived1->attr.sequence && derived2->attr.sequence)
       && !(derived1->attr.is_bind_c && derived2->attr.is_bind_c)
+      && !(derived1->attr.is_class && derived2->attr.is_class)
+      && !(derived1->attr.vtype && derived2->attr.vtype)
       && !(derived1->attr.pdt_type && derived2->attr.pdt_type))
     return false;
 
diff --git a/gcc/fortran/match.cc b/gcc/fortran/match.cc
index 715a74e..205811b 100644
--- a/gcc/fortran/match.cc
+++ b/gcc/fortran/match.cc
@@ -2857,83 +2857,107 @@
 
   for (o = p, cnt = 0; o->state == COMP_DO && o->previous != NULL; cnt++)
     o = o->previous;
+
+  int count = 1;
   if (cnt > 0
       && o != NULL
-      && o->state == COMP_OMP_STRUCTURED_BLOCK
-      && (o->head->op == EXEC_OACC_LOOP
-	  || o->head->op == EXEC_OACC_KERNELS_LOOP
-	  || o->head->op == EXEC_OACC_PARALLEL_LOOP
-	  || o->head->op == EXEC_OACC_SERIAL_LOOP))
-    {
-      int collapse = 1;
-      gcc_assert (o->head->next != NULL
+      && o->state == COMP_OMP_STRUCTURED_BLOCK)
+    switch (o->head->op)
+      {
+      case EXEC_OACC_LOOP:
+      case EXEC_OACC_KERNELS_LOOP:
+      case EXEC_OACC_PARALLEL_LOOP:
+      case EXEC_OACC_SERIAL_LOOP:
+	gcc_assert (o->head->next != NULL
+		    && (o->head->next->op == EXEC_DO
+			|| o->head->next->op == EXEC_DO_WHILE)
+		    && o->previous != NULL
+		    && o->previous->tail->op == o->head->op);
+	if (o->previous->tail->ext.omp_clauses != NULL)
+	  {
+	    /* Both collapsed and tiled loops are lowered the same way, but are
+	       not compatible.  In gfc_trans_omp_do, the tile is prioritized. */
+	    if (o->previous->tail->ext.omp_clauses->tile_list)
+	      {
+		count = 0;
+		gfc_expr_list *el
+		  = o->previous->tail->ext.omp_clauses->tile_list;
+		for ( ; el; el = el->next)
+		  ++count;
+	      }
+	    else if (o->previous->tail->ext.omp_clauses->collapse > 1)
+	      count = o->previous->tail->ext.omp_clauses->collapse;
+	  }
+	if (st == ST_EXIT && cnt <= count)
+	  {
+	    gfc_error ("EXIT statement at %C terminating !$ACC LOOP loop");
+	    return MATCH_ERROR;
+	  }
+	if (st == ST_CYCLE && cnt < count)
+	  {
+	    gfc_error (o->previous->tail->ext.omp_clauses->tile_list
+		       ? G_("CYCLE statement at %C to non-innermost tiled "
+			    "!$ACC LOOP loop")
+		       : G_("CYCLE statement at %C to non-innermost collapsed "
+			    "!$ACC LOOP loop"));
+	    return MATCH_ERROR;
+	  }
+	break;
+      case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
+      case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
+      case EXEC_OMP_TARGET_SIMD:
+      case EXEC_OMP_TASKLOOP_SIMD:
+      case EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD:
+      case EXEC_OMP_MASTER_TASKLOOP_SIMD:
+      case EXEC_OMP_PARALLEL_MASKED_TASKLOOP_SIMD:
+      case EXEC_OMP_MASKED_TASKLOOP_SIMD:
+      case EXEC_OMP_PARALLEL_DO_SIMD:
+      case EXEC_OMP_DISTRIBUTE_SIMD:
+      case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD:
+      case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
+      case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
+      case EXEC_OMP_LOOP:
+      case EXEC_OMP_PARALLEL_LOOP:
+      case EXEC_OMP_TEAMS_LOOP:
+      case EXEC_OMP_TARGET_PARALLEL_LOOP:
+      case EXEC_OMP_TARGET_TEAMS_LOOP:
+      case EXEC_OMP_DO:
+      case EXEC_OMP_PARALLEL_DO:
+      case EXEC_OMP_SIMD:
+      case EXEC_OMP_DO_SIMD:
+      case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
+      case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
+      case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
+      case EXEC_OMP_TARGET_PARALLEL_DO:
+      case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
+
+	gcc_assert (o->head->next != NULL
 		  && (o->head->next->op == EXEC_DO
 		      || o->head->next->op == EXEC_DO_WHILE)
 		  && o->previous != NULL
 		  && o->previous->tail->op == o->head->op);
-      if (o->previous->tail->ext.omp_clauses != NULL)
-	{
-	  /* Both collapsed and tiled loops are lowered the same way, but are not
-	     compatible.  In gfc_trans_omp_do, the tile is prioritized.  */
-	  if (o->previous->tail->ext.omp_clauses->tile_list)
-	    {
-	      collapse = 0;
-	      gfc_expr_list *el = o->previous->tail->ext.omp_clauses->tile_list;
-	      for ( ; el; el = el->next)
-		++collapse;
-	    }
-	  else if (o->previous->tail->ext.omp_clauses->collapse > 1)
-	    collapse = o->previous->tail->ext.omp_clauses->collapse;
-	}
-      if (st == ST_EXIT && cnt <= collapse)
-	{
-	  gfc_error ("EXIT statement at %C terminating !$ACC LOOP loop");
-	  return MATCH_ERROR;
-	}
-      if (st == ST_CYCLE && cnt < collapse)
-	{
-	  gfc_error (o->previous->tail->ext.omp_clauses->tile_list
-		     ? G_("CYCLE statement at %C to non-innermost tiled"
-			  " !$ACC LOOP loop")
-		     : G_("CYCLE statement at %C to non-innermost collapsed"
-			  " !$ACC LOOP loop"));
-	  return MATCH_ERROR;
-	}
-    }
-  if (cnt > 0
-      && o != NULL
-      && (o->state == COMP_OMP_STRUCTURED_BLOCK)
-      && (o->head->op == EXEC_OMP_DO
-	  || o->head->op == EXEC_OMP_PARALLEL_DO
-	  || o->head->op == EXEC_OMP_SIMD
-	  || o->head->op == EXEC_OMP_DO_SIMD
-	  || o->head->op == EXEC_OMP_PARALLEL_DO_SIMD))
-    {
-      int count = 1;
-      gcc_assert (o->head->next != NULL
-		  && (o->head->next->op == EXEC_DO
-		      || o->head->next->op == EXEC_DO_WHILE)
-		  && o->previous != NULL
-		  && o->previous->tail->op == o->head->op);
-      if (o->previous->tail->ext.omp_clauses != NULL)
-	{
-	  if (o->previous->tail->ext.omp_clauses->collapse > 1)
-	    count = o->previous->tail->ext.omp_clauses->collapse;
-	  if (o->previous->tail->ext.omp_clauses->orderedc)
-	    count = o->previous->tail->ext.omp_clauses->orderedc;
-	}
-      if (st == ST_EXIT && cnt <= count)
-	{
-	  gfc_error ("EXIT statement at %C terminating !$OMP DO loop");
-	  return MATCH_ERROR;
-	}
-      if (st == ST_CYCLE && cnt < count)
-	{
-	  gfc_error ("CYCLE statement at %C to non-innermost collapsed"
-		     " !$OMP DO loop");
-	  return MATCH_ERROR;
-	}
-    }
+	if (o->previous->tail->ext.omp_clauses != NULL)
+	  {
+	    if (o->previous->tail->ext.omp_clauses->collapse > 1)
+	      count = o->previous->tail->ext.omp_clauses->collapse;
+	    if (o->previous->tail->ext.omp_clauses->orderedc)
+	      count = o->previous->tail->ext.omp_clauses->orderedc;
+	  }
+	if (st == ST_EXIT && cnt <= count)
+	  {
+	    gfc_error ("EXIT statement at %C terminating !$OMP DO loop");
+	    return MATCH_ERROR;
+	  }
+	if (st == ST_CYCLE && cnt < count)
+	  {
+	    gfc_error ("CYCLE statement at %C to non-innermost collapsed "
+		       "!$OMP DO loop");
+	    return MATCH_ERROR;
+	  }
+	break;
+      default:
+	break;
+      }
 
   /* Save the first statement in the construct - needed by the backend.  */
   new_st.ext.which_construct = p->construct;
diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
index 21c8797..29df531 100644
--- a/gcc/fortran/resolve.cc
+++ b/gcc/fortran/resolve.cc
@@ -8108,12 +8108,13 @@
 	    goto failure;
 
 	  case  DIMEN_RANGE:
-	    if (ar->start[i] == 0 || ar->end[i] == 0)
+	    /* F2018:R937:
+	     * allocate-coshape-spec is [ lower-bound-expr : ] upper-bound-expr
+	     */
+	    if (ar->start[i] == 0 || ar->end[i] == 0 || ar->stride[i] != NULL)
 	      {
-		/* If ar->stride[i] is NULL, we issued a previous error.  */
-		if (ar->stride[i] == NULL)
-		  gfc_error ("Bad array specification in ALLOCATE statement "
-			     "at %L", &e->where);
+		gfc_error ("Bad coarray specification in ALLOCATE statement "
+			   "at %L", &e->where);
 		goto failure;
 	      }
 	    else if (gfc_dep_compare_expr (ar->start[i], ar->end[i]) == 1)
@@ -15150,7 +15151,10 @@
 
       /* Nothing more to do for unlimited polymorphic entities.  */
       if (data->ts.u.derived->attr.unlimited_polymorphic)
-	return true;
+	{
+	  add_dt_to_dt_list (sym);
+	  return true;
+	}
       else if (vptr->ts.u.derived == NULL)
 	{
 	  gfc_symbol *vtab = gfc_find_derived_vtab (data->ts.u.derived);
diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index b3f8871..0513495 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -172,7 +172,7 @@
 gfc_get_cfi_dim_item (tree desc, tree idx, unsigned field_idx)
 {
   tree tmp = gfc_get_cfi_descriptor_field (desc, CFI_FIELD_DIM);
-  tmp = gfc_build_array_ref (tmp, idx, NULL);
+  tmp = gfc_build_array_ref (tmp, idx, NULL_TREE, true);
   tree field = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (tmp)), field_idx);
   gcc_assert (field != NULL_TREE);
   return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
@@ -424,7 +424,7 @@
 
   tmp = gfc_get_descriptor_dimension (desc);
 
-  return gfc_build_array_ref (tmp, dim, NULL);
+  return gfc_build_array_ref (tmp, dim, NULL_TREE, true);
 }
 
 
@@ -3664,10 +3664,52 @@
 }
 
 
+/* Indicates that the tree EXPR is a reference to an array that can’t
+   have any negative stride.  */
+
+static bool
+non_negative_strides_array_p (tree expr)
+{
+  if (expr == NULL_TREE)
+    return false;
+
+  tree type = TREE_TYPE (expr);
+  if (POINTER_TYPE_P (type))
+    type = TREE_TYPE (type);
+
+  if (TYPE_LANG_SPECIFIC (type))
+    {
+      gfc_array_kind array_kind = GFC_TYPE_ARRAY_AKIND (type);
+
+      if (array_kind == GFC_ARRAY_ALLOCATABLE
+	  || array_kind == GFC_ARRAY_ASSUMED_SHAPE_CONT)
+	return true;
+    }
+
+  /* An array with descriptor can have negative strides.
+     We try to be conservative and return false by default here
+     if we don’t recognize a contiguous array instead of
+     returning false if we can identify a non-contiguous one.  */
+  if (!GFC_ARRAY_TYPE_P (type))
+    return false;
+
+  /* If the array was originally a dummy with a descriptor, strides can be
+     negative.  */
+  if (DECL_P (expr)
+      && DECL_LANG_SPECIFIC (expr)
+      && GFC_DECL_SAVED_DESCRIPTOR (expr)
+      && GFC_DECL_SAVED_DESCRIPTOR (expr) != expr)
+    return non_negative_strides_array_p (GFC_DECL_SAVED_DESCRIPTOR (expr));
+
+  return true;
+}
+
+
 /* Build a scalarized reference to an array.  */
 
 static void
-gfc_conv_scalarized_array_ref (gfc_se * se, gfc_array_ref * ar)
+gfc_conv_scalarized_array_ref (gfc_se * se, gfc_array_ref * ar,
+			       bool tmp_array = false)
 {
   gfc_array_info *info;
   tree decl = NULL_TREE;
@@ -3717,7 +3759,10 @@
 	decl = info->descriptor;
     }
 
-  se->expr = gfc_build_array_ref (base, index, decl);
+  bool non_negative_stride = tmp_array
+			     || non_negative_strides_array_p (info->descriptor);
+  se->expr = gfc_build_array_ref (base, index, decl,
+				  non_negative_stride);
 }
 
 
@@ -3727,7 +3772,7 @@
 gfc_conv_tmp_array_ref (gfc_se * se)
 {
   se->string_length = se->ss->info->string_length;
-  gfc_conv_scalarized_array_ref (se, NULL);
+  gfc_conv_scalarized_array_ref (se, NULL, true);
   gfc_advance_se_ss_chain (se);
 }
 
@@ -3779,7 +3824,9 @@
 
   tmp = gfc_conv_array_data (desc);
   tmp = build_fold_indirect_ref_loc (input_location, tmp);
-  tmp = gfc_build_array_ref (tmp, offset, decl, vptr);
+  tmp = gfc_build_array_ref (tmp, offset, decl,
+			     non_negative_strides_array_p (desc),
+			     vptr);
   return tmp;
 }
 
@@ -7723,7 +7770,7 @@
       lse.ss = loop.temp_ss;
       rse.ss = ss;
 
-      gfc_conv_scalarized_array_ref (&lse, NULL);
+      gfc_conv_tmp_array_ref (&lse);
       if (expr->ts.type == BT_CHARACTER)
 	{
 	  gfc_conv_expr (&rse, expr);
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 06713f2..850007f 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -2612,7 +2612,7 @@
       /* For BIND(C), a BT_CHARACTER is not an ARRAY_TYPE.  */
       if (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
 	{
-	  tmp = gfc_build_array_ref (tmp, start.expr, NULL);
+	  tmp = gfc_build_array_ref (tmp, start.expr, NULL_TREE, true);
 	  se->expr = gfc_build_addr_expr (type, tmp);
 	}
     }
@@ -8093,6 +8093,13 @@
   cond2 = fold_build2_loc (input_location, LT_EXPR, logical_type_node, slen,
 			   dlen);
 
+  /* Pre-evaluate pointers unless one of the IF arms will be optimized away.  */
+  if (!CONSTANT_CLASS_P (cond2))
+    {
+      dest = gfc_evaluate_now (dest, block);
+      src = gfc_evaluate_now (src, block);
+    }
+
   /* Copy and pad with spaces.  */
   tmp3 = build_call_expr_loc (input_location,
 			      builtin_decl_explicit (BUILT_IN_MEMMOVE),
@@ -9194,8 +9201,8 @@
   return gfc_finish_block (&block);
 }
 
-void
-gfc_conv_union_initializer (vec<constructor_elt, va_gc> *v,
+static void
+gfc_conv_union_initializer (vec<constructor_elt, va_gc> *&v,
                             gfc_component *un, gfc_expr *init)
 {
   gfc_constructor *ctor;
diff --git a/gcc/fortran/trans-io.cc b/gcc/fortran/trans-io.cc
index 732221f..9f86815 100644
--- a/gcc/fortran/trans-io.cc
+++ b/gcc/fortran/trans-io.cc
@@ -737,7 +737,6 @@
 static void
 gfc_convert_array_to_string (gfc_se * se, gfc_expr * e)
 {
-  tree size;
 
   if (e->rank == 0)
     {
@@ -755,12 +754,13 @@
       array = sym->backend_decl;
       type = TREE_TYPE (array);
 
+      tree elts_count;
       if (GFC_ARRAY_TYPE_P (type))
-	size = GFC_TYPE_ARRAY_SIZE (type);
+	elts_count = GFC_TYPE_ARRAY_SIZE (type);
       else
 	{
 	  gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
-	  size = gfc_conv_array_stride (array, rank);
+	  tree stride = gfc_conv_array_stride (array, rank);
 	  tmp = fold_build2_loc (input_location, MINUS_EXPR,
 				 gfc_array_index_type,
 				 gfc_conv_array_ubound (array, rank),
@@ -768,23 +768,49 @@
 	  tmp = fold_build2_loc (input_location, PLUS_EXPR,
 				 gfc_array_index_type, tmp,
 				 gfc_index_one_node);
+	  elts_count = fold_build2_loc (input_location, MULT_EXPR,
+					gfc_array_index_type, tmp, stride);
+	}
+      gcc_assert (elts_count);
+
+      tree elt_size = TYPE_SIZE_UNIT (gfc_get_element_type (type));
+      elt_size = fold_convert (gfc_array_index_type, elt_size);
+
+      tree size;
+      if (TREE_CODE (se->expr) == ARRAY_REF)
+	{
+	  tree index = TREE_OPERAND (se->expr, 1);
+	  index = fold_convert (gfc_array_index_type, index);
+
+	  elts_count = fold_build2_loc (input_location, MINUS_EXPR,
+					gfc_array_index_type,
+					elts_count, index);
+
 	  size = fold_build2_loc (input_location, MULT_EXPR,
-				  gfc_array_index_type, tmp, size);
+				  gfc_array_index_type, elts_count, elt_size);
+	}
+      else
+	{
+	  gcc_assert (TREE_CODE (se->expr) == INDIRECT_REF);
+	  tree ptr = TREE_OPERAND (se->expr, 0);
+
+	  gcc_assert (TREE_CODE (ptr) == POINTER_PLUS_EXPR);
+	  tree offset = fold_convert_loc (input_location, gfc_array_index_type,
+					  TREE_OPERAND (ptr, 1));
+
+	  size = fold_build2_loc (input_location, MULT_EXPR,
+				  gfc_array_index_type, elts_count, elt_size);
+	  size = fold_build2_loc (input_location, MINUS_EXPR,
+				  gfc_array_index_type, size, offset);
 	}
       gcc_assert (size);
 
-      size = fold_build2_loc (input_location, MINUS_EXPR,
-			      gfc_array_index_type, size,
-			      TREE_OPERAND (se->expr, 1));
       se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
-      tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
-      size = fold_build2_loc (input_location, MULT_EXPR,
-			      gfc_array_index_type, size,
-			      fold_convert (gfc_array_index_type, tmp));
       se->string_length = fold_convert (gfc_charlen_type_node, size);
       return;
     }
 
+  tree size;
   gfc_conv_array_parameter (se, e, true, NULL, NULL, &size);
   se->string_length = fold_convert (gfc_charlen_type_node, size);
 }
diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc
index 25dde82..43d59ab 100644
--- a/gcc/fortran/trans-openmp.cc
+++ b/gcc/fortran/trans-openmp.cc
@@ -4444,7 +4444,9 @@
   gfc_start_block (&block);
   oacc_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
 					code->loc, false, true);
+  pushlevel ();
   stmt = gfc_trans_omp_code (code->block->next, true);
+  stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
   stmt = build2_loc (gfc_get_location (&code->loc), construct_code,
 		     void_type_node, stmt, oacc_clauses);
   gfc_add_expr_to_block (&block, stmt);
diff --git a/gcc/fortran/trans.cc b/gcc/fortran/trans.cc
index 333dfa6..f0a5dfb 100644
--- a/gcc/fortran/trans.cc
+++ b/gcc/fortran/trans.cc
@@ -446,10 +446,14 @@
 }
 
 
-/* Build an ARRAY_REF with its natural type.  */
+/* Build an ARRAY_REF with its natural type.
+   NON_NEGATIVE_OFFSET indicates if it’s true that OFFSET can’t be negative,
+   and thus that an ARRAY_REF can safely be generated.  If it’s false, we
+   have to play it safe and use pointer arithmetic.  */
 
 tree
-gfc_build_array_ref (tree base, tree offset, tree decl, tree vptr)
+gfc_build_array_ref (tree base, tree offset, tree decl,
+		     bool non_negative_offset, tree vptr)
 {
   tree type = TREE_TYPE (base);
   tree span = NULL_TREE;
@@ -495,10 +499,40 @@
      pointer arithmetic.  */
   if (span != NULL_TREE)
     return gfc_build_spanned_array_ref (base, offset, span);
-  /* Otherwise use a straightforward array reference.  */
-  else
+  /* Else use a straightforward array reference if possible.  */
+  else if (non_negative_offset)
     return build4_loc (input_location, ARRAY_REF, type, base, offset,
 		       NULL_TREE, NULL_TREE);
+  /* Otherwise use pointer arithmetic.  */
+  else
+    {
+      gcc_assert (TREE_CODE (TREE_TYPE (base)) == ARRAY_TYPE);
+      tree min = NULL_TREE;
+      if (TYPE_DOMAIN (TREE_TYPE (base))
+	  && !integer_zerop (TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (base)))))
+	min = TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (base)));
+
+      tree zero_based_index
+	   = min ? fold_build2_loc (input_location, MINUS_EXPR,
+				    gfc_array_index_type,
+				    fold_convert (gfc_array_index_type, offset),
+				    fold_convert (gfc_array_index_type, min))
+		 : fold_convert (gfc_array_index_type, offset);
+
+      tree elt_size = fold_convert (gfc_array_index_type,
+				    TYPE_SIZE_UNIT (type));
+
+      tree offset_bytes = fold_build2_loc (input_location, MULT_EXPR,
+					   gfc_array_index_type,
+					   zero_based_index, elt_size);
+
+      tree base_addr = gfc_build_addr_expr (pvoid_type_node, base);
+
+      tree ptr = fold_build_pointer_plus_loc (input_location, base_addr,
+					      offset_bytes);
+      return build1_loc (input_location, INDIRECT_REF, type,
+			 fold_convert (build_pointer_type (type), ptr));
+    }
 }
 
 
diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h
index 738c748..623acee 100644
--- a/gcc/fortran/trans.h
+++ b/gcc/fortran/trans.h
@@ -619,7 +619,9 @@
 tree gfc_build_addr_expr (tree, tree);
 
 /* Build an ARRAY_REF.  */
-tree gfc_build_array_ref (tree, tree, tree, tree vptr = NULL_TREE);
+tree gfc_build_array_ref (tree, tree, tree,
+			  bool non_negative_offset = false,
+			  tree vptr = NULL_TREE);
 
 /* Build an array ref using pointer arithmetic.  */
 tree gfc_build_spanned_array_ref (tree base, tree offset, tree span);
diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc
index 97880a5f..863ee3d 100644
--- a/gcc/gimple-fold.cc
+++ b/gcc/gimple-fold.cc
@@ -1048,6 +1048,7 @@
 			  gsi_replace (gsi, new_stmt, false);
 			  return true;
 			}
+		      gimple_set_location (new_stmt, loc);
 		      gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
 		      goto done;
 		    }
@@ -1302,6 +1303,7 @@
 						   new_stmt);
 	      gimple_assign_set_lhs (new_stmt, srcvar);
 	      gimple_set_vuse (new_stmt, gimple_vuse (stmt));
+	      gimple_set_location (new_stmt, loc);
 	      gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
 	    }
 	  new_stmt = gimple_build_assign (destvar, srcvar);
@@ -1338,6 +1340,7 @@
 	  gsi_replace (gsi, new_stmt, false);
 	  return true;
 	}
+      gimple_set_location (new_stmt, loc);
       gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
     }
 
@@ -4747,7 +4750,7 @@
 				      "have well defined padding bits for %qs",
 			    field, "__builtin_clear_padding");
 	      }
-	    else if (is_empty_type (TREE_TYPE (field)))
+	    else if (is_empty_type (ftype))
 	      continue;
 	    else
 	      {
@@ -4758,8 +4761,9 @@
 		gcc_assert (pos >= 0 && fldsz >= 0 && pos >= cur_pos);
 		clear_padding_add_padding (buf, pos - cur_pos);
 		cur_pos = pos;
-		clear_padding_type (buf, TREE_TYPE (field),
-				    fldsz, for_auto_init);
+		if (tree asbase = lang_hooks.types.classtype_as_base (field))
+		  ftype = asbase;
+		clear_padding_type (buf, ftype, fldsz, for_auto_init);
 		cur_pos += fldsz;
 	      }
 	  }
diff --git a/gcc/gimple-isel.cc b/gcc/gimple-isel.cc
index 3635585..a8f7a0d 100644
--- a/gcc/gimple-isel.cc
+++ b/gcc/gimple-isel.cc
@@ -245,6 +245,14 @@
 			GET_MODE_NUNITS (cmp_op_mode)));
 
   icode = get_vcond_icode (mode, cmp_op_mode, unsignedp);
+  /* Some targets do not have vcondeq and only vcond with NE/EQ
+     but not vcondu, so make sure to also try vcond here as
+     vcond_icode_p would canonicalize the optab query to.  */
+  if (icode == CODE_FOR_nothing
+      && (tcode == NE_EXPR || tcode == EQ_EXPR)
+      && ((icode = get_vcond_icode (mode, cmp_op_mode, !unsignedp))
+	  != CODE_FOR_nothing))
+    unsignedp = !unsignedp;
   if (icode == CODE_FOR_nothing)
     {
       if (tcode == LT_EXPR
diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc
index 04075a9..f0caefc 100644
--- a/gcc/gimple-range.cc
+++ b/gcc/gimple-range.cc
@@ -394,6 +394,10 @@
 	      // Fold and save the value for NAME.
 	      stmt = SSA_NAME_DEF_STMT (name);
 	      fold_range_internal (r, stmt, name);
+	      // Make sure we don't lose any current global info.
+	      int_range_max tmp;
+	      m_cache.get_global_range (tmp, name);
+	      r.intersect (tmp);
 	      m_cache.set_global_range (name, r);
 	    }
 	  continue;
diff --git a/gcc/gimple-ssa-warn-access.cc b/gcc/gimple-ssa-warn-access.cc
index 879dbcc..39aa818 100644
--- a/gcc/gimple-ssa-warn-access.cc
+++ b/gcc/gimple-ssa-warn-access.cc
@@ -3923,7 +3923,8 @@
       return;
     }
 
-  if ((maybe && warn_dangling_pointer < 2)
+  if (equality
+      || (maybe && warn_dangling_pointer < 2)
       || warning_suppressed_p (use_stmt, OPT_Wdangling_pointer_))
     return;
 
@@ -4241,7 +4242,7 @@
 	      basic_block use_bb = gimple_bb (use_stmt);
 	      bool this_maybe
 		= (maybe
-		   || !dominated_by_p (CDI_POST_DOMINATORS, use_bb, stmt_bb));
+		   || !dominated_by_p (CDI_POST_DOMINATORS, stmt_bb, use_bb));
 	      warn_invalid_pointer (*use_p->use, use_stmt, stmt, var,
 				    this_maybe, equality);
 	      continue;
@@ -4486,7 +4487,7 @@
 
   basic_block use_bb = gimple_bb (use_stmt);
   basic_block clob_bb = gimple_bb (*pclob);
-  maybe = maybe || !dominated_by_p (CDI_POST_DOMINATORS, use_bb, clob_bb);
+  maybe = maybe || !dominated_by_p (CDI_POST_DOMINATORS, clob_bb, use_bb);
   warn_invalid_pointer (var, use_stmt, *pclob, decl, maybe, false);
 }
 
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index f93eaf4..ef20a0a 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-45108f37070afb696b069768700e39a269f1fecb
+70ca85f08edf63f46c87d540fa99c45e2903edc2
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc
index 30d5c9f..d35c6ba 100644
--- a/gcc/go/gofrontend/gogo.cc
+++ b/gcc/go/gofrontend/gogo.cc
@@ -1612,31 +1612,16 @@
               // The initializer is constant if it is the zero-value of the
               // variable's type or if the initial value is an immutable value
               // that is not copied to the heap.
-	      Expression* init = var->init();
-
-	      // If we see "a = b; b = x", and x is a static
-	      // initializer, just set a to x.
-	      while (init != NULL && init->var_expression() != NULL)
-		{
-		  Named_object* ino = init->var_expression()->named_object();
-		  if (!ino->is_variable() || ino->package() != NULL)
-		    break;
-		  Expression* ino_init = ino->var_value()->init();
-		  if (ino->var_value()->has_pre_init()
-		      || ino_init == NULL
-		      || !ino_init->is_static_initializer())
-		    break;
-		  init = ino_init;
-		}
-
-              bool is_static_initializer;
-              if (init == NULL)
+              bool is_static_initializer = false;
+              if (var->init() == NULL)
                 is_static_initializer = true;
               else
                 {
                   Type* var_type = var->type();
-                  init = Expression::make_cast(var_type, init, var->location());
-                  is_static_initializer = init->is_static_initializer();
+                  Expression* init = var->init();
+                  Expression* init_cast =
+                      Expression::make_cast(var_type, init, var->location());
+                  is_static_initializer = init_cast->is_static_initializer();
                 }
 
 	      // Non-constant variable initializations might need to create
@@ -1655,15 +1640,7 @@
                     }
 		  var_init_fn = init_fndecl;
 		}
-
-	      Bexpression* var_binit;
-	      if (init == NULL)
-		var_binit = NULL;
-	      else
-		{
-		  Translate_context context(this, var_init_fn, NULL, NULL);
-		  var_binit = init->get_backend(&context);
-		}
+              Bexpression* var_binit = var->get_init(this, var_init_fn);
 
               if (var_binit == NULL)
 		;
diff --git a/gcc/ifcvt.cc b/gcc/ifcvt.cc
index 22960a6..b983e87 100644
--- a/gcc/ifcvt.cc
+++ b/gcc/ifcvt.cc
@@ -1678,10 +1678,10 @@
   reversep = 0;
 
   if ((if_info->a == const0_rtx
-       && rtx_equal_p (if_info->b, if_info->x))
+       && (REG_P (if_info->b) || rtx_equal_p (if_info->b, if_info->x)))
       || ((reversep = (noce_reversed_cond_code (if_info) != UNKNOWN))
 	  && if_info->b == const0_rtx
-	  && rtx_equal_p (if_info->a, if_info->x)))
+	  && (REG_P (if_info->a) || rtx_equal_p (if_info->a, if_info->x))))
     {
       start_sequence ();
       target = noce_emit_store_flag (if_info,
@@ -1689,7 +1689,7 @@
 				     reversep, -1);
       if (target)
         target = expand_simple_binop (GET_MODE (if_info->x), AND,
-				      if_info->x,
+				      reversep ? if_info->a : if_info->b,
 				      target, if_info->x, 0,
 				      OPTAB_WIDEN);
 
diff --git a/gcc/ipa-fnsummary.cc b/gcc/ipa-fnsummary.cc
index 0d7e395..b12e7a1 100644
--- a/gcc/ipa-fnsummary.cc
+++ b/gcc/ipa-fnsummary.cc
@@ -2587,7 +2587,7 @@
 	  && DECL_BY_REFERENCE (DECL_RESULT (current_function_decl))
 	  && t == ssa_default_def (cfun, DECL_RESULT (current_function_decl)))
 	return true;
-      return !ptr_deref_may_alias_global_p (t);
+      return !ptr_deref_may_alias_global_p (t, false);
     }
   if (TREE_CODE (t) == ADDR_EXPR)
     return refs_local_or_readonly_memory_p (TREE_OPERAND (t, 0));
diff --git a/gcc/ipa-free-lang-data.cc b/gcc/ipa-free-lang-data.cc
index f596eef..a742156 100644
--- a/gcc/ipa-free-lang-data.cc
+++ b/gcc/ipa-free-lang-data.cc
@@ -672,7 +672,7 @@
         }
     }
   /* We need to keep field decls associated with their trees. Otherwise tree
-     merging may merge some fileds and keep others disjoint wich in turn will
+     merging may merge some fields and keep others disjoint which in turn will
      not do well with TREE_CHAIN pointers linking them.
 
      Also do not drop containing types for virtual methods and tables because
diff --git a/gcc/ipa-modref-tree.cc b/gcc/ipa-modref-tree.cc
index f19af8c..44cb645 100644
--- a/gcc/ipa-modref-tree.cc
+++ b/gcc/ipa-modref-tree.cc
@@ -267,34 +267,42 @@
 
 
   /* Now compute distance of the intervals.  */
-  poly_int64 dist1, dist2;
+  poly_offset_int dist1, dist2;
   if (known_le (offseta1, offsetb1))
     {
       if (!known_size_p (a1.max_size))
 	dist1 = 0;
       else
-	dist1 = offsetb1 - offseta1 - a1.max_size;
+	dist1 = (poly_offset_int)offsetb1
+		- (poly_offset_int)offseta1
+		- (poly_offset_int)a1.max_size;
     }
   else
     {
       if (!known_size_p (b1.max_size))
 	dist1 = 0;
       else
-	dist1 = offseta1 - offsetb1 - b1.max_size;
+	dist1 = (poly_offset_int)offseta1
+		 - (poly_offset_int)offsetb1
+		 - (poly_offset_int)b1.max_size;
     }
   if (known_le (offseta2, offsetb2))
     {
       if (!known_size_p (a2.max_size))
 	dist2 = 0;
       else
-	dist2 = offsetb2 - offseta2 - a2.max_size;
+	dist2 = (poly_offset_int)offsetb2
+		- (poly_offset_int)offseta2
+		- (poly_offset_int)a2.max_size;
     }
   else
     {
       if (!known_size_p (b2.max_size))
 	dist2 = 0;
       else
-	dist2 = offseta2 - offsetb2 - b2.max_size;
+	dist2 = offseta2
+		- (poly_offset_int)offsetb2
+		- (poly_offset_int)b2.max_size;
     }
   /* It may happen that intervals overlap in case size
      is different.  Prefer the overlap to non-overlap.  */
@@ -380,9 +388,16 @@
     new_max_size = max_size2;
   else
     {
-      new_max_size = max_size2 + offset2 - offset1;
-      if (known_le (new_max_size, max_size1))
-	new_max_size = max_size1;
+      poly_offset_int s = (poly_offset_int)max_size2
+			  + (poly_offset_int)offset2
+			  - (poly_offset_int)offset1;
+      if (s.to_shwi (&new_max_size))
+	{
+	  if (known_le (new_max_size, max_size1))
+	    new_max_size = max_size1;
+	}
+      else
+	new_max_size = -1;
     }
 
   update (parm_offset1, offset1,
diff --git a/gcc/ipa-modref.cc b/gcc/ipa-modref.cc
index acfd7d8..556816a 100644
--- a/gcc/ipa-modref.cc
+++ b/gcc/ipa-modref.cc
@@ -5281,6 +5281,29 @@
       if (!ignore_stores)
 	to_info_lto->stores->collapse ();
     }
+  /* Merge side effects and non-determinism.
+     PURE/CONST flags makes functions deterministic and if there is
+     no LOOPING_CONST_OR_PURE they also have no side effects.  */
+  if (!(flags & (ECF_CONST | ECF_NOVOPS | ECF_PURE))
+      || (flags & ECF_LOOPING_CONST_OR_PURE))
+    {
+      if (to_info)
+	{
+	  if (!callee_info || callee_info->side_effects)
+	    to_info->side_effects = true;
+	  if ((!callee_info || callee_info->nondeterministic)
+	      && !ignore_nondeterminism_p (edge->caller->decl, flags))
+	    to_info->nondeterministic = true;
+	}
+      if (to_info_lto)
+	{
+	  if (!callee_info_lto || callee_info_lto->side_effects)
+	    to_info_lto->side_effects = true;
+	  if ((!callee_info_lto || callee_info_lto->nondeterministic)
+	      && !ignore_nondeterminism_p (edge->caller->decl, flags))
+	    to_info_lto->nondeterministic = true;
+	}
+     }
   if (callee_info || callee_info_lto)
     {
       auto_vec <modref_parm_map, 32> parm_map;
diff --git a/gcc/jit/ChangeLog b/gcc/jit/ChangeLog
index 535daa4..faab3a7 100644
--- a/gcc/jit/ChangeLog
+++ b/gcc/jit/ChangeLog
@@ -1,3 +1,119 @@
+2022-04-14  Iain Sandoe  <iain@sandoe.co.uk>
+
+	* jit-playback.cc (new_bitcast): Cast values returned by tree_to_uhwi
+	to 'long' to match the print format.
+
+2022-04-12  Antoni Boucher  <bouanto@zoho.com>
+
+	PR jit/104293
+	* docs/_build/texinfo/libgccjit.texi: Regenerate.
+	* docs/topics/compatibility.rst (LIBGCCJIT_ABI_24): New ABI tag.
+	* docs/topics/expressions.rst: Add documentation for the
+	functions gcc_jit_lvalue_set_alignment and
+	gcc_jit_lvalue_get_alignment.
+	* jit-playback.h: New function (set_alignment).
+	* jit-recording.cc: New function (set_alignment).
+	* jit-recording.h: New functions (set_alignment, get_alignment)
+	and new field (m_alignment).
+	* libgccjit.cc: New functions (gcc_jit_lvalue_get_alignment,
+	gcc_jit_lvalue_set_alignment)
+	* libgccjit.h: New functions (gcc_jit_lvalue_get_alignment,
+	gcc_jit_lvalue_set_alignment)
+	* libgccjit.map (LIBGCCJIT_ABI_24): New ABI tag.
+
+2022-04-12  Antoni Boucher  <bouanto@zoho.com>
+
+	PR jit/104073
+	* docs/_build/texinfo/libgccjit.texi: Regenerate.
+	* docs/topics/compatibility.rst (LIBGCCJIT_ABI_23): New ABI tag.
+	* docs/topics/contexts.rst: Add documentation for the new
+	function gcc_jit_context_set_bool_print_errors_to_stderr.
+	* jit-common.h: New enum value
+	(INNER_BOOL_OPTION_PRINT_ERRORS_TO_STDERR).
+	* jit-recording.cc: Handle the new option
+	INNER_BOOL_OPTION_PRINT_ERRORS_TO_STDERR.
+	* libgccjit.cc: New function
+	(gcc_jit_context_set_bool_print_errors_to_stderr).
+	* libgccjit.h: New function
+	(gcc_jit_context_set_bool_print_errors_to_stderr).
+	* libgccjit.map (LIBGCCJIT_ABI_23): New ABI tag.
+
+2022-04-12  Antoni Boucher  <bouanto@zoho.com>
+
+	PR jit/104072
+	* docs/_build/texinfo/libgccjit.texi: Regenerate.
+	* docs/topics/compatibility.rst (LIBGCCJIT_ABI_22): New ABI tag.
+	* docs/topics/expressions.rst: Add documentation for the
+	function gcc_jit_lvalue_set_register_name.
+	* jit-playback.h: New function (set_register_name).
+	* jit-recording.cc: New function (set_register_name) and add
+	support for register variables.
+	* jit-recording.h: New field (m_reg_name) and new function
+	(set_register_name).
+	* libgccjit.cc: New function (gcc_jit_lvalue_set_register_name).
+	* libgccjit.h: New function (gcc_jit_lvalue_set_register_name).
+	* libgccjit.map (LIBGCCJIT_ABI_22): New ABI tag.
+
+2022-04-12  Antoni Boucher  <bouanto@zoho.com>
+
+	PR jit/104071
+	* docs/_build/texinfo/libgccjit.texi: Regenerate.
+	* docs/topics/compatibility.rst (LIBGCCJIT_ABI_21): New ABI tag.
+	* docs/topics/expressions.rst: Add documentation for the
+	function gcc_jit_context_new_bitcast.
+	* jit-playback.cc: New function (new_bitcast).
+	* jit-playback.h: New function (new_bitcast).
+	* jit-recording.cc: New functions (new_bitcast,
+	bitcast::replay_into, bitcast::visit_children,
+	bitcast::make_debug_string, bitcast::write_reproducer).
+	* jit-recording.h: New class (bitcast) and new function
+	(new_bitcast, bitcast::replay_into, bitcast::visit_children,
+	bitcast::make_debug_string, bitcast::write_reproducer,
+	bitcast::get_precedence).
+	* libgccjit.cc: New function (gcc_jit_context_new_bitcast)
+	* libgccjit.h: New function (gcc_jit_context_new_bitcast)
+	* libgccjit.map (LIBGCCJIT_ABI_21): New ABI tag.
+
+2022-04-12  Antoni Boucher  <bouanto@zoho.com>
+
+	PR target/95325
+	* docs/_build/texinfo/libgccjit.texi: Regenerate
+	* docs/topics/compatibility.rst (LIBGCCJIT_ABI_20): New ABI tag.
+	* docs/topics/types.rst: Add documentation for the new types
+	GCC_JIT_TYPE_UINT8_T, GCC_JIT_TYPE_UINT16_T,
+	GCC_JIT_TYPE_UINT32_T, GCC_JIT_TYPE_UINT64_T,
+	GCC_JIT_TYPE_UINT128_T, GCC_JIT_TYPE_INT8_T, GCC_JIT_TYPE_INT16_T,
+	GCC_JIT_TYPE_INT32_T, GCC_JIT_TYPE_INT64_T, GCC_JIT_TYPE_INT128_T and
+	new functions (gcc_jit_compatible_types, gcc_jit_type_get_size).
+	* jit-builtins.cc: Add support for BT_UINT128.
+	* jit-common.h: Update the value of NUM_GCC_JIT_TYPES.
+	* jit-playback.cc: Add support for the sized integer types.
+	* jit-recording.cc: Add support for the sized integer types.
+	* jit-recording.h: Add support for comparing integer types
+	and new function (is_signed).
+	* libgccjit.cc (gcc_jit_compatible_types): New.
+	(gcc_jit_type_get_size) New.
+	* libgccjit.h: New enum variants for gcc_jit_types
+	(GCC_JIT_TYPE_UINT8_T, GCC_JIT_TYPE_UINT16_T,
+	GCC_JIT_TYPE_UINT32_T, GCC_JIT_TYPE_UINT64_T,
+	GCC_JIT_TYPE_UINT128_T, GCC_JIT_TYPE_INT8_T,
+	GCC_JIT_TYPE_INT16_T, GCC_JIT_TYPE_INT32_T,
+	GCC_JIT_TYPE_INT64_T, GCC_JIT_TYPE_INT128_T) and new functions
+	(gcc_jit_compatible_types, gcc_jit_type_get_size).
+	* libgccjit.map (LIBGCCJIT_ABI_20): New ABI tag.
+
+2022-04-06  David Malcolm  <dmalcolm@redhat.com>
+
+	PR jit/102824
+	* docs/_build/texinfo/factorial.png: Move to...
+	* docs/_build/texinfo/libgccjit-figures/factorial.png: ...here.
+	* docs/_build/texinfo/factorial1.png: Move to...
+	* docs/_build/texinfo/libgccjit-figures/factorial1.png: ...here.
+	* docs/_build/texinfo/sum-of-squares.png: Move to...
+	* docs/_build/texinfo/libgccjit-figures/sum-of-squares.png: ...here.
+	* docs/_build/texinfo/sum-of-squares1.png: Move to...
+	* docs/_build/texinfo/libgccjit-figures/sum-of-squares1.png: ...here.
+
 2022-04-01  David Malcolm  <dmalcolm@redhat.com>
 
 	* docs/topics/expressions.rst: Fix formatting.
diff --git a/gcc/jit/docs/_build/texinfo/factorial.png b/gcc/jit/docs/_build/texinfo/libgccjit-figures/factorial.png
similarity index 100%
rename from gcc/jit/docs/_build/texinfo/factorial.png
rename to gcc/jit/docs/_build/texinfo/libgccjit-figures/factorial.png
Binary files differ
diff --git a/gcc/jit/docs/_build/texinfo/factorial1.png b/gcc/jit/docs/_build/texinfo/libgccjit-figures/factorial1.png
similarity index 100%
rename from gcc/jit/docs/_build/texinfo/factorial1.png
rename to gcc/jit/docs/_build/texinfo/libgccjit-figures/factorial1.png
Binary files differ
diff --git a/gcc/jit/docs/_build/texinfo/sum-of-squares.png b/gcc/jit/docs/_build/texinfo/libgccjit-figures/sum-of-squares.png
similarity index 100%
rename from gcc/jit/docs/_build/texinfo/sum-of-squares.png
rename to gcc/jit/docs/_build/texinfo/libgccjit-figures/sum-of-squares.png
Binary files differ
diff --git a/gcc/jit/docs/_build/texinfo/sum-of-squares1.png b/gcc/jit/docs/_build/texinfo/libgccjit-figures/sum-of-squares1.png
similarity index 100%
rename from gcc/jit/docs/_build/texinfo/sum-of-squares1.png
rename to gcc/jit/docs/_build/texinfo/libgccjit-figures/sum-of-squares1.png
Binary files differ
diff --git a/gcc/jit/docs/_build/texinfo/libgccjit.texi b/gcc/jit/docs/_build/texinfo/libgccjit.texi
index c1ca5aa..9c90de3 100644
--- a/gcc/jit/docs/_build/texinfo/libgccjit.texi
+++ b/gcc/jit/docs/_build/texinfo/libgccjit.texi
@@ -21,7 +21,7 @@
 
 @copying
 @quotation
-libgccjit 12.0.1 (experimental 20220331), Mar 31, 2022
+libgccjit 12.0.1 (experimental 20220411), Apr 12, 2022
 
 David Malcolm
 
@@ -260,6 +260,11 @@
 * LIBGCCJIT_ABI_17:: 
 * LIBGCCJIT_ABI_18:: 
 * LIBGCCJIT_ABI_19:: 
+* LIBGCCJIT_ABI_20:: 
+* LIBGCCJIT_ABI_21:: 
+* LIBGCCJIT_ABI_22:: 
+* LIBGCCJIT_ABI_23:: 
+* LIBGCCJIT_ABI_24:: 
 
 Performance
 
@@ -5022,8 +5027,24 @@
 @end example
 @end deffn
 
+@geindex gcc_jit_context_set_bool_print_errors_to_stderr (C function)
+@anchor{topics/contexts c gcc_jit_context_set_bool_print_errors_to_stderr}@anchor{6f}
+@deffn {C Function} void            gcc_jit_context_set_bool_print_errors_to_stderr (gcc_jit_context@w{ }*ctxt, int@w{ }enabled)
+
+By default, libgccjit will print errors to stderr.
+
+This entrypoint can be used to disable the printing.
+
+This entrypoint was added in @ref{70,,LIBGCCJIT_ABI_23}; you can test for
+its presence using
+
+@example
+#ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_bool_print_errors_to_stderr
+@end example
+@end deffn
+
 @node Integer options,Additional command-line options,Boolean options,Options<2>
-@anchor{topics/contexts integer-options}@anchor{6f}
+@anchor{topics/contexts integer-options}@anchor{71}
 @subsubsection Integer options
 
 
@@ -5034,7 +5055,7 @@
 Set an integer option of the context.
 
 @geindex gcc_jit_int_option (C type)
-@anchor{topics/contexts c gcc_jit_int_option}@anchor{70}
+@anchor{topics/contexts c gcc_jit_int_option}@anchor{72}
 @deffn {C Type} enum gcc_jit_int_option
 @end deffn
 
@@ -5054,12 +5075,12 @@
 @end deffn
 
 @node Additional command-line options,,Integer options,Options<2>
-@anchor{topics/contexts additional-command-line-options}@anchor{71}
+@anchor{topics/contexts additional-command-line-options}@anchor{73}
 @subsubsection Additional command-line options
 
 
 @geindex gcc_jit_context_add_command_line_option (C function)
-@anchor{topics/contexts c gcc_jit_context_add_command_line_option}@anchor{72}
+@anchor{topics/contexts c gcc_jit_context_add_command_line_option}@anchor{74}
 @deffn {C Function} void gcc_jit_context_add_command_line_option (gcc_jit_context@w{ }*ctxt, const char@w{ }*optname)
 
 Add an arbitrary gcc command-line option to the context, for use
@@ -5085,7 +5106,7 @@
 “frontend” within libgccjit, so typically only those affecting
 optimization and code-generation are likely to be useful.
 
-This entrypoint was added in @ref{73,,LIBGCCJIT_ABI_1}; you can test for
+This entrypoint was added in @ref{75,,LIBGCCJIT_ABI_1}; you can test for
 its presence using
 
 @example
@@ -5094,7 +5115,7 @@
 @end deffn
 
 @geindex gcc_jit_context_add_driver_option (C function)
-@anchor{topics/contexts c gcc_jit_context_add_driver_option}@anchor{74}
+@anchor{topics/contexts c gcc_jit_context_add_driver_option}@anchor{76}
 @deffn {C Function} void gcc_jit_context_add_driver_option (gcc_jit_context@w{ }*ctxt, const char@w{ }*optname)
 
 Add an arbitrary gcc driver option to the context, for use by
@@ -5125,7 +5146,7 @@
 “frontend” within libgccjit, so typically only those affecting
 assembler and linker are likely to be useful.
 
-This entrypoint was added in @ref{75,,LIBGCCJIT_ABI_11}; you can test for
+This entrypoint was added in @ref{77,,LIBGCCJIT_ABI_11}; you can test for
 its presence using
 
 @example
@@ -5151,7 +5172,7 @@
 @c <https://www.gnu.org/licenses/>.
 
 @node Objects,Types,Compilation contexts,Topic Reference
-@anchor{topics/objects doc}@anchor{76}@anchor{topics/objects objects}@anchor{77}
+@anchor{topics/objects doc}@anchor{78}@anchor{topics/objects objects}@anchor{79}
 @section Objects
 
 
@@ -5209,7 +5230,7 @@
 The object “base class” has the following operations:
 
 @geindex gcc_jit_object_get_context (C function)
-@anchor{topics/objects c gcc_jit_object_get_context}@anchor{78}
+@anchor{topics/objects c gcc_jit_object_get_context}@anchor{7a}
 @deffn {C Function} gcc_jit_context *gcc_jit_object_get_context (gcc_jit_object@w{ }*obj)
 
 Which context is “obj” within?
@@ -5261,7 +5282,7 @@
 @c <https://www.gnu.org/licenses/>.
 
 @node Types,Expressions,Objects,Topic Reference
-@anchor{topics/types doc}@anchor{79}@anchor{topics/types types}@anchor{7a}
+@anchor{topics/types doc}@anchor{7b}@anchor{topics/types types}@anchor{7c}
 @section Types
 
 
@@ -5296,7 +5317,7 @@
 
 @item 
 derived types can be accessed by using functions such as
-@ref{7b,,gcc_jit_type_get_pointer()} and @ref{7c,,gcc_jit_type_get_const()}:
+@ref{7d,,gcc_jit_type_get_pointer()} and @ref{7e,,gcc_jit_type_get_const()}:
 
 @example
 gcc_jit_type *const_int_star = gcc_jit_type_get_pointer (gcc_jit_type_get_const (int_type));
@@ -5318,7 +5339,7 @@
 @end menu
 
 @node Standard types,Pointers const and volatile,,Types
-@anchor{topics/types standard-types}@anchor{7d}
+@anchor{topics/types standard-types}@anchor{7f}
 @subsection Standard types
 
 
@@ -5454,6 +5475,86 @@
 
 @item
 
+@code{GCC_JIT_TYPE_UINT8_T}
+
+@tab
+
+C99’s @code{uint8_t}
+
+@item
+
+@code{GCC_JIT_TYPE_UINT16_T}
+
+@tab
+
+C99’s @code{uint16_t}
+
+@item
+
+@code{GCC_JIT_TYPE_UINT32_T}
+
+@tab
+
+C99’s @code{uint32_t}
+
+@item
+
+@code{GCC_JIT_TYPE_UINT64_T}
+
+@tab
+
+C99’s @code{uint64_t}
+
+@item
+
+@code{GCC_JIT_TYPE_UINT128_T}
+
+@tab
+
+C99’s @code{__uint128_t}
+
+@item
+
+@code{GCC_JIT_TYPE_INT8_T}
+
+@tab
+
+C99’s @code{int8_t}
+
+@item
+
+@code{GCC_JIT_TYPE_INT16_T}
+
+@tab
+
+C99’s @code{int16_t}
+
+@item
+
+@code{GCC_JIT_TYPE_INT32_T}
+
+@tab
+
+C99’s @code{int32_t}
+
+@item
+
+@code{GCC_JIT_TYPE_INT64_T}
+
+@tab
+
+C99’s @code{int64_t}
+
+@item
+
+@code{GCC_JIT_TYPE_INT128_T}
+
+@tab
+
+C99’s @code{__int128_t}
+
+@item
+
 @code{GCC_JIT_TYPE_FLOAT}
 
 @tab
@@ -5523,47 +5624,47 @@
 @end deffn
 
 @geindex gcc_jit_context_get_int_type (C function)
-@anchor{topics/types c gcc_jit_context_get_int_type}@anchor{7e}
+@anchor{topics/types c gcc_jit_context_get_int_type}@anchor{80}
 @deffn {C Function} gcc_jit_type *           gcc_jit_context_get_int_type (gcc_jit_context@w{ }*ctxt, int@w{ }num_bytes, int@w{ }is_signed)
 
 Access the integer type of the given size.
 @end deffn
 
 @node Pointers const and volatile,Vector types,Standard types,Types
-@anchor{topics/types pointers-const-and-volatile}@anchor{7f}
+@anchor{topics/types pointers-const-and-volatile}@anchor{81}
 @subsection Pointers, @cite{const}, and @cite{volatile}
 
 
 @geindex gcc_jit_type_get_pointer (C function)
-@anchor{topics/types c gcc_jit_type_get_pointer}@anchor{7b}
+@anchor{topics/types c gcc_jit_type_get_pointer}@anchor{7d}
 @deffn {C Function} gcc_jit_type *gcc_jit_type_get_pointer (gcc_jit_type@w{ }*type)
 
 Given type “T”, get type “T*”.
 @end deffn
 
 @geindex gcc_jit_type_get_const (C function)
-@anchor{topics/types c gcc_jit_type_get_const}@anchor{7c}
+@anchor{topics/types c gcc_jit_type_get_const}@anchor{7e}
 @deffn {C Function} gcc_jit_type *gcc_jit_type_get_const (gcc_jit_type@w{ }*type)
 
 Given type “T”, get type “const T”.
 @end deffn
 
 @geindex gcc_jit_type_get_volatile (C function)
-@anchor{topics/types c gcc_jit_type_get_volatile}@anchor{80}
+@anchor{topics/types c gcc_jit_type_get_volatile}@anchor{82}
 @deffn {C Function} gcc_jit_type *gcc_jit_type_get_volatile (gcc_jit_type@w{ }*type)
 
 Given type “T”, get type “volatile T”.
 @end deffn
 
 @geindex gcc_jit_context_new_array_type (C function)
-@anchor{topics/types c gcc_jit_context_new_array_type}@anchor{81}
+@anchor{topics/types c gcc_jit_context_new_array_type}@anchor{83}
 @deffn {C Function} gcc_jit_type *            gcc_jit_context_new_array_type (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, gcc_jit_type@w{ }*element_type, int@w{ }num_elements)
 
 Given non-@cite{void} type “T”, get type “T[N]” (for a constant N).
 @end deffn
 
 @geindex gcc_jit_type_get_aligned (C function)
-@anchor{topics/types c gcc_jit_type_get_aligned}@anchor{82}
+@anchor{topics/types c gcc_jit_type_get_aligned}@anchor{84}
 @deffn {C Function} gcc_jit_type *            gcc_jit_type_get_aligned (gcc_jit_type@w{ }*type, size_t@w{ }alignment_in_bytes)
 
 Given non-@cite{void} type “T”, get type:
@@ -5574,7 +5675,7 @@
 
 The alignment must be a power of two.
 
-This entrypoint was added in @ref{83,,LIBGCCJIT_ABI_7}; you can test for
+This entrypoint was added in @ref{85,,LIBGCCJIT_ABI_7}; you can test for
 its presence using
 
 @example
@@ -5583,12 +5684,12 @@
 @end deffn
 
 @node Vector types,Structures and unions,Pointers const and volatile,Types
-@anchor{topics/types vector-types}@anchor{84}
+@anchor{topics/types vector-types}@anchor{86}
 @subsection Vector types
 
 
 @geindex gcc_jit_type_get_vector (C function)
-@anchor{topics/types c gcc_jit_type_get_vector}@anchor{85}
+@anchor{topics/types c gcc_jit_type_get_vector}@anchor{87}
 @deffn {C Function} gcc_jit_type *            gcc_jit_type_get_vector (gcc_jit_type@w{ }*type, size_t@w{ }num_units)
 
 Given type “T”, get type:
@@ -5618,7 +5719,7 @@
 gcc_jit_type *v4si_type = gcc_jit_type_get_vector (int_type, 4);
 @end example
 
-This API entrypoint was added in @ref{86,,LIBGCCJIT_ABI_8}; you can test
+This API entrypoint was added in @ref{88,,LIBGCCJIT_ABI_8}; you can test
 for its presence using
 
 @example
@@ -5626,30 +5727,30 @@
 @end example
 
 Vector rvalues can be generated using
-@ref{87,,gcc_jit_context_new_rvalue_from_vector()}.
+@ref{89,,gcc_jit_context_new_rvalue_from_vector()}.
 @end deffn
 
 @node Structures and unions,Function pointer types,Vector types,Types
-@anchor{topics/types structures-and-unions}@anchor{88}
+@anchor{topics/types structures-and-unions}@anchor{8a}
 @subsection Structures and unions
 
 
 @geindex gcc_jit_struct (C type)
-@anchor{topics/types c gcc_jit_struct}@anchor{89}
+@anchor{topics/types c gcc_jit_struct}@anchor{8b}
 @deffn {C Type} gcc_jit_struct
 @end deffn
 
 A compound type analagous to a C @cite{struct}.
 
 @geindex gcc_jit_field (C type)
-@anchor{topics/types c gcc_jit_field}@anchor{8a}
+@anchor{topics/types c gcc_jit_field}@anchor{8c}
 @deffn {C Type} gcc_jit_field
 @end deffn
 
-A field within a @ref{89,,gcc_jit_struct}.
+A field within a @ref{8b,,gcc_jit_struct}.
 
-You can model C @cite{struct} types by creating @ref{89,,gcc_jit_struct} and
-@ref{8a,,gcc_jit_field} instances, in either order:
+You can model C @cite{struct} types by creating @ref{8b,,gcc_jit_struct} and
+@ref{8c,,gcc_jit_field} instances, in either order:
 
 
 @itemize *
@@ -5698,7 +5799,7 @@
 @end itemize
 
 @geindex gcc_jit_context_new_field (C function)
-@anchor{topics/types c gcc_jit_context_new_field}@anchor{8b}
+@anchor{topics/types c gcc_jit_context_new_field}@anchor{8d}
 @deffn {C Function} gcc_jit_field *           gcc_jit_context_new_field (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, gcc_jit_type@w{ }*type, const char@w{ }*name)
 
 Construct a new field, with the given type and name.
@@ -5711,7 +5812,7 @@
 @end deffn
 
 @geindex gcc_jit_context_new_bitfield (C function)
-@anchor{topics/types c gcc_jit_context_new_bitfield}@anchor{8c}
+@anchor{topics/types c gcc_jit_context_new_bitfield}@anchor{8e}
 @deffn {C Function} gcc_jit_field *           gcc_jit_context_new_bitfield (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, gcc_jit_type@w{ }*type, int@w{ }width, const char@w{ }*name)
 
 Construct a new bit field, with the given type width and name.
@@ -5725,7 +5826,7 @@
 The parameter @code{width} must be a positive integer that does not exceed the
 size of @code{type}.
 
-This API entrypoint was added in @ref{8d,,LIBGCCJIT_ABI_12}; you can test
+This API entrypoint was added in @ref{8f,,LIBGCCJIT_ABI_12}; you can test
 for its presence using
 
 @example
@@ -5734,14 +5835,14 @@
 @end deffn
 
 @geindex gcc_jit_field_as_object (C function)
-@anchor{topics/types c gcc_jit_field_as_object}@anchor{8e}
+@anchor{topics/types c gcc_jit_field_as_object}@anchor{90}
 @deffn {C Function} gcc_jit_object *           gcc_jit_field_as_object (gcc_jit_field@w{ }*field)
 
 Upcast from field to object.
 @end deffn
 
 @geindex gcc_jit_context_new_struct_type (C function)
-@anchor{topics/types c gcc_jit_context_new_struct_type}@anchor{8f}
+@anchor{topics/types c gcc_jit_context_new_struct_type}@anchor{91}
 @deffn {C Function} gcc_jit_struct *gcc_jit_context_new_struct_type (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, const char@w{ }*name, int@w{ }num_fields, gcc_jit_field@w{ }**fields)
 
 @quotation
@@ -5755,13 +5856,13 @@
 @end deffn
 
 @geindex gcc_jit_context_new_opaque_struct (C function)
-@anchor{topics/types c gcc_jit_context_new_opaque_struct}@anchor{90}
+@anchor{topics/types c gcc_jit_context_new_opaque_struct}@anchor{92}
 @deffn {C Function} gcc_jit_struct *         gcc_jit_context_new_opaque_struct (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, const char@w{ }*name)
 
 Construct a new struct type, with the given name, but without
 specifying the fields.   The fields can be omitted (in which case the
 size of the struct is not known), or later specified using
-@ref{91,,gcc_jit_struct_set_fields()}.
+@ref{93,,gcc_jit_struct_set_fields()}.
 
 The parameter @code{name} must be non-NULL.  The call takes a copy of
 the underlying string, so it is valid to pass in a pointer to an
@@ -5769,14 +5870,14 @@
 @end deffn
 
 @geindex gcc_jit_struct_as_type (C function)
-@anchor{topics/types c gcc_jit_struct_as_type}@anchor{92}
+@anchor{topics/types c gcc_jit_struct_as_type}@anchor{94}
 @deffn {C Function} gcc_jit_type *           gcc_jit_struct_as_type (gcc_jit_struct@w{ }*struct_type)
 
 Upcast from struct to type.
 @end deffn
 
 @geindex gcc_jit_struct_set_fields (C function)
-@anchor{topics/types c gcc_jit_struct_set_fields}@anchor{91}
+@anchor{topics/types c gcc_jit_struct_set_fields}@anchor{93}
 @deffn {C Function} void           gcc_jit_struct_set_fields (gcc_jit_struct@w{ }*struct_type, gcc_jit_location@w{ }*loc, int@w{ }num_fields, gcc_jit_field@w{ }**fields)
 
 Populate the fields of a formerly-opaque struct type.
@@ -5785,7 +5886,7 @@
 @end deffn
 
 @geindex gcc_jit_context_new_union_type (C function)
-@anchor{topics/types c gcc_jit_context_new_union_type}@anchor{93}
+@anchor{topics/types c gcc_jit_context_new_union_type}@anchor{95}
 @deffn {C Function} gcc_jit_type *         gcc_jit_context_new_union_type (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, const char@w{ }*name, int@w{ }num_fields, gcc_jit_field@w{ }**fields)
 
 Construct a new union type, with the given name and fields.
@@ -5873,104 +5974,104 @@
 @end deffn
 
 @node Function pointer types,Reflection API,Structures and unions,Types
-@anchor{topics/types function-pointer-types}@anchor{94}
+@anchor{topics/types function-pointer-types}@anchor{96}
 @subsection Function pointer types
 
 
 Function pointer types can be created using
-@ref{95,,gcc_jit_context_new_function_ptr_type()}.
+@ref{97,,gcc_jit_context_new_function_ptr_type()}.
 
 @node Reflection API,,Function pointer types,Types
-@anchor{topics/types reflection-api}@anchor{96}
+@anchor{topics/types reflection-api}@anchor{98}
 @subsection Reflection API
 
 
 @geindex gcc_jit_type_dyncast_array (C function)
-@anchor{topics/types c gcc_jit_type_dyncast_array}@anchor{97}
+@anchor{topics/types c gcc_jit_type_dyncast_array}@anchor{99}
 @deffn {C Function} gcc_jit_type *          gcc_jit_type_dyncast_array (gcc_jit_type@w{ }*type)
 
 Get the element type of an array type or NULL if it’s not an array.
 @end deffn
 
 @geindex gcc_jit_type_is_bool (C function)
-@anchor{topics/types c gcc_jit_type_is_bool}@anchor{98}
+@anchor{topics/types c gcc_jit_type_is_bool}@anchor{9a}
 @deffn {C Function} int          gcc_jit_type_is_bool (gcc_jit_type@w{ }*type)
 
 Return non-zero if the type is a bool.
 @end deffn
 
 @geindex gcc_jit_type_dyncast_function_ptr_type (C function)
-@anchor{topics/types c gcc_jit_type_dyncast_function_ptr_type}@anchor{99}
+@anchor{topics/types c gcc_jit_type_dyncast_function_ptr_type}@anchor{9b}
 @deffn {C Function} gcc_jit_function_type *          gcc_jit_type_dyncast_function_ptr_type (gcc_jit_type@w{ }*type)
 
 Return the function type if it is one or NULL.
 @end deffn
 
 @geindex gcc_jit_function_type_get_return_type (C function)
-@anchor{topics/types c gcc_jit_function_type_get_return_type}@anchor{9a}
+@anchor{topics/types c gcc_jit_function_type_get_return_type}@anchor{9c}
 @deffn {C Function} gcc_jit_type *          gcc_jit_function_type_get_return_type (gcc_jit_function_type@w{ }*function_type)
 
 Given a function type, return its return type.
 @end deffn
 
 @geindex gcc_jit_function_type_get_param_count (C function)
-@anchor{topics/types c gcc_jit_function_type_get_param_count}@anchor{9b}
+@anchor{topics/types c gcc_jit_function_type_get_param_count}@anchor{9d}
 @deffn {C Function} size_t          gcc_jit_function_type_get_param_count (gcc_jit_function_type@w{ }*function_type)
 
 Given a function type, return its number of parameters.
 @end deffn
 
 @geindex gcc_jit_function_type_get_param_type (C function)
-@anchor{topics/types c gcc_jit_function_type_get_param_type}@anchor{9c}
+@anchor{topics/types c gcc_jit_function_type_get_param_type}@anchor{9e}
 @deffn {C Function} gcc_jit_type *          gcc_jit_function_type_get_param_type (gcc_jit_function_type@w{ }*function_type, size_t@w{ }index)
 
 Given a function type, return the type of the specified parameter.
 @end deffn
 
 @geindex gcc_jit_type_is_integral (C function)
-@anchor{topics/types c gcc_jit_type_is_integral}@anchor{9d}
+@anchor{topics/types c gcc_jit_type_is_integral}@anchor{9f}
 @deffn {C Function} int          gcc_jit_type_is_integral (gcc_jit_type@w{ }*type)
 
 Return non-zero if the type is an integral.
 @end deffn
 
 @geindex gcc_jit_type_is_pointer (C function)
-@anchor{topics/types c gcc_jit_type_is_pointer}@anchor{9e}
+@anchor{topics/types c gcc_jit_type_is_pointer}@anchor{a0}
 @deffn {C Function} gcc_jit_type *          gcc_jit_type_is_pointer (gcc_jit_type@w{ }*type)
 
 Return the type pointed by the pointer type or NULL if it’s not a pointer.
 @end deffn
 
 @geindex gcc_jit_type_dyncast_vector (C function)
-@anchor{topics/types c gcc_jit_type_dyncast_vector}@anchor{9f}
+@anchor{topics/types c gcc_jit_type_dyncast_vector}@anchor{a1}
 @deffn {C Function} gcc_jit_vector_type *          gcc_jit_type_dyncast_vector (gcc_jit_type@w{ }*type)
 
 Given a type, return a dynamic cast to a vector type or NULL.
 @end deffn
 
 @geindex gcc_jit_type_is_struct (C function)
-@anchor{topics/types c gcc_jit_type_is_struct}@anchor{a0}
+@anchor{topics/types c gcc_jit_type_is_struct}@anchor{a2}
 @deffn {C Function} gcc_jit_struct *          gcc_jit_type_is_struct (gcc_jit_type@w{ }*type)
 
 Given a type, return a dynamic cast to a struct type or NULL.
 @end deffn
 
 @geindex gcc_jit_vector_type_get_num_units (C function)
-@anchor{topics/types c gcc_jit_vector_type_get_num_units}@anchor{a1}
+@anchor{topics/types c gcc_jit_vector_type_get_num_units}@anchor{a3}
 @deffn {C Function} size_t          gcc_jit_vector_type_get_num_units (gcc_jit_vector_type@w{ }*vector_type)
 
 Given a vector type, return the number of units it contains.
 @end deffn
 
 @geindex gcc_jit_vector_type_get_element_type (C function)
-@anchor{topics/types c gcc_jit_vector_type_get_element_type}@anchor{a2}
+@anchor{topics/types c gcc_jit_vector_type_get_element_type}@anchor{a4}
 @deffn {C Function} gcc_jit_type *          gcc_jit_vector_type_get_element_type (gcc_jit_vector_type *@w{ }vector_type)
 
 Given a vector type, return the type of its elements.
 @end deffn
 
 @geindex gcc_jit_type_unqualified (C function)
-@anchor{topics/types c gcc_jit_type_unqualified}@anchor{a3}
+@anchor{topics/types c gcc_jit_type_unqualified}@anchor{a5}
 @deffn {C Function} gcc_jit_type *          gcc_jit_type_unqualified (gcc_jit_type@w{ }*type)
 
 Given a type, return the unqualified type, removing “const”, “volatile” and
@@ -5978,14 +6079,14 @@
 @end deffn
 
 @geindex gcc_jit_struct_get_field (C function)
-@anchor{topics/types c gcc_jit_struct_get_field}@anchor{a4}
+@anchor{topics/types c gcc_jit_struct_get_field}@anchor{a6}
 @deffn {C Function} gcc_jit_field *          gcc_jit_struct_get_field (gcc_jit_struct@w{ }*struct_type, size_t@w{ }index)
 
 Get a struct field by index.
 @end deffn
 
 @geindex gcc_jit_struct_get_field_count (C function)
-@anchor{topics/types c gcc_jit_struct_get_field_count}@anchor{a5}
+@anchor{topics/types c gcc_jit_struct_get_field_count}@anchor{a7}
 @deffn {C Function} size_t            gcc_jit_struct_get_field_count (gcc_jit_struct@w{ }*struct_type)
 
 @quotation
@@ -6001,53 +6102,53 @@
 @itemize *
 
 @item 
-@ref{9a,,gcc_jit_function_type_get_return_type()}
+@ref{9c,,gcc_jit_function_type_get_return_type()}
 
 @item 
-@ref{9b,,gcc_jit_function_type_get_param_count()}
+@ref{9d,,gcc_jit_function_type_get_param_count()}
 
 @item 
-@ref{9c,,gcc_jit_function_type_get_param_type()}
+@ref{9e,,gcc_jit_function_type_get_param_type()}
 
 @item 
-@ref{a3,,gcc_jit_type_unqualified()}
+@ref{a5,,gcc_jit_type_unqualified()}
 
 @item 
-@ref{97,,gcc_jit_type_dyncast_array()}
+@ref{99,,gcc_jit_type_dyncast_array()}
 
 @item 
-@ref{98,,gcc_jit_type_is_bool()}
+@ref{9a,,gcc_jit_type_is_bool()}
 
 @item 
-@ref{99,,gcc_jit_type_dyncast_function_ptr_type()}
+@ref{9b,,gcc_jit_type_dyncast_function_ptr_type()}
 
 @item 
-@ref{9d,,gcc_jit_type_is_integral()}
+@ref{9f,,gcc_jit_type_is_integral()}
 
 @item 
-@ref{9e,,gcc_jit_type_is_pointer()}
+@ref{a0,,gcc_jit_type_is_pointer()}
 
 @item 
-@ref{9f,,gcc_jit_type_dyncast_vector()}
+@ref{a1,,gcc_jit_type_dyncast_vector()}
 
 @item 
-@ref{a2,,gcc_jit_vector_type_get_element_type()}
+@ref{a4,,gcc_jit_vector_type_get_element_type()}
 
 @item 
-@ref{a1,,gcc_jit_vector_type_get_num_units()}
+@ref{a3,,gcc_jit_vector_type_get_num_units()}
 
 @item 
-@ref{a4,,gcc_jit_struct_get_field()}
+@ref{a6,,gcc_jit_struct_get_field()}
 
 @item 
-@ref{a0,,gcc_jit_type_is_struct()}
+@ref{a2,,gcc_jit_type_is_struct()}
 
 @item 
-@ref{a5,,gcc_jit_struct_get_field_count()}
+@ref{a7,,gcc_jit_struct_get_field_count()}
 @end itemize
 @end quotation
 
-were added in @ref{a6,,LIBGCCJIT_ABI_16}; you can test for their presence
+were added in @ref{a8,,LIBGCCJIT_ABI_16}; you can test for their presence
 using
 
 @example
@@ -6055,11 +6156,51 @@
 @end example
 
 @geindex gcc_jit_case (C type)
-@anchor{topics/types c gcc_jit_case}@anchor{a7}
+@anchor{topics/types c gcc_jit_case}@anchor{a9}
 @deffn {C Type} gcc_jit_case
 @end deffn
 @end deffn
 
+@geindex gcc_jit_compatible_types (C function)
+@anchor{topics/types c gcc_jit_compatible_types}@anchor{aa}
+@deffn {C Function} int            gcc_jit_compatible_types (gcc_jit_type@w{ }*ltype, gcc_jit_type@w{ }*rtype)
+
+@quotation
+
+Return non-zero if the two types are compatible. For instance,
+if @code{GCC_JIT_TYPE_UINT64_T} and @code{GCC_JIT_TYPE_UNSIGNED_LONG}
+are the same size on the target, this will return non-zero.
+The parameters @code{ltype} and @code{rtype} must be non-NULL.
+Return 0 on errors.
+@end quotation
+
+This entrypoint was added in @ref{ab,,LIBGCCJIT_ABI_20}; you can test for
+its presence using
+
+@example
+#ifdef LIBGCCJIT_HAVE_SIZED_INTEGERS
+@end example
+@end deffn
+
+@geindex gcc_jit_type_get_size (C function)
+@anchor{topics/types c gcc_jit_type_get_size}@anchor{ac}
+@deffn {C Function} ssize_t            gcc_jit_type_get_size (gcc_jit_type@w{ }*type)
+
+@quotation
+
+Return the size of a type, in bytes. It only works on integer types for now.
+The parameter @code{type} must be non-NULL.
+Return -1 on errors.
+@end quotation
+
+This entrypoint was added in @ref{ab,,LIBGCCJIT_ABI_20}; you can test for
+its presence using
+
+@example
+#ifdef LIBGCCJIT_HAVE_SIZED_INTEGERS
+@end example
+@end deffn
+
 @c Copyright (C) 2014-2022 Free Software Foundation, Inc.
 @c Originally contributed by David Malcolm <dmalcolm@redhat.com>
 @c 
@@ -6078,7 +6219,7 @@
 @c <https://www.gnu.org/licenses/>.
 
 @node Expressions,Creating and using functions,Types,Topic Reference
-@anchor{topics/expressions doc}@anchor{a8}@anchor{topics/expressions expressions}@anchor{a9}
+@anchor{topics/expressions doc}@anchor{ad}@anchor{topics/expressions expressions}@anchor{ae}
 @section Expressions
 
 
@@ -6090,7 +6231,7 @@
 @end menu
 
 @node Rvalues,Lvalues,,Expressions
-@anchor{topics/expressions rvalues}@anchor{aa}
+@anchor{topics/expressions rvalues}@anchor{af}
 @subsection Rvalues
 
 
@@ -6144,7 +6285,7 @@
 that types match up correctly (otherwise the context will emit an error).
 
 @geindex gcc_jit_rvalue_get_type (C function)
-@anchor{topics/expressions c gcc_jit_rvalue_get_type}@anchor{ab}
+@anchor{topics/expressions c gcc_jit_rvalue_get_type}@anchor{b0}
 @deffn {C Function} gcc_jit_type *gcc_jit_rvalue_get_type (gcc_jit_rvalue@w{ }*rvalue)
 
 Get the type of this rvalue.
@@ -6171,7 +6312,7 @@
 @end menu
 
 @node Simple expressions,Constructor expressions,,Rvalues
-@anchor{topics/expressions simple-expressions}@anchor{ac}
+@anchor{topics/expressions simple-expressions}@anchor{b1}
 @subsubsection Simple expressions
 
 
@@ -6184,7 +6325,7 @@
 @end deffn
 
 @geindex gcc_jit_context_new_rvalue_from_long (C function)
-@anchor{topics/expressions c gcc_jit_context_new_rvalue_from_long}@anchor{ad}
+@anchor{topics/expressions c gcc_jit_context_new_rvalue_from_long}@anchor{b2}
 @deffn {C Function} gcc_jit_rvalue *           gcc_jit_context_new_rvalue_from_long (gcc_jit_context@w{ }*ctxt, gcc_jit_type@w{ }*numeric_type, long@w{ }value)
 
 Given a numeric type (integer or floating point), build an rvalue for
@@ -6224,14 +6365,14 @@
 @end deffn
 
 @geindex gcc_jit_context_new_rvalue_from_ptr (C function)
-@anchor{topics/expressions c gcc_jit_context_new_rvalue_from_ptr}@anchor{ae}
+@anchor{topics/expressions c gcc_jit_context_new_rvalue_from_ptr}@anchor{b3}
 @deffn {C Function} gcc_jit_rvalue *           gcc_jit_context_new_rvalue_from_ptr (gcc_jit_context@w{ }*ctxt, gcc_jit_type@w{ }*pointer_type, void@w{ }*value)
 
 Given a pointer type, build an rvalue for the given address.
 @end deffn
 
 @geindex gcc_jit_context_null (C function)
-@anchor{topics/expressions c gcc_jit_context_null}@anchor{af}
+@anchor{topics/expressions c gcc_jit_context_null}@anchor{b4}
 @deffn {C Function} gcc_jit_rvalue *gcc_jit_context_null (gcc_jit_context@w{ }*ctxt, gcc_jit_type@w{ }*pointer_type)
 
 Given a pointer type, build an rvalue for @code{NULL}.  Essentially this
@@ -6243,7 +6384,7 @@
 @end deffn
 
 @geindex gcc_jit_context_new_string_literal (C function)
-@anchor{topics/expressions c gcc_jit_context_new_string_literal}@anchor{b0}
+@anchor{topics/expressions c gcc_jit_context_new_string_literal}@anchor{b5}
 @deffn {C Function} gcc_jit_rvalue *           gcc_jit_context_new_string_literal (gcc_jit_context@w{ }*ctxt, const char@w{ }*value)
 
 Generate an rvalue for the given NIL-terminated string, of type
@@ -6255,7 +6396,7 @@
 @end deffn
 
 @node Constructor expressions,Vector expressions,Simple expressions,Rvalues
-@anchor{topics/expressions constructor-expressions}@anchor{b1}
+@anchor{topics/expressions constructor-expressions}@anchor{b6}
 @subsubsection Constructor expressions
 
 
@@ -6266,7 +6407,7 @@
 
 The constructor rvalue can be used for assignment to locals.
 It can be used to initialize global variables with
-@ref{b2,,gcc_jit_global_set_initializer_rvalue()}. It can also be used as a
+@ref{b7,,gcc_jit_global_set_initializer_rvalue()}. It can also be used as a
 temporary value for function calls and return values, but its address
 can’t be taken.
 
@@ -6280,7 +6421,7 @@
 Note that a string literal rvalue can’t be used to construct a char array;
 the latter needs one rvalue for each char.
 
-These entrypoints were added in @ref{b3,,LIBGCCJIT_ABI_19}; you can test for
+These entrypoints were added in @ref{b8,,LIBGCCJIT_ABI_19}; you can test for
 their presence using:
 
 @example
@@ -6289,7 +6430,7 @@
 @end quotation
 
 @geindex gcc_jit_context_new_array_constructor (C function)
-@anchor{topics/expressions c gcc_jit_context_new_array_constructor}@anchor{b4}
+@anchor{topics/expressions c gcc_jit_context_new_array_constructor}@anchor{b9}
 @deffn {C Function} gcc_jit_rvalue *           gcc_jit_context_new_array_constructor (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, gcc_jit_type@w{ }*type, size_t@w{ }num_values, gcc_jit_rvalue@w{ }**values)
 
 Create a constructor for an array as an rvalue.
@@ -6313,7 +6454,7 @@
 If @code{num_values} is 0, the @code{values} parameter will be
 ignored and zero initialization will be used.
 
-This entrypoint was added in @ref{b3,,LIBGCCJIT_ABI_19}; you can test for its
+This entrypoint was added in @ref{b8,,LIBGCCJIT_ABI_19}; you can test for its
 presence using:
 
 @example
@@ -6322,7 +6463,7 @@
 @end deffn
 
 @geindex gcc_jit_context_new_struct_constructor (C function)
-@anchor{topics/expressions c gcc_jit_context_new_struct_constructor}@anchor{b5}
+@anchor{topics/expressions c gcc_jit_context_new_struct_constructor}@anchor{ba}
 @deffn {C Function} gcc_jit_rvalue *           gcc_jit_context_new_struct_constructor (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, gcc_jit_type@w{ }*type, size_t@w{ }num_values, gcc_jit_field@w{ }**fields, gcc_jit_rvalue@w{ }**values)
 
 Create a constructor for a struct as an rvalue.
@@ -6359,7 +6500,7 @@
 If @code{num_values} is 0, the array parameters will be
 ignored and zero initialization will be used.
 
-This entrypoint was added in @ref{b3,,LIBGCCJIT_ABI_19}; you can test for its
+This entrypoint was added in @ref{b8,,LIBGCCJIT_ABI_19}; you can test for its
 presence using:
 
 @example
@@ -6368,7 +6509,7 @@
 @end deffn
 
 @geindex gcc_jit_context_new_union_constructor (C function)
-@anchor{topics/expressions c gcc_jit_context_new_union_constructor}@anchor{b6}
+@anchor{topics/expressions c gcc_jit_context_new_union_constructor}@anchor{bb}
 @deffn {C Function} gcc_jit_rvalue *           gcc_jit_context_new_union_constructor (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, gcc_jit_type@w{ }*type, gcc_jit_field@w{ }*field, gcc_jit_rvalue@w{ }*value)
 
 Create a constructor for a union as an rvalue.
@@ -6388,7 +6529,7 @@
 Each value has to have have the same unqualified type as the field
 it is applied to.
 
-This entrypoint was added in @ref{b3,,LIBGCCJIT_ABI_19}; you can test for its
+This entrypoint was added in @ref{b8,,LIBGCCJIT_ABI_19}; you can test for its
 presence using:
 
 @example
@@ -6397,22 +6538,22 @@
 @end deffn
 
 @node Vector expressions,Unary Operations,Constructor expressions,Rvalues
-@anchor{topics/expressions vector-expressions}@anchor{b7}
+@anchor{topics/expressions vector-expressions}@anchor{bc}
 @subsubsection Vector expressions
 
 
 @geindex gcc_jit_context_new_rvalue_from_vector (C function)
-@anchor{topics/expressions c gcc_jit_context_new_rvalue_from_vector}@anchor{87}
+@anchor{topics/expressions c gcc_jit_context_new_rvalue_from_vector}@anchor{89}
 @deffn {C Function} gcc_jit_rvalue *            gcc_jit_context_new_rvalue_from_vector (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, gcc_jit_type@w{ }*vec_type, size_t@w{ }num_elements, gcc_jit_rvalue@w{ }**elements)
 
 Build a vector rvalue from an array of elements.
 
 “vec_type” should be a vector type, created using
-@ref{85,,gcc_jit_type_get_vector()}.
+@ref{87,,gcc_jit_type_get_vector()}.
 
 “num_elements” should match that of the vector type.
 
-This entrypoint was added in @ref{b8,,LIBGCCJIT_ABI_10}; you can test for
+This entrypoint was added in @ref{bd,,LIBGCCJIT_ABI_10}; you can test for
 its presence using
 
 @example
@@ -6421,12 +6562,12 @@
 @end deffn
 
 @node Unary Operations,Binary Operations,Vector expressions,Rvalues
-@anchor{topics/expressions unary-operations}@anchor{b9}
+@anchor{topics/expressions unary-operations}@anchor{be}
 @subsubsection Unary Operations
 
 
 @geindex gcc_jit_context_new_unary_op (C function)
-@anchor{topics/expressions c gcc_jit_context_new_unary_op}@anchor{ba}
+@anchor{topics/expressions c gcc_jit_context_new_unary_op}@anchor{bf}
 @deffn {C Function} gcc_jit_rvalue *            gcc_jit_context_new_unary_op (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, enum gcc_jit_unary_o