# DP: updates from the 13 branch upto 20240904 (cc2c50b1949).

LANG=C git diff --no-renames --src-prefix=a/src/ --dst-prefix=b/src/ \
	b71f1de6e9cf7181a288c0f39f9b1ef6580cf5c8 cc2c50b19491b6adbbe7927d9aa35f9b5683c233 \
	| awk '/^diff .*\.texi/ {skip=1; next} /^diff / { skip=0 } skip==0' \
	| grep -v -E '^(diff|index)'

--- a/src/gcc/ChangeLog
+++ b/src/gcc/ChangeLog
@@ -1,3 +1,720 @@
+2024-09-03  Haochen Jiang  <haochen.jiang@intel.com>
+
+	* config/i386/avx512fp16intrin.h
+	(_mm512_mask_fpclass_ph_mask): Correct mask type to __mmask32.
+	(_mm512_fpclass_ph_mask): Ditto.
+
+2024-09-03  Vineet Gupta  <vineetg@rivosinc.com>
+
+	* config/riscv/riscv.cc (riscv_promote_function_mode): Fix mode
+	returned for libcall case.
+
+2024-09-02  liuhongt  <hongtao.liu@intel.com>
+
+	Backported from master:
+	2024-08-30  liuhongt  <hongtao.liu@intel.com>
+
+	PR target/116512
+	* config/i386/i386.cc (ix86_check_avx_upper_register): Iterate
+	subrtx to scan for avx upper register.
+	(ix86_check_avx_upper_stores): Inline old
+	ix86_check_avx_upper_register.
+	(ix86_avx_u128_mode_needed): Ditto, and replace
+	FOR_EACH_SUBRTX with call to new
+	ix86_check_avx_upper_register.
+
+2024-08-22  liuhongt  <hongtao.liu@intel.com>
+
+	Backported from master:
+	2024-08-22  liuhongt  <hongtao.liu@intel.com>
+
+	* config/i386/i386-options.cc (ix86_option_override_internal):
+	set ix86_{move_max,store_max} to PVW_AVX256 when TARGET_AVX
+	instead of PVW_AVX128.
+
+2024-08-19  Jan Hubicka  <hubicka@ucw.cz>
+
+	Backported from master:
+	2024-07-22  Jan Hubicka  <hubicka@ucw.cz>
+
+	PR ipa/115277
+	* ipa-icf-gimple.cc (func_checker::compare_loops): compare loop
+	bounds.
+
+2024-08-18  Georg-Johann Lay  <avr@gjlay.de>
+
+	Backported from master:
+	2024-08-18  Georg-Johann Lay  <avr@gjlay.de>
+
+	PR target/116407
+	* config/avr/avr-protos.h (avr_jump_mode): Add an int argument.
+	* config/avr/avr.cc (avr_jump_mode): Add an int argument to increase
+	the computed jump offset of backwards branches.
+	* config/avr/avr.md (*dec-and-branchhi!=-1, *dec-and-branchsi!=-1):
+	Increase the jump offset used by avr_jump_mode() as needed.
+
+2024-08-16  Richard Sandiford  <richard.sandiford@arm.com>
+
+	Backported from master:
+	2024-04-05  Richard Sandiford  <richard.sandiford@arm.com>
+
+	PR target/114603
+	* config/aarch64/aarch64-sve.md (@aarch64_pred_cnot<mode>): Replace
+	with...
+	(@aarch64_ptrue_cnot<mode>): ...this, requiring operand 1 to be
+	a ptrue.
+	(*cnot<mode>): Require operand 1 to be a ptrue.
+	* config/aarch64/aarch64-sve-builtins-base.cc (svcnot_impl::expand):
+	Use aarch64_ptrue_cnot<mode> for _x operations that are predicated
+	with a ptrue.  Represent other _x operations as fully-defined _m
+	operations.
+
+2024-08-16  Richard Sandiford  <richard.sandiford@arm.com>
+
+	Backported from master:
+	2024-04-08  Richard Sandiford  <richard.sandiford@arm.com>
+
+	PR target/114607
+	* config/aarch64/aarch64-sve-builtins-base.cc
+	(svusdot_impl::expand): Fix botched attempt to swap the operands
+	for svsudot.
+
+2024-08-12  liuhongt  <hongtao.liu@intel.com>
+
+	Backported from master:
+	2024-07-30  liuhongt  <hongtao.liu@intel.com>
+
+	PR target/116043
+	* config/i386/constraints.md (Bk): Refine to
+	define_special_memory_constraint.
+
+2024-08-06  John David Anglin  <danglin@gcc.gnu.org>
+
+	PR target/113384
+	* config/pa/pa.cc (hppa_legitimize_address): Add check to
+	ensure constant is an integral multiple of shift the value.
+
+2024-08-06  Andrew Pinski  <quic_apinski@quicinc.com>
+
+	Backported from master:
+	2024-08-06  Andrew Pinski  <quic_apinski@quicinc.com>
+
+	PR target/116189
+	* config/sh/sh.cc (sh_recog_treg_set_expr): Don't call make_insn_raw,
+	make the insn with a fake uid.
+
+2024-07-30  Haochen Jiang  <haochen.jiang@intel.com>
+
+	* config/i386/prfchiintrin.h
+	(_m_prefetchit0): Add macro for non-optimized option.
+	(_m_prefetchit1): Ditto.
+
+2024-07-29  Haochen Jiang  <haochen.jiang@intel.com>
+
+	* config/i386/avx512dqintrin.h (_mm_reduce_round_sd): Use
+	_mm_setzero_pd instead of _mm_avx512_setzero_pd.
+	(_mm_reduce_round_ss): Use _mm_setzero_ps instead of
+	_mm_avx512_setzero_ps.
+
+2024-07-29  Haochen Jiang  <haochen.jiang@intel.com>
+
+	* config/i386/avx512dqintrin.h
+	(_mm_mask_fpclass_ss_mask): Correct operand order.
+	(_mm_mask_fpclass_sd_mask): Ditto.
+	(_mm256_maskz_reduce_round_ss): Use __builtin_ia32_reducess_mask_round
+	instead of __builtin_ia32_reducesd_mask_round.
+	(_mm_reduce_round_sd): Use -1 as mask since it is non-mask.
+	(_mm_reduce_round_ss): Ditto.
+	* config/i386/avx512vlbwintrin.h
+	(_mm256_mask_alignr_epi8): Correct operand usage.
+	(_mm_mask_alignr_epi8): Ditto.
+	* config/i386/avx512vlintrin.h (_mm_mask_alignr_epi64): Ditto.
+
+2024-07-24  Peter Bergner  <bergner@linux.ibm.com>
+
+	Backported from master:
+	2024-07-17  Peter Bergner  <bergner@linux.ibm.com>
+
+	PR target/114759
+	* config/rs6000/rs6000.cc (rs6000_option_override_internal): Disallow
+	CPUs and ABIs that do no support the ROP protection insns.
+	* config/rs6000/rs6000-logue.cc (rs6000_stack_info): Remove now
+	unneeded tests.
+	(rs6000_emit_prologue): Likewise.
+	Remove unneeded gcc_assert.
+	(rs6000_emit_epilogue): Likewise.
+	* config/rs6000/rs6000.md: Likewise.
+
+2024-07-24  Peter Bergner  <bergner@linux.ibm.com>
+
+	Backported from master:
+	2024-07-17  Peter Bergner  <bergner@linux.ibm.com>
+
+	PR target/114759
+	* config/rs6000/rs6000-logue.cc (rs6000_stack_info): Use TARGET_POWER8.
+	(rs6000_emit_prologue): Likewise.
+	* config/rs6000/rs6000.md (hashchk): Likewise.
+	(hashst): Likewise.
+	Fix whitespace.
+
+2024-07-24  Peter Bergner  <bergner@linux.ibm.com>
+
+	Backported from master:
+	2024-06-17  Peter Bergner  <bergner@linux.ibm.com>
+
+	PR target/115389
+	* config/rs6000/rs6000-logue.cc (rs6000_stack_info): Compute
+	rop_hash_save_offset for non-Altivec compiles.
+
+2024-07-24  Peter Bergner  <bergner@linux.ibm.com>
+
+	Backported from master:
+	2024-06-08  Peter Bergner  <bergner@linux.ibm.com>
+
+	* config/rs6000/rs6000-logue.cc (rs6000_stack_info): Update comment.
+
+2024-07-23  Richard Biener  <rguenther@suse.de>
+
+	Backported from master:
+	2024-07-16  Richard Biener  <rguenther@suse.de>
+
+	PR tree-optimization/115843
+	* config/i386/x86-tune-costs.h (znver4_cost): Update unaligned
+	load and store cost from the aligned costs.
+
+2024-07-23  Haochen Jiang  <haochen.jiang@intel.com>
+
+	* config/i386/i386.md (prefetchi): Change to %a.
+
+2024-07-22  Maciej W. Rozycki  <macro@orcam.me.uk>
+
+	Backported from master:
+	2024-06-29  Maciej W. Rozycki  <macro@orcam.me.uk>
+
+	PR rtl-optimization/115565
+	* cse.cc (record_jump_cond): Use INT_MIN rather than -1 for
+	`comparison_qty' if !REG_P.
+
+2024-07-20  Siddhesh Poyarekar  <siddhesh@gotplt.org>
+
+	Backported from master:
+	2024-07-20  Siddhesh Poyarekar  <siddhesh@gotplt.org>
+
+	* opt-suggestions.cc
+	(option_proposer::build_option_suggestions): Pull OPTB
+	definition out of the innermost loop.
+
+2024-07-20  Stefan Schulze Frielinghaus  <stefansf@gcc.gnu.org>
+
+	* config/s390/3931.md (vlbr, vstbr, vrepi): Remove.
+	* config/s390/s390.md (xdee): Add FPRX2 mapping.
+	* config/s390/vector.md (bhfgq): Add TF mapping.
+
+2024-07-20  René Rebe  <rene@exactcode.de>
+
+	Backported from master:
+	2024-07-18  René Rebe  <rene@exactcode.de>
+		    Peter Bergner  <bergner@linux.ibm.com>
+
+	PR target/97367
+	* config/rs6000/rs6000.cc (rs6000_machine_from_flags): Do not consider
+	OPTION_MASK_ALTIVEC.
+	(emit_asm_machine): For Altivec compiles, emit a ".machine altivec".
+
+2024-07-19  LIU Hao  <lh_mouse@126.com>
+
+	Backported from master:
+	2024-07-18  LIU Hao  <lh_mouse@126.com>
+
+	PR rtl-optimization/115049
+	* varasm.cc (decl_binds_to_current_def_p): Add a check for COMDAT
+	declarations too, like weak ones.
+
+2024-07-17  Uros Bizjak  <ubizjak@gmail.com>
+
+	Backported from master:
+	2024-07-17  Uros Bizjak  <ubizjak@gmail.com>
+
+	PR target/115526
+	* config/alpha/alpha.md (movdi_er_high_g): Add cannot_copy attribute.
+	(movdi_er_tlsgd): Ditto.
+	(movdi_er_tlsldm): Ditto.
+	(call_value_osf_<tls>): Ditto.
+
+2024-07-16  Stefan Schulze Frielinghaus  <stefansf@gcc.gnu.org>
+
+	Backported from master:
+	2024-07-12  Stefan Schulze Frielinghaus  <stefansf@gcc.gnu.org>
+
+	* config/s390/vector.md (mov<mode>): Fix output template for
+	movv1qi.
+
+2024-07-16  Stefan Schulze Frielinghaus  <stefansf@gcc.gnu.org>
+
+	Backported from master:
+	2024-07-12  Stefan Schulze Frielinghaus  <stefansf@gcc.gnu.org>
+
+	* config/s390/s390.md (*icjump_64): Allow raw CC comparisons,
+	i.e., any constant integer between 0 and 15 for CC comparisons.
+
+2024-07-16  Alexandre Oliva  <oliva@adacore.com>
+
+	Backported from master:
+	2024-07-15  Alexandre Oliva  <oliva@adacore.com>
+
+	PR target/113719
+	* config/i386/i386-options.cc (ix86_option_override_internal):
+	Move flag_omit_frame_pointer final overrider...
+	(ix86_recompute_optlev_based_flags): ... here.
+
+2024-07-16  Alexandre Oliva  <oliva@adacore.com>
+
+	Backported from master:
+	2024-07-03  Alexandre Oliva  <oliva@adacore.com>
+
+	PR target/113719
+	* config/i386/i386-options.cc
+	(ix86_override_options_after_change_1): Add opts and opts_set
+	parms, operate on them, after factoring out of...
+	(ix86_override_options_after_change): ... this.  Restore calls
+	of ix86_default_align and ix86_recompute_optlev_based_flags.
+	(ix86_option_override_internal): Call the factored-out bits.
+
+2024-07-15  liuhongt  <hongtao.liu@intel.com>
+
+	Backported from master:
+	2024-07-15  liuhongt  <hongtao.liu@intel.com>
+
+	PR target/115872
+	* tree-ssa-ccp.cc (convert_atomic_bit_not): Remove use_stmt after use_nop_stmt is removed.
+	(optimize_atomic_bit_test_and): Ditto.
+
+2024-07-13  Lulu Cheng  <chenglulu@loongson.cn>
+
+	Backported from master:
+	2024-07-12  Lulu Cheng  <chenglulu@loongson.cn>
+
+	PR target/115752
+	* config/loongarch/loongarch.cc
+	(loongarch_hard_regno_mode_ok_uncached): Replace
+	UNITS_PER_FPVALUE with UNITS_PER_HWFPVALUE.
+	* config/loongarch/loongarch.h (UNITS_PER_FPVALUE): Delete.
+
+2024-07-11  Andre Vieira  <andre.simoesdiasvieira@arm.com>
+
+	Backported from master:
+	2024-07-11  Andre Vieira  <andre.simoesdiasvieira@arm.com>
+
+	PR target/115611
+	* config/arm/mve.md (mve_vec_setv2di_internal): Fix printing of input
+	scalar register pair when lane = 1.
+
+2024-07-10  Uros Bizjak  <ubizjak@gmail.com>
+
+	Backported from master:
+	2024-07-10  Uros Bizjak  <ubizjak@gmail.com>
+
+	PR middle-end/115836
+	* expmed.cc (emit_store_flag_1): Move calculation of
+	scode just before its only usage site.
+
+2024-07-05  Georg-Johann Lay  <avr@gjlay.de>
+
+	Backported from master:
+	2024-07-05  Georg-Johann Lay  <avr@gjlay.de>
+
+	PR target/87376
+	* config/avr/avr-dimode.md: Use "nop_general_operand" instead
+	of "general_operand" as predicate for all input operands.
+
+2024-07-04  Kyrylo Tkachov  <ktkachov@nvidia.com>
+
+	Backported from master:
+	2024-07-03  Kyrylo Tkachov  <ktkachov@nvidia.com>
+
+	PR target/115475
+	* config/aarch64/aarch64-c.cc (aarch64_update_cpp_builtins):
+	Define __ARM_FEATURE_SVE_BF16 for TARGET_SVE_BF16.
+
+2024-07-04  Kyrylo Tkachov  <ktkachov@nvidia.com>
+
+	Backported from master:
+	2024-07-03  Kyrylo Tkachov  <ktkachov@nvidia.com>
+
+	PR target/115457
+	* config/aarch64/aarch64-c.cc (aarch64_update_cpp_builtins):
+	Define __ARM_FEATURE_BF16 for TARGET_BF16_FP.
+
+2024-07-03  John David Anglin  <danglin@gcc.gnu.org>
+
+	PR target/115691
+	* config/pa/pa.md: Remove incorrect xmpyu patterns.
+
+2024-07-03  Georg-Johann Lay  <avr@gjlay.de>
+
+	Backported from master:
+	2024-07-03  Georg-Johann Lay  <avr@gjlay.de>
+
+	PR target/98762
+	* config/avr/avr.cc (avr_out_movqi_r_mr_reg_disp_tiny): Properly
+	restore the base register when it is partially clobbered.
+
+2024-07-03  Kewen Lin  <linkw@linux.ibm.com>
+
+	Backported from master:
+	2024-06-26  Kewen Lin  <linkw@linux.ibm.com>
+		    Xionghu Luo  <xionghuluo@tencent.com>
+
+	PR target/106069
+	PR target/115355
+	* config/rs6000/altivec.md (altivec_vmrghh_direct): Rename to ...
+	(altivec_vmrghh_direct_be): ... this.  Add condition BYTES_BIG_ENDIAN.
+	(altivec_vmrghh_direct_le): New define_insn.
+	(altivec_vmrglh_direct): Rename to ...
+	(altivec_vmrglh_direct_be): ... this.  Add condition BYTES_BIG_ENDIAN.
+	(altivec_vmrglh_direct_le): New define_insn.
+	(altivec_vmrghh): Adjust by calling gen_altivec_vmrghh_direct_be
+	for BE and gen_altivec_vmrglh_direct_le for LE.
+	(altivec_vmrglh): Adjust by calling gen_altivec_vmrglh_direct_be
+	for BE and gen_altivec_vmrghh_direct_le for LE.
+	(vec_widen_umult_hi_v16qi): Adjust the call to
+	gen_altivec_vmrghh_direct by gen_altivec_vmrghh for BE
+	and by gen_altivec_vmrglh for LE.
+	(vec_widen_smult_hi_v16qi): Likewise.
+	(vec_widen_umult_lo_v16qi): Adjust the call to
+	gen_altivec_vmrglh_direct by gen_altivec_vmrglh for BE
+	and by gen_altivec_vmrghh for LE.
+	(vec_widen_smult_lo_v16qi): Likewise.
+	* config/rs6000/rs6000.cc (altivec_expand_vec_perm_const): Replace
+	CODE_FOR_altivec_vmrghh_direct by
+	CODE_FOR_altivec_vmrghh_direct_be for BE and
+	CODE_FOR_altivec_vmrghh_direct_le for LE.  And replace
+	CODE_FOR_altivec_vmrglh_direct by
+	CODE_FOR_altivec_vmrglh_direct_be for BE and
+	CODE_FOR_altivec_vmrglh_direct_le for LE.
+
+2024-07-03  Kewen Lin  <linkw@linux.ibm.com>
+
+	Backported from master:
+	2024-06-26  Kewen Lin  <linkw@linux.ibm.com>
+		    Xionghu Luo  <xionghuluo@tencent.com>
+
+	PR target/106069
+	PR target/115355
+	* config/rs6000/altivec.md (altivec_vmrghb_direct): Rename to ...
+	(altivec_vmrghb_direct_be): ... this.  Add condition BYTES_BIG_ENDIAN.
+	(altivec_vmrghb_direct_le): New define_insn.
+	(altivec_vmrglb_direct): Rename to ...
+	(altivec_vmrglb_direct_be): ... this.  Add condition BYTES_BIG_ENDIAN.
+	(altivec_vmrglb_direct_le): New define_insn.
+	(altivec_vmrghb): Adjust by calling gen_altivec_vmrghb_direct_be
+	for BE and gen_altivec_vmrglb_direct_le for LE.
+	(altivec_vmrglb): Adjust by calling gen_altivec_vmrglb_direct_be
+	for BE and gen_altivec_vmrghb_direct_le for LE.
+	* config/rs6000/rs6000.cc (altivec_expand_vec_perm_const): Replace
+	CODE_FOR_altivec_vmrghb_direct by
+	CODE_FOR_altivec_vmrghb_direct_be for BE and
+	CODE_FOR_altivec_vmrghb_direct_le for LE.  And replace
+	CODE_FOR_altivec_vmrglb_direct by
+	CODE_FOR_altivec_vmrglb_direct_be for BE and
+	CODE_FOR_altivec_vmrglb_direct_le for LE.
+
+2024-07-01  Georg-Johann Lay  <avr@gjlay.de>
+
+	Backported from master:
+	2024-07-01  Georg-Johann Lay  <avr@gjlay.de>
+
+	PR target/88236
+	PR target/115726
+	* config/avr/avr.md (mov<mode>) [avr_mem_memx_p]: Expand in such a
+	way that the destination does not overlap with any hard register
+	clobbered / used by xload8qi_A resp. xload<mode>_A.
+	* config/avr/avr.cc (avr_out_xload): Avoid early-clobber
+	situation for Z by executing just one load when the output register
+	overlaps with Z.
+
+2024-06-28  Kewen Lin  <linkw@linux.ibm.com>
+
+	Backported from master:
+	2024-06-21  Kewen Lin  <linkw@linux.ibm.com>
+		    Xionghu Luo  <xionghuluo@tencent.com>
+
+	PR target/106069
+	PR target/115355
+	* config/rs6000/altivec.md (altivec_vmrghw_direct_<VSX_W:mode>): Rename
+	to ...
+	(altivec_vmrghw_direct_<VSX_W:mode>_be): ... this.  Add the condition
+	BYTES_BIG_ENDIAN.
+	(altivec_vmrghw_direct_<VSX_W:mode>_le): New define_insn.
+	(altivec_vmrglw_direct_<VSX_W:mode>): Rename to ...
+	(altivec_vmrglw_direct_<VSX_W:mode>_be): ... this.  Add the condition
+	BYTES_BIG_ENDIAN.
+	(altivec_vmrglw_direct_<VSX_W:mode>_le): New define_insn.
+	(altivec_vmrghw): Adjust by calling gen_altivec_vmrghw_direct_v4si_be
+	for BE and gen_altivec_vmrglw_direct_v4si_le for LE.
+	(altivec_vmrglw): Adjust by calling gen_altivec_vmrglw_direct_v4si_be
+	for BE and gen_altivec_vmrghw_direct_v4si_le for LE.
+	(vec_widen_umult_hi_v8hi): Adjust the call to
+	gen_altivec_vmrghw_direct_v4si by gen_altivec_vmrghw for BE
+	and by gen_altivec_vmrglw for LE.
+	(vec_widen_smult_hi_v8hi): Likewise.
+	(vec_widen_umult_lo_v8hi): Adjust the call to
+	gen_altivec_vmrglw_direct_v4si by gen_altivec_vmrglw for BE
+	and by gen_altivec_vmrghw for LE
+	(vec_widen_smult_lo_v8hi): Likewise.
+	* config/rs6000/rs6000.cc (altivec_expand_vec_perm_const): Replace
+	CODE_FOR_altivec_vmrghw_direct_v4si by
+	CODE_FOR_altivec_vmrghw_direct_v4si_be for BE and
+	CODE_FOR_altivec_vmrghw_direct_v4si_le for LE.  And replace
+	CODE_FOR_altivec_vmrglw_direct_v4si by
+	CODE_FOR_altivec_vmrglw_direct_v4si_be for BE and
+	CODE_FOR_altivec_vmrglw_direct_v4si_le for LE.
+	* config/rs6000/vsx.md (vsx_xxmrghw_<VSX_W:mode>): Adjust by calling
+	gen_altivec_vmrghw_direct_v4si_be for BE and
+	gen_altivec_vmrglw_direct_v4si_le for LE.
+	(vsx_xxmrglw_<VSX_W:mode>): Adjust by calling
+	gen_altivec_vmrglw_direct_v4si_be for BE and
+	gen_altivec_vmrghw_direct_v4si_le for LE.
+
+2024-06-27  Wilco Dijkstra  <wilco.dijkstra@arm.com>
+
+	Backported from master:
+	2023-11-30  Wilco Dijkstra  <wilco.dijkstra@arm.com>
+
+	PR target/103100
+	* config/aarch64/aarch64.md (cpymemdi): Remove pattern condition.
+	(setmemdi): Likewise.
+	* config/aarch64/aarch64.cc (aarch64_expand_cpymem): Support
+	strict-align.  Cleanup condition for using MOPS.
+	(aarch64_expand_setmem): Likewise.
+
+2024-06-27  Andrew Carlotti  <andrew.carlotti@arm.com>
+
+	Backported from master:
+	2023-12-16  Andrew Carlotti  <andrew.carlotti@arm.com>
+
+	PR target/115618
+	* common/config/aarch64/aarch64-common.cc
+	(aarch64_get_extension_string_for_isa_flags): Fix generation of
+	the "+nocrypto" extension.
+	* config/aarch64/aarch64.h (AARCH64_ISA_CRYPTO): Remove.
+	(TARGET_CRYPTO): Remove.
+	* config/aarch64/aarch64-c.cc (aarch64_update_cpp_builtins):
+	Don't use TARGET_CRYPTO.
+
+2024-06-27  Kyrylo Tkachov  <ktkachov@nvidia.com>
+
+	* config/aarch64/aarch64-cores.def (grace): New entry.
+	* config/aarch64/aarch64-tune.md: Regenerate.
+	* doc/invoke.texi (AArch64 Options): Document the above.
+
+2024-06-24  Kewen Lin  <linkw@linux.ibm.com>
+
+	Backported from master:
+	2024-05-29  Kewen Lin  <linkw@linux.ibm.com>
+
+	PR target/114846
+	* config/rs6000/rs6000-logue.cc (rs6000_emit_epilogue): As
+	EPILOGUE_TYPE_EH_RETURN would be passed as epilogue_type directly
+	now, adjust the relevant handlings on it.
+	* config/rs6000/rs6000.md (eh_return expander): Append by calling
+	gen_eh_return_internal and emit_barrier.
+	(eh_return_internal): New define_insn_and_split, call function
+	rs6000_emit_epilogue with epilogue type EPILOGUE_TYPE_EH_RETURN.
+
+2024-06-20  Jakub Jelinek  <jakub@redhat.com>
+
+	Backported from master:
+	2024-06-17  Jakub Jelinek  <jakub@redhat.com>
+
+	PR driver/115440
+	* opts-common.cc (add_misspelling_candidates): If opt1 is non-NULL,
+	add a space and opt1 to the alternative suggestion text.
+
+2024-06-12  Torbjörn SVENSSON  <torbjorn.svensson@foss.st.com>
+
+	Backported from master:
+	2024-06-12  Torbjörn SVENSSON  <torbjorn.svensson@foss.st.com>
+		    Yvan ROUX  <yvan.roux@foss.st.com>
+
+	PR target/115253
+	* config/arm/arm.cc (cmse_nonsecure_call_inline_register_clear):
+	Sign extend for Thumb1.
+	(thumb1_expand_prologue): Add zero/sign extend.
+
+2024-06-11  Jakub Jelinek  <jakub@redhat.com>
+
+	Backported from master:
+	2024-06-04  Jakub Jelinek  <jakub@redhat.com>
+
+	PR tree-optimization/115337
+	* fold-const.cc (tree_call_nonnegative_warnv_p) <CASE_CFN_CLZ>:
+	If fn is CFN_CLZ, use CLZ_DEFINED_VALUE_AT.
+
+2024-06-11  Jakub Jelinek  <jakub@redhat.com>
+
+	Backported from master:
+	2024-06-04  Jakub Jelinek  <jakub@redhat.com>
+
+	PR middle-end/108789
+	* builtins.cc (fold_builtin_arith_overflow): For ovf_only,
+	don't call save_expr and don't build REALPART_EXPR, otherwise
+	set TREE_SIDE_EFFECTS on call before calling save_expr.
+
+2024-06-11  Jakub Jelinek  <jakub@redhat.com>
+
+	Backported from master:
+	2024-06-04  Jakub Jelinek  <jakub@redhat.com>
+
+	* doc/invoke.texi (lujiazui): Clarify that while the CPUs do support
+	AVX and F16C, -march=lujiazui actually doesn't enable those.
+
+2024-06-11  Jakub Jelinek  <jakub@redhat.com>
+
+	Backported from master:
+	2024-06-03  Jakub Jelinek  <jakub@redhat.com>
+
+	PR target/115324
+	* config/rs6000/rs6000-gen-builtins.cc (write_decls): Remove
+	GTY markup from struct bifdata and struct ovlddata and remove their
+	fntype members.  Change next member in struct ovlddata and
+	first_instance member of struct ovldrecord to have int type rather
+	than struct ovlddata *.  Remove GTY markup from rs6000_builtin_info
+	and rs6000_instance_info arrays, declare new
+	rs6000_builtin_info_fntype and rs6000_instance_info_fntype arrays,
+	which have GTY markup.
+	(write_bif_static_init): Adjust for the above changes.
+	(write_ovld_static_init): Likewise.
+	(write_init_bif_table): Likewise.
+	(write_init_ovld_table): Likewise.
+	* config/rs6000/rs6000-builtin.cc (rs6000_init_builtins): Likewise.
+	* config/rs6000/rs6000-c.cc (find_instance): Likewise.  Make static.
+	(altivec_resolve_overloaded_builtin): Adjust for the above changes.
+
+2024-06-11  Jakub Jelinek  <jakub@redhat.com>
+
+	Backported from master:
+	2024-05-15  Jakub Jelinek  <jakub@redhat.com>
+
+	PR rtl-optimization/114902
+	PR rtl-optimization/115092
+	* combine.cc (simplify_compare_const): Don't optimize
+	GE op0 SIGNED_MIN or LT op0 SIGNED_MIN into NE op0 const0_rtx or
+	EQ op0 const0_rtx.
+
+2024-06-07  Jan Hubicka  <jh@suse.cz>
+
+	Backported from master:
+	2023-12-29  Jan Hubicka  <jh@suse.cz>
+
+	* config/i386/x86-tune.def (X86_TUNE_AVOID_128FMA_CHAINS,
+	X86_TUNE_AVOID_256FMA_CHAINS): Enable for znver4 and Core.
+
+2024-06-03  Uros Bizjak  <ubizjak@gmail.com>
+
+	Backported from master:
+	2024-05-31  Uros Bizjak  <ubizjak@gmail.com>
+
+	PR target/115297
+	* config/alpha/alpha.md (<any_divmod:code>si3): Wrap DImode
+	operands 3 and 4 with truncate:SI RTX.
+	(*divmodsi_internal_er): Ditto for operands 1 and 2.
+	(*divmodsi_internal_er_1): Ditto.
+	(*divmodsi_internal): Ditto.
+	* config/alpha/constraints.md ("b"): Correct register
+	number in the description.
+
+2024-06-01  Georg-Johann Lay  <avr@gjlay.de>
+
+	Backported from master:
+	2024-06-01  Georg-Johann Lay  <avr@gjlay.de>
+
+	PR tree-optimization/115307
+	* config/avr/avr.md (SFDF): New mode iterator.
+	(isinf<mode>2) [sf, df]: New expanders.
+
+2024-05-31  Richard Sandiford  <richard.sandiford@arm.com>
+
+	Backported from master:
+	2024-01-29  Richard Sandiford  <richard.sandiford@arm.com>
+
+	PR target/113281
+	* tree-vect-patterns.cc (vect_recog_over_widening_pattern): Remove
+	workaround for right shifts.
+	(vect_truncatable_operation_p): Handle NEGATE_EXPR and BIT_NOT_EXPR.
+	(vect_determine_precisions_from_range): Be more selective about
+	which codes can be narrowed based on their input and output ranges.
+	For shifts, require at least one more bit of precision than the
+	maximum shift amount.
+
+2024-05-31  Richard Sandiford  <richard.sandiford@arm.com>
+
+	Backported from master:
+	2024-05-24  Richard Sandiford  <richard.sandiford@arm.com>
+
+	PR tree-optimization/115192
+	* tree-data-ref.cc (create_intersect_range_checks): Take the
+	alignment of the access sizes into account.
+
+2024-05-31  Hongyu Wang  <hongyu.wang@intel.com>
+
+	Backported from master:
+	2024-05-29  Hongyu Wang  <hongyu.wang@intel.com>
+
+	PR target/113719
+	* config/i386/i386-options.cc (ix86_override_options_after_change):
+	Remove call to ix86_default_align and
+	ix86_recompute_optlev_based_flags.
+	(ix86_option_override_internal): Call ix86_default_align and
+	ix86_recompute_optlev_based_flags.
+
+2024-05-30  YunQiang Su  <syq@gcc.gnu.org>
+
+	Backported from master:
+	2024-05-29  YunQiang Su  <syq@gcc.gnu.org>
+
+	* config/mips/mips.cc(mips16_gp_pseudo_reg): Mark
+	MIPS16_PIC_TEMP and MIPS_PROLOGUE_TEMP clobbered.
+	(mips_emit_call_insn): Mark MIPS16_PIC_TEMP and
+	MIPS_PROLOGUE_TEMP clobbered if MIPS16 and CALL_CLOBBERED_GP.
+
+2024-05-22  Jakub Jelinek  <jakub@redhat.com>
+
+	Backported from master:
+	2024-05-22  Jakub Jelinek  <jakub@redhat.com>
+
+	PR tree-optimization/115152
+	* tree-ssa-strlen.cc (strlen_pass::count_nonzero_bytes_addr): If
+	!si->full_string_p, clear *nulterm and set maxlen to nbytes.
+
+2024-05-22  Jakub Jelinek  <jakub@redhat.com>
+
+	Backported from master:
+	2024-05-22  Jakub Jelinek  <jakub@redhat.com>
+
+	PR sanitizer/115172
+	* ubsan.cc (instrument_bool_enum_load): If rhs is not in generic
+	address space, use qualified version of utype with the right
+	address space.  Formatting fix.
+
+2024-05-21  Andrew Pinski  <quic_apinski@quicinc.com>
+
+	Backported from master:
+	2024-05-20  Andrew Pinski  <quic_apinski@quicinc.com>
+
+	PR tree-optimization/115143
+	* tree-ssa-phiopt.cc (minmax_replacement): Check for empty
+	phi nodes for middle bbs for the case where middle bb is not empty.
+
+2024-05-21  Andrew Pinski  <quic_apinski@quicinc.com>
+
+	Backported from master:
+	2024-05-21  Andrew Pinski  <quic_apinski@quicinc.com>
+
+	PR tree-optimization/115154
+	* match.pd (convert (mult zero_one_valued_p@1 INTEGER_CST@2)): Disable
+	for 1bit signed types.
+
 2024-05-21  Release Manager
 
 	* GCC 13.3.0 released.
--- a/src/gcc/DATESTAMP
+++ b/src/gcc/DATESTAMP
@@ -1 +1 @@
-20240521
+20240904
--- a/src/gcc/ada/ChangeLog
+++ b/src/gcc/ada/ChangeLog
@@ -1,3 +1,16 @@
+2024-06-10  Eric Botcazou  <ebotcazou@adacore.com>
+
+	PR ada/114708
+	* exp_util.adb (Finalize_Address): Add guard for incomplete types.
+
+2024-06-10  Javier Miranda  <miranda@adacore.com>
+
+	* sem_ch6.adb (Might_Need_BIP_Task_Actuals): Add support
+	for access-to-subprogram parameter types.
+	* exp_ch6.adb (Add_Task_Actuals_To_Build_In_Place_Call):
+	Add dummy BIP parameters to access-to-subprogram types
+	that may reference a function that has BIP parameters.
+
 2024-05-21  Release Manager
 
 	* GCC 13.3.0 released.
--- a/src/gcc/ada/exp_ch6.adb
+++ b/src/gcc/ada/exp_ch6.adb
@@ -640,15 +640,20 @@ package body Exp_Ch6 is
       Master_Formal : Node_Id;
 
    begin
+      pragma Assert (Ekind (Function_Id) in E_Function
+                                          | E_Subprogram_Type);
+
       --  No such extra parameters are needed if there are no tasks
 
       if not Needs_BIP_Task_Actuals (Function_Id) then
 
          --  However we must add dummy extra actuals if the function is
-         --  a dispatching operation that inherited these extra formals.
+         --  a dispatching operation that inherited these extra formals
+         --  or an access-to-subprogram type that requires these extra
+         --  actuals.
 
-         if Is_Dispatching_Operation (Function_Id)
-           and then Has_BIP_Extra_Formal (Function_Id, BIP_Task_Master)
+         if Has_BIP_Extra_Formal (Function_Id, BIP_Task_Master,
+              Must_Be_Frozen => False)
          then
             Master_Formal :=
               Build_In_Place_Formal (Function_Id, BIP_Task_Master);
--- a/src/gcc/ada/exp_util.adb
+++ b/src/gcc/ada/exp_util.adb
@@ -6013,6 +6013,12 @@ package body Exp_Util is
 
       Utyp := Underlying_Type (Base_Type (Utyp));
 
+      --  Handle incomplete types
+
+      if No (Utyp) then
+         return Empty;
+      end if;
+
       --  Deal with untagged derivation of private views. If the parent is
       --  now known to be protected, the finalization routine is the one
       --  defined on the corresponding record of the ancestor (corresponding
--- a/src/gcc/ada/sem_ch6.adb
+++ b/src/gcc/ada/sem_ch6.adb
@@ -8588,9 +8588,12 @@ package body Sem_Ch6 is
       --  Determines if E has its extra formals
 
       function Might_Need_BIP_Task_Actuals (E : Entity_Id) return Boolean;
-      --  Determines if E is a dispatching primitive returning a limited tagged
-      --  type object since some descendant might return an object with tasks
-      --  (and therefore need the BIP task extra actuals).
+      --  Determines if E is a function or an access to a function returning a
+      --  limited tagged type object. On dispatching primitives this predicate
+      --  is used to determine if some descendant of the function might return
+      --  an object with tasks (and therefore need the BIP task extra actuals).
+      --  On access-to-subprogram types it is used to determine if the target
+      --  function might return an object with tasks.
 
       function Needs_Accessibility_Check_Extra
         (E      : Entity_Id;
@@ -8711,9 +8714,8 @@ package body Sem_Ch6 is
 
          Func_Typ := Root_Type (Underlying_Type (Etype (Subp_Id)));
 
-         return Ekind (Subp_Id) = E_Function
+         return Ekind (Subp_Id) in E_Function | E_Subprogram_Type
            and then not Has_Foreign_Convention (Func_Typ)
-           and then Is_Dispatching_Operation (Subp_Id)
            and then Is_Tagged_Type (Func_Typ)
            and then Is_Limited_Type (Func_Typ)
            and then not Has_Aspect (Func_Typ, Aspect_No_Task_Parts);
--- a/src/gcc/builtins.cc
+++ b/src/gcc/builtins.cc
@@ -9539,7 +9539,21 @@ fold_builtin_arith_overflow (location_t loc, enum built_in_function fcode,
       tree ctype = build_complex_type (type);
       tree call = build_call_expr_internal_loc (loc, ifn, ctype, 2,
 						arg0, arg1);
-      tree tgt = save_expr (call);
+      tree tgt;
+      if (ovf_only)
+	{
+	  tgt = call;
+	  intres = NULL_TREE;
+	}
+      else
+	{
+	  /* Force SAVE_EXPR even for calls which satisfy tree_invariant_p_1,
+	     as while the call itself is const, the REALPART_EXPR store is
+	     certainly not.  And in any case, we want just one call,
+	     not multiple and trying to CSE them later.  */
+	  TREE_SIDE_EFFECTS (call) = 1;
+	  tgt = save_expr (call);
+	}
       intres = build1_loc (loc, REALPART_EXPR, type, tgt);
       ovfres = build1_loc (loc, IMAGPART_EXPR, type, tgt);
       ovfres = fold_convert_loc (loc, boolean_type_node, ovfres);
--- a/src/gcc/c-family/ChangeLog
+++ b/src/gcc/c-family/ChangeLog
@@ -1,3 +1,13 @@
+2024-06-17  Jakub Jelinek  <jakub@redhat.com>
+
+	Backported from master:
+	2024-06-17  Jakub Jelinek  <jakub@redhat.com>
+
+	PR c/115290
+	* c-warn.cc (do_warn_array_compare): Use %E rather than %D for
+	printing op0 and op1; if those operands aren't decls, also print
+	parens around them.
+
 2024-05-21  Release Manager
 
 	* GCC 13.3.0 released.
--- a/src/gcc/c-family/c-warn.cc
+++ b/src/gcc/c-family/c-warn.cc
@@ -3827,11 +3827,16 @@ do_warn_array_compare (location_t location, tree_code code, tree op0, tree op1)
       /* C doesn't allow +arr.  */
       if (c_dialect_cxx ())
 	inform (location, "use unary %<+%> which decays operands to pointers "
-		"or %<&%D[0] %s &%D[0]%> to compare the addresses",
-		op0, op_symbol_code (code), op1);
+		"or %<&%s%E%s[0] %s &%s%E%s[0]%> to compare the addresses",
+		DECL_P (op0) ? "" : "(", op0, DECL_P (op0) ? "" : ")",
+		op_symbol_code (code),
+		DECL_P (op1) ? "" : "(", op1, DECL_P (op1) ? "" : ")");
       else
-	inform (location, "use %<&%D[0] %s &%D[0]%> to compare the addresses",
-		op0, op_symbol_code (code), op1);
+	inform (location,
+		"use %<&%s%E%s[0] %s &%s%E%s[0]%> to compare the addresses",
+		DECL_P (op0) ? "" : "(", op0, DECL_P (op0) ? "" : ")",
+		op_symbol_code (code),
+		DECL_P (op1) ? "" : "(", op1, DECL_P (op1) ? "" : ")");
     }
 }
 
--- a/src/gcc/c/ChangeLog
+++ b/src/gcc/c/ChangeLog
@@ -1,3 +1,13 @@
+2024-06-11  Jakub Jelinek  <jakub@redhat.com>
+
+	Backported from master:
+	2024-06-06  Jakub Jelinek  <jakub@redhat.com>
+
+	PR c/114493
+	* c-decl.cc (c_fixup_may_alias): New function.
+	(finish_struct): Call it if "may_alias" attribute is
+	specified.
+
 2024-05-21  Release Manager
 
 	* GCC 13.3.0 released.
--- a/src/gcc/c/c-decl.cc
+++ b/src/gcc/c/c-decl.cc
@@ -9115,6 +9115,17 @@ is_flexible_array_member_p (bool is_last_field,
 }
 
 
+/* TYPE is a struct or union that we're applying may_alias to after the body is
+   parsed.  Fixup any POINTER_TO types.  */
+
+static void
+c_fixup_may_alias (tree type)
+{
+  for (tree t = TYPE_POINTER_TO (type); t; t = TYPE_NEXT_PTR_TO (t))
+    for (tree v = TYPE_MAIN_VARIANT (t); v; v = TYPE_NEXT_VARIANT (v))
+      TYPE_REF_CAN_ALIAS_ALL (v) = true;
+}
+
 /* Fill in the fields of a RECORD_TYPE or UNION_TYPE node, T.
    LOC is the location of the RECORD_TYPE or UNION_TYPE's definition.
    FIELDLIST is a chain of FIELD_DECL nodes for the fields.
@@ -9409,6 +9420,10 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
       warning_at (loc, 0, "union cannot be made transparent");
     }
 
+  if (lookup_attribute ("may_alias", TYPE_ATTRIBUTES (t)))
+    for (x = TYPE_MAIN_VARIANT (t); x; x = TYPE_NEXT_VARIANT (x))
+      c_fixup_may_alias (x);
+
   tree incomplete_vars = C_TYPE_INCOMPLETE_VARS (TYPE_MAIN_VARIANT (t));
   for (x = TYPE_MAIN_VARIANT (t); x; x = TYPE_NEXT_VARIANT (x))
     {
--- a/src/gcc/combine.cc
+++ b/src/gcc/combine.cc
@@ -11801,8 +11801,10 @@ simplify_compare_const (enum rtx_code code, machine_mode mode,
      `and'ed with that bit), we can replace this with a comparison
      with zero.  */
   if (const_op
-      && (code == EQ || code == NE || code == GE || code == GEU
-	  || code == LT || code == LTU)
+      && (code == EQ || code == NE || code == GEU || code == LTU
+	  /* This optimization is incorrect for signed >= INT_MIN or
+	     < INT_MIN, those are always true or always false.  */
+	  || ((code == GE || code == LT) && const_op > 0))
       && is_a <scalar_int_mode> (mode, &int_mode)
       && GET_MODE_PRECISION (int_mode) - 1 < HOST_BITS_PER_WIDE_INT
       && pow2p_hwi (const_op & GET_MODE_MASK (int_mode))
--- a/src/gcc/common/config/aarch64/aarch64-common.cc
+++ b/src/gcc/common/config/aarch64/aarch64-common.cc
@@ -310,6 +310,7 @@ aarch64_get_extension_string_for_isa_flags
      But in order to make the output more readable, it seems better
      to add the strings in definition order.  */
   aarch64_feature_flags added = 0;
+  auto flags_crypto = AARCH64_FL_AES | AARCH64_FL_SHA2;
   for (unsigned int i = ARRAY_SIZE (all_extensions); i-- > 0; )
     {
       auto &opt = all_extensions[i];
@@ -319,7 +320,7 @@ aarch64_get_extension_string_for_isa_flags
 	 per-feature crypto flags.  */
       auto flags = opt.flag_canonical;
       if (flags == AARCH64_FL_CRYPTO)
-	flags = AARCH64_FL_AES | AARCH64_FL_SHA2;
+	flags = flags_crypto;
 
       if ((flags & isa_flags & (explicit_flags | ~current_flags)) == flags)
 	{
@@ -338,14 +339,32 @@ aarch64_get_extension_string_for_isa_flags
      not have an HWCAPs then it shouldn't be taken into account for feature
      detection because one way or another we can't tell if it's available
      or not.  */
+
   for (auto &opt : all_extensions)
-    if (opt.native_detect_p
-	&& (opt.flag_canonical & current_flags & ~isa_flags))
-      {
-	current_flags &= ~opt.flags_off;
-	outstr += "+no";
-	outstr += opt.name;
-      }
+    {
+      auto flags = opt.flag_canonical;
+      /* As a special case, don't emit "+noaes" or "+nosha2" when we could emit
+	 "+nocrypto" instead, in order to support assemblers that predate the
+	 separate per-feature crypto flags.  Only allow "+nocrypto" when "sm4"
+	 is not already enabled (to avoid dependending on whether "+nocrypto"
+	 also disables "sm4").  */
+      if (flags & flags_crypto
+	  && (flags_crypto & current_flags & ~isa_flags) == flags_crypto
+	  && !(current_flags & AARCH64_FL_SM4))
+	  continue;
+
+      if (flags == AARCH64_FL_CRYPTO)
+	/* If either crypto flag needs removing here, then both do.  */
+	flags = flags_crypto;
+
+      if (opt.native_detect_p
+	  && (flags & current_flags & ~isa_flags))
+	{
+	  current_flags &= ~opt.flags_off;
+	  outstr += "+no";
+	  outstr += opt.name;
+	}
+    }
 
   return outstr;
 }
--- a/src/gcc/config/aarch64/aarch64-c.cc
+++ b/src/gcc/config/aarch64/aarch64-c.cc
@@ -139,7 +139,7 @@ aarch64_update_cpp_builtins (cpp_reader *pfile)
   aarch64_def_or_undef (TARGET_ILP32, "_ILP32", pfile);
   aarch64_def_or_undef (TARGET_ILP32, "__ILP32__", pfile);
 
-  aarch64_def_or_undef (TARGET_CRYPTO, "__ARM_FEATURE_CRYPTO", pfile);
+  aarch64_def_or_undef (TARGET_AES && TARGET_SHA2, "__ARM_FEATURE_CRYPTO", pfile);
   aarch64_def_or_undef (TARGET_SIMD_RDMA, "__ARM_FEATURE_QRDMX", pfile);
   aarch64_def_or_undef (TARGET_SVE, "__ARM_FEATURE_SVE", pfile);
   cpp_undef (pfile, "__ARM_FEATURE_SVE_BITS");
@@ -202,6 +202,11 @@ aarch64_update_cpp_builtins (cpp_reader *pfile)
 			"__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", pfile);
   aarch64_def_or_undef (TARGET_BF16_FP,
 			"__ARM_FEATURE_BF16_SCALAR_ARITHMETIC", pfile);
+  aarch64_def_or_undef (TARGET_BF16_FP,
+			"__ARM_FEATURE_BF16", pfile);
+  aarch64_def_or_undef (TARGET_SVE_BF16,
+			"__ARM_FEATURE_SVE_BF16", pfile);
+
   aarch64_def_or_undef (TARGET_LS64,
 			"__ARM_FEATURE_LS64", pfile);
   aarch64_def_or_undef (AARCH64_ISA_RCPC, "__ARM_FEATURE_RCPC", pfile);
--- a/src/gcc/config/aarch64/aarch64-cores.def
+++ b/src/gcc/config/aarch64/aarch64-cores.def
@@ -182,6 +182,8 @@ AARCH64_CORE("neoverse-n2", neoversen2, cortexa57, V9A, (I8MM, BF16, SVE2_BITPER
 AARCH64_CORE("cobalt-100",   cobalt100, cortexa57, V9A, (I8MM, BF16, SVE2_BITPERM, RNG, MEMTAG, PROFILE), neoversen2, 0x6d, 0xd49, -1)
 
 AARCH64_CORE("neoverse-v2", neoversev2, cortexa57, V9A, (I8MM, BF16, SVE2_BITPERM, RNG, MEMTAG, PROFILE), neoversev2, 0x41, 0xd4f, -1)
+AARCH64_CORE("grace", grace, cortexa57, V9A, (I8MM, BF16, CRYPTO, SVE2_BITPERM, SVE2_AES, SVE2_SHA3, SVE2_SM4, PROFILE), neoversev2, 0x41, 0xd4f, -1)
+
 AARCH64_CORE("demeter", demeter, cortexa57, V9A, (I8MM, BF16, SVE2_BITPERM, RNG, MEMTAG, PROFILE), neoversev2, 0x41, 0xd4f, -1)
 
 #undef AARCH64_CORE
--- a/src/gcc/config/aarch64/aarch64-sve-builtins-base.cc
+++ b/src/gcc/config/aarch64/aarch64-sve-builtins-base.cc
@@ -496,15 +496,22 @@ public:
   expand (function_expander &e) const override
   {
     machine_mode mode = e.vector_mode (0);
-    if (e.pred == PRED_x)
-      {
-	/* The pattern for CNOT includes an UNSPEC_PRED_Z, so needs
-	   a ptrue hint.  */
-	e.add_ptrue_hint (0, e.gp_mode (0));
-	return e.use_pred_x_insn (code_for_aarch64_pred_cnot (mode));
-      }
+    machine_mode pred_mode = e.gp_mode (0);
+    /* The underlying _x pattern is effectively:
+
+	 dst = src == 0 ? 1 : 0
+
+       rather than an UNSPEC_PRED_X.  Using this form allows autovec
+       constructs to be matched by combine, but it means that the
+       predicate on the src == 0 comparison must be all-true.
 
-    return e.use_cond_insn (code_for_cond_cnot (mode), 0);
+       For simplicity, represent other _x operations as fully-defined _m
+       operations rather than using a separate bespoke pattern.  */
+    if (e.pred == PRED_x
+	&& gen_lowpart (pred_mode, e.args[0]) == CONSTM1_RTX (pred_mode))
+      return e.use_pred_x_insn (code_for_aarch64_ptrue_cnot (mode));
+    return e.use_cond_insn (code_for_cond_cnot (mode),
+			    e.pred == PRED_x ? 1 : 0);
   }
 };
 
@@ -2403,7 +2410,7 @@ public:
        version) is through the USDOT instruction but with the second and third
        inputs swapped.  */
     if (m_su)
-      e.rotate_inputs_left (1, 2);
+      e.rotate_inputs_left (1, 3);
     /* The ACLE function has the same order requirements as for svdot.
        While there's no requirement for the RTL pattern to have the same sort
        of order as that for <sur>dot_prod, it's easier to read.
--- a/src/gcc/config/aarch64/aarch64-sve.md
+++ b/src/gcc/config/aarch64/aarch64-sve.md
@@ -3225,24 +3225,24 @@ (define_insn_and_split "trunc<SVE_HSDI:mode><SVE_PARTIAL_I:mode>2"
 ;; - CNOT
 ;; -------------------------------------------------------------------------
 
-;; Predicated logical inverse.
-(define_expand "@aarch64_pred_cnot<mode>"
+;; Logical inverse, predicated with a ptrue.
+(define_expand "@aarch64_ptrue_cnot<mode>"
   [(set (match_operand:SVE_FULL_I 0 "register_operand")
 	(unspec:SVE_FULL_I
 	  [(unspec:<VPRED>
 	     [(match_operand:<VPRED> 1 "register_operand")
-	      (match_operand:SI 2 "aarch64_sve_ptrue_flag")
+	      (const_int SVE_KNOWN_PTRUE)
 	      (eq:<VPRED>
-		(match_operand:SVE_FULL_I 3 "register_operand")
-		(match_dup 4))]
+		(match_operand:SVE_FULL_I 2 "register_operand")
+		(match_dup 3))]
 	     UNSPEC_PRED_Z)
-	   (match_dup 5)
-	   (match_dup 4)]
+	   (match_dup 4)
+	   (match_dup 3)]
 	  UNSPEC_SEL))]
   "TARGET_SVE"
   {
-    operands[4] = CONST0_RTX (<MODE>mode);
-    operands[5] = CONST1_RTX (<MODE>mode);
+    operands[3] = CONST0_RTX (<MODE>mode);
+    operands[4] = CONST1_RTX (<MODE>mode);
   }
 )
 
@@ -3251,7 +3251,7 @@ (define_insn "*cnot<mode>"
 	(unspec:SVE_I
 	  [(unspec:<VPRED>
 	     [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
-	      (match_operand:SI 5 "aarch64_sve_ptrue_flag")
+	      (const_int SVE_KNOWN_PTRUE)
 	      (eq:<VPRED>
 		(match_operand:SVE_I 2 "register_operand" "0, w")
 		(match_operand:SVE_I 3 "aarch64_simd_imm_zero"))]
--- a/src/gcc/config/aarch64/aarch64-tune.md
+++ b/src/gcc/config/aarch64/aarch64-tune.md
@@ -1,5 +1,5 @@
 ;; -*- buffer-read-only: t -*-
 ;; Generated automatically by gentune.sh from aarch64-cores.def
 (define_attr "tune"
-	"cortexa34,cortexa35,cortexa53,cortexa57,cortexa72,cortexa73,thunderx,thunderxt88p1,thunderxt88,octeontx,octeontxt81,octeontxt83,thunderxt81,thunderxt83,ampere1,ampere1a,emag,xgene1,falkor,qdf24xx,exynosm1,phecda,thunderx2t99p1,vulcan,thunderx2t99,cortexa55,cortexa75,cortexa76,cortexa76ae,cortexa77,cortexa78,cortexa78ae,cortexa78c,cortexa65,cortexa65ae,cortexx1,cortexx1c,neoversen1,ares,neoversee1,octeontx2,octeontx2t98,octeontx2t96,octeontx2t93,octeontx2f95,octeontx2f95n,octeontx2f95mm,a64fx,tsv110,thunderx3t110,neoversev1,zeus,neoverse512tvb,saphira,cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35,cortexa73cortexa53,cortexa75cortexa55,cortexa76cortexa55,cortexr82,cortexa510,cortexa710,cortexa715,cortexx2,cortexx3,neoversen2,cobalt100,neoversev2,demeter"
+	"cortexa34,cortexa35,cortexa53,cortexa57,cortexa72,cortexa73,thunderx,thunderxt88p1,thunderxt88,octeontx,octeontxt81,octeontxt83,thunderxt81,thunderxt83,ampere1,ampere1a,emag,xgene1,falkor,qdf24xx,exynosm1,phecda,thunderx2t99p1,vulcan,thunderx2t99,cortexa55,cortexa75,cortexa76,cortexa76ae,cortexa77,cortexa78,cortexa78ae,cortexa78c,cortexa65,cortexa65ae,cortexx1,cortexx1c,neoversen1,ares,neoversee1,octeontx2,octeontx2t98,octeontx2t96,octeontx2t93,octeontx2f95,octeontx2f95n,octeontx2f95mm,a64fx,tsv110,thunderx3t110,neoversev1,zeus,neoverse512tvb,saphira,cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35,cortexa73cortexa53,cortexa75cortexa55,cortexa76cortexa55,cortexr82,cortexa510,cortexa710,cortexa715,cortexx2,cortexx3,neoversen2,cobalt100,neoversev2,grace,demeter"
 	(const (symbol_ref "((enum attr_tune) aarch64_tune)")))
--- a/src/gcc/config/aarch64/aarch64.cc
+++ b/src/gcc/config/aarch64/aarch64.cc
@@ -24897,27 +24897,23 @@ aarch64_expand_cpymem (rtx *operands)
   int mode_bits;
   rtx dst = operands[0];
   rtx src = operands[1];
+  unsigned align = UINTVAL (operands[3]);
   rtx base;
   machine_mode cur_mode = BLKmode;
+  bool size_p = optimize_function_for_size_p (cfun);
 
-  /* Variable-sized memcpy can go through the MOPS expansion if available.  */
-  if (!CONST_INT_P (operands[2]))
+  /* Variable-sized or strict-align copies may use the MOPS expansion.  */
+  if (!CONST_INT_P (operands[2]) || (STRICT_ALIGNMENT && align < 16))
     return aarch64_expand_cpymem_mops (operands);
 
-  unsigned HOST_WIDE_INT size = INTVAL (operands[2]);
-
-  /* Try to inline up to 256 bytes or use the MOPS threshold if available.  */
-  unsigned HOST_WIDE_INT max_copy_size
-    = TARGET_MOPS ? aarch64_mops_memcpy_size_threshold : 256;
+  unsigned HOST_WIDE_INT size = UINTVAL (operands[2]);
 
-  bool size_p = optimize_function_for_size_p (cfun);
+  /* Try to inline up to 256 bytes.  */
+  unsigned max_copy_size = 256;
+  unsigned mops_threshold = aarch64_mops_memcpy_size_threshold;
 
-  /* Large constant-sized cpymem should go through MOPS when possible.
-     It should be a win even for size optimization in the general case.
-     For speed optimization the choice between MOPS and the SIMD sequence
-     depends on the size of the copy, rather than number of instructions,
-     alignment etc.  */
-  if (size > max_copy_size)
+  /* Large copies use MOPS when available or a library call.  */
+  if (size > max_copy_size || (TARGET_MOPS && size > mops_threshold))
     return aarch64_expand_cpymem_mops (operands);
 
   int copy_bits = 256;
@@ -25081,12 +25077,13 @@ aarch64_expand_setmem (rtx *operands)
   unsigned HOST_WIDE_INT len;
   rtx dst = operands[0];
   rtx val = operands[2], src;
+  unsigned align = UINTVAL (operands[3]);
   rtx base;
   machine_mode cur_mode = BLKmode, next_mode;
 
-  /* If we don't have SIMD registers or the size is variable use the MOPS
-     inlined sequence if possible.  */
-  if (!CONST_INT_P (operands[1]) || !TARGET_SIMD)
+  /* Variable-sized or strict-align memset may use the MOPS expansion.  */
+  if (!CONST_INT_P (operands[1]) || !TARGET_SIMD
+      || (STRICT_ALIGNMENT && align < 16))
     return aarch64_expand_setmem_mops (operands);
 
   bool size_p = optimize_function_for_size_p (cfun);
@@ -25094,10 +25091,13 @@ aarch64_expand_setmem (rtx *operands)
   /* Default the maximum to 256-bytes when considering only libcall vs
      SIMD broadcast sequence.  */
   unsigned max_set_size = 256;
+  unsigned mops_threshold = aarch64_mops_memset_size_threshold;
 
-  len = INTVAL (operands[1]);
-  if (len > max_set_size && !TARGET_MOPS)
-    return false;
+  len = UINTVAL (operands[1]);
+
+  /* Large memset uses MOPS when available or a library call.  */
+  if (len > max_set_size || (TARGET_MOPS && len > mops_threshold))
+    return aarch64_expand_setmem_mops (operands);
 
   int cst_val = !!(CONST_INT_P (val) && (INTVAL (val) != 0));
   /* The MOPS sequence takes:
@@ -25110,12 +25110,6 @@ aarch64_expand_setmem (rtx *operands)
      the arguments + 1 for the call.  */
   unsigned libcall_cost = 4;
 
-  /* Upper bound check.  For large constant-sized setmem use the MOPS sequence
-     when available.  */
-  if (TARGET_MOPS
-      && len >= (unsigned HOST_WIDE_INT) aarch64_mops_memset_size_threshold)
-    return aarch64_expand_setmem_mops (operands);
-
   /* Attempt a sequence with a vector broadcast followed by stores.
      Count the number of operations involved to see if it's worth it
      against the alternatives.  A simple counter simd_ops on the
@@ -25157,10 +25151,8 @@ aarch64_expand_setmem (rtx *operands)
       simd_ops++;
       n -= mode_bits;
 
-      /* Do certain trailing copies as overlapping if it's going to be
-	 cheaper.  i.e. less instructions to do so.  For instance doing a 15
-	 byte copy it's more efficient to do two overlapping 8 byte copies than
-	 8 + 4 + 2 + 1.  Only do this when -mstrict-align is not supplied.  */
+      /* Emit trailing writes using overlapping unaligned accesses
+	(when !STRICT_ALIGNMENT) - this is smaller and faster.  */
       if (n > 0 && n < copy_limit / 2 && !STRICT_ALIGNMENT)
 	{
 	  next_mode = smallest_mode_for_size (n, MODE_INT);
--- a/src/gcc/config/aarch64/aarch64.h
+++ b/src/gcc/config/aarch64/aarch64.h
@@ -177,10 +177,13 @@ enum class aarch64_feature : unsigned char {
 
 #endif
 
-/* Macros to test ISA flags.  */
+/* Macros to test ISA flags.
+
+   There is intentionally no macro for AARCH64_FL_CRYPTO, since this flag bit
+   is not always set when its constituent features are present.
+   Check (TARGET_AES && TARGET_SHA2) instead.  */
 
 #define AARCH64_ISA_CRC            (aarch64_isa_flags & AARCH64_FL_CRC)
-#define AARCH64_ISA_CRYPTO         (aarch64_isa_flags & AARCH64_FL_CRYPTO)
 #define AARCH64_ISA_FP             (aarch64_isa_flags & AARCH64_FL_FP)
 #define AARCH64_ISA_SIMD           (aarch64_isa_flags & AARCH64_FL_SIMD)
 #define AARCH64_ISA_LSE		   (aarch64_isa_flags & AARCH64_FL_LSE)
@@ -224,9 +227,6 @@ enum class aarch64_feature : unsigned char {
 #define AARCH64_ISA_CSSC	   (aarch64_isa_flags & AARCH64_FL_CSSC)
 #define AARCH64_ISA_RCPC           (aarch64_isa_flags & AARCH64_FL_RCPC)
 
-/* Crypto is an optional extension to AdvSIMD.  */
-#define TARGET_CRYPTO (AARCH64_ISA_CRYPTO)
-
 /* SHA2 is an optional extension to AdvSIMD.  */
 #define TARGET_SHA2 (AARCH64_ISA_SHA2)
 
--- a/src/gcc/config/aarch64/aarch64.md
+++ b/src/gcc/config/aarch64/aarch64.md
@@ -1659,7 +1659,7 @@ (define_expand "cpymemdi"
    (match_operand:BLK 1 "memory_operand")
    (match_operand:DI 2 "general_operand")
    (match_operand:DI 3 "immediate_operand")]
-   "!STRICT_ALIGNMENT || TARGET_MOPS"
+   ""
 {
   if (aarch64_expand_cpymem (operands))
     DONE;
@@ -1756,7 +1756,7 @@ (define_expand "setmemdi"
         (match_operand:QI  2 "nonmemory_operand")) ;; Value
    (use (match_operand:DI  1 "general_operand")) ;; Length
    (match_operand          3 "immediate_operand")] ;; Align
- "TARGET_SIMD || TARGET_MOPS"
+ ""
  {
   if (aarch64_expand_setmem (operands))
     DONE;
--- a/src/gcc/config/alpha/alpha.md
+++ b/src/gcc/config/alpha/alpha.md
@@ -756,7 +756,8 @@ (define_expand "<code>si3"
 	(sign_extend:DI (match_operand:SI 2 "nonimmediate_operand")))
    (parallel [(set (match_dup 5)
 		   (sign_extend:DI
-		    (any_divmod:SI (match_dup 3) (match_dup 4))))
+		    (any_divmod:SI (truncate:SI (match_dup 3))
+				   (truncate:SI (match_dup 4)))))
 	      (clobber (reg:DI 23))
 	      (clobber (reg:DI 28))])
    (set (match_operand:SI 0 "nonimmediate_operand")
@@ -782,9 +783,10 @@ (define_expand "<code>di3"
 
 (define_insn_and_split "*divmodsi_internal_er"
   [(set (match_operand:DI 0 "register_operand" "=c")
-	(sign_extend:DI (match_operator:SI 3 "divmod_operator"
-			[(match_operand:DI 1 "register_operand" "a")
-			 (match_operand:DI 2 "register_operand" "b")])))
+	(sign_extend:DI
+	 (match_operator:SI 3 "divmod_operator"
+	  [(truncate:SI (match_operand:DI 1 "register_operand" "a"))
+	   (truncate:SI (match_operand:DI 2 "register_operand" "b"))])))
    (clobber (reg:DI 23))
    (clobber (reg:DI 28))]
   "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
@@ -826,8 +828,8 @@ (define_insn_and_split "*divmodsi_internal_er"
 (define_insn "*divmodsi_internal_er_1"
   [(set (match_operand:DI 0 "register_operand" "=c")
 	(sign_extend:DI (match_operator:SI 3 "divmod_operator"
-                        [(match_operand:DI 1 "register_operand" "a")
-                         (match_operand:DI 2 "register_operand" "b")])))
+	 [(truncate:SI (match_operand:DI 1 "register_operand" "a"))
+	  (truncate:SI (match_operand:DI 2 "register_operand" "b"))])))
    (use (match_operand:DI 4 "register_operand" "c"))
    (use (match_operand 5 "const_int_operand"))
    (clobber (reg:DI 23))
@@ -839,9 +841,10 @@ (define_insn "*divmodsi_internal_er_1"
 
 (define_insn "*divmodsi_internal"
   [(set (match_operand:DI 0 "register_operand" "=c")
-	(sign_extend:DI (match_operator:SI 3 "divmod_operator"
-			[(match_operand:DI 1 "register_operand" "a")
-			 (match_operand:DI 2 "register_operand" "b")])))
+	(sign_extend:DI
+	 (match_operator:SI 3 "divmod_operator"
+	  [(truncate:SI (match_operand:DI 1 "register_operand" "a"))
+	   (truncate:SI (match_operand:DI 2 "register_operand" "b"))])))
    (clobber (reg:DI 23))
    (clobber (reg:DI 28))]
   "TARGET_ABI_OSF"
@@ -3930,7 +3933,8 @@ (define_insn "movdi_er_high_g"
   else
     return "ldq %0,%2(%1)\t\t!literal!%3";
 }
-  [(set_attr "type" "ldsym")])
+  [(set_attr "type" "ldsym")
+   (set_attr "cannot_copy" "true")])
 
 (define_split
   [(set (match_operand:DI 0 "register_operand")
@@ -3954,7 +3958,8 @@ (define_insn "movdi_er_tlsgd"
     return "lda %0,%2(%1)\t\t!tlsgd";
   else
     return "lda %0,%2(%1)\t\t!tlsgd!%3";
-})
+}
+  [(set_attr "cannot_copy" "true")])
 
 (define_insn "movdi_er_tlsldm"
   [(set (match_operand:DI 0 "register_operand" "=r")
@@ -3967,7 +3972,8 @@ (define_insn "movdi_er_tlsldm"
     return "lda %0,%&(%1)\t\t!tlsldm";
   else
     return "lda %0,%&(%1)\t\t!tlsldm!%2";
-})
+}
+  [(set_attr "cannot_copy" "true")])
 
 (define_insn "*movdi_er_gotdtp"
   [(set (match_operand:DI 0 "register_operand" "=r")
@@ -5936,6 +5942,7 @@ (define_insn "call_value_osf_<tls>"
   "HAVE_AS_TLS"
   "ldq $27,%1($29)\t\t!literal!%2\;jsr $26,($27),%1\t\t!lituse_<tls>!%2\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*"
   [(set_attr "type" "jsr")
+   (set_attr "cannot_copy" "true")
    (set_attr "length" "16")])
 
 ;; We must use peep2 instead of a split because we need accurate life
--- a/src/gcc/config/alpha/constraints.md
+++ b/src/gcc/config/alpha/constraints.md
@@ -27,7 +27,7 @@ (define_register_constraint "a" "R24_REG"
  "General register 24, input to division routine")
 
 (define_register_constraint "b" "R25_REG"
- "General register 24, input to division routine")
+ "General register 25, input to division routine")
 
 (define_register_constraint "c" "R27_REG"
  "General register 27, function call address")
--- a/src/gcc/config/arm/arm.cc
+++ b/src/gcc/config/arm/arm.cc
@@ -19143,17 +19143,25 @@ cmse_nonsecure_call_inline_register_clear (void)
 	      || TREE_CODE (ret_type) == BOOLEAN_TYPE)
 	      && known_lt (GET_MODE_SIZE (TYPE_MODE (ret_type)), 4))
 	    {
-	      machine_mode ret_mode = TYPE_MODE (ret_type);
+	      rtx ret_reg = gen_rtx_REG (TYPE_MODE (ret_type), R0_REGNUM);
+	      rtx si_reg = gen_rtx_REG (SImode, R0_REGNUM);
 	      rtx extend;
 	      if (TYPE_UNSIGNED (ret_type))
-		extend = gen_rtx_ZERO_EXTEND (SImode,
-					      gen_rtx_REG (ret_mode, R0_REGNUM));
+		extend = gen_rtx_SET (si_reg, gen_rtx_ZERO_EXTEND (SImode,
+								   ret_reg));
 	      else
-		extend = gen_rtx_SIGN_EXTEND (SImode,
-					      gen_rtx_REG (ret_mode, R0_REGNUM));
-	      emit_insn_after (gen_rtx_SET (gen_rtx_REG (SImode, R0_REGNUM),
-					     extend), insn);
-
+		{
+		  /* Signed-extension is a special case because of
+		     thumb1_extendhisi2.  */
+		  if (TARGET_THUMB1
+		      && known_eq (GET_MODE_SIZE (TYPE_MODE (ret_type)), 2))
+		    extend = gen_thumb1_extendhisi2 (si_reg, ret_reg);
+		  else
+		    extend = gen_rtx_SET (si_reg,
+					  gen_rtx_SIGN_EXTEND (SImode,
+							       ret_reg));
+		}
+	      emit_insn_after (extend, insn);
 	    }
 
 
@@ -27172,6 +27180,58 @@ thumb1_expand_prologue (void)
   live_regs_mask = offsets->saved_regs_mask;
   lr_needs_saving = live_regs_mask & (1 << LR_REGNUM);
 
+  /* The AAPCS requires the callee to widen integral types narrower
+     than 32 bits to the full width of the register; but when handling
+     calls to non-secure space, we cannot trust the callee to have
+     correctly done so.  So forcibly re-widen the result here.  */
+  if (IS_CMSE_ENTRY (func_type))
+    {
+      function_args_iterator args_iter;
+      CUMULATIVE_ARGS args_so_far_v;
+      cumulative_args_t args_so_far;
+      bool first_param = true;
+      tree arg_type;
+      tree fndecl = current_function_decl;
+      tree fntype = TREE_TYPE (fndecl);
+      arm_init_cumulative_args (&args_so_far_v, fntype, NULL_RTX, fndecl);
+      args_so_far = pack_cumulative_args (&args_so_far_v);
+      FOREACH_FUNCTION_ARGS (fntype, arg_type, args_iter)
+	{
+	  rtx arg_rtx;
+
+	  if (VOID_TYPE_P (arg_type))
+	    break;
+
+	  function_arg_info arg (arg_type, /*named=*/true);
+	  if (!first_param)
+	    /* We should advance after processing the argument and pass
+	       the argument we're advancing past.  */
+	    arm_function_arg_advance (args_so_far, arg);
+	  first_param = false;
+	  arg_rtx = arm_function_arg (args_so_far, arg);
+	  gcc_assert (REG_P (arg_rtx));
+	  if ((TREE_CODE (arg_type) == INTEGER_TYPE
+	      || TREE_CODE (arg_type) == ENUMERAL_TYPE
+	      || TREE_CODE (arg_type) == BOOLEAN_TYPE)
+	      && known_lt (GET_MODE_SIZE (GET_MODE (arg_rtx)), 4))
+	    {
+	      rtx res_reg = gen_rtx_REG (SImode, REGNO (arg_rtx));
+	      if (TYPE_UNSIGNED (arg_type))
+		emit_set_insn (res_reg, gen_rtx_ZERO_EXTEND (SImode, arg_rtx));
+	      else
+		{
+		  /* Signed-extension is a special case because of
+		     thumb1_extendhisi2.  */
+		  if (known_eq (GET_MODE_SIZE (GET_MODE (arg_rtx)), 2))
+		    emit_insn (gen_thumb1_extendhisi2 (res_reg, arg_rtx));
+		  else
+		    emit_set_insn (res_reg,
+				   gen_rtx_SIGN_EXTEND (SImode, arg_rtx));
+		}
+	    }
+	}
+    }
+
   /* Extract a mask of the ones we can give to the Thumb's push instruction.  */
   l_mask = live_regs_mask & 0x40ff;
   /* Then count how many other high registers will need to be pushed.  */
--- a/src/gcc/config/arm/mve.md
+++ b/src/gcc/config/arm/mve.md
@@ -10166,7 +10166,7 @@ (define_insn "mve_vec_setv2di_internal"
   if (elt == 0)
    return "vmov\t%e0, %Q1, %R1";
   else
-   return "vmov\t%f0, %J1, %K1";
+   return "vmov\t%f0, %Q1, %R1";
 }
  [(set_attr "type" "mve_move")])
 
--- a/src/gcc/config/avr/avr-dimode.md
+++ b/src/gcc/config/avr/avr-dimode.md
@@ -62,8 +62,8 @@ (define_mode_iterator ALL8S [ DQ  DA  TA])
 ;; "addta3" "adduta3"
 (define_expand "add<mode>3"
   [(parallel [(match_operand:ALL8 0 "general_operand" "")
-              (match_operand:ALL8 1 "general_operand" "")
-              (match_operand:ALL8 2 "general_operand" "")])]
+              (match_operand:ALL8 1 "nop_general_operand")
+              (match_operand:ALL8 2 "nop_general_operand")])]
   "avr_have_dimode"
   {
     rtx acc_a = gen_rtx_REG (<MODE>mode, ACC_A);
@@ -178,8 +178,8 @@ (define_insn "*add<mode>3_const_insn"
 ;; "subta3" "subuta3"
 (define_expand "sub<mode>3"
   [(parallel [(match_operand:ALL8 0 "general_operand" "")
-              (match_operand:ALL8 1 "general_operand" "")
-              (match_operand:ALL8 2 "general_operand" "")])]
+              (match_operand:ALL8 1 "nop_general_operand")
+              (match_operand:ALL8 2 "nop_general_operand")])]
   "avr_have_dimode"
   {
     rtx acc_a = gen_rtx_REG (<MODE>mode, ACC_A);
@@ -259,8 +259,8 @@ (define_insn "*sub<mode>3_const_insn"
 
 (define_expand "<code_stdname><mode>3"
   [(set (match_operand:ALL8S 0 "general_operand" "")
-        (ss_addsub:ALL8S (match_operand:ALL8S 1 "general_operand" "")
-                         (match_operand:ALL8S 2 "general_operand" "")))]
+        (ss_addsub:ALL8S (match_operand:ALL8S 1 "nop_general_operand")
+                         (match_operand:ALL8S 2 "nop_general_operand")))]
   "avr_have_dimode"
   {
     rtx acc_a = gen_rtx_REG (<MODE>mode, ACC_A);
@@ -332,8 +332,8 @@ (define_insn "*<code_stdname><mode>3_const_insn"
 
 (define_expand "<code_stdname><mode>3"
   [(set (match_operand:ALL8U 0 "general_operand" "")
-        (us_addsub:ALL8U (match_operand:ALL8U 1 "general_operand" "")
-                         (match_operand:ALL8U 2 "general_operand" "")))]
+        (us_addsub:ALL8U (match_operand:ALL8U 1 "nop_general_operand")
+                         (match_operand:ALL8U 2 "nop_general_operand")))]
   "avr_have_dimode"
   {
     rtx acc_a = gen_rtx_REG (<MODE>mode, ACC_A);
@@ -405,7 +405,7 @@ (define_insn "*<code_stdname><mode>3_const_insn"
 
 (define_expand "negdi2"
   [(parallel [(match_operand:DI 0 "general_operand" "")
-              (match_operand:DI 1 "general_operand" "")])]
+              (match_operand:DI 1 "nop_general_operand")])]
   "avr_have_dimode"
   {
     rtx acc_a = gen_rtx_REG (DImode, ACC_A);
@@ -602,8 +602,8 @@ (define_code_iterator di_shifts
 ;; "ashluta3"  "ashruta3"  "lshruta3"  "rotluta3"
 (define_expand "<code_stdname><mode>3"
   [(parallel [(match_operand:ALL8 0 "general_operand" "")
-              (di_shifts:ALL8 (match_operand:ALL8 1 "general_operand" "")
-                              (match_operand:QI 2 "general_operand" ""))])]
+              (di_shifts:ALL8 (match_operand:ALL8 1 "nop_general_operand")
+                              (match_operand:QI 2 "nop_general_operand"))])]
   "avr_have_dimode"
   {
     rtx acc_a = gen_rtx_REG (<MODE>mode, ACC_A);
@@ -648,8 +648,8 @@ (define_insn "*<code_stdname><mode>3_insn"
 ;; "mulsidi3"
 (define_expand "<extend_u>mulsidi3"
   [(parallel [(match_operand:DI 0 "register_operand" "")
-              (match_operand:SI 1 "general_operand" "")
-              (match_operand:SI 2 "general_operand" "")
+              (match_operand:SI 1 "nop_general_operand")
+              (match_operand:SI 2 "nop_general_operand")
               ;; Just to mention the iterator 
               (clobber (any_extend:SI (match_dup 1)))])]
   "avr_have_dimode
--- a/src/gcc/config/avr/avr-protos.h
+++ b/src/gcc/config/avr/avr-protos.h
@@ -108,7 +108,7 @@ extern const char* avr_out_lpm (rtx_insn *, rtx*, int*);
 extern void avr_notice_update_cc (rtx body, rtx_insn *insn);
 extern int reg_unused_after (rtx_insn *insn, rtx reg);
 extern int _reg_unused_after (rtx_insn *insn, rtx reg);
-extern int avr_jump_mode (rtx x, rtx_insn *insn);
+extern int avr_jump_mode (rtx x, rtx_insn *insn, int = 0);
 extern int test_hard_reg_class (enum reg_class rclass, rtx x);
 extern int jump_over_one_insn_p (rtx_insn *insn, rtx dest);
 
--- a/src/gcc/config/avr/avr.cc
+++ b/src/gcc/config/avr/avr.cc
@@ -3388,19 +3388,22 @@ avr_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size,
 /* Choose mode for jump insn:
    1 - relative jump in range -63 <= x <= 62 ;
    2 - relative jump in range -2046 <= x <= 2045 ;
-   3 - absolute jump (only for ATmega[16]03).  */
+   3 - absolute jump (only when we have JMP / CALL).
+
+   When jumping backwards, assume the jump offset is EXTRA words
+   bigger than inferred from insn addresses.  */
 
 int
-avr_jump_mode (rtx x, rtx_insn *insn)
+avr_jump_mode (rtx x, rtx_insn *insn, int extra)
 {
   int dest_addr = INSN_ADDRESSES (INSN_UID (GET_CODE (x) == LABEL_REF
                                             ? XEXP (x, 0) : x));
   int cur_addr = INSN_ADDRESSES (INSN_UID (insn));
   int jump_distance = cur_addr - dest_addr;
 
-  if (IN_RANGE (jump_distance, -63, 62))
+  if (IN_RANGE (jump_distance, -63, 62 - extra))
     return 1;
-  else if (IN_RANGE (jump_distance, -2046, 2045))
+  else if (IN_RANGE (jump_distance, -2046, 2045 - extra))
     return 2;
   else if (AVR_HAVE_JMP_CALL)
     return 3;
@@ -4093,7 +4096,13 @@ avr_out_xload (rtx_insn *insn ATTRIBUTE_UNUSED, rtx *op, int *plen)
   xop[2] = lpm_addr_reg_rtx;
   xop[3] = AVR_HAVE_LPMX ? op[0] : lpm_reg_rtx;
 
-  avr_asm_len (AVR_HAVE_LPMX ? "lpm %3,%a2" : "lpm", xop, plen, -1);
+  if (plen)
+    *plen = 0;
+
+  if (reg_overlap_mentioned_p (xop[3], lpm_addr_reg_rtx))
+    avr_asm_len ("sbrs %1,7", xop, plen, 1);
+
+  avr_asm_len (AVR_HAVE_LPMX ? "lpm %3,%a2" : "lpm", xop, plen, 1);
 
   avr_asm_len ("sbrc %1,7" CR_TAB
                "ld %3,%a2", xop, plen, 2);
@@ -4239,13 +4248,30 @@ avr_out_movqi_r_mr_reg_disp_tiny (rtx_insn *insn, rtx op[], int *plen)
   rtx dest = op[0];
   rtx src = op[1];
   rtx x = XEXP (src, 0);
+  rtx base = XEXP (x, 0);
+
+  if (plen)
+    *plen = 0;
 
-  avr_asm_len (TINY_ADIW (%I1, %J1, %o1) CR_TAB
-               "ld %0,%b1" , op, plen, -3);
+  if (!reg_overlap_mentioned_p (dest, base))
+    {
+      avr_asm_len (TINY_ADIW (%I1, %J1, %o1) CR_TAB
+		   "ld %0,%b1", op, plen, 3);
+      if (!reg_unused_after (insn, base))
+	avr_asm_len (TINY_SBIW (%I1, %J1, %o1), op, plen, 2);
+    }
+  else
+    {
+      // PR98762: The base register overlaps dest and is only partly clobbered.
+      rtx base2 = all_regs_rtx[1 ^ REGNO (dest)];
 
-  if (!reg_overlap_mentioned_p (dest, XEXP (x, 0))
-      && !reg_unused_after (insn, XEXP (x, 0)))
-    avr_asm_len (TINY_SBIW (%I1, %J1, %o1), op, plen, 2);
+      if (!reg_unused_after (insn, base2))
+	avr_asm_len ("mov __tmp_reg__,%0" , &base2, plen, 1);
+      avr_asm_len (TINY_ADIW (%I1, %J1, %o1) CR_TAB
+		   "ld %0,%b1", op, plen, 3);
+      if (!reg_unused_after (insn, base2))
+	avr_asm_len ("mov %0,__tmp_reg__" , &base2, plen, 1);
+    }
 
   return "";
 }
--- a/src/gcc/config/avr/avr.md
+++ b/src/gcc/config/avr/avr.md
@@ -285,6 +285,8 @@ (define_mode_iterator ORDERED234 [HI SI PSI
 (define_mode_iterator SPLIT34 [SI SF PSI
                                SQ USQ SA USA])
 
+(define_mode_iterator SFDF [SF DF])
+
 ;; Define code iterators
 ;; Define two incarnations so that we can build the cartesian product.
 (define_code_iterator any_extend  [sign_extend zero_extend])
@@ -716,12 +718,26 @@ (define_expand "mov<mode>"
         if (!REG_P (addr))
           src = replace_equiv_address (src, copy_to_mode_reg (PSImode, addr));
 
+        rtx dest2 = reg_overlap_mentioned_p (dest, lpm_addr_reg_rtx)
+          ? gen_reg_rtx (<MODE>mode)
+          : dest;
+
         if (!avr_xload_libgcc_p (<MODE>mode))
           /* ; No <mode> here because gen_xload8<mode>_A only iterates over ALL1.
              ; insn-emit does not depend on the mode, it's all about operands.  */
-          emit_insn (gen_xload8qi_A (dest, src));
+          emit_insn (gen_xload8qi_A (dest2, src));
         else
-          emit_insn (gen_xload<mode>_A (dest, src));
+          {
+            rtx reg_22 = gen_rtx_REG (<MODE>mode, 22);
+            if (reg_overlap_mentioned_p (dest2, reg_22)
+                || reg_overlap_mentioned_p (dest2, all_regs_rtx[21]))
+              dest2 = gen_reg_rtx (<MODE>mode);
+
+            emit_insn (gen_xload<mode>_A (dest2, src));
+          }
+
+        if (dest2 != dest)
+          emit_move_insn (dest, dest2);
 
         DONE;
       }
@@ -7609,8 +7625,6 @@ (define_peephole ; "*dec-and-branchsi!=-1.d.clobber"
                       (pc)))]
   "dead_or_set_regno_p (insn, REG_CC)"
   {
-    const char *op;
-    int jump_mode;
     if (avr_adiw_reg_p (operands[0]))
       output_asm_insn ("sbiw %0,1" CR_TAB
                        "sbc %C0,__zero_reg__" CR_TAB
@@ -7621,8 +7635,8 @@ (define_peephole ; "*dec-and-branchsi!=-1.d.clobber"
                        "sbc %C0,__zero_reg__" CR_TAB
                        "sbc %D0,__zero_reg__", operands);
 
-    jump_mode = avr_jump_mode (operands[2], insn);
-    op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
+    int jump_mode = avr_jump_mode (operands[2], insn, 3 - avr_adiw_reg_p (operands[0]));
+    const char *op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
     operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
 
     switch (jump_mode)
@@ -7652,16 +7666,14 @@ (define_peephole ; "*dec-and-branchhi!=-1"
                       (pc)))]
   "dead_or_set_regno_p (insn, REG_CC)"
   {
-    const char *op;
-    int jump_mode;
     if (avr_adiw_reg_p (operands[0]))
       output_asm_insn ("sbiw %0,1", operands);
     else
       output_asm_insn ("subi %A0,1" CR_TAB
                        "sbc %B0,__zero_reg__", operands);
 
-    jump_mode = avr_jump_mode (operands[2], insn);
-    op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
+    int jump_mode = avr_jump_mode (operands[2], insn, 1 - avr_adiw_reg_p (operands[0]));
+    const char *op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
     operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
 
     switch (jump_mode)
@@ -7693,16 +7705,14 @@ (define_peephole ; "*dec-and-branchhi!=-1.d.clobber"
                       (pc)))]
   "dead_or_set_regno_p (insn, REG_CC)"
   {
-    const char *op;
-    int jump_mode;
     if (avr_adiw_reg_p (operands[0]))
       output_asm_insn ("sbiw %0,1", operands);
     else
       output_asm_insn ("subi %A0,1" CR_TAB
                        "sbc %B0,__zero_reg__", operands);
 
-    jump_mode = avr_jump_mode (operands[2], insn);
-    op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
+    int jump_mode = avr_jump_mode (operands[2], insn, 1 - avr_adiw_reg_p (operands[0]));
+    const char *op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
     operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
 
     switch (jump_mode)
@@ -7734,14 +7744,12 @@ (define_peephole ; "*dec-and-branchhi!=-1.l.clobber"
                       (pc)))]
   "dead_or_set_regno_p (insn, REG_CC)"
   {
-    const char *op;
-    int jump_mode;
     output_asm_insn ("ldi %3,1"   CR_TAB
                      "sub %A0,%3" CR_TAB
                      "sbc %B0,__zero_reg__", operands);
 
-    jump_mode = avr_jump_mode (operands[2], insn);
-    op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
+    int jump_mode = avr_jump_mode (operands[2], insn, 2);
+    const char *op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
     operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
 
     switch (jump_mode)
@@ -9780,6 +9788,20 @@ (define_insn_and_split "*extract.subreg.bit"
     operands[4] = GEN_INT (bitno % 8);
   })
 
+
+;; Work around PR115307: Early passes expand isinf/f/l to a bloat.
+;; These passes do not consider costs, and there is no way to
+;; hook in or otherwise disable the generated bloat.
+
+;; isinfsf2  isinfdf2
+(define_expand "isinf<mode>2"
+  [(parallel [(match_operand:HI 0)
+              (match_operand:SFDF 1)])]
+  ""
+  {
+    FAIL;
+  })
+
 
 ;; Fixed-point instructions
 (include "avr-fixed.md")
--- a/src/gcc/config/i386/avx512dqintrin.h
+++ b/src/gcc/config/i386/avx512dqintrin.h
@@ -2800,11 +2800,11 @@ _mm512_fpclass_ps_mask (__m512 __A, const int __imm)
   ((__mmask8) __builtin_ia32_fpclasssd_mask ((__v2df) (__m128d) (X),	\
 					     (int) (C), (__mmask8) (-1))) \
 
-#define _mm_mask_fpclass_ss_mask(X, C, U)				\
+#define _mm_mask_fpclass_ss_mask(U, X, C)				\
   ((__mmask8) __builtin_ia32_fpclassss_mask ((__v4sf) (__m128) (X),	\
 					     (int) (C), (__mmask8) (U)))
 
-#define _mm_mask_fpclass_sd_mask(X, C, U)				\
+#define _mm_mask_fpclass_sd_mask(U, X, C)				\
   ((__mmask8) __builtin_ia32_fpclasssd_mask ((__v2df) (__m128d) (X),	\
 					     (int) (C), (__mmask8) (U)))
 
@@ -2839,8 +2839,9 @@ _mm512_fpclass_ps_mask (__m512 __A, const int __imm)
     (__mmask8)(U)))
 
 #define _mm_reduce_round_sd(A, B, C, R)				       \
-  ((__m128d) __builtin_ia32_reducesd_round ((__v2df)(__m128d)(A),      \
-    (__v2df)(__m128d)(B), (int)(C), (__mmask8)(U), (int)(R)))
+  ((__m128d) __builtin_ia32_reducesd_mask_round ((__v2df)(__m128d)(A), \
+    (__v2df)(__m128d)(B), (int)(C), (__v2df) _mm_setzero_pd (),	       \
+    (__mmask8)(-1), (int)(R)))
 
 #define _mm_mask_reduce_round_sd(W, U, A, B, C, R)		       \
   ((__m128d) __builtin_ia32_reducesd_mask_round ((__v2df)(__m128d)(A), \
@@ -2867,8 +2868,9 @@ _mm512_fpclass_ps_mask (__m512 __A, const int __imm)
     (__mmask8)(U)))
 
 #define _mm_reduce_round_ss(A, B, C, R)				       \
-  ((__m128) __builtin_ia32_reducess_round ((__v4sf)(__m128)(A),	       \
-    (__v4sf)(__m128)(B), (int)(C), (__mmask8)(U), (int)(R)))
+  ((__m128) __builtin_ia32_reducess_mask_round ((__v4sf)(__m128)(A),   \
+    (__v4sf)(__m128)(B), (int)(C), (__v4sf) _mm_setzero_ps (),	       \
+    (__mmask8)(-1), (int)(R)))
 
 #define _mm_mask_reduce_round_ss(W, U, A, B, C, R)		       \
   ((__m128) __builtin_ia32_reducess_mask_round ((__v4sf)(__m128)(A),   \
@@ -2876,7 +2878,7 @@ _mm512_fpclass_ps_mask (__m512 __A, const int __imm)
     (__mmask8)(U), (int)(R)))
 
 #define _mm_maskz_reduce_round_ss(U, A, B, C, R)		       \
-  ((__m128) __builtin_ia32_reducesd_mask_round ((__v4sf)(__m128)(A),   \
+  ((__m128) __builtin_ia32_reducess_mask_round ((__v4sf)(__m128)(A),   \
     (__v4sf)(__m128)(B), (int)(C), (__v4sf) _mm_setzero_ps (),	       \
     (__mmask8)(U), (int)(R)))
 
--- a/src/gcc/config/i386/avx512fp16intrin.h
+++ b/src/gcc/config/i386/avx512fp16intrin.h
@@ -2322,11 +2322,11 @@ _mm512_fpclass_ph_mask (__m512h __A, const int __imm)
 #else
 #define _mm512_mask_fpclass_ph_mask(u, x, c)				\
   ((__mmask32) __builtin_ia32_fpclassph512_mask ((__v32hf) (__m512h) (x), \
-						 (int) (c),(__mmask8)(u)))
+						 (int) (c),(__mmask32)(u)))
 
 #define _mm512_fpclass_ph_mask(x, c)                                    \
   ((__mmask32) __builtin_ia32_fpclassph512_mask ((__v32hf) (__m512h) (x), \
-						 (int) (c),(__mmask8)-1))
+						 (int) (c),(__mmask32)-1))
 #endif /* __OPIMTIZE__ */
 
 /* Intrinsics vgetexpph, vgetexpsh.  */
--- a/src/gcc/config/i386/avx512vlbwintrin.h
+++ b/src/gcc/config/i386/avx512vlbwintrin.h
@@ -1839,7 +1839,7 @@ _mm_maskz_slli_epi16 (__mmask8 __U, __m128i __A, int __B)
 #define _mm256_mask_alignr_epi8(W, U, X, Y, N)					    \
   ((__m256i) __builtin_ia32_palignr256_mask ((__v4di)(__m256i)(X),		    \
 					    (__v4di)(__m256i)(Y), (int)((N) * 8),   \
-					    (__v4di)(__m256i)(X), (__mmask32)(U)))
+					    (__v4di)(__m256i)(W), (__mmask32)(U)))
 
 #define _mm256_mask_srli_epi16(W, U, A, B)                              \
   ((__m256i) __builtin_ia32_psrlwi256_mask ((__v16hi)(__m256i)(A),      \
@@ -1922,7 +1922,7 @@ _mm_maskz_slli_epi16 (__mmask8 __U, __m128i __A, int __B)
 #define _mm_mask_alignr_epi8(W, U, X, Y, N)					    \
   ((__m128i) __builtin_ia32_palignr128_mask ((__v2di)(__m128i)(X),		    \
 					    (__v2di)(__m128i)(Y), (int)((N) * 8),   \
-					    (__v2di)(__m128i)(X), (__mmask16)(U)))
+					    (__v2di)(__m128i)(W), (__mmask16)(U)))
 
 #define _mm_maskz_alignr_epi8(U, X, Y, N)					    \
   ((__m128i) __builtin_ia32_palignr128_mask ((__v2di)(__m128i)(X),		    \
--- a/src/gcc/config/i386/avx512vlintrin.h
+++ b/src/gcc/config/i386/avx512vlintrin.h
@@ -13609,7 +13609,7 @@ _mm256_permutex_pd (__m256d __X, const int __M)
 
 #define _mm_mask_alignr_epi64(W, U, X, Y, C)                                \
     ((__m128i)__builtin_ia32_alignq128_mask ((__v2di)(__m128i)(X),          \
-        (__v2di)(__m128i)(Y), (int)(C), (__v2di)(__m128i)(X), (__mmask8)-1))
+        (__v2di)(__m128i)(Y), (int)(C), (__v2di)(__m128i)(W), (__mmask8)(U)))
 
 #define _mm_maskz_alignr_epi64(U, X, Y, C)                                  \
     ((__m128i)__builtin_ia32_alignq128_mask ((__v2di)(__m128i)(X),          \
--- a/src/gcc/config/i386/constraints.md
+++ b/src/gcc/config/i386/constraints.md
@@ -190,7 +190,7 @@ (define_special_memory_constraint "Bc"
   (and (match_operand 0 "memory_operand")
        (match_test "constant_address_p (XEXP (op, 0))")))
 
-(define_memory_constraint "Bk"
+(define_special_memory_constraint "Bk"
   "@internal TLS address that allows insn using non-integer registers."
   (and (match_operand 0 "memory_operand")
        (not (match_test "ix86_gpr_tls_address_pattern_p (op)"))))
--- a/src/gcc/config/i386/i386-options.cc
+++ b/src/gcc/config/i386/i386-options.cc
@@ -1868,44 +1868,66 @@ ix86_recompute_optlev_based_flags (struct gcc_options *opts,
 	    opts->x_flag_pcc_struct_return = DEFAULT_PCC_STRUCT_RETURN;
 	}
     }
+
+  /* Keep nonleaf frame pointers.  */
+  if (opts->x_flag_omit_frame_pointer)
+    opts->x_target_flags &= ~MASK_OMIT_LEAF_FRAME_POINTER;
+  else if (TARGET_OMIT_LEAF_FRAME_POINTER_P (opts->x_target_flags))
+    opts->x_flag_omit_frame_pointer = 1;
 }
 
-/* Implement TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE hook.  */
+/* Implement part of TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE hook.  */
 
-void
-ix86_override_options_after_change (void)
+static void
+ix86_override_options_after_change_1 (struct gcc_options *opts,
+				      struct gcc_options *opts_set)
 {
-  /* Default align_* from the processor table.  */
-  ix86_default_align (&global_options);
-
-  ix86_recompute_optlev_based_flags (&global_options, &global_options_set);
+#define OPTS_SET_P(OPTION) opts_set->x_ ## OPTION
+#define OPTS(OPTION) opts->x_ ## OPTION
 
   /* Disable unrolling small loops when there's explicit
      -f{,no}unroll-loop.  */
-  if ((OPTION_SET_P (flag_unroll_loops))
-     || (OPTION_SET_P (flag_unroll_all_loops)
-	 && flag_unroll_all_loops))
+  if ((OPTS_SET_P (flag_unroll_loops))
+     || (OPTS_SET_P (flag_unroll_all_loops)
+	 && OPTS (flag_unroll_all_loops)))
     {
-      if (!OPTION_SET_P (ix86_unroll_only_small_loops))
-	ix86_unroll_only_small_loops = 0;
+      if (!OPTS_SET_P (ix86_unroll_only_small_loops))
+	OPTS (ix86_unroll_only_small_loops) = 0;
       /* Re-enable -frename-registers and -fweb if funroll-loops
 	 enabled.  */
-      if (!OPTION_SET_P (flag_web))
-	flag_web = flag_unroll_loops;
-      if (!OPTION_SET_P (flag_rename_registers))
-	flag_rename_registers = flag_unroll_loops;
+      if (!OPTS_SET_P (flag_web))
+	OPTS (flag_web) = OPTS (flag_unroll_loops);
+      if (!OPTS_SET_P (flag_rename_registers))
+	OPTS (flag_rename_registers) = OPTS (flag_unroll_loops);
       /* -fcunroll-grow-size default follws -f[no]-unroll-loops.  */
-      if (!OPTION_SET_P (flag_cunroll_grow_size))
-	flag_cunroll_grow_size = flag_unroll_loops
-				 || flag_peel_loops
-				 || optimize >= 3;
+      if (!OPTS_SET_P (flag_cunroll_grow_size))
+	OPTS (flag_cunroll_grow_size)
+	  = (OPTS (flag_unroll_loops)
+	     || OPTS (flag_peel_loops)
+	     || OPTS (optimize) >= 3);
     }
   else
     {
-      if (!OPTION_SET_P (flag_cunroll_grow_size))
-	flag_cunroll_grow_size = flag_peel_loops || optimize >= 3;
+      if (!OPTS_SET_P (flag_cunroll_grow_size))
+	OPTS (flag_cunroll_grow_size)
+	  = (OPTS (flag_peel_loops)
+	     || OPTS (optimize) >= 3);
     }
 
+#undef OPTS
+#undef OPTS_SET_P
+}
+
+/* Implement TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE hook.  */
+
+void
+ix86_override_options_after_change (void)
+{
+  ix86_default_align (&global_options);
+
+  ix86_recompute_optlev_based_flags (&global_options, &global_options_set);
+
+  ix86_override_options_after_change_1 (&global_options, &global_options_set);
 }
 
 /* Clear stack slot assignments remembered from previous functions.
@@ -2420,7 +2442,9 @@ ix86_option_override_internal (bool main_args_p,
 
   set_ix86_tune_features (opts, ix86_tune, opts->x_ix86_dump_tunes);
 
-  ix86_override_options_after_change ();
+  ix86_recompute_optlev_based_flags (opts, opts_set);
+
+  ix86_override_options_after_change_1 (opts, opts_set);
 
   ix86_tune_cost = processor_cost_table[ix86_tune];
   /* TODO: ix86_cost should be chosen at instruction or function granuality
@@ -2451,6 +2475,9 @@ ix86_option_override_internal (bool main_args_p,
       || TARGET_64BIT_P (opts->x_ix86_isa_flags))
     opts->x_ix86_regparm = REGPARM_MAX;
 
+  /* Default align_* from the processor table.  */
+  ix86_default_align (&global_options);
+
   /* Provide default for -mbranch-cost= value.  */
   SET_OPTION_IF_UNSET (opts, opts_set, ix86_branch_cost,
 		       ix86_tune_cost->branch_cost);
@@ -2488,12 +2515,6 @@ ix86_option_override_internal (bool main_args_p,
         opts->x_target_flags |= MASK_NO_RED_ZONE;
     }
 
-  /* Keep nonleaf frame pointers.  */
-  if (opts->x_flag_omit_frame_pointer)
-    opts->x_target_flags &= ~MASK_OMIT_LEAF_FRAME_POINTER;
-  else if (TARGET_OMIT_LEAF_FRAME_POINTER_P (opts->x_target_flags))
-    opts->x_flag_omit_frame_pointer = 1;
-
   /* If we're doing fast math, we don't care about comparison order
      wrt NaNs.  This lets us use a shorter comparison sequence.  */
   if (opts->x_flag_finite_math_only)
@@ -2819,6 +2840,9 @@ ix86_option_override_internal (bool main_args_p,
 	    {
 	      if (TARGET_AVX512F_P (opts->x_ix86_isa_flags))
 		opts->x_ix86_move_max = PVW_AVX512;
+	      /* Align with vectorizer to avoid potential STLF issue.  */
+	      else if (TARGET_AVX_P (opts->x_ix86_isa_flags))
+		opts->x_ix86_move_max = PVW_AVX256;
 	      else
 		opts->x_ix86_move_max = PVW_AVX128;
 	    }
@@ -2840,6 +2864,9 @@ ix86_option_override_internal (bool main_args_p,
 	    {
 	      if (TARGET_AVX512F_P (opts->x_ix86_isa_flags))
 		opts->x_ix86_store_max = PVW_AVX512;
+	      /* Align with vectorizer to avoid potential STLF issue.  */
+	      else if (TARGET_AVX_P (opts->x_ix86_isa_flags))
+		opts->x_ix86_store_max = PVW_AVX256;
 	      else
 		opts->x_ix86_store_max = PVW_AVX128;
 	    }
--- a/src/gcc/config/i386/i386.cc
+++ b/src/gcc/config/i386/i386.cc
@@ -14432,9 +14432,19 @@ ix86_dirflag_mode_needed (rtx_insn *insn)
 static bool
 ix86_check_avx_upper_register (const_rtx exp)
 {
-  return (SSE_REG_P (exp)
-	  && !EXT_REX_SSE_REG_P (exp)
-	  && GET_MODE_BITSIZE (GET_MODE (exp)) > 128);
+  /* construct_container may return a parallel with expr_list
+     which contains the real reg and mode  */
+  subrtx_iterator::array_type array;
+  FOR_EACH_SUBRTX (iter, array, exp, NONCONST)
+    {
+      const_rtx x = *iter;
+      if (SSE_REG_P (x)
+	  && !EXT_REX_SSE_REG_P (x)
+	  && GET_MODE_BITSIZE (GET_MODE (x)) > 128)
+	return true;
+    }
+
+  return false;
 }
 
 /* Check if a 256bit or 512bit AVX register is referenced in stores.   */
@@ -14442,7 +14452,9 @@ ix86_check_avx_upper_register (const_rtx exp)
 static void
 ix86_check_avx_upper_stores (rtx dest, const_rtx, void *data)
 {
-  if (ix86_check_avx_upper_register (dest))
+  if (SSE_REG_P (dest)
+      && !EXT_REX_SSE_REG_P (dest)
+      && GET_MODE_BITSIZE (GET_MODE (dest)) > 128)
     {
       bool *used = (bool *) data;
       *used = true;
@@ -14500,14 +14512,14 @@ ix86_avx_u128_mode_needed (rtx_insn *insn)
       return AVX_U128_CLEAN;
     }
 
-  subrtx_iterator::array_type array;
-
   rtx set = single_set (insn);
   if (set)
     {
       rtx dest = SET_DEST (set);
       rtx src = SET_SRC (set);
-      if (ix86_check_avx_upper_register (dest))
+      if (SSE_REG_P (dest)
+	  && !EXT_REX_SSE_REG_P (dest)
+	  && GET_MODE_BITSIZE (GET_MODE (dest)) > 128)
 	{
 	  /* This is an YMM/ZMM load.  Return AVX_U128_DIRTY if the
 	     source isn't zero.  */
@@ -14518,9 +14530,8 @@ ix86_avx_u128_mode_needed (rtx_insn *insn)
 	}
       else
 	{
-	  FOR_EACH_SUBRTX (iter, array, src, NONCONST)
-	    if (ix86_check_avx_upper_register (*iter))
-	      return AVX_U128_DIRTY;
+	  if (ix86_check_avx_upper_register (src))
+	    return AVX_U128_DIRTY;
 	}
 
       /* This isn't YMM/ZMM load/store.  */
@@ -14531,9 +14542,8 @@ ix86_avx_u128_mode_needed (rtx_insn *insn)
      Hardware changes state only when a 256bit register is written to,
      but we need to prevent the compiler from moving optimal insertion
      point above eventual read from 256bit or 512 bit register.  */
-  FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST)
-    if (ix86_check_avx_upper_register (*iter))
-      return AVX_U128_DIRTY;
+  if (ix86_check_avx_upper_register (PATTERN (insn)))
+    return AVX_U128_DIRTY;
 
   return AVX_U128_ANY;
 }
--- a/src/gcc/config/i386/i386.md
+++ b/src/gcc/config/i386/i386.md
@@ -24291,7 +24291,7 @@ (define_insn "prefetchi"
   "TARGET_PREFETCHI && TARGET_64BIT"
 {
   static const char * const patterns[2] = {
-    "prefetchit1\t%0", "prefetchit0\t%0"
+    "prefetchit1\t%a0", "prefetchit0\t%a0"
   };
 
   int locality = INTVAL (operands[1]);
--- a/src/gcc/config/i386/prfchiintrin.h
+++ b/src/gcc/config/i386/prfchiintrin.h
@@ -37,6 +37,7 @@
 #define __DISABLE_PREFETCHI__
 #endif /* __PREFETCHI__ */
 
+#ifdef __OPTIMIZE__
 extern __inline void
 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
 _m_prefetchit0 (void* __P)
@@ -50,6 +51,14 @@ _m_prefetchit1 (void* __P)
 {
   __builtin_ia32_prefetchi (__P, 2);
 }
+#else
+#define _m_prefetchit0(P)	\
+  __builtin_ia32_prefetchi(P, 3);
+
+#define _m_prefetchit1(P)	\
+  __builtin_ia32_prefetchi(P, 2);
+
+#endif
 
 #ifdef __DISABLE_PREFETCHI__
 #undef __DISABLE_PREFETCHI__
--- a/src/gcc/config/i386/x86-tune-costs.h
+++ b/src/gcc/config/i386/x86-tune-costs.h
@@ -1924,8 +1924,8 @@ struct processor_costs znver4_cost = {
 					   in 32bit, 64bit, 128bit, 256bit and 512bit */
   {8, 8, 8, 12, 12},			/* cost of storing SSE register
 					   in 32bit, 64bit, 128bit, 256bit and 512bit */
-  {6, 6, 6, 6, 6},			/* cost of unaligned loads.  */
-  {8, 8, 8, 8, 8},			/* cost of unaligned stores.  */
+  {6, 6, 10, 10, 12},			/* cost of unaligned loads.  */
+  {8, 8, 8, 12, 12},			/* cost of unaligned stores.  */
   2, 2, 2,				/* cost of moving XMM,YMM,ZMM
 					   register.  */
   6,					/* cost of moving SSE register to integer.  */
--- a/src/gcc/config/i386/x86-tune.def
+++ b/src/gcc/config/i386/x86-tune.def
@@ -518,7 +518,7 @@ DEF_TUNE (X86_TUNE_AVOID_128FMA_CHAINS, "avoid_fma_chains", m_ZNVER1 | m_ZNVER2
 /* X86_TUNE_AVOID_256FMA_CHAINS: Avoid creating loops with tight 256bit or
    smaller FMA chain.  */
 DEF_TUNE (X86_TUNE_AVOID_256FMA_CHAINS, "avoid_fma256_chains", m_ZNVER2 | m_ZNVER3
-	  | m_ALDERLAKE | m_SAPPHIRERAPIDS | m_CORE_ATOM)
+	  | m_ALDERLAKE | m_SAPPHIRERAPIDS | m_CORE_ATOM | m_GENERIC | m_ZNVER4)
 
 /* X86_TUNE_AVOID_512FMA_CHAINS: Avoid creating loops with tight 512bit or
    smaller FMA chain.  */
--- a/src/gcc/config/loongarch/loongarch.cc
+++ b/src/gcc/config/loongarch/loongarch.cc
@@ -5491,7 +5491,7 @@ loongarch_hard_regno_mode_ok_uncached (unsigned int regno, machine_mode mode)
       if (mclass == MODE_FLOAT
 	  || mclass == MODE_COMPLEX_FLOAT
 	  || mclass == MODE_VECTOR_FLOAT)
-	return size <= UNITS_PER_FPVALUE;
+	return size <= UNITS_PER_HWFPVALUE;
 
       /* Allow integer modes that fit into a single register.  We need
 	 to put integers into FPRs when using instructions like CVT
--- a/src/gcc/config/loongarch/loongarch.h
+++ b/src/gcc/config/loongarch/loongarch.h
@@ -202,13 +202,6 @@ along with GCC; see the file COPYING3.  If not see
 #define UNITS_PER_HWFPVALUE \
   (TARGET_SOFT_FLOAT ? 0 : UNITS_PER_FPREG)
 
-/* The largest size of value that can be held in floating-point
-   registers.  */
-#define UNITS_PER_FPVALUE \
-  (TARGET_SOFT_FLOAT ? 0 \
-   : TARGET_SINGLE_FLOAT ? UNITS_PER_FPREG \
-			 : LONG_DOUBLE_TYPE_SIZE / BITS_PER_UNIT)
-
 /* The number of bytes in a double.  */
 #define UNITS_PER_DOUBLE (TYPE_PRECISION (double_type_node) / BITS_PER_UNIT)
 
--- a/src/gcc/config/mips/mips.cc
+++ b/src/gcc/config/mips/mips.cc
@@ -3140,6 +3140,9 @@ mips_emit_call_insn (rtx pattern, rtx orig_addr, rtx addr, bool lazy_p)
     {
       rtx post_call_tmp_reg = gen_rtx_REG (word_mode, POST_CALL_TMP_REG);
       clobber_reg (&CALL_INSN_FUNCTION_USAGE (insn), post_call_tmp_reg);
+      clobber_reg (&CALL_INSN_FUNCTION_USAGE (insn), MIPS16_PIC_TEMP);
+      clobber_reg (&CALL_INSN_FUNCTION_USAGE (insn),
+			MIPS_PROLOGUE_TEMP (word_mode));
     }
 
   return insn;
@@ -3236,7 +3239,13 @@ mips16_gp_pseudo_reg (void)
       rtx set = gen_load_const_gp (cfun->machine->mips16_gp_pseudo_rtx);
       rtx_insn *insn = emit_insn_after (set, scan);
       INSN_LOCATION (insn) = 0;
-
+      /* NewABI support hasn't been implement.  NewABI should generate RTL
+	 sequence instead of ASM sequence directly.  */
+      if (mips_current_loadgp_style () == LOADGP_OLDABI)
+	{
+	  emit_clobber (MIPS16_PIC_TEMP);
+	  emit_clobber (MIPS_PROLOGUE_TEMP (Pmode));
+	}
       pop_topmost_sequence ();
     }
 
--- a/src/gcc/config/pa/pa.cc
+++ b/src/gcc/config/pa/pa.cc
@@ -1263,6 +1263,7 @@ hppa_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
       /* If the index adds a large constant, try to scale the
 	 constant so that it can be loaded with only one insn.  */
       if (GET_CODE (XEXP (idx, 1)) == CONST_INT
+	  && INTVAL (XEXP (idx, 1)) % (1 << shift_val) == 0
 	  && VAL_14_BITS_P (INTVAL (XEXP (idx, 1))
 			    / INTVAL (XEXP (XEXP (idx, 0), 1)))
 	  && INTVAL (XEXP (idx, 1)) % INTVAL (XEXP (XEXP (idx, 0), 1)) == 0)
--- a/src/gcc/config/pa/pa.md
+++ b/src/gcc/config/pa/pa.md
@@ -5493,24 +5493,6 @@ (define_insn "umulsidi3"
   [(set_attr "type" "fpmuldbl")
    (set_attr "length" "4")])
 
-(define_insn ""
-  [(set (match_operand:DI 0 "register_operand" "=f")
-	(mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "f"))
-		 (match_operand:DI 2 "uint32_operand" "f")))]
-  "TARGET_PA_11 && ! TARGET_SOFT_FLOAT && ! TARGET_SOFT_MULT && !TARGET_64BIT"
-  "xmpyu %1,%R2,%0"
-  [(set_attr "type" "fpmuldbl")
-   (set_attr "length" "4")])
-
-(define_insn ""
-  [(set (match_operand:DI 0 "register_operand" "=f")
-	(mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "f"))
-		 (match_operand:DI 2 "uint32_operand" "f")))]
-  "TARGET_PA_11 && ! TARGET_SOFT_FLOAT && ! TARGET_SOFT_MULT && TARGET_64BIT"
-  "xmpyu %1,%2R,%0"
-  [(set_attr "type" "fpmuldbl")
-   (set_attr "length" "4")])
-
 (define_insn ""
   [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
    (clobber (match_operand:SI 0 "register_operand" "=a"))
--- a/src/gcc/config/riscv/riscv.cc
+++ b/src/gcc/config/riscv/riscv.cc
@@ -6794,9 +6794,10 @@ riscv_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
     return promote_mode (type, mode, punsignedp);
 
   unsignedp = *punsignedp;
-  PROMOTE_MODE (as_a <scalar_mode> (mode), unsignedp, type);
+  scalar_mode smode = as_a <scalar_mode> (mode);
+  PROMOTE_MODE (smode, unsignedp, type);
   *punsignedp = unsignedp;
-  return mode;
+  return smode;
 }
 
 /* Implement TARGET_MACHINE_DEPENDENT_REORG.  */
--- a/src/gcc/config/rs6000/altivec.md
+++ b/src/gcc/config/rs6000/altivec.md
@@ -1152,15 +1152,16 @@ (define_expand "altivec_vmrghb"
    (use (match_operand:V16QI 2 "register_operand"))]
   "TARGET_ALTIVEC"
 {
-  rtx (*fun) (rtx, rtx, rtx) = BYTES_BIG_ENDIAN ? gen_altivec_vmrghb_direct
-						: gen_altivec_vmrglb_direct;
-  if (!BYTES_BIG_ENDIAN)
-    std::swap (operands[1], operands[2]);
-  emit_insn (fun (operands[0], operands[1], operands[2]));
+  if (BYTES_BIG_ENDIAN)
+    emit_insn (
+      gen_altivec_vmrghb_direct_be (operands[0], operands[1], operands[2]));
+  else
+    emit_insn (
+      gen_altivec_vmrglb_direct_le (operands[0], operands[2], operands[1]));
   DONE;
 })
 
-(define_insn "altivec_vmrghb_direct"
+(define_insn "altivec_vmrghb_direct_be"
   [(set (match_operand:V16QI 0 "register_operand" "=v")
 	(vec_select:V16QI
 	  (vec_concat:V32QI
@@ -1174,7 +1175,25 @@ (define_insn "altivec_vmrghb_direct"
 		     (const_int 5) (const_int 21)
 		     (const_int 6) (const_int 22)
 		     (const_int 7) (const_int 23)])))]
-  "TARGET_ALTIVEC"
+  "TARGET_ALTIVEC && BYTES_BIG_ENDIAN"
+  "vmrghb %0,%1,%2"
+  [(set_attr "type" "vecperm")])
+
+(define_insn "altivec_vmrghb_direct_le"
+  [(set (match_operand:V16QI 0 "register_operand" "=v")
+	(vec_select:V16QI
+	  (vec_concat:V32QI
+	    (match_operand:V16QI 2 "register_operand" "v")
+	    (match_operand:V16QI 1 "register_operand" "v"))
+	  (parallel [(const_int  8) (const_int 24)
+		     (const_int  9) (const_int 25)
+		     (const_int 10) (const_int 26)
+		     (const_int 11) (const_int 27)
+		     (const_int 12) (const_int 28)
+		     (const_int 13) (const_int 29)
+		     (const_int 14) (const_int 30)
+		     (const_int 15) (const_int 31)])))]
+  "TARGET_ALTIVEC && !BYTES_BIG_ENDIAN"
   "vmrghb %0,%1,%2"
   [(set_attr "type" "vecperm")])
 
@@ -1184,17 +1203,18 @@ (define_expand "altivec_vmrghh"
    (use (match_operand:V8HI 2 "register_operand"))]
   "TARGET_ALTIVEC"
 {
-  rtx (*fun) (rtx, rtx, rtx) = BYTES_BIG_ENDIAN ? gen_altivec_vmrghh_direct
-						: gen_altivec_vmrglh_direct;
-  if (!BYTES_BIG_ENDIAN)
-    std::swap (operands[1], operands[2]);
-  emit_insn (fun (operands[0], operands[1], operands[2]));
+  if (BYTES_BIG_ENDIAN)
+    emit_insn (
+      gen_altivec_vmrghh_direct_be (operands[0], operands[1], operands[2]));
+  else
+    emit_insn (
+      gen_altivec_vmrglh_direct_le (operands[0], operands[2], operands[1]));
   DONE;
 })
 
-(define_insn "altivec_vmrghh_direct"
+(define_insn "altivec_vmrghh_direct_be"
   [(set (match_operand:V8HI 0 "register_operand" "=v")
-        (vec_select:V8HI
+	(vec_select:V8HI
 	  (vec_concat:V16HI
 	    (match_operand:V8HI 1 "register_operand" "v")
 	    (match_operand:V8HI 2 "register_operand" "v"))
@@ -1202,7 +1222,21 @@ (define_insn "altivec_vmrghh_direct"
 		     (const_int 1) (const_int 9)
 		     (const_int 2) (const_int 10)
 		     (const_int 3) (const_int 11)])))]
-  "TARGET_ALTIVEC"
+  "TARGET_ALTIVEC && BYTES_BIG_ENDIAN"
+  "vmrghh %0,%1,%2"
+  [(set_attr "type" "vecperm")])
+
+(define_insn "altivec_vmrghh_direct_le"
+  [(set (match_operand:V8HI 0 "register_operand" "=v")
+        (vec_select:V8HI
+	  (vec_concat:V16HI
+	    (match_operand:V8HI 2 "register_operand" "v")
+	    (match_operand:V8HI 1 "register_operand" "v"))
+	  (parallel [(const_int 4) (const_int 12)
+		     (const_int 5) (const_int 13)
+		     (const_int 6) (const_int 14)
+		     (const_int 7) (const_int 15)])))]
+  "TARGET_ALTIVEC && !BYTES_BIG_ENDIAN"
   "vmrghh %0,%1,%2"
   [(set_attr "type" "vecperm")])
 
@@ -1212,16 +1246,18 @@ (define_expand "altivec_vmrghw"
    (use (match_operand:V4SI 2 "register_operand"))]
   "VECTOR_MEM_ALTIVEC_P (V4SImode)"
 {
-  rtx (*fun) (rtx, rtx, rtx);
-  fun = BYTES_BIG_ENDIAN ? gen_altivec_vmrghw_direct_v4si
-			 : gen_altivec_vmrglw_direct_v4si;
-  if (!BYTES_BIG_ENDIAN)
-    std::swap (operands[1], operands[2]);
-  emit_insn (fun (operands[0], operands[1], operands[2]));
+  if (BYTES_BIG_ENDIAN)
+    emit_insn (gen_altivec_vmrghw_direct_v4si_be (operands[0],
+						  operands[1],
+						  operands[2]));
+  else
+    emit_insn (gen_altivec_vmrglw_direct_v4si_le (operands[0],
+						  operands[2],
+						  operands[1]));
   DONE;
 })
 
-(define_insn "altivec_vmrghw_direct_<mode>"
+(define_insn "altivec_vmrghw_direct_<mode>_be"
   [(set (match_operand:VSX_W 0 "register_operand" "=wa,v")
 	(vec_select:VSX_W
 	  (vec_concat:<VS_double>
@@ -1229,7 +1265,21 @@ (define_insn "altivec_vmrghw_direct_<mode>"
 	    (match_operand:VSX_W 2 "register_operand" "wa,v"))
 	  (parallel [(const_int 0) (const_int 4)
 		     (const_int 1) (const_int 5)])))]
-  "TARGET_ALTIVEC"
+  "TARGET_ALTIVEC && BYTES_BIG_ENDIAN"
+  "@
+   xxmrghw %x0,%x1,%x2
+   vmrghw %0,%1,%2"
+  [(set_attr "type" "vecperm")])
+
+(define_insn "altivec_vmrghw_direct_<mode>_le"
+  [(set (match_operand:VSX_W 0 "register_operand" "=wa,v")
+	(vec_select:VSX_W
+	  (vec_concat:<VS_double>
+	    (match_operand:VSX_W 2 "register_operand" "wa,v")
+	    (match_operand:VSX_W 1 "register_operand" "wa,v"))
+	  (parallel [(const_int 2) (const_int 6)
+		     (const_int 3) (const_int 7)])))]
+  "TARGET_ALTIVEC && !BYTES_BIG_ENDIAN"
   "@
    xxmrghw %x0,%x1,%x2
    vmrghw %0,%1,%2"
@@ -1258,15 +1308,16 @@ (define_expand "altivec_vmrglb"
    (use (match_operand:V16QI 2 "register_operand"))]
   "TARGET_ALTIVEC"
 {
-  rtx (*fun) (rtx, rtx, rtx) = BYTES_BIG_ENDIAN ? gen_altivec_vmrglb_direct
-						: gen_altivec_vmrghb_direct;
-  if (!BYTES_BIG_ENDIAN)
-    std::swap (operands[1], operands[2]);
-  emit_insn (fun (operands[0], operands[1], operands[2]));
+  if (BYTES_BIG_ENDIAN)
+    emit_insn (
+      gen_altivec_vmrglb_direct_be (operands[0], operands[1], operands[2]));
+  else
+    emit_insn (
+      gen_altivec_vmrghb_direct_le (operands[0], operands[2], operands[1]));
   DONE;
 })
 
-(define_insn "altivec_vmrglb_direct"
+(define_insn "altivec_vmrglb_direct_be"
   [(set (match_operand:V16QI 0 "register_operand" "=v")
 	(vec_select:V16QI
 	  (vec_concat:V32QI
@@ -1280,7 +1331,25 @@ (define_insn "altivec_vmrglb_direct"
 		     (const_int 13) (const_int 29)
 		     (const_int 14) (const_int 30)
 		     (const_int 15) (const_int 31)])))]
-  "TARGET_ALTIVEC"
+  "TARGET_ALTIVEC && BYTES_BIG_ENDIAN"
+  "vmrglb %0,%1,%2"
+  [(set_attr "type" "vecperm")])
+
+(define_insn "altivec_vmrglb_direct_le"
+  [(set (match_operand:V16QI 0 "register_operand" "=v")
+	(vec_select:V16QI
+	  (vec_concat:V32QI
+	    (match_operand:V16QI 2 "register_operand" "v")
+	    (match_operand:V16QI 1 "register_operand" "v"))
+	  (parallel [(const_int 0) (const_int 16)
+		     (const_int 1) (const_int 17)
+		     (const_int 2) (const_int 18)
+		     (const_int 3) (const_int 19)
+		     (const_int 4) (const_int 20)
+		     (const_int 5) (const_int 21)
+		     (const_int 6) (const_int 22)
+		     (const_int 7) (const_int 23)])))]
+  "TARGET_ALTIVEC && !BYTES_BIG_ENDIAN"
   "vmrglb %0,%1,%2"
   [(set_attr "type" "vecperm")])
 
@@ -1290,15 +1359,16 @@ (define_expand "altivec_vmrglh"
    (use (match_operand:V8HI 2 "register_operand"))]
   "TARGET_ALTIVEC"
 {
-  rtx (*fun) (rtx, rtx, rtx) = BYTES_BIG_ENDIAN ? gen_altivec_vmrglh_direct
-						: gen_altivec_vmrghh_direct;
-  if (!BYTES_BIG_ENDIAN)
-    std::swap (operands[1], operands[2]);
-  emit_insn (fun (operands[0], operands[1], operands[2]));
+  if (BYTES_BIG_ENDIAN)
+    emit_insn (
+      gen_altivec_vmrglh_direct_be (operands[0], operands[1], operands[2]));
+  else
+    emit_insn (
+      gen_altivec_vmrghh_direct_le (operands[0], operands[2], operands[1]));
   DONE;
 })
 
-(define_insn "altivec_vmrglh_direct"
+(define_insn "altivec_vmrglh_direct_be"
   [(set (match_operand:V8HI 0 "register_operand" "=v")
         (vec_select:V8HI
 	  (vec_concat:V16HI
@@ -1308,7 +1378,21 @@ (define_insn "altivec_vmrglh_direct"
 		     (const_int 5) (const_int 13)
 		     (const_int 6) (const_int 14)
 		     (const_int 7) (const_int 15)])))]
-  "TARGET_ALTIVEC"
+  "TARGET_ALTIVEC && BYTES_BIG_ENDIAN"
+  "vmrglh %0,%1,%2"
+  [(set_attr "type" "vecperm")])
+
+(define_insn "altivec_vmrglh_direct_le"
+  [(set (match_operand:V8HI 0 "register_operand" "=v")
+	(vec_select:V8HI
+	  (vec_concat:V16HI
+	    (match_operand:V8HI 2 "register_operand" "v")
+	    (match_operand:V8HI 1 "register_operand" "v"))
+	  (parallel [(const_int 0) (const_int 8)
+		     (const_int 1) (const_int 9)
+		     (const_int 2) (const_int 10)
+		     (const_int 3) (const_int 11)])))]
+  "TARGET_ALTIVEC && !BYTES_BIG_ENDIAN"
   "vmrglh %0,%1,%2"
   [(set_attr "type" "vecperm")])
 
@@ -1318,16 +1402,18 @@ (define_expand "altivec_vmrglw"
    (use (match_operand:V4SI 2 "register_operand"))]
   "VECTOR_MEM_ALTIVEC_P (V4SImode)"
 {
-  rtx (*fun) (rtx, rtx, rtx);
-  fun = BYTES_BIG_ENDIAN ? gen_altivec_vmrglw_direct_v4si
-			 : gen_altivec_vmrghw_direct_v4si;
-  if (!BYTES_BIG_ENDIAN)
-    std::swap (operands[1], operands[2]);
-  emit_insn (fun (operands[0], operands[1], operands[2]));
+  if (BYTES_BIG_ENDIAN)
+    emit_insn (gen_altivec_vmrglw_direct_v4si_be (operands[0],
+						  operands[1],
+						  operands[2]));
+  else
+    emit_insn (gen_altivec_vmrghw_direct_v4si_le (operands[0],
+						  operands[2],
+						  operands[1]));
   DONE;
 })
 
-(define_insn "altivec_vmrglw_direct_<mode>"
+(define_insn "altivec_vmrglw_direct_<mode>_be"
   [(set (match_operand:VSX_W 0 "register_operand" "=wa,v")
 	(vec_select:VSX_W
 	  (vec_concat:<VS_double>
@@ -1335,7 +1421,21 @@ (define_insn "altivec_vmrglw_direct_<mode>"
 	    (match_operand:VSX_W 2 "register_operand" "wa,v"))
 	  (parallel [(const_int 2) (const_int 6)
 		     (const_int 3) (const_int 7)])))]
-  "TARGET_ALTIVEC"
+  "TARGET_ALTIVEC && BYTES_BIG_ENDIAN"
+  "@
+   xxmrglw %x0,%x1,%x2
+   vmrglw %0,%1,%2"
+  [(set_attr "type" "vecperm")])
+
+(define_insn "altivec_vmrglw_direct_<mode>_le"
+  [(set (match_operand:VSX_W 0 "register_operand" "=wa,v")
+	(vec_select:VSX_W
+	  (vec_concat:<VS_double>
+	    (match_operand:VSX_W 2 "register_operand" "wa,v")
+	    (match_operand:VSX_W 1 "register_operand" "wa,v"))
+	  (parallel [(const_int 0) (const_int 4)
+		     (const_int 1) (const_int 5)])))]
+  "TARGET_ALTIVEC && !BYTES_BIG_ENDIAN"
   "@
    xxmrglw %x0,%x1,%x2
    vmrglw %0,%1,%2"
@@ -3707,13 +3807,13 @@ (define_expand "vec_widen_umult_hi_v16qi"
     {
       emit_insn (gen_altivec_vmuleub (ve, operands[1], operands[2]));
       emit_insn (gen_altivec_vmuloub (vo, operands[1], operands[2]));
-      emit_insn (gen_altivec_vmrghh_direct (operands[0], ve, vo));
+      emit_insn (gen_altivec_vmrghh (operands[0], ve, vo));
     }
   else
     {
       emit_insn (gen_altivec_vmuloub (ve, operands[1], operands[2]));
       emit_insn (gen_altivec_vmuleub (vo, operands[1], operands[2]));
-      emit_insn (gen_altivec_vmrghh_direct (operands[0], vo, ve));
+      emit_insn (gen_altivec_vmrglh (operands[0], ve, vo));
     }
   DONE;
 })
@@ -3732,13 +3832,13 @@ (define_expand "vec_widen_umult_lo_v16qi"
     {
       emit_insn (gen_altivec_vmuleub (ve, operands[1], operands[2]));
       emit_insn (gen_altivec_vmuloub (vo, operands[1], operands[2]));
-      emit_insn (gen_altivec_vmrglh_direct (operands[0], ve, vo));
+      emit_insn (gen_altivec_vmrglh (operands[0], ve, vo));
     }
   else
     {
       emit_insn (gen_altivec_vmuloub (ve, operands[1], operands[2]));
       emit_insn (gen_altivec_vmuleub (vo, operands[1], operands[2]));
-      emit_insn (gen_altivec_vmrglh_direct (operands[0], vo, ve));
+      emit_insn (gen_altivec_vmrghh (operands[0], ve, vo));
     }
   DONE;
 })
@@ -3757,13 +3857,13 @@ (define_expand "vec_widen_smult_hi_v16qi"
     {
       emit_insn (gen_altivec_vmulesb (ve, operands[1], operands[2]));
       emit_insn (gen_altivec_vmulosb (vo, operands[1], operands[2]));
-      emit_insn (gen_altivec_vmrghh_direct (operands[0], ve, vo));
+      emit_insn (gen_altivec_vmrghh (operands[0], ve, vo));
     }
   else
     {
       emit_insn (gen_altivec_vmulosb (ve, operands[1], operands[2]));
       emit_insn (gen_altivec_vmulesb (vo, operands[1], operands[2]));
-      emit_insn (gen_altivec_vmrghh_direct (operands[0], vo, ve));
+      emit_insn (gen_altivec_vmrglh (operands[0], ve, vo));
     }
   DONE;
 })
@@ -3782,13 +3882,13 @@ (define_expand "vec_widen_smult_lo_v16qi"
     {
       emit_insn (gen_altivec_vmulesb (ve, operands[1], operands[2]));
       emit_insn (gen_altivec_vmulosb (vo, operands[1], operands[2]));
-      emit_insn (gen_altivec_vmrglh_direct (operands[0], ve, vo));
+      emit_insn (gen_altivec_vmrglh (operands[0], ve, vo));
     }
   else
     {
       emit_insn (gen_altivec_vmulosb (ve, operands[1], operands[2]));
       emit_insn (gen_altivec_vmulesb (vo, operands[1], operands[2]));
-      emit_insn (gen_altivec_vmrglh_direct (operands[0], vo, ve));
+      emit_insn (gen_altivec_vmrghh (operands[0], ve, vo));
     }
   DONE;
 })
@@ -3807,13 +3907,13 @@ (define_expand "vec_widen_umult_hi_v8hi"
     {
       emit_insn (gen_altivec_vmuleuh (ve, operands[1], operands[2]));
       emit_insn (gen_altivec_vmulouh (vo, operands[1], operands[2]));
-      emit_insn (gen_altivec_vmrghw_direct_v4si (operands[0], ve, vo));
+      emit_insn (gen_altivec_vmrghw (operands[0], ve, vo));
     }
   else
     {
       emit_insn (gen_altivec_vmulouh (ve, operands[1], operands[2]));
       emit_insn (gen_altivec_vmuleuh (vo, operands[1], operands[2]));
-      emit_insn (gen_altivec_vmrghw_direct_v4si (operands[0], vo, ve));
+      emit_insn (gen_altivec_vmrglw (operands[0], ve, vo));
     }
   DONE;
 })
@@ -3832,13 +3932,13 @@ (define_expand "vec_widen_umult_lo_v8hi"
     {
       emit_insn (gen_altivec_vmuleuh (ve, operands[1], operands[2]));
       emit_insn (gen_altivec_vmulouh (vo, operands[1], operands[2]));
-      emit_insn (gen_altivec_vmrglw_direct_v4si (operands[0], ve, vo));
+      emit_insn (gen_altivec_vmrglw (operands[0], ve, vo));
     }
   else
     {
       emit_insn (gen_altivec_vmulouh (ve, operands[1], operands[2]));
       emit_insn (gen_altivec_vmuleuh (vo, operands[1], operands[2]));
-      emit_insn (gen_altivec_vmrglw_direct_v4si (operands[0], vo, ve));
+      emit_insn (gen_altivec_vmrghw (operands[0], ve, vo));
     }
   DONE;
 })
@@ -3857,13 +3957,13 @@ (define_expand "vec_widen_smult_hi_v8hi"
     {
       emit_insn (gen_altivec_vmulesh (ve, operands[1], operands[2]));
       emit_insn (gen_altivec_vmulosh (vo, operands[1], operands[2]));
-      emit_insn (gen_altivec_vmrghw_direct_v4si (operands[0], ve, vo));
+      emit_insn (gen_altivec_vmrghw (operands[0], ve, vo));
     }
   else
     {
       emit_insn (gen_altivec_vmulosh (ve, operands[1], operands[2]));
       emit_insn (gen_altivec_vmulesh (vo, operands[1], operands[2]));
-      emit_insn (gen_altivec_vmrghw_direct_v4si (operands[0], vo, ve));
+      emit_insn (gen_altivec_vmrglw (operands[0], ve, vo));
     }
   DONE;
 })
@@ -3882,13 +3982,13 @@ (define_expand "vec_widen_smult_lo_v8hi"
     {
       emit_insn (gen_altivec_vmulesh (ve, operands[1], operands[2]));
       emit_insn (gen_altivec_vmulosh (vo, operands[1], operands[2]));
-      emit_insn (gen_altivec_vmrglw_direct_v4si (operands[0], ve, vo));
+      emit_insn (gen_altivec_vmrglw (operands[0], ve, vo));
     }
   else
     {
       emit_insn (gen_altivec_vmulosh (ve, operands[1], operands[2]));
       emit_insn (gen_altivec_vmulesh (vo, operands[1], operands[2]));
-      emit_insn (gen_altivec_vmrglw_direct_v4si (operands[0], vo, ve));
+      emit_insn (gen_altivec_vmrghw (operands[0], ve, vo));
     }
   DONE;
 })
--- a/src/gcc/config/rs6000/rs6000-builtin.cc
+++ b/src/gcc/config/rs6000/rs6000-builtin.cc
@@ -845,7 +845,7 @@ rs6000_init_builtins (void)
 	  enum rs6000_gen_builtins fn_code = (enum rs6000_gen_builtins) i;
 	  if (!rs6000_builtin_is_supported (fn_code))
 	    continue;
-	  tree fntype = rs6000_builtin_info[i].fntype;
+	  tree fntype = rs6000_builtin_info_fntype[i];
 	  tree t = TREE_TYPE (fntype);
 	  fprintf (stderr, "%s %s (", rs6000_type_string (t),
 		   rs6000_builtin_info[i].bifname);
--- a/src/gcc/config/rs6000/rs6000-c.cc
+++ b/src/gcc/config/rs6000/rs6000-c.cc
@@ -1658,34 +1658,37 @@ resolve_vec_step (resolution *res, vec<tree, va_gc> *arglist, unsigned nargs)
    UNSUPPORTED_BUILTIN to true.  If we don't match, return error_mark_node
    and leave UNSUPPORTED_BUILTIN alone.  */
 
-tree
-find_instance (bool *unsupported_builtin, ovlddata **instance,
+static tree
+find_instance (bool *unsupported_builtin, int *instance,
 	       rs6000_gen_builtins instance_code,
 	       rs6000_gen_builtins fcode,
 	       tree *types, tree *args)
 {
-  while (*instance && (*instance)->bifid != instance_code)
-    *instance = (*instance)->next;
+  while (*instance != -1
+	 && rs6000_instance_info[*instance].bifid != instance_code)
+    *instance = rs6000_instance_info[*instance].next;
 
-  ovlddata *inst = *instance;
-  gcc_assert (inst != NULL);
+  int inst = *instance;
+  gcc_assert (inst != -1);
   /* It is possible for an instance to require a data type that isn't
-     defined on this target, in which case inst->fntype will be NULL.  */
-  if (!inst->fntype)
+     defined on this target, in which case rs6000_instance_info_fntype[inst]
+     will be NULL.  */
+  if (!rs6000_instance_info_fntype[inst])
     return error_mark_node;
-  tree fntype = rs6000_builtin_info[inst->bifid].fntype;
+  rs6000_gen_builtins bifid = rs6000_instance_info[inst].bifid;
+  tree fntype = rs6000_builtin_info_fntype[bifid];
   tree parmtype0 = TREE_VALUE (TYPE_ARG_TYPES (fntype));
   tree parmtype1 = TREE_VALUE (TREE_CHAIN (TYPE_ARG_TYPES (fntype)));
 
   if (rs6000_builtin_type_compatible (types[0], parmtype0)
       && rs6000_builtin_type_compatible (types[1], parmtype1))
     {
-      if (rs6000_builtin_decl (inst->bifid, false) != error_mark_node
-	  && rs6000_builtin_is_supported (inst->bifid))
+      if (rs6000_builtin_decl (bifid, false) != error_mark_node
+	  && rs6000_builtin_is_supported (bifid))
 	{
-	  tree ret_type = TREE_TYPE (inst->fntype);
+	  tree ret_type = TREE_TYPE (rs6000_instance_info_fntype[inst]);
 	  return altivec_build_resolved_builtin (args, 2, fntype, ret_type,
-						 inst->bifid, fcode);
+						 bifid, fcode);
 	}
       else
 	*unsupported_builtin = true;
@@ -1868,11 +1871,11 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
   bool unsupported_builtin = false;
   rs6000_gen_builtins instance_code;
   bool supported = false;
-  ovlddata *instance = rs6000_overload_info[adj_fcode].first_instance;
-  gcc_assert (instance != NULL);
+  int instance = rs6000_overload_info[adj_fcode].first_instance;
+  gcc_assert (instance != -1);
 
   /* Functions with no arguments can have only one overloaded instance.  */
-  gcc_assert (nargs > 0 || !instance->next);
+  gcc_assert (nargs > 0 || rs6000_instance_info[instance].next == -1);
 
   /* Standard overload processing involves determining whether an instance
      exists that is type-compatible with the overloaded function call.  In
@@ -1946,16 +1949,18 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
       /* Standard overload processing.  Look for an instance with compatible
 	 parameter types.  If it is supported in the current context, resolve
 	 the overloaded call to that instance.  */
-      for (; instance != NULL; instance = instance->next)
+      for (; instance != -1; instance = rs6000_instance_info[instance].next)
 	{
+	  tree fntype = rs6000_instance_info_fntype[instance];
+	  rs6000_gen_builtins bifid = rs6000_instance_info[instance].bifid;
 	  /* It is possible for an instance to require a data type that isn't
-	     defined on this target, in which case instance->fntype will be
+	     defined on this target, in which case fntype will be
 	     NULL.  */
-	  if (!instance->fntype)
+	  if (!fntype)
 	    continue;
 
 	  bool mismatch = false;
-	  tree nextparm = TYPE_ARG_TYPES (instance->fntype);
+	  tree nextparm = TYPE_ARG_TYPES (fntype);
 
 	  for (unsigned int arg_i = 0;
 	       arg_i < nargs && nextparm != NULL;
@@ -1973,15 +1978,14 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
 	  if (mismatch)
 	    continue;
 
-	  supported = rs6000_builtin_is_supported (instance->bifid);
-	  if (rs6000_builtin_decl (instance->bifid, false) != error_mark_node
+	  supported = rs6000_builtin_is_supported (bifid);
+	  if (rs6000_builtin_decl (bifid, false) != error_mark_node
 	      && supported)
 	    {
-	      tree fntype = rs6000_builtin_info[instance->bifid].fntype;
-	      tree ret_type = TREE_TYPE (instance->fntype);
+	      tree ret_type = TREE_TYPE (fntype);
+	      fntype = rs6000_builtin_info_fntype[bifid];
 	      return altivec_build_resolved_builtin (args, nargs, fntype,
-						     ret_type, instance->bifid,
-						     fcode);
+						     ret_type, bifid, fcode);
 	    }
 	  else
 	    {
@@ -1998,12 +2002,12 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
 	{
 	  /* Indicate that the instantiation of the overloaded builtin
 	     name is not available with the target flags in effect.  */
-	  rs6000_gen_builtins fcode = (rs6000_gen_builtins) instance->bifid;
+	  rs6000_gen_builtins bifid = rs6000_instance_info[instance].bifid;
+	  rs6000_gen_builtins fcode = (rs6000_gen_builtins) bifid;
 	  rs6000_invalid_builtin (fcode);
 	  /* Provide clarity of the relationship between the overload
 	     and the instantiation.  */
-	  const char *internal_name
-	    = rs6000_builtin_info[instance->bifid].bifname;
+	  const char *internal_name = rs6000_builtin_info[bifid].bifname;
 	  rich_location richloc (line_table, input_location);
 	  inform (&richloc,
 		  "overloaded builtin %qs is implemented by builtin %qs",
--- a/src/gcc/config/rs6000/rs6000-gen-builtins.cc
+++ b/src/gcc/config/rs6000/rs6000-gen-builtins.cc
@@ -2261,20 +2261,19 @@ write_decls (void)
   fprintf (header_file, "};\n\n");
 
   fprintf (header_file, "#define PPC_MAXRESTROPNDS 3\n");
-  fprintf (header_file, "struct GTY(()) bifdata\n");
+  fprintf (header_file, "struct bifdata\n");
   fprintf (header_file, "{\n");
-  fprintf (header_file, "  const char *GTY((skip(\"\"))) bifname;\n");
-  fprintf (header_file, "  bif_enable GTY((skip(\"\"))) enable;\n");
-  fprintf (header_file, "  tree fntype;\n");
-  fprintf (header_file, "  insn_code GTY((skip(\"\"))) icode;\n");
-  fprintf (header_file, "  int  nargs;\n");
-  fprintf (header_file, "  int  bifattrs;\n");
-  fprintf (header_file, "  int  restr_opnd[PPC_MAXRESTROPNDS];\n");
-  fprintf (header_file, "  restriction GTY((skip(\"\"))) restr[PPC_MAXRESTROPNDS];\n");
-  fprintf (header_file, "  int  restr_val1[PPC_MAXRESTROPNDS];\n");
-  fprintf (header_file, "  int  restr_val2[PPC_MAXRESTROPNDS];\n");
-  fprintf (header_file, "  const char *GTY((skip(\"\"))) attr_string;\n");
-  fprintf (header_file, "  rs6000_gen_builtins GTY((skip(\"\"))) assoc_bif;\n");
+  fprintf (header_file, "  const char *bifname;\n");
+  fprintf (header_file, "  bif_enable enable;\n");
+  fprintf (header_file, "  insn_code icode;\n");
+  fprintf (header_file, "  int nargs;\n");
+  fprintf (header_file, "  int bifattrs;\n");
+  fprintf (header_file, "  int restr_opnd[PPC_MAXRESTROPNDS];\n");
+  fprintf (header_file, "  restriction restr[PPC_MAXRESTROPNDS];\n");
+  fprintf (header_file, "  int restr_val1[PPC_MAXRESTROPNDS];\n");
+  fprintf (header_file, "  int restr_val2[PPC_MAXRESTROPNDS];\n");
+  fprintf (header_file, "  const char *attr_string;\n");
+  fprintf (header_file, "  rs6000_gen_builtins assoc_bif;\n");
   fprintf (header_file, "};\n\n");
 
   fprintf (header_file, "#define bif_init_bit\t\t(0x00000001)\n");
@@ -2353,24 +2352,28 @@ write_decls (void)
   fprintf (header_file, "\n");
 
   fprintf (header_file,
-	   "extern GTY(()) bifdata rs6000_builtin_info[RS6000_BIF_MAX];\n\n");
+	   "extern bifdata rs6000_builtin_info[RS6000_BIF_MAX];\n\n");
 
-  fprintf (header_file, "struct GTY(()) ovlddata\n");
+  fprintf (header_file,
+	   "extern GTY(()) tree rs6000_builtin_info_fntype[RS6000_BIF_MAX];\n\n");
+
+  fprintf (header_file, "struct ovlddata\n");
   fprintf (header_file, "{\n");
-  fprintf (header_file, "  const char *GTY((skip(\"\"))) bifname;\n");
-  fprintf (header_file, "  rs6000_gen_builtins GTY((skip(\"\"))) bifid;\n");
-  fprintf (header_file, "  tree fntype;\n");
-  fprintf (header_file, "  ovlddata *GTY((skip(\"\"))) next;\n");
+  fprintf (header_file, "  const char *bifname;\n");
+  fprintf (header_file, "  rs6000_gen_builtins bifid;\n");
+  fprintf (header_file, "  int next;\n");
   fprintf (header_file, "};\n\n");
 
   fprintf (header_file, "struct ovldrecord\n");
   fprintf (header_file, "{\n");
   fprintf (header_file, "  const char *ovld_name;\n");
-  fprintf (header_file, "  ovlddata *first_instance;\n");
+  fprintf (header_file, "  int first_instance;\n");
   fprintf (header_file, "};\n\n");
 
   fprintf (header_file,
-	   "extern GTY(()) ovlddata rs6000_instance_info[RS6000_INST_MAX];\n");
+	   "extern ovlddata rs6000_instance_info[RS6000_INST_MAX];\n");
+  fprintf (header_file, "extern GTY(()) tree "
+	   "rs6000_instance_info_fntype[RS6000_INST_MAX];\n");
   fprintf (header_file, "extern ovldrecord rs6000_overload_info[];\n\n");
 
   fprintf (header_file, "extern void rs6000_init_generated_builtins ();\n\n");
@@ -2481,7 +2484,7 @@ write_bif_static_init (void)
   fprintf (init_file, "bifdata rs6000_builtin_info[RS6000_BIF_MAX] =\n");
   fprintf (init_file, "  {\n");
   fprintf (init_file, "    { /* RS6000_BIF_NONE: */\n");
-  fprintf (init_file, "      \"\", ENB_ALWAYS, 0, CODE_FOR_nothing, 0,\n");
+  fprintf (init_file, "      \"\", ENB_ALWAYS, CODE_FOR_nothing, 0,\n");
   fprintf (init_file, "      0, {0, 0, 0}, {RES_NONE, RES_NONE, RES_NONE},\n");
   fprintf (init_file, "      {0, 0, 0}, {0, 0, 0}, \"\", RS6000_BIF_NONE\n");
   fprintf (init_file, "    },\n");
@@ -2493,8 +2496,6 @@ write_bif_static_init (void)
 	       bifp->proto.bifname);
       fprintf (init_file, "      /* enable*/\t%s,\n",
 	       enable_string[bifp->stanza]);
-      /* Type must be instantiated at run time.  */
-      fprintf (init_file, "      /* fntype */\t0,\n");
       fprintf (init_file, "      /* icode */\tCODE_FOR_%s,\n",
 	       bifp->patname);
       fprintf (init_file, "      /* nargs */\t%d,\n",
@@ -2586,6 +2587,8 @@ write_bif_static_init (void)
       fprintf (init_file, "    },\n");
     }
   fprintf (init_file, "  };\n\n");
+
+  fprintf (init_file, "tree rs6000_builtin_info_fntype[RS6000_BIF_MAX];\n\n");
 }
 
 /* Write the decls and initializers for rs6000_overload_info[] and
@@ -2598,7 +2601,7 @@ write_ovld_static_init (void)
 	   "- RS6000_OVLD_NONE] =\n");
   fprintf (init_file, "  {\n");
   fprintf (init_file, "    { /* RS6000_OVLD_NONE: */\n");
-  fprintf (init_file, "      \"\", NULL\n");
+  fprintf (init_file, "      \"\", -1\n");
   fprintf (init_file, "    },\n");
   for (int i = 0; i <= curr_ovld_stanza; i++)
     {
@@ -2607,7 +2610,7 @@ write_ovld_static_init (void)
       fprintf (init_file, "      /* ovld_name */\t\"%s\",\n",
 	       ovld_stanzas[i].intern_name);
       /* First-instance must currently be instantiated at run time.  */
-      fprintf (init_file, "      /* first_instance */\tNULL\n");
+      fprintf (init_file, "      /* first_instance */\t-1\n");
       fprintf (init_file, "    },\n");
     }
   fprintf (init_file, "  };\n\n");
@@ -2615,7 +2618,7 @@ write_ovld_static_init (void)
   fprintf (init_file, "ovlddata rs6000_instance_info[RS6000_INST_MAX] =\n");
   fprintf (init_file, "  {\n");
   fprintf (init_file, "    { /* RS6000_INST_NONE: */\n");
-  fprintf (init_file, "      \"\", RS6000_BIF_NONE, NULL_TREE, NULL\n");
+  fprintf (init_file, "      \"\", RS6000_BIF_NONE, -1\n");
   fprintf (init_file, "    },\n");
   for (int i = 0; i <= curr_ovld; i++)
     {
@@ -2625,19 +2628,20 @@ write_ovld_static_init (void)
 	       ovlds[i].proto.bifname);
       fprintf (init_file, "      /* bifid */\tRS6000_BIF_%s,\n",
 	       ovlds[i].bif_id_name);
-      /* Type must be instantiated at run time.  */
-      fprintf (init_file, "      /* fntype */\t0,\n");
       fprintf (init_file, "      /* next */\t");
       if (i < curr_ovld
 	  && !strcmp (ovlds[i+1].proto.bifname, ovlds[i].proto.bifname))
 	fprintf (init_file,
-		 "&rs6000_instance_info[RS6000_INST_%s]\n",
+		 "RS6000_INST_%s\n",
 		 ovlds[i+1].ovld_id_name);
       else
-	fprintf (init_file, "NULL\n");
+	fprintf (init_file, "-1\n");
       fprintf (init_file, "    },\n");
     }
   fprintf (init_file, "  };\n\n");
+
+  fprintf (init_file,
+	   "tree rs6000_instance_info_fntype[RS6000_INST_MAX];\n\n");
 }
 
 /* Write code to initialize the built-in function table.  */
@@ -2647,7 +2651,7 @@ write_init_bif_table (void)
   for (int i = 0; i <= curr_bif; i++)
     {
       fprintf (init_file,
-	       "  rs6000_builtin_info[RS6000_BIF_%s].fntype"
+	       "  rs6000_builtin_info_fntype[RS6000_BIF_%s]"
 	       "\n    = %s;\n",
 	       bifs[i].idname, bifs[i].fndecl);
 
@@ -2736,7 +2740,7 @@ write_init_ovld_table (void)
   for (int i = 0; i <= curr_ovld; i++)
     {
       fprintf (init_file,
-	       "  rs6000_instance_info[RS6000_INST_%s].fntype"
+	       "  rs6000_instance_info_fntype[RS6000_INST_%s]"
 	       "\n    = %s;\n",
 	       ovlds[i].ovld_id_name, ovlds[i].fndecl);
 
@@ -2793,7 +2797,7 @@ write_init_ovld_table (void)
 		   ".first_instance\n",
 		   stanza->stanza_id);
 	  fprintf (init_file,
-		   "    = &rs6000_instance_info[RS6000_INST_%s];\n\n",
+		   "    = RS6000_INST_%s;\n\n",
 		   ovlds[i].ovld_id_name);
 	}
     }
--- a/src/gcc/config/rs6000/rs6000-logue.cc
+++ b/src/gcc/config/rs6000/rs6000-logue.cc
@@ -591,21 +591,21 @@ rs6000_savres_strategy (rs6000_stack_t *info,
 		+---------------------------------------+
 		| Parameter save area (+padding*) (P)	|  32
 		+---------------------------------------+
-		| Optional ROP hash slot (R)		|  32+P
+		| Alloca space (A)			|  32+P
 		+---------------------------------------+
-		| Alloca space (A)			|  32+P+R
+		| Local variable space (L)		|  32+P+A
 		+---------------------------------------+
-		| Local variable space (L)		|  32+P+R+A
+		| Optional ROP hash slot (R)		|  32+P+A+L
 		+---------------------------------------+
-		| Save area for AltiVec registers (W)	|  32+P+R+A+L
+		| Save area for AltiVec registers (W)	|  32+P+A+L+R
 		+---------------------------------------+
-		| AltiVec alignment padding (Y)		|  32+P+R+A+L+W
+		| AltiVec alignment padding (Y)		|  32+P+A+L+R+W
 		+---------------------------------------+
-		| Save area for GP registers (G)	|  32+P+R+A+L+W+Y
+		| Save area for GP registers (G)	|  32+P+A+L+R+W+Y
 		+---------------------------------------+
-		| Save area for FP registers (F)	|  32+P+R+A+L+W+Y+G
+		| Save area for FP registers (F)	|  32+P+A+L+R+W+Y+G
 		+---------------------------------------+
-	old SP->| back chain to caller's caller		|  32+P+R+A+L+W+Y+G+F
+	old SP->| back chain to caller's caller		|  32+P+A+L+R+W+Y+G+F
 		+---------------------------------------+
 
      * If the alloca area is present, the parameter save area is
@@ -716,17 +716,11 @@ rs6000_stack_info (void)
   info->calls_p = (!crtl->is_leaf || cfun->machine->ra_needs_full_frame);
   info->rop_hash_size = 0;
 
-  if (TARGET_POWER10
-      && info->calls_p
-      && DEFAULT_ABI == ABI_ELFv2
-      && rs6000_rop_protect)
+  /* If we want ROP protection and this function makes a call, indicate
+     we need to create a stack slot to save the hashed return address in.  */
+  if (rs6000_rop_protect
+      && info->calls_p)
     info->rop_hash_size = 8;
-  else if (rs6000_rop_protect && DEFAULT_ABI != ABI_ELFv2)
-    {
-      /* We can't check this in rs6000_option_override_internal since
-	 DEFAULT_ABI isn't established yet.  */
-      error ("%qs requires the ELFv2 ABI", "-mrop-protect");
-    }
 
   /* Determine if we need to save the condition code registers.  */
   if (save_reg_p (CR2_REGNO)
@@ -817,17 +811,16 @@ rs6000_stack_info (void)
 	  gcc_assert (info->altivec_size == 0
 		      || info->altivec_save_offset % 16 == 0);
 
-	  /* Adjust for AltiVec case.  */
-	  info->ehrd_offset = info->altivec_save_offset - ehrd_size;
-
 	  /* Adjust for ROP protection.  */
 	  info->rop_hash_save_offset
 	    = info->altivec_save_offset - info->rop_hash_size;
-	  info->ehrd_offset -= info->rop_hash_size;
 	}
       else
-	info->ehrd_offset = info->gp_save_offset - ehrd_size;
+	  /* Adjust for ROP protection.  */
+	  info->rop_hash_save_offset
+	    = info->gp_save_offset - info->rop_hash_size;
 
+      info->ehrd_offset = info->rop_hash_save_offset - ehrd_size;
       info->ehcr_offset = info->ehrd_offset - ehcr_size;
       info->cr_save_offset = reg_size; /* first word when 64-bit.  */
       info->lr_save_offset = 2*reg_size;
@@ -3276,9 +3269,8 @@ rs6000_emit_prologue (void)
   /* NOTE: The hashst isn't needed if we're going to do a sibcall,
      but there's no way to know that here.  Harmless except for
      performance, of course.  */
-  if (TARGET_POWER10 && rs6000_rop_protect && info->rop_hash_size != 0)
+  if (info->rop_hash_size)
     {
-      gcc_assert (DEFAULT_ABI == ABI_ELFv2);
       rtx stack_ptr = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
       rtx addr = gen_rtx_PLUS (Pmode, stack_ptr,
 			       GEN_INT (info->rop_hash_save_offset));
@@ -4311,9 +4303,6 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type)
 
   rs6000_stack_t *info = rs6000_stack_info ();
 
-  if (epilogue_type == EPILOGUE_TYPE_NORMAL && crtl->calls_eh_return)
-    epilogue_type = EPILOGUE_TYPE_EH_RETURN;
-
   int strategy = info->savres_strategy;
   bool using_load_multiple = !!(strategy & REST_MULTIPLE);
   bool restoring_GPRs_inline = !!(strategy & REST_INLINE_GPRS);
@@ -4791,7 +4780,9 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type)
 
   /* In the ELFv2 ABI we need to restore all call-saved CR fields from
      *separate* slots if the routine calls __builtin_eh_return, so
-     that they can be independently restored by the unwinder.  */
+     that they can be independently restored by the unwinder.  Since
+     it is for CR fields restoring, it should be done for any epilogue
+     types (not EPILOGUE_TYPE_EH_RETURN specific).  */
   if (DEFAULT_ABI == ABI_ELFv2 && crtl->calls_eh_return)
     {
       int i, cr_off = info->ehcr_offset;
@@ -5056,12 +5047,9 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type)
 
   /* The ROP hash check must occur after the stack pointer is restored
      (since the hash involves r1), and is not performed for a sibcall.  */
-  if (TARGET_POWER10
-      && rs6000_rop_protect
-      && info->rop_hash_size != 0
+  if (info->rop_hash_size
       && epilogue_type != EPILOGUE_TYPE_SIBCALL)
     {
-      gcc_assert (DEFAULT_ABI == ABI_ELFv2);
       rtx stack_ptr = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
       rtx addr = gen_rtx_PLUS (Pmode, stack_ptr,
 			       GEN_INT (info->rop_hash_save_offset));
--- a/src/gcc/config/rs6000/rs6000.cc
+++ b/src/gcc/config/rs6000/rs6000.cc
@@ -4850,6 +4850,18 @@ rs6000_option_override_internal (bool global_init_p)
 	}
     }
 
+  /* We only support ROP protection on certain targets.  */
+  if (rs6000_rop_protect)
+    {
+      /* Disallow CPU targets we don't support.  */
+      if (!TARGET_POWER8)
+	error ("%<-mrop-protect%> requires %<-mcpu=power8%> or later");
+
+      /* Disallow ABI targets we don't support.  */
+      if (DEFAULT_ABI != ABI_ELFv2)
+	error ("%<-mrop-protect%> requires the ELFv2 ABI");
+    }
+
   /* Initialize all of the registers.  */
   rs6000_init_hard_regno_mode_ok (global_init_p);
 
@@ -5894,7 +5906,8 @@ rs6000_machine_from_flags (void)
   HOST_WIDE_INT flags = rs6000_isa_flags;
 
   /* Disable the flags that should never influence the .machine selection.  */
-  flags &= ~(OPTION_MASK_PPC_GFXOPT | OPTION_MASK_PPC_GPOPT | OPTION_MASK_ISEL);
+  flags &= ~(OPTION_MASK_PPC_GFXOPT | OPTION_MASK_PPC_GPOPT | OPTION_MASK_ISEL
+	     | OPTION_MASK_ALTIVEC);
 
   if ((flags & (ISA_3_1_MASKS_SERVER & ~ISA_3_0_MASKS_SERVER)) != 0)
     return "power10";
@@ -5919,6 +5932,8 @@ void
 emit_asm_machine (void)
 {
   fprintf (asm_out_file, "\t.machine %s\n", rs6000_machine);
+  if (TARGET_ALTIVEC)
+    fprintf (asm_out_file, "\t.machine altivec\n");
 }
 #endif
 
@@ -23166,28 +23181,28 @@ altivec_expand_vec_perm_const (rtx target, rtx op0, rtx op1,
      CODE_FOR_altivec_vpkuwum_direct,
      {2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27, 30, 31}},
     {OPTION_MASK_ALTIVEC,
-     BYTES_BIG_ENDIAN ? CODE_FOR_altivec_vmrghb_direct
-		      : CODE_FOR_altivec_vmrglb_direct,
+     BYTES_BIG_ENDIAN ? CODE_FOR_altivec_vmrghb_direct_be
+		      : CODE_FOR_altivec_vmrglb_direct_le,
      {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23}},
     {OPTION_MASK_ALTIVEC,
-     BYTES_BIG_ENDIAN ? CODE_FOR_altivec_vmrghh_direct
-		      : CODE_FOR_altivec_vmrglh_direct,
+     BYTES_BIG_ENDIAN ? CODE_FOR_altivec_vmrghh_direct_be
+		      : CODE_FOR_altivec_vmrglh_direct_le,
      {0, 1, 16, 17, 2, 3, 18, 19, 4, 5, 20, 21, 6, 7, 22, 23}},
     {OPTION_MASK_ALTIVEC,
-     BYTES_BIG_ENDIAN ? CODE_FOR_altivec_vmrghw_direct_v4si
-		      : CODE_FOR_altivec_vmrglw_direct_v4si,
+     BYTES_BIG_ENDIAN ? CODE_FOR_altivec_vmrghw_direct_v4si_be
+		      : CODE_FOR_altivec_vmrglw_direct_v4si_le,
      {0, 1, 2, 3, 16, 17, 18, 19, 4, 5, 6, 7, 20, 21, 22, 23}},
     {OPTION_MASK_ALTIVEC,
-     BYTES_BIG_ENDIAN ? CODE_FOR_altivec_vmrglb_direct
-		      : CODE_FOR_altivec_vmrghb_direct,
+     BYTES_BIG_ENDIAN ? CODE_FOR_altivec_vmrglb_direct_be
+		      : CODE_FOR_altivec_vmrghb_direct_le,
      {8, 24, 9, 25, 10, 26, 11, 27, 12, 28, 13, 29, 14, 30, 15, 31}},
     {OPTION_MASK_ALTIVEC,
-     BYTES_BIG_ENDIAN ? CODE_FOR_altivec_vmrglh_direct
-		      : CODE_FOR_altivec_vmrghh_direct,
+     BYTES_BIG_ENDIAN ? CODE_FOR_altivec_vmrglh_direct_be
+		      : CODE_FOR_altivec_vmrghh_direct_le,
      {8, 9, 24, 25, 10, 11, 26, 27, 12, 13, 28, 29, 14, 15, 30, 31}},
     {OPTION_MASK_ALTIVEC,
-     BYTES_BIG_ENDIAN ? CODE_FOR_altivec_vmrglw_direct_v4si
-		      : CODE_FOR_altivec_vmrghw_direct_v4si,
+     BYTES_BIG_ENDIAN ? CODE_FOR_altivec_vmrglw_direct_v4si_be
+		      : CODE_FOR_altivec_vmrghw_direct_v4si_le,
      {8, 9, 10, 11, 24, 25, 26, 27, 12, 13, 14, 15, 28, 29, 30, 31}},
     {OPTION_MASK_P8_VECTOR,
      BYTES_BIG_ENDIAN ? CODE_FOR_p8_vmrgew_v4sf_direct
--- a/src/gcc/config/rs6000/rs6000.md
+++ b/src/gcc/config/rs6000/rs6000.md
@@ -14147,6 +14147,8 @@ (define_expand "eh_return"
   ""
 {
   emit_insn (gen_eh_set_lr (Pmode, operands[0]));
+  emit_jump_insn (gen_eh_return_internal ());
+  emit_barrier ();
   DONE;
 })
 
@@ -14163,6 +14165,19 @@ (define_insn_and_split "@eh_set_lr_<mode>"
   DONE;
 })
 
+(define_insn_and_split "eh_return_internal"
+  [(eh_return)]
+  ""
+  "#"
+  "epilogue_completed"
+  [(const_int 0)]
+{
+  if (!TARGET_SCHED_PROLOG)
+    emit_insn (gen_blockage ());
+  rs6000_emit_epilogue (EPILOGUE_TYPE_EH_RETURN);
+  DONE;
+})
+
 (define_insn "prefetch"
   [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
 	     (match_operand:SI 1 "const_int_operand" "n")
@@ -15650,9 +15665,9 @@ (define_insn "*cmpeqb_internal"
 
 (define_insn "hashst"
   [(set (match_operand:DI 0 "simple_offsettable_mem_operand" "=m")
-        (unspec_volatile:DI [(match_operand:DI 1 "int_reg_operand" "r")]
+	(unspec_volatile:DI [(match_operand:DI 1 "int_reg_operand" "r")]
 			    UNSPEC_HASHST))]
-  "TARGET_POWER10 && rs6000_rop_protect"
+  "rs6000_rop_protect"
 {
   static char templ[32];
   const char *p = rs6000_privileged ? "p" : "";
@@ -15665,7 +15680,7 @@ (define_insn "hashchk"
   [(unspec_volatile [(match_operand:DI 0 "int_reg_operand" "r")
 		     (match_operand:DI 1 "simple_offsettable_mem_operand" "m")]
 		    UNSPEC_HASHCHK)]
-  "TARGET_POWER10 && rs6000_rop_protect"
+  "rs6000_rop_protect"
 {
   static char templ[32];
   const char *p = rs6000_privileged ? "p" : "";
--- a/src/gcc/config/rs6000/vsx.md
+++ b/src/gcc/config/rs6000/vsx.md
@@ -4683,12 +4683,14 @@ (define_expand "vsx_xxmrghw_<mode>"
 		     (const_int 1) (const_int 5)])))]
   "VECTOR_MEM_VSX_P (<MODE>mode)"
 {
-  rtx (*fun) (rtx, rtx, rtx);
-  fun = BYTES_BIG_ENDIAN ? gen_altivec_vmrghw_direct_<mode>
-			 : gen_altivec_vmrglw_direct_<mode>;
-  if (!BYTES_BIG_ENDIAN)
-    std::swap (operands[1], operands[2]);
-  emit_insn (fun (operands[0], operands[1], operands[2]));
+  if (BYTES_BIG_ENDIAN)
+    emit_insn (gen_altivec_vmrghw_direct_v4si_be (operands[0],
+						  operands[1],
+						  operands[2]));
+  else
+    emit_insn (gen_altivec_vmrglw_direct_v4si_le (operands[0],
+						  operands[2],
+						  operands[1]));
   DONE;
 }
   [(set_attr "type" "vecperm")])
@@ -4703,12 +4705,14 @@ (define_expand "vsx_xxmrglw_<mode>"
 		     (const_int 3) (const_int 7)])))]
   "VECTOR_MEM_VSX_P (<MODE>mode)"
 {
-  rtx (*fun) (rtx, rtx, rtx);
-  fun = BYTES_BIG_ENDIAN ? gen_altivec_vmrglw_direct_<mode>
-			 : gen_altivec_vmrghw_direct_<mode>;
-  if (!BYTES_BIG_ENDIAN)
-    std::swap (operands[1], operands[2]);
-  emit_insn (fun (operands[0], operands[1], operands[2]));
+  if (BYTES_BIG_ENDIAN)
+    emit_insn (gen_altivec_vmrglw_direct_v4si_be (operands[0],
+						  operands[1],
+						  operands[2]));
+  else
+    emit_insn (gen_altivec_vmrghw_direct_v4si_le (operands[0],
+						  operands[2],
+						  operands[1]));
   DONE;
 }
   [(set_attr "type" "vecperm")])
--- a/src/gcc/config/s390/3931.md
+++ b/src/gcc/config/s390/3931.md
@@ -404,7 +404,6 @@ (define_attr "z16_unit_fxb" ""
 vlvgh,
 vlvgp,
 vst,
-vstbr,
 vstbrf,
 vstbrg,
 vstbrh,
@@ -627,7 +626,6 @@ (define_attr "z16_unit_lsu" ""
 tmy,
 vl,
 vlbb,
-vlbr,
 vlbrf,
 vlbrg,
 vlbrh,
@@ -661,7 +659,6 @@ (define_attr "z16_unit_lsu" ""
 vlrl,
 vlrlr,
 vst,
-vstbr,
 vstbrf,
 vstbrg,
 vstbrh,
@@ -1077,7 +1074,6 @@ (define_attr "z16_unit_vfu" ""
 vrepf,
 vrepg,
 vreph,
-vrepi,
 vrepib,
 vrepif,
 vrepig,
@@ -1930,7 +1926,6 @@ (define_insn_reservation "z16_1" 1
 vrepf,
 vrepg,
 vreph,
-vrepi,
 vrepib,
 vrepif,
 vrepig,
@@ -2156,7 +2151,6 @@ (define_insn_reservation "z16_3" 3
 vistrhs,
 vl,
 vlbb,
-vlbr,
 vlbrf,
 vlbrg,
 vlbrh,
@@ -2248,7 +2242,6 @@ (define_insn_reservation "z16_4" 4
 tbeginc,
 tend,
 vst,
-vstbr,
 vstbrf,
 vstbrg,
 vstbrh,
--- a/src/gcc/config/s390/s390.md
+++ b/src/gcc/config/s390/s390.md
@@ -744,7 +744,7 @@ (define_mode_attr xde [(TF "x") (FPRX2 "x") (DF "d") (SF "e") (TD "x")
 ;; In FP templates, a <dee> in "m<dee><bt>r" will expand to "mx<bt>r" in
 ;; TF/TDmode, "md<bt>r" in DF/DDmode, "mee<bt>r" in SFmode and "me<bt>r in
 ;; SDmode.
-(define_mode_attr xdee [(TF "x") (DF "d") (SF "ee") (TD "x") (DD "d") (SD "e")])
+(define_mode_attr xdee [(TF "x") (FPRX2 "x") (DF "d") (SF "ee") (TD "x") (DD "d") (SD "e")])
 
 ;; The decimal floating point variants of add, sub, div and mul support 3
 ;; fp register operands.  The following attributes allow to merge the bfp and
@@ -9480,7 +9480,8 @@ (define_insn "*c<code>"
 (define_insn "*icjump_64"
   [(set (pc)
         (if_then_else
-          (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
+          (match_operator 1 "s390_comparison" [(reg CC_REGNUM)
+					       (match_operand 2 "const_int_operand" "")])
           (pc)
           (label_ref (match_operand 0 "" ""))))]
   ""
--- a/src/gcc/config/s390/vector.md
+++ b/src/gcc/config/s390/vector.md
@@ -134,7 +134,7 @@ (define_mode_attr bhfgq[(V1QI "b") (V2QI "b") (V4QI "b") (V8QI "b") (V16QI "b")
 			(V1TI "q") (TI "q")
 			(V1SF "f") (V2SF "f") (V4SF "f")
 			(V1DF "g") (V2DF "g")
-			(V1TF "q")])
+			(V1TF "q") (TF "q")])
 
 ; This is for vmalhw. It gets an 'w' attached to avoid confusion with
 ; multiply and add logical high vmalh.
@@ -359,8 +359,8 @@ (define_insn "mov<mode>"
    lr\t%0,%1
    mvi\t%0,0
    mviy\t%0,0
-   mvi\t%0,-1
-   mviy\t%0,-1
+   mvi\t%0,255
+   mviy\t%0,255
    lhi\t%0,0
    lhi\t%0,-1
    llc\t%0,%1
--- a/src/gcc/config/sh/sh.cc
+++ b/src/gcc/config/sh/sh.cc
@@ -12279,7 +12279,17 @@ sh_recog_treg_set_expr (rtx op, machine_mode mode)
      have to capture its current state and restore it afterwards.  */
   recog_data_d prev_recog_data = recog_data;
 
-  rtx_insn* i = make_insn_raw (gen_rtx_SET (get_t_reg_rtx (), op));
+  /* Note we can't use insn_raw here since that increases the uid
+     and could cause debug compare differences; this insn never leaves
+     this function so create a dummy one. */
+  rtx_insn* i = as_a <rtx_insn *> (rtx_alloc (INSN));
+
+  INSN_UID (i) = 1;
+  PATTERN (i) = gen_rtx_SET (get_t_reg_rtx (), op);
+  INSN_CODE (i) = -1;
+  REG_NOTES (i) = NULL;
+  INSN_LOCATION (i) = curr_insn_location ();
+  BLOCK_FOR_INSN (i) = NULL;
   SET_PREV_INSN (i) = NULL;
   SET_NEXT_INSN (i) = NULL;
 
--- a/src/gcc/cp/ChangeLog
+++ b/src/gcc/cp/ChangeLog
@@ -1,3 +1,49 @@
+2024-08-09  Patrick Palka  <ppalka@redhat.com>
+
+	PR c++/113063
+	PR c++/116289
+	* method.cc (synthesize_method): Use cp_evaluated.
+
+2024-06-17  Jakub Jelinek  <jakub@redhat.com>
+
+	Backported from master:
+	2024-06-17  Jakub Jelinek  <jakub@redhat.com>
+
+	PR target/111343
+	PR c++/115511
+	* typeck.cc (cp_compare_floating_point_conversion_ranks): If an
+	extended floating point type mv1 has same set of values as more
+	than one standard floating point type and mv2 is float, return 2.
+
+2024-05-24  Jason Merrill  <jason@redhat.com>
+
+	Backported from master:
+	2023-09-22  Jason Merrill  <jason@redhat.com>
+
+	PR c++/111529
+	* parser.cc (cp_parser_lambda_declarator_opt): Don't suggest
+	-std=c++14 for lambda templates.
+	* pt.cc (tsubst_expr): Move ANNOTATE_EXPR handling...
+	(tsubst_copy_and_build): ...here.
+
+2024-05-24  Jason Merrill  <jason@redhat.com>
+
+	Backported from master:
+	2024-01-25  Jason Merrill  <jason@redhat.com>
+
+	PR c++/113598
+	* init.cc (build_vec_init): Don't use {} for PMF.
+
+2024-05-21  Jonathan Wakely  <jwakely@redhat.com>
+
+	Backported from master:
+	2024-05-21  Jonathan Wakely  <jwakely@redhat.com>
+
+	PR libstdc++/107800
+	* cxxapi-data.csv <to_address>: Change dialect to cxx20.
+	* std-name-hint.gperf: Regenerate.
+	* std-name-hint.h: Regenerate.
+
 2024-05-21  Release Manager
 
 	* GCC 13.3.0 released.
--- a/src/gcc/cp/cxxapi-data.csv
+++ b/src/gcc/cp/cxxapi-data.csv
@@ -460,7 +460,7 @@
 # unimplemented <mdspan>,default_accessor,1,no
 # unimplemented <mdspan>,mdspan,1,cxx23
 <memory>,pointer_traits,1,cxx11
-<memory>,to_address,1,cxx11
+<memory>,to_address,1,cxx20
 <memory>,align,1,cxx11
 <memory>,assume_aligned,1,cxx20
 <memory>,allocator_arg_t,1,cxx11
--- a/src/gcc/cp/init.cc
+++ b/src/gcc/cp/init.cc
@@ -4859,7 +4859,9 @@ build_vec_init (tree base, tree maxindex, tree init,
 	 But for non-classes, that's the same as value-initialization.  */
       if (empty_list)
 	{
-	  if (cxx_dialect >= cxx11 && AGGREGATE_TYPE_P (type))
+	  if (cxx_dialect >= cxx11
+	      && (CLASS_TYPE_P (type)
+		  || TREE_CODE (type) == ARRAY_TYPE))
 	    {
 	      init = build_constructor (init_list_type_node, NULL);
 	    }
--- a/src/gcc/cp/method.cc
+++ b/src/gcc/cp/method.cc
@@ -1797,6 +1797,7 @@ synthesize_method (tree fndecl)
      it now.  */
   push_deferring_access_checks (dk_no_deferred);
 
+  cp_evaluated ev;
   if (! context)
     push_to_top_level ();
   else if (nested)
--- a/src/gcc/cp/parser.cc
+++ b/src/gcc/cp/parser.cc
@@ -11558,11 +11558,8 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
      an opening angle if present.  */
   if (cp_lexer_next_token_is (parser->lexer, CPP_LESS))
     {
-      if (cxx_dialect < cxx14)
-	pedwarn (parser->lexer->next_token->location, OPT_Wc__14_extensions,
-		 "lambda templates are only available with "
-		 "%<-std=c++14%> or %<-std=gnu++14%>");
-      else if (pedantic && cxx_dialect < cxx20)
+      if (cxx_dialect < cxx20
+	  && (pedantic || cxx_dialect < cxx14))
 	pedwarn (parser->lexer->next_token->location, OPT_Wc__20_extensions,
 		 "lambda templates are only available with "
 		 "%<-std=c++20%> or %<-std=gnu++20%>");
--- a/src/gcc/cp/pt.cc
+++ b/src/gcc/cp/pt.cc
@@ -19926,13 +19926,6 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 				    templated_operator_saved_lookups (t),
 				    complain));
 
-    case ANNOTATE_EXPR:
-      tmp = RECUR (TREE_OPERAND (t, 0));
-      RETURN (build3_loc (EXPR_LOCATION (t), ANNOTATE_EXPR,
-			  TREE_TYPE (tmp), tmp,
-			  RECUR (TREE_OPERAND (t, 1)),
-			  RECUR (TREE_OPERAND (t, 2))));
-
     case PREDICT_EXPR:
       RETURN (add_stmt (copy_node (t)));
 
@@ -21862,6 +21855,13 @@ tsubst_copy_and_build (tree t,
 	RETURN (op);
       }
 
+    case ANNOTATE_EXPR:
+      op1 = RECUR (TREE_OPERAND (t, 0));
+      RETURN (build3_loc (EXPR_LOCATION (t), ANNOTATE_EXPR,
+			  TREE_TYPE (op1), op1,
+			  RECUR (TREE_OPERAND (t, 1)),
+			  RECUR (TREE_OPERAND (t, 2))));
+
     default:
       /* Handle Objective-C++ constructs, if appropriate.  */
       {
--- a/src/gcc/cp/std-name-hint.gperf
+++ b/src/gcc/cp/std-name-hint.gperf
@@ -220,7 +220,7 @@ pointer_traits, "<memory>", cxx11
 reinterpret_pointer_cast, "<memory>", cxx17
 shared_ptr, "<memory>", cxx11
 static_pointer_cast, "<memory>", cxx11
-to_address, "<memory>", cxx11
+to_address, "<memory>", cxx20
 uninitialized_construct_using_allocator, "<memory>", cxx20
 unique_ptr, "<memory>", cxx11
 uses_allocator, "<memory>", cxx11
--- a/src/gcc/cp/std-name-hint.h
+++ b/src/gcc/cp/std-name-hint.h
@@ -291,7 +291,7 @@ std_name_hint_lookup::find (const char *str, size_t len)
 #line 472 "std-name-hint.gperf"
       {"variant_npos", "<variant>", cxx17},
 #line 223 "std-name-hint.gperf"
-      {"to_address", "<memory>", cxx11},
+      {"to_address", "<memory>", cxx20},
 #line 460 "std-name-hint.gperf"
       {"pair", "<utility>", cxx98},
 #line 269 "std-name-hint.gperf"
--- a/src/gcc/cp/typeck.cc
+++ b/src/gcc/cp/typeck.cc
@@ -393,6 +393,9 @@ cp_compare_floating_point_conversion_ranks (tree t1, tree t2)
      has higher rank.  */
   if (cnt > 1 && mv2 == long_double_type_node)
     return -2;
+  /* And similarly if t2 is float, t2 has lower rank.  */
+  if (cnt > 1 && mv2 == float_type_node)
+    return 2;
   /* Otherwise, they have equal rank, but extended types
      (other than std::bfloat16_t) have higher subrank.
      std::bfloat16_t shouldn't have equal rank to any standard
--- a/src/gcc/cse.cc
+++ b/src/gcc/cse.cc
@@ -239,7 +239,7 @@ static int next_qty;
    the constant being compared against, or zero if the comparison
    is not against a constant.  `comparison_qty' holds the quantity
    being compared against when the result is known.  If the comparison
-   is not with a register, `comparison_qty' is -1.  */
+   is not with a register, `comparison_qty' is INT_MIN.  */
 
 struct qty_table_elem
 {
@@ -4068,7 +4068,7 @@ record_jump_cond (enum rtx_code code, machine_mode mode, rtx op0,
       else
 	{
 	  ent->comparison_const = op1;
-	  ent->comparison_qty = -1;
+	  ent->comparison_qty = INT_MIN;
 	}
 
       return;
--- a/src/gcc/expmed.cc
+++ b/src/gcc/expmed.cc
@@ -5607,11 +5607,9 @@ emit_store_flag_1 (rtx target, enum rtx_code code, rtx op0, rtx op1,
   enum insn_code icode;
   machine_mode compare_mode;
   enum mode_class mclass;
-  enum rtx_code scode;
 
   if (unsignedp)
     code = unsigned_condition (code);
-  scode = swap_condition (code);
 
   /* If one operand is constant, make it the second one.  Only do this
      if the other operand is not constant as well.  */
@@ -5726,6 +5724,8 @@ emit_store_flag_1 (rtx target, enum rtx_code code, rtx op0, rtx op1,
 
 	  if (GET_MODE_CLASS (mode) == MODE_FLOAT)
 	    {
+	      enum rtx_code scode = swap_condition (code);
+
 	      tem = emit_cstore (target, icode, scode, mode, compare_mode,
 				 unsignedp, op1, op0, normalizep, target_mode);
 	      if (tem)
--- a/src/gcc/fold-const.cc
+++ b/src/gcc/fold-const.cc
@@ -85,6 +85,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "vec-perm-indices.h"
 #include "asan.h"
 #include "gimple-range.h"
+#include "internal-fn.h"
 
 /* Nonzero if we are folding constants inside an initializer or a C++
    manifestly-constant-evaluated context; zero otherwise.
@@ -14887,7 +14888,6 @@ tree_call_nonnegative_warnv_p (tree type, combined_fn fn, tree arg0, tree arg1,
     CASE_CFN_FFS:
     CASE_CFN_PARITY:
     CASE_CFN_POPCOUNT:
-    CASE_CFN_CLZ:
     CASE_CFN_CLRSB:
     case CFN_BUILT_IN_BSWAP16:
     case CFN_BUILT_IN_BSWAP32:
@@ -14896,6 +14896,22 @@ tree_call_nonnegative_warnv_p (tree type, combined_fn fn, tree arg0, tree arg1,
       /* Always true.  */
       return true;
 
+    CASE_CFN_CLZ:
+      if (fn != CFN_CLZ)
+	return true;
+      else if (INTEGRAL_TYPE_P (TREE_TYPE (arg0)))
+	{
+	  tree atype = TREE_TYPE (arg0);
+	  int val = 0;
+	  if (direct_internal_fn_supported_p (IFN_CLZ, atype,
+					      OPTIMIZE_FOR_BOTH)
+              && CLZ_DEFINED_VALUE_AT_ZERO (SCALAR_INT_TYPE_MODE (atype),
+                                            val) == 2
+	      && val >= 0)
+	    return true;
+	}
+      break;
+
     CASE_CFN_SQRT:
     CASE_CFN_SQRT_FN:
       /* sqrt(-0.0) is -0.0.  */
--- a/src/gcc/fortran/ChangeLog
+++ b/src/gcc/fortran/ChangeLog
@@ -1,3 +1,150 @@
+2024-08-05  Paul Thomas  <pault@gcc.gnu.org>
+
+	Backported from master:
+	2024-07-18  Paul Thomas  <pault@gcc.gnu.org>
+
+	PR fortran/108889
+	* gfortran.h: Add bit field 'allocated_in_scope' to gfc_symbol.
+	* trans-array.cc (gfc_array_allocate): Set 'allocated_in_scope'
+	after allocation if not a component reference.
+	(gfc_alloc_allocatable_for_assignment): If 'allocated_in_scope'
+	not set, not a component ref and not allocated, set the array
+	bounds and offset to give zero length in all dimensions. Then
+	set allocated_in_scope.
+
+2024-07-21  Harald Anlauf  <anlauf@gmx.de>
+
+	Backported from master:
+	2024-07-19  Harald Anlauf  <anlauf@gmx.de>
+
+	PR fortran/103115
+	* trans-array.cc (gfc_trans_array_constructor_value): If the first
+	element of an array constructor is deferred-length character and
+	therefore does not have an element size known at compile time, do
+	not try to collect subsequent constant elements into a constructor
+	for optimization.
+
+2024-07-20  Paul Thomas  <pault@gcc.gnu.org>
+
+	Backported from master:
+	2024-05-13  Paul Thomas  <pault@gcc.gnu.org>
+
+	PR fortran/113363
+	* trans-array.cc (gfc_array_init_size): Use the expr3 dtype so
+	that the correct element size is used.
+	* trans-expr.cc (gfc_conv_procedure_call): Remove restriction
+	that ss and ss->loop be present for the finalization of class
+	array function results.
+	(trans_class_assignment): Use free and malloc, rather than
+	realloc, for character expressions assigned to unlimited poly
+	entities.
+	* trans-stmt.cc (gfc_trans_allocate): Build a correct rhs for
+	the assignment of an unlimited polymorphic 'source'.
+
+2024-07-12  Paul Thomas  <pault@gcc.gnu.org>
+
+	Backported from master:
+	2024-05-23  Paul Thomas  <pault@gcc.gnu.org>
+
+	PR fortran/103312
+	* dependency.cc (gfc_dep_compare_expr): Handle component call
+	expressions. Return -2 as default and return 0 if compared with
+	a function expression that is from an interface body and has
+	the same name.
+	* expr.cc (gfc_reduce_init_expr): If the expression is a comp
+	call do not attempt to reduce, defer to resolution and return
+	false.
+	* trans-types.cc (gfc_get_dtype_rank_type,
+	gfc_get_nodesc_array_type): Fix whitespace.
+
+2024-07-08  Paul Thomas  <pault@gcc.gnu.org>
+
+	Backported from master:
+	2024-05-12  Paul Thomas  <pault@gcc.gnu.org>
+
+	PR fortran/84006
+	PR fortran/100027
+	PR fortran/98534
+	* iresolve.cc (gfc_resolve_transfer): Emit a TODO error for
+	unlimited polymorphic mold.
+	* trans-expr.cc (gfc_resize_class_size_with_len): Use the fold
+	even if a block is not available in which to fix the result.
+	(trans_class_assignment): Enable correct assignment of
+	character expressions to unlimited polymorphic variables using
+	lhs _len field and rse string_length.
+	* trans-intrinsic.cc (gfc_conv_intrinsic_storage_size): Extract
+	the class expression so that the unlimited polymorphic class
+	expression can be used in gfc_resize_class_size_with_len to
+	obtain the storage size for character payloads. Guard the use
+	of GFC_DECL_SAVED_DESCRIPTOR by testing for DECL_LANG_SPECIFIC
+	to prevent the ICE. Also, invert the order to use the class
+	expression extracted from the argument.
+	(gfc_conv_intrinsic_transfer): In same way as 'storage_size',
+	use the _len field to obtaining the correct length for arg 1.
+	Add a branch for the element size in bytes of class expressions
+	with provision to make use of the unlimited polymorphic _len
+	field. Again, the class references are explicitly identified.
+	'mold_expr' was already declared. Use it instead of 'arg'. Do
+	not fix 'dest_word_len' for deferred character sources because
+	reallocation on assign makes use of it before it is assigned.
+
+2024-06-19  Harald Anlauf  <anlauf@gmx.de>
+
+	Backported from master:
+	2024-06-04  Harald Anlauf  <anlauf@gmx.de>
+
+	PR fortran/83865
+	* trans-stmt.cc (gfc_trans_allocate): Restrict special case for
+	source-expression with zero-length character to rank 0, so that
+	the array shape is not discarded.
+
+2024-05-28  Tobias Burnus  <tburnus@baylibre.com>
+
+	Backported from master:
+	2024-05-20  Tobias Burnus  <tburnus@baylibre.com>
+
+	PR fortran/115150
+	* trans-intrinsic.cc (gfc_conv_intrinsic_bound): Fix SHAPE
+	for zero-size arrays
+
+2024-05-22  Harald Anlauf  <anlauf@gmx.de>
+
+	Backported from master:
+	2024-05-05  Harald Anlauf  <anlauf@gmx.de>
+
+	PR fortran/114827
+	* trans-array.cc (gfc_alloc_allocatable_for_assignment): Take into
+	account _len of unlimited polymorphic entities when calculating
+	the effective element size for allocation size and array span.
+	Set _len of lhs to _len of rhs.
+	* trans-expr.cc (trans_class_assignment): Take into account _len
+	of unlimited polymorphic entities for allocation size.
+
+2024-05-22  Andrew Jenner  <andrew@codesourcery.com>
+
+	Backported from master:
+	2023-11-28  Andrew Jenner  <andrew@codesourcery.com>
+		    Tobias Burnus   <tobias@codesourcery.com>
+
+	PR fortran/110415
+	* trans-expr.cc (trans_class_vptr_len_assignment): Add
+	from_vptrp parameter. Populate it. Don't check for DECL_P
+	when deciding whether to create temporary.
+	(trans_class_pointer_fcn, gfc_trans_pointer_assignment): Add
+	NULL argument to trans_class_vptr_len_assignment calls.
+	(trans_class_assignment): Get rhs_vptr from
+	trans_class_vptr_len_assignment and use it for determining size
+	for allocation/reallocation. Use return value from realloc.
+
+2024-05-21  Harald Anlauf  <anlauf@gmx.de>
+
+	Backported from master:
+	2024-05-11  Harald Anlauf  <anlauf@gmx.de>
+
+	PR fortran/115039
+	* expr.cc (gfc_traverse_expr): An inquiry ref does not constitute
+	a dependency and cannot collide with a symbol.
+
 2024-05-21  Release Manager
 
 	* GCC 13.3.0 released.
--- a/src/gcc/fortran/dependency.cc
+++ b/src/gcc/fortran/dependency.cc
@@ -440,6 +440,38 @@ gfc_dep_compare_expr (gfc_expr *e1, gfc_expr *e2)
 	return mpz_sgn (e2->value.op.op2->value.integer);
     }
 
+
+  if (e1->expr_type == EXPR_COMPCALL)
+    {
+      /* This will have emerged from interface.cc(gfc_check_typebound_override)
+	 via gfc_check_result_characteristics. It is possible that other
+	 variants exist that are 'equal' but play it safe for now by setting
+	 the relationship as 'indeterminate'.  */
+      if (e2->expr_type == EXPR_FUNCTION && e2->ref)
+	{
+	  gfc_ref *ref = e2->ref;
+	  gfc_symbol *s = NULL;
+
+	  if (e1->value.compcall.tbp->u.specific)
+	    s = e1->value.compcall.tbp->u.specific->n.sym;
+
+	  /* Check if the proc ptr points to an interface declaration and the
+	     names are the same; ie. the overriden proc. of an abstract type.
+	     The checking of the arguments will already have been done.  */
+	  for (; ref && s; ref = ref->next)
+	    if (!ref->next && ref->type == REF_COMPONENT
+		&& ref->u.c.component->attr.proc_pointer
+		&& ref->u.c.component->ts.interface
+		&& ref->u.c.component->ts.interface->attr.if_source
+							== IFSRC_IFBODY
+		&& !strcmp (s->name, ref->u.c.component->name))
+	      return 0;
+	}
+
+      /* Assume as default that TKR checking is sufficient.  */
+     return -2;
+  }
+
   if (e1->expr_type != e2->expr_type)
     return -3;
 
--- a/src/gcc/fortran/expr.cc
+++ b/src/gcc/fortran/expr.cc
@@ -3188,6 +3188,11 @@ gfc_reduce_init_expr (gfc_expr *expr)
 {
   bool t;
 
+  /* It is far too early to resolve a class compcall. Punt to resolution.  */
+  if (expr && expr->expr_type == EXPR_COMPCALL
+      && expr->symtree->n.sym->ts.type == BT_CLASS)
+    return false;
+
   gfc_init_expr_flag = true;
   t = gfc_resolve_expr (expr);
   if (t)
@@ -5483,7 +5488,7 @@ gfc_traverse_expr (gfc_expr *expr, gfc_symbol *sym,
 	  break;
 
 	case REF_INQUIRY:
-	  return true;
+	  return false;
 
 	default:
 	  gcc_unreachable ();
--- a/src/gcc/fortran/gfortran.h
+++ b/src/gcc/fortran/gfortran.h
@@ -1927,6 +1927,10 @@ typedef struct gfc_symbol
   /* Set if this should be passed by value, but is not a VALUE argument
      according to the Fortran standard.  */
   unsigned pass_as_value:1;
+  /* Set if an allocatable array variable has been allocated in the current
+     scope. Used in the suppression of uninitialized warnings in reallocation
+     on assignment.  */
+  unsigned allocated_in_scope:1;
 
   int refs;
   struct gfc_namespace *ns;	/* namespace containing this symbol */
--- a/src/gcc/fortran/iresolve.cc
+++ b/src/gcc/fortran/iresolve.cc
@@ -3017,6 +3017,10 @@ gfc_resolve_transfer (gfc_expr *f, gfc_expr *source ATTRIBUTE_UNUSED,
 	}
     }
 
+  if (UNLIMITED_POLY (mold))
+    gfc_error ("TODO: unlimited polymorphic MOLD in TRANSFER intrinsic at %L",
+	       &mold->where);
+
   f->ts = mold->ts;
 
   if (size == NULL && mold->rank == 0)
--- a/src/gcc/fortran/trans-array.cc
+++ b/src/gcc/fortran/trans-array.cc
@@ -2119,7 +2119,9 @@ gfc_trans_array_constructor_value (stmtblock_t * pblock,
 	      p = gfc_constructor_next (p);
 	      n++;
 	    }
-	  if (n < 4)
+	  /* Constructor with few constant elements, or element size not
+	     known at compile time (e.g. deferred-length character).  */
+	  if (n < 4 || !INTEGER_CST_P (TYPE_SIZE_UNIT (type)))
 	    {
 	      /* Scalar values.  */
 	      gfc_init_se (&se, NULL);
@@ -5795,6 +5797,11 @@ gfc_array_init_size (tree descriptor, int rank, int corank, tree * poffset,
       tmp = gfc_conv_descriptor_dtype (descriptor);
       gfc_add_modify (pblock, tmp, gfc_get_dtype_rank_type (rank, type));
     }
+  else if (expr3_desc && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (expr3_desc)))
+    {
+      tmp = gfc_conv_descriptor_dtype (descriptor);
+      gfc_add_modify (pblock, tmp, gfc_conv_descriptor_dtype (expr3_desc));
+    }
   else
     {
       tmp = gfc_conv_descriptor_dtype (descriptor);
@@ -6334,6 +6341,8 @@ gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree status, tree errmsg,
   else
       gfc_add_expr_to_block (&se->pre, set_descriptor);
 
+  expr->symtree->n.sym->allocated_in_scope = 1;
+
   return true;
 }
 
@@ -10638,6 +10647,8 @@ gfc_alloc_allocatable_for_assignment (gfc_loopinfo *loop,
   stmtblock_t realloc_block;
   stmtblock_t alloc_block;
   stmtblock_t fblock;
+  stmtblock_t loop_pre_block;
+  gfc_ref *ref;
   gfc_ss *rss;
   gfc_ss *lss;
   gfc_array_info *linfo;
@@ -10838,6 +10849,45 @@ gfc_alloc_allocatable_for_assignment (gfc_loopinfo *loop,
 			 array1, build_int_cst (TREE_TYPE (array1), 0));
   cond_null= gfc_evaluate_now (cond_null, &fblock);
 
+  /* If the data is null, set the descriptor bounds and offset. This suppresses
+     the maybe used uninitialized warning and forces the use of malloc because
+     the size is zero in all dimensions. Note that this block is only executed
+     if the lhs is unallocated and is only applied once in any namespace.
+     Component references are not subject to the warnings.  */
+  for (ref = expr1->ref; ref; ref = ref->next)
+    if (ref->type == REF_COMPONENT)
+      break;
+
+  if (!expr1->symtree->n.sym->allocated_in_scope && !ref)
+    {
+      gfc_start_block (&loop_pre_block);
+      for (n = 0; n < expr1->rank; n++)
+	{
+	  gfc_conv_descriptor_lbound_set (&loop_pre_block, desc,
+					  gfc_rank_cst[n],
+					  gfc_index_one_node);
+	  gfc_conv_descriptor_ubound_set (&loop_pre_block, desc,
+					  gfc_rank_cst[n],
+					  gfc_index_zero_node);
+	  gfc_conv_descriptor_stride_set (&loop_pre_block, desc,
+					  gfc_rank_cst[n],
+					  gfc_index_zero_node);
+	}
+
+      tmp = gfc_conv_descriptor_offset (desc);
+      gfc_add_modify (&loop_pre_block, tmp, gfc_index_zero_node);
+
+      tmp = fold_build2_loc (input_location, EQ_EXPR,
+			     logical_type_node, array1,
+			     build_int_cst (TREE_TYPE (array1), 0));
+      tmp = build3_v (COND_EXPR, tmp,
+		      gfc_finish_block (&loop_pre_block),
+		      build_empty_stmt (input_location));
+      gfc_prepend_expr_to_block (&loop->pre, tmp);
+
+      expr1->symtree->n.sym->allocated_in_scope = 1;
+    }
+
   tmp = build3_v (COND_EXPR, cond_null,
 		  build1_v (GOTO_EXPR, jump_label1),
 		  build_empty_stmt (input_location));
@@ -11008,6 +11058,19 @@ gfc_alloc_allocatable_for_assignment (gfc_loopinfo *loop,
 	gfc_add_modify (&fblock, linfo->delta[dim], tmp);
     }
 
+  /* Take into account _len of unlimited polymorphic entities, so that span
+     for array descriptors and allocation sizes are computed correctly.  */
+  if (UNLIMITED_POLY (expr2))
+    {
+      tree len = gfc_class_len_get (TREE_OPERAND (desc2, 0));
+      len = fold_build2_loc (input_location, MAX_EXPR, size_type_node,
+			     fold_convert (size_type_node, len),
+			     size_one_node);
+      elemsize2 = fold_build2_loc (input_location, MULT_EXPR,
+				   gfc_array_index_type, elemsize2,
+				   fold_convert (gfc_array_index_type, len));
+    }
+
   if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)))
     gfc_conv_descriptor_span_set (&fblock, desc, elemsize2);
 
@@ -11054,6 +11117,9 @@ gfc_alloc_allocatable_for_assignment (gfc_loopinfo *loop,
 	    gfc_add_modify (&fblock, tmp,
 			    fold_convert (TREE_TYPE (tmp),
 					  TYPE_SIZE_UNIT (type)));
+	  else if (UNLIMITED_POLY (expr2))
+	    gfc_add_modify (&fblock, tmp,
+			    gfc_class_len_get (TREE_OPERAND (desc2, 0)));
 	  else
 	    gfc_add_modify (&fblock, tmp,
 			    build_int_cst (TREE_TYPE (tmp), 0));
--- a/src/gcc/fortran/trans-expr.cc
+++ b/src/gcc/fortran/trans-expr.cc
@@ -317,6 +317,8 @@ gfc_resize_class_size_with_len (stmtblock_t * block, tree class_expr, tree size)
 	  size = gfc_evaluate_now (size, block);
 	  tmp = gfc_evaluate_now (fold_convert (type , tmp), block);
 	}
+      else
+	tmp = fold_convert (type , tmp);
       tmp2 = fold_build2_loc (input_location, MULT_EXPR,
 			      type, size, tmp);
       tmp = fold_build2_loc (input_location, GT_EXPR,
@@ -7982,8 +7984,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
 	 call the finalization function of the temporary. Note that the
 	 nullification of allocatable components needed by the result
 	 is done in gfc_trans_assignment_1.  */
-      if (expr && ((gfc_is_class_array_function (expr)
-		    && se->ss && se->ss->loop)
+      if (expr && (gfc_is_class_array_function (expr)
 		   || gfc_is_alloc_class_scalar_function (expr))
 	  && se->expr && GFC_CLASS_TYPE_P (TREE_TYPE (se->expr))
 	  && expr->must_finalize)
@@ -9748,7 +9749,8 @@ trans_get_upoly_len (stmtblock_t *block, gfc_expr *expr)
 static tree
 trans_class_vptr_len_assignment (stmtblock_t *block, gfc_expr * le,
 				 gfc_expr * re, gfc_se *rse,
-				 tree * to_lenp, tree * from_lenp)
+				 tree * to_lenp, tree * from_lenp,
+				 tree * from_vptrp)
 {
   gfc_se se;
   gfc_expr * vptr_expr;
@@ -9756,10 +9758,11 @@ trans_class_vptr_len_assignment (stmtblock_t *block, gfc_expr * le,
   bool set_vptr = false, temp_rhs = false;
   stmtblock_t *pre = block;
   tree class_expr = NULL_TREE;
+  tree from_vptr = NULL_TREE;
 
   /* Create a temporary for complicated expressions.  */
   if (re->expr_type != EXPR_VARIABLE && re->expr_type != EXPR_NULL
-      && rse->expr != NULL_TREE && !DECL_P (rse->expr))
+      && rse->expr != NULL_TREE)
     {
       if (re->ts.type == BT_CLASS && !GFC_CLASS_TYPE_P (TREE_TYPE (rse->expr)))
 	class_expr = gfc_get_class_from_expr (rse->expr);
@@ -9856,6 +9859,7 @@ trans_class_vptr_len_assignment (stmtblock_t *block, gfc_expr * le,
 		tmp = rse->expr;
 
 	      se.expr = gfc_class_vptr_get (tmp);
+	      from_vptr = se.expr;
 	      if (UNLIMITED_POLY (re))
 		from_len = gfc_class_len_get (tmp);
 
@@ -9877,6 +9881,7 @@ trans_class_vptr_len_assignment (stmtblock_t *block, gfc_expr * le,
 	  gfc_free_expr (vptr_expr);
 	  gfc_add_block_to_block (block, &se.pre);
 	  gcc_assert (se.post.head == NULL_TREE);
+	  from_vptr = se.expr;
 	}
       gfc_add_modify (pre, lhs_vptr, fold_convert (TREE_TYPE (lhs_vptr),
 						se.expr));
@@ -9905,11 +9910,13 @@ trans_class_vptr_len_assignment (stmtblock_t *block, gfc_expr * le,
 	}
     }
 
-  /* Return the _len trees only, when requested.  */
+  /* Return the _len and _vptr trees only, when requested.  */
   if (to_lenp)
     *to_lenp = to_len;
   if (from_lenp)
     *from_lenp = from_len;
+  if (from_vptrp)
+    *from_vptrp = from_vptr;
   return lhs_vptr;
 }
 
@@ -9978,7 +9985,7 @@ trans_class_pointer_fcn (stmtblock_t *block, gfc_se *lse, gfc_se *rse,
     {
       expr1_vptr = trans_class_vptr_len_assignment (block, expr1,
 						    expr2, rse,
-						    NULL, NULL);
+						    NULL, NULL, NULL);
       gfc_add_block_to_block (block, &rse->pre);
       tmp = gfc_create_var (TREE_TYPE (rse->expr), "ptrtemp");
       gfc_add_modify (&lse->pre, tmp, rse->expr);
@@ -10054,7 +10061,7 @@ gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
       if (non_proc_ptr_assign && expr1->ts.type == BT_CLASS)
 	{
 	  trans_class_vptr_len_assignment (&block, expr1, expr2, &rse, NULL,
-					   NULL);
+					   NULL, NULL);
 	  lse.expr = gfc_class_data_get (lse.expr);
 	}
 
@@ -10183,7 +10190,8 @@ gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
 	      if (expr1->ts.type == BT_CLASS)
 		expr1_vptr = trans_class_vptr_len_assignment (&block, expr1,
 							      expr2, &rse,
-							      NULL, NULL);
+							      NULL, NULL,
+							      NULL);
 	    }
 	}
       else if (expr2->expr_type == EXPR_VARIABLE)
@@ -10200,7 +10208,7 @@ gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
 	      rse.expr = NULL_TREE;
 	      rse.string_length = strlen_rhs;
 	      trans_class_vptr_len_assignment (&block, expr1, expr2, &rse,
-					       NULL, NULL);
+					       NULL, NULL, NULL);
 	    }
 
 	  if (remap == NULL)
@@ -10233,7 +10241,7 @@ gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
 	    {
 	      expr1_vptr = trans_class_vptr_len_assignment (&block, expr1,
 							    expr2, &rse, NULL,
-							    NULL);
+							    NULL, NULL);
 	      gfc_add_block_to_block (&block, &rse.pre);
 	      tmp = gfc_create_var (TREE_TYPE (rse.expr), "ptrtemp");
 	      gfc_add_modify (&lse.pre, tmp, rse.expr);
@@ -11621,7 +11629,7 @@ trans_class_assignment (stmtblock_t *block, gfc_expr *lhs, gfc_expr *rhs,
 			gfc_se *lse, gfc_se *rse, bool use_vptr_copy,
 			bool class_realloc)
 {
-  tree tmp, fcn, stdcopy, to_len, from_len, vptr, old_vptr;
+  tree tmp, fcn, stdcopy, to_len, from_len, vptr, old_vptr, rhs_vptr;
   vec<tree, va_gc> *args = NULL;
   bool final_expr;
 
@@ -11645,7 +11653,9 @@ trans_class_assignment (stmtblock_t *block, gfc_expr *lhs, gfc_expr *rhs,
     }
 
   vptr = trans_class_vptr_len_assignment (block, lhs, rhs, rse, &to_len,
-					 &from_len);
+					  &from_len, &rhs_vptr);
+  if (rhs_vptr == NULL_TREE)
+    rhs_vptr = vptr;
 
   /* Generate (re)allocation of the lhs.  */
   if (class_realloc)
@@ -11658,7 +11668,29 @@ trans_class_assignment (stmtblock_t *block, gfc_expr *lhs, gfc_expr *rhs,
       else
 	old_vptr = build_int_cst (TREE_TYPE (vptr), 0);
 
-      size = gfc_vptr_size_get (vptr);
+      size = gfc_vptr_size_get (rhs_vptr);
+
+      /* Take into account _len of unlimited polymorphic entities.
+	 TODO: handle class(*) allocatable function results on rhs.  */
+      if (UNLIMITED_POLY (rhs))
+	{
+	  tree len;
+	  if (rhs->expr_type == EXPR_VARIABLE)
+	    len = trans_get_upoly_len (block, rhs);
+	  else
+	    len = gfc_class_len_get (tmp);
+	  len = fold_build2_loc (input_location, MAX_EXPR, size_type_node,
+				 fold_convert (size_type_node, len),
+				 size_one_node);
+	  size = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (size),
+				  size, fold_convert (TREE_TYPE (size), len));
+	}
+      else if (rhs->ts.type == BT_CHARACTER && rse->string_length)
+	size = fold_build2_loc (input_location, MULT_EXPR,
+				gfc_charlen_type_node, size,
+				rse->string_length);
+
+
       tmp = lse->expr;
       class_han = GFC_CLASS_TYPE_P (TREE_TYPE (tmp))
 	  ? gfc_class_data_get (tmp) : tmp;
@@ -11672,16 +11704,25 @@ trans_class_assignment (stmtblock_t *block, gfc_expr *lhs, gfc_expr *rhs,
 
       /* Reallocate if dynamic types are different. */
       gfc_init_block (&re_alloc);
-      re = build_call_expr_loc (input_location,
-				builtin_decl_explicit (BUILT_IN_REALLOC), 2,
-				fold_convert (pvoid_type_node, class_han),
-				size);
-      tmp = fold_build2_loc (input_location, NE_EXPR,
-			     logical_type_node, vptr, old_vptr);
-      re = fold_build3_loc (input_location, COND_EXPR, void_type_node,
-			    tmp, re, build_empty_stmt (input_location));
-      gfc_add_expr_to_block (&re_alloc, re);
-
+      if (UNLIMITED_POLY (lhs) && rhs->ts.type == BT_CHARACTER)
+	{
+	  gfc_add_expr_to_block (&re_alloc, gfc_call_free (class_han));
+	  gfc_allocate_using_malloc (&re_alloc, class_han, size, NULL_TREE);
+	}
+      else
+	{
+	  tmp = fold_convert (pvoid_type_node, class_han);
+	  re = build_call_expr_loc (input_location,
+				    builtin_decl_explicit (BUILT_IN_REALLOC),
+				    2, tmp, size);
+	  re = fold_build2_loc (input_location, MODIFY_EXPR, TREE_TYPE (tmp),
+				tmp, re);
+	  tmp = fold_build2_loc (input_location, NE_EXPR,
+				 logical_type_node, rhs_vptr, old_vptr);
+	  re = fold_build3_loc (input_location, COND_EXPR, void_type_node,
+				tmp, re, build_empty_stmt (input_location));
+	  gfc_add_expr_to_block (&re_alloc, re);
+	}
       tree realloc_expr = lhs->ts.type == BT_CLASS ?
 					  gfc_finish_block (&re_alloc) :
 					  build_empty_stmt (input_location);
--- a/src/gcc/fortran/trans-intrinsic.cc
+++ b/src/gcc/fortran/trans-intrinsic.cc
@@ -3090,7 +3090,9 @@ gfc_conv_intrinsic_bound (gfc_se * se, gfc_expr * expr, enum gfc_isym_id op)
 				      lbound, gfc_index_one_node);
 	}
       else if (op == GFC_ISYM_SHAPE)
-	se->expr = size;
+	se->expr = fold_build2_loc (input_location, MAX_EXPR,
+				    gfc_array_index_type, size,
+				    gfc_index_zero_node);
       else
 	gcc_unreachable ();
 
@@ -8252,7 +8254,9 @@ gfc_conv_intrinsic_storage_size (gfc_se *se, gfc_expr *expr)
 {
   gfc_expr *arg;
   gfc_se argse;
-  tree type, result_type, tmp;
+  tree type, result_type, tmp, class_decl = NULL;
+  gfc_symbol *sym;
+  bool unlimited = false;
 
   arg = expr->value.function.actual->expr;
 
@@ -8263,10 +8267,12 @@ gfc_conv_intrinsic_storage_size (gfc_se *se, gfc_expr *expr)
     {
       if (arg->ts.type == BT_CLASS)
 	{
+	  unlimited = UNLIMITED_POLY (arg);
 	  gfc_add_vptr_component (arg);
 	  gfc_add_size_component (arg);
 	  gfc_conv_expr (&argse, arg);
 	  tmp = fold_convert (result_type, argse.expr);
+	  class_decl = gfc_get_class_from_expr (argse.expr);
 	  goto done;
 	}
 
@@ -8278,14 +8284,20 @@ gfc_conv_intrinsic_storage_size (gfc_se *se, gfc_expr *expr)
     {
       argse.want_pointer = 0;
       gfc_conv_expr_descriptor (&argse, arg);
+      sym = arg->expr_type == EXPR_VARIABLE ? arg->symtree->n.sym : NULL;
       if (arg->ts.type == BT_CLASS)
 	{
-	  if (arg->rank > 0)
+	  unlimited = UNLIMITED_POLY (arg);
+	  if (TREE_CODE (argse.expr) == COMPONENT_REF)
+	    tmp = gfc_class_vtab_size_get (TREE_OPERAND (argse.expr, 0));
+	  else if (arg->rank > 0 && sym
+		   && DECL_LANG_SPECIFIC (sym->backend_decl))
 	    tmp = gfc_class_vtab_size_get (
-		 GFC_DECL_SAVED_DESCRIPTOR (arg->symtree->n.sym->backend_decl));
+		 GFC_DECL_SAVED_DESCRIPTOR (sym->backend_decl));
 	  else
-	    tmp = gfc_class_vtab_size_get (TREE_OPERAND (argse.expr, 0));
+	    gcc_unreachable ();
 	  tmp = fold_convert (result_type, tmp);
+	  class_decl = gfc_get_class_from_expr (argse.expr);
 	  goto done;
 	}
       type = gfc_get_element_type (TREE_TYPE (argse.expr));
@@ -8299,6 +8311,9 @@ gfc_conv_intrinsic_storage_size (gfc_se *se, gfc_expr *expr)
   tmp = fold_convert (result_type, tmp);
 
 done:
+  if (unlimited && class_decl)
+    tmp = gfc_resize_class_size_with_len (NULL, class_decl, tmp);
+
   se->expr = fold_build2_loc (input_location, MULT_EXPR, result_type, tmp,
 			      build_int_cst (result_type, BITS_PER_UNIT));
   gfc_add_block_to_block (&se->pre, &argse.pre);
@@ -8421,7 +8436,10 @@ gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
 	{
 	  tmp = build_fold_indirect_ref_loc (input_location, argse.expr);
 	  if (GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
-	    source = gfc_class_data_get (tmp);
+	    {
+	      source = gfc_class_data_get (tmp);
+	      class_ref = tmp;
+	    }
 	  else
 	    {
 	      /* Array elements are evaluated as a reference to the data.
@@ -8448,9 +8466,17 @@ gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
 	  break;
 	case BT_CLASS:
 	  if (class_ref != NULL_TREE)
-	    tmp = gfc_class_vtab_size_get (class_ref);
+	    {
+	      tmp = gfc_class_vtab_size_get (class_ref);
+	      if (UNLIMITED_POLY (source_expr))
+		tmp = gfc_resize_class_size_with_len (NULL, class_ref, tmp);
+	    }
 	  else
-	    tmp = gfc_class_vtab_size_get (argse.expr);
+	    {
+	      tmp = gfc_class_vtab_size_get (argse.expr);
+	      if (UNLIMITED_POLY (source_expr))
+		tmp = gfc_resize_class_size_with_len (NULL, argse.expr, tmp);
+	    }
 	  break;
 	default:
 	  source_type = TREE_TYPE (build_fold_indirect_ref_loc (input_location,
@@ -8503,6 +8529,13 @@ gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
       if (arg->expr->ts.type == BT_CHARACTER)
 	tmp = size_of_string_in_bytes (arg->expr->ts.kind,
 				       argse.string_length);
+      else if (arg->expr->ts.type == BT_CLASS)
+	{
+	  class_ref = TREE_OPERAND (argse.expr, 0);
+	  tmp = gfc_class_vtab_size_get (class_ref);
+	  if (UNLIMITED_POLY (arg->expr))
+	    tmp = gfc_resize_class_size_with_len (&argse.pre, class_ref, tmp);
+	}
       else
 	tmp = fold_convert (gfc_array_index_type,
 			    size_in_bytes (source_type));
@@ -8543,15 +8576,14 @@ gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
 
   if (arg->expr->rank == 0)
     {
-      gfc_conv_expr_reference (&argse, arg->expr);
+      gfc_conv_expr_reference (&argse, mold_expr);
       mold_type = TREE_TYPE (build_fold_indirect_ref_loc (input_location,
 							  argse.expr));
     }
   else
     {
-      gfc_init_se (&argse, NULL);
       argse.want_pointer = 0;
-      gfc_conv_expr_descriptor (&argse, arg->expr);
+      gfc_conv_expr_descriptor (&argse, mold_expr);
       mold_type = gfc_get_element_type (TREE_TYPE (argse.expr));
     }
 
@@ -8562,27 +8594,41 @@ gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
     {
       /* If this TRANSFER is nested in another TRANSFER, use a type
 	 that preserves all bits.  */
-      if (arg->expr->ts.type == BT_LOGICAL)
-	mold_type = gfc_get_int_type (arg->expr->ts.kind);
+      if (mold_expr->ts.type == BT_LOGICAL)
+	mold_type = gfc_get_int_type (mold_expr->ts.kind);
     }
 
   /* Obtain the destination word length.  */
-  switch (arg->expr->ts.type)
+  switch (mold_expr->ts.type)
     {
     case BT_CHARACTER:
-      tmp = size_of_string_in_bytes (arg->expr->ts.kind, argse.string_length);
-      mold_type = gfc_get_character_type_len (arg->expr->ts.kind,
+      tmp = size_of_string_in_bytes (mold_expr->ts.kind, argse.string_length);
+      mold_type = gfc_get_character_type_len (mold_expr->ts.kind,
 					      argse.string_length);
       break;
     case BT_CLASS:
-      tmp = gfc_class_vtab_size_get (argse.expr);
+      if (scalar_mold)
+	class_ref = argse.expr;
+      else
+	class_ref = TREE_OPERAND (argse.expr, 0);
+      tmp = gfc_class_vtab_size_get (class_ref);
+      if (UNLIMITED_POLY (arg->expr))
+	tmp = gfc_resize_class_size_with_len (&argse.pre, class_ref, tmp);
       break;
     default:
       tmp = fold_convert (gfc_array_index_type, size_in_bytes (mold_type));
       break;
     }
-  dest_word_len = gfc_create_var (gfc_array_index_type, NULL);
-  gfc_add_modify (&se->pre, dest_word_len, tmp);
+
+  /* Do not fix dest_word_len if it is a variable, since the temporary can wind
+     up being used before the assignment.  */
+  if (mold_expr->ts.type == BT_CHARACTER && mold_expr->ts.deferred)
+    dest_word_len = tmp;
+  else
+    {
+      dest_word_len = gfc_create_var (gfc_array_index_type, NULL);
+      gfc_add_modify (&se->pre, dest_word_len, tmp);
+    }
 
   /* Finally convert SIZE, if it is present.  */
   arg = arg->next;
--- a/src/gcc/fortran/trans-stmt.cc
+++ b/src/gcc/fortran/trans-stmt.cc
@@ -6398,8 +6398,9 @@ gfc_trans_allocate (gfc_code * code)
       else
 	gfc_add_block_to_block (&post, &se.post);
 
-      /* Special case when string in expr3 is zero.  */
+      /* Special case when string in expr3 is scalar and has length zero.  */
       if (code->expr3->ts.type == BT_CHARACTER
+	  && code->expr3->rank == 0
 	  && integer_zerop (se.string_length))
 	{
 	  gfc_init_se (&se, NULL);
@@ -7058,6 +7059,46 @@ gfc_trans_allocate (gfc_code * code)
 	  gfc_expr *rhs = e3rhs ? e3rhs : gfc_copy_expr (code->expr3);
 	  flag_realloc_lhs = 0;
 
+	  /* The handling of code->expr3 above produces a derived type of
+	     type "STAR", whose size defaults to size(void*). In order to
+	     have the right type information for the assignment, we must
+	     reconstruct an unlimited polymorphic rhs.  */
+	  if (UNLIMITED_POLY (code->expr3)
+	      && e3rhs && e3rhs->ts.type == BT_DERIVED
+	      && !strcmp (e3rhs->ts.u.derived->name, "STAR"))
+	    {
+	      gfc_ref *ref;
+	      gcc_assert (TREE_CODE (expr3_vptr) == COMPONENT_REF);
+	      tmp = gfc_create_var (gfc_typenode_for_spec (&code->expr3->ts),
+				    "e3");
+	      gfc_add_modify (&block, tmp,
+			      gfc_get_class_from_expr (expr3_vptr));
+	      rhs->symtree->n.sym->backend_decl = tmp;
+	      rhs->ts = code->expr3->ts;
+	      rhs->symtree->n.sym->ts = rhs->ts;
+	      for (ref = init_expr->ref; ref; ref = ref->next)
+		{
+		  /* Copy over the lhs _data component ref followed by the
+		     full array reference for source expressions with rank.
+		     Otherwise, just copy the _data component ref.  */
+		  if (code->expr3->rank
+		      && ref && ref->next && !ref->next->next)
+		    {
+		      rhs->ref = gfc_copy_ref (ref);
+		      break;
+		    }
+		  else if ((init_expr->rank && !code->expr3->rank
+			    && ref && ref->next && !ref->next->next)
+			   || (ref && !ref->next))
+		    {
+		      rhs->ref = gfc_copy_ref (ref);
+		      gfc_free_ref_list (rhs->ref->next);
+		      rhs->ref->next = NULL;
+		      break;
+		    }
+		}
+	    }
+
 	  /* Set the symbol to be artificial so that the result is not finalized.  */
 	  init_expr->symtree->n.sym->attr.artificial = 1;
 	  tmp = gfc_trans_assignment (init_expr, rhs, true, false, true,
--- a/src/gcc/fortran/trans-types.cc
+++ b/src/gcc/fortran/trans-types.cc
@@ -1591,7 +1591,7 @@ gfc_get_dtype_rank_type (int rank, tree etype)
       size = size_in_bytes (etype);
       break;
     }
-      
+
   gcc_assert (size);
 
   STRIP_NOPS (size);
@@ -1736,7 +1736,7 @@ gfc_get_nodesc_array_type (tree etype, gfc_array_spec * as, gfc_packed packed,
 	tmp = gfc_conv_mpz_to_tree (expr->value.integer,
 				    gfc_index_integer_kind);
       else
-      	tmp = NULL_TREE;
+	tmp = NULL_TREE;
       GFC_TYPE_ARRAY_LBOUND (type, n) = tmp;
 
       expr = as->upper[n];
--- a/src/gcc/ipa-icf-gimple.cc
+++ b/src/gcc/ipa-icf-gimple.cc
@@ -542,6 +542,10 @@ func_checker::compare_loops (basic_block bb1, basic_block bb2)
     return return_false_with_msg ("unroll");
   if (!compare_variable_decl (l1->simduid, l2->simduid))
     return return_false_with_msg ("simduid");
+  if ((l1->any_upper_bound != l2->any_upper_bound)
+      || (l1->any_upper_bound
+	  && (l1->nb_iterations_upper_bound != l2->nb_iterations_upper_bound)))
+    return return_false_with_msg ("nb_iterations_upper_bound");
 
   return true;
 }
--- a/src/gcc/jit/ChangeLog
+++ b/src/gcc/jit/ChangeLog
@@ -1,3 +1,12 @@
+2024-06-11  Andrew Pinski  <quic_apinski@quicinc.com>
+
+	Backported from master:
+	2024-06-11  Andrew Pinski  <quic_apinski@quicinc.com>
+
+	PR jit/115442
+	* jit-recording.cc: Define INCLUDE_SSTREAM before including
+	system.h and don't directly incldue sstream.
+
 2024-05-21  Release Manager
 
 	* GCC 13.3.0 released.
--- a/src/gcc/jit/jit-recording.cc
+++ b/src/gcc/jit/jit-recording.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
+#define INCLUDE_SSTREAM
 #include "system.h"
 #include "coretypes.h"
 #include "tm.h"
--- a/src/gcc/match.pd
+++ b/src/gcc/match.pd
@@ -2023,12 +2023,14 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   (mult (convert @0) @1)))
 
 /* Narrow integer multiplication by a zero_one_valued_p operand.
-   Multiplication by [0,1] is guaranteed not to overflow.  */
+   Multiplication by [0,1] is guaranteed not to overflow except for
+   1bit signed types.  */
 (simplify
  (convert (mult@0 zero_one_valued_p@1 INTEGER_CST@2))
  (if (INTEGRAL_TYPE_P (type)
       && INTEGRAL_TYPE_P (TREE_TYPE (@0))
-      && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (@0)))
+      && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (@0))
+      && (TYPE_UNSIGNED (type) || TYPE_PRECISION (type) > 1))
   (mult (convert @1) (convert @2))))
 
 /* (X << C) != 0 can be simplified to X, when C is zero_one_valued_p.
--- a/src/gcc/opt-suggestions.cc
+++ b/src/gcc/opt-suggestions.cc
@@ -167,9 +167,9 @@ option_proposer::build_option_suggestions (const char *prefix)
 	    add_misspelling_candidates (m_option_suggestions, option,
 					opt_text);
 
+	    struct cl_option optb;
 	    for (int j = 0; sanitizer_opts[j].name != NULL; ++j)
 	      {
-		struct cl_option optb;
 		/* -fsanitize=all is not valid, only -fno-sanitize=all.
 		   So don't register the positive misspelling candidates
 		   for it.  */
--- a/src/gcc/opts-common.cc
+++ b/src/gcc/opts-common.cc
@@ -502,6 +502,7 @@ add_misspelling_candidates (auto_vec<char *> *candidates,
   for (unsigned i = 0; i < ARRAY_SIZE (option_map); i++)
     {
       const char *opt0 = option_map[i].opt0;
+      const char *opt1 = option_map[i].opt1;
       const char *new_prefix = option_map[i].new_prefix;
       size_t new_prefix_len = strlen (new_prefix);
 
@@ -510,8 +511,9 @@ add_misspelling_candidates (auto_vec<char *> *candidates,
 
       if (strncmp (opt_text, new_prefix, new_prefix_len) == 0)
 	{
-	  char *alternative = concat (opt0 + 1, opt_text + new_prefix_len,
-				      NULL);
+	  char *alternative
+	    = concat (opt0 + 1, opt1 ? " " : "", opt1 ? opt1 : "",
+		      opt_text + new_prefix_len, NULL);
 	  candidates->safe_push (alternative);
 	}
     }
--- a/src/gcc/testsuite/ChangeLog
+++ b/src/gcc/testsuite/ChangeLog
@@ -1,3 +1,573 @@
+2024-09-03  Haochen Jiang  <haochen.jiang@intel.com>
+
+	* gcc.target/i386/avx512fp16-vfpclassph-1c.c: New test.
+
+2024-09-02  liuhongt  <hongtao.liu@intel.com>
+
+	Backported from master:
+	2024-08-30  liuhongt  <hongtao.liu@intel.com>
+
+	* gcc.target/i386/pr116512.c: New test.
+
+2024-08-22  liuhongt  <hongtao.liu@intel.com>
+
+	* gcc.target/i386/pieces-memcpy-10.c: Use -mmove-max=256 and
+	-mstore-max=256.
+	* gcc.target/i386/pieces-memcpy-6.c: Ditto.
+	* gcc.target/i386/pieces-memset-38.c: Ditto.
+	* gcc.target/i386/pieces-memset-40.c: Ditto.
+	* gcc.target/i386/pieces-memset-41.c: Ditto.
+	* gcc.target/i386/pieces-memset-42.c: Ditto.
+	* gcc.target/i386/pieces-memset-43.c: Ditto.
+	* gcc.target/i386/pieces-strcpy-2.c: Ditto.
+
+2024-08-22  liuhongt  <hongtao.liu@intel.com>
+
+	Backported from master:
+	2024-08-22  liuhongt  <hongtao.liu@intel.com>
+
+	* gcc.target/i386/pieces-memcpy-10.c: Add -mprefer-vector-width=128.
+	* gcc.target/i386/pieces-memcpy-6.c: Ditto.
+	* gcc.target/i386/pieces-memset-38.c: Ditto.
+	* gcc.target/i386/pieces-memset-40.c: Ditto.
+	* gcc.target/i386/pieces-memset-41.c: Ditto.
+	* gcc.target/i386/pieces-memset-42.c: Ditto.
+	* gcc.target/i386/pieces-memset-43.c: Ditto.
+	* gcc.target/i386/pieces-strcpy-2.c: Ditto.
+	* gcc.target/i386/pieces-memcpy-22.c: New test.
+	* gcc.target/i386/pieces-memset-51.c: New test.
+	* gcc.target/i386/pieces-strcpy-3.c: New test.
+
+2024-08-21  Alexandre Oliva  <oliva@adacore.com>
+
+	Backported from master:
+	2024-06-26  Alexandre Oliva  <oliva@adacore.com>
+		    Richard Earnshaw  <Richard.Earnshaw@arm.com>
+
+	PR tree-optimization/113281
+	* gcc.target/arm/simd/mve-vshr.c: Add expected ranges.
+
+2024-08-19  Jan Hubicka  <hubicka@ucw.cz>
+
+	Backported from master:
+	2024-07-22  Jan Hubicka  <hubicka@ucw.cz>
+
+	* gcc.c-torture/compile/pr115277.c: New test.
+
+2024-08-18  Georg-Johann Lay  <avr@gjlay.de>
+
+	Backported from master:
+	2024-08-18  Georg-Johann Lay  <avr@gjlay.de>
+
+	PR target/116407
+	* gcc.target/avr/torture/pr116407-2.c: New test.
+	* gcc.target/avr/torture/pr116407-4.c: New test.
+
+2024-08-16  Richard Sandiford  <richard.sandiford@arm.com>
+
+	Backported from master:
+	2024-04-05  Richard Sandiford  <richard.sandiford@arm.com>
+
+	PR target/114603
+	* gcc.target/aarch64/sve/acle/general/cnot_1.c: New test.
+
+2024-08-16  Richard Sandiford  <richard.sandiford@arm.com>
+
+	Backported from master:
+	2024-04-08  Richard Sandiford  <richard.sandiford@arm.com>
+
+	PR target/114607
+	* gcc.target/aarch64/sve/acle/asm/sudot_s32.c: New test.
+
+2024-08-12  liuhongt  <hongtao.liu@intel.com>
+
+	Backported from master:
+	2024-07-30  liuhongt  <hongtao.liu@intel.com>
+
+	* gcc.target/i386/pr116043.c: New test.
+
+2024-08-09  Patrick Palka  <ppalka@redhat.com>
+
+	PR c++/113063
+	PR c++/116289
+	* g++.dg/cpp2a/spaceship-synth16.C: New test.
+	* g++.dg/cpp2a/spaceship-synth16a.C: New test.
+
+2024-08-06  Andrew Pinski  <quic_apinski@quicinc.com>
+
+	Backported from master:
+	2024-08-06  Andrew Pinski  <quic_apinski@quicinc.com>
+
+	PR target/116189
+	* c-c++-common/torture/pr116189-1.c: New test.
+
+2024-08-05  Paul Thomas  <pault@gcc.gnu.org>
+
+	Backported from master:
+	2024-07-18  Paul Thomas  <pault@gcc.gnu.org>
+
+	PR fortran/108889
+	* gfortran.dg/pr108889.f90: New test.
+
+2024-07-30  Haochen Jiang  <haochen.jiang@intel.com>
+
+	* gcc.target/i386/prefetchi-1b.c: New test.
+
+2024-07-29  Haochen Jiang  <haochen.jiang@intel.com>
+
+	* gcc.target/i386/avx512bw-vpalignr-1b.c: New test.
+	* gcc.target/i386/avx512dq-vfpclasssd-1b.c: Ditto.
+	* gcc.target/i386/avx512dq-vfpclassss-1b.c: Ditto.
+	* gcc.target/i386/avx512dq-vreducesd-1b.c: Ditto.
+	* gcc.target/i386/avx512dq-vreducess-1b.c: Ditto.
+	* gcc.target/i386/avx512vl-valignq-1b.c: Ditto.
+
+2024-07-24  Peter Bergner  <bergner@linux.ibm.com>
+
+	Backported from master:
+	2024-07-19  Peter Bergner  <bergner@linux.ibm.com>
+
+	PR target/114759
+	PR target/115988
+	* gcc.target/powerpc/pr114759-3.c: Catch unsupported ABI errors.
+
+2024-07-24  Peter Bergner  <bergner@linux.ibm.com>
+
+	Backported from master:
+	2024-07-17  Peter Bergner  <bergner@linux.ibm.com>
+
+	PR target/114759
+	* gcc.target/powerpc/pr114759-3.c: New test.
+
+2024-07-24  Peter Bergner  <bergner@linux.ibm.com>
+
+	Backported from master:
+	2024-07-17  Peter Bergner  <bergner@linux.ibm.com>
+
+	PR target/114759
+	* gcc.target/powerpc/pr114759-2.c: New test.
+	* lib/target-supports.exp (rop_ok): Use
+	check_effective_target_has_arch_pwr8.
+
+2024-07-24  Peter Bergner  <bergner@linux.ibm.com>
+
+	Backported from master:
+	2024-06-17  Peter Bergner  <bergner@linux.ibm.com>
+
+	PR target/115389
+	* gcc.target/powerpc/pr115389.c: New test.
+
+2024-07-23  Haochen Jiang  <haochen.jiang@intel.com>
+
+	* gcc.target/i386/prefetchi-1.c: Check (%rip).
+
+2024-07-23  Alexandre Oliva  <oliva@adacore.com>
+
+	Backported from master:
+	2024-07-23  Alexandre Oliva  <oliva@adacore.com>
+
+	PR target/106069
+	* g++.target/powerpc/pr106069.C: Reorder dg directives.
+
+2024-07-21  Harald Anlauf  <anlauf@gmx.de>
+
+	Backported from master:
+	2024-07-19  Harald Anlauf  <anlauf@gmx.de>
+
+	PR fortran/103115
+	* gfortran.dg/string_array_constructor_4.f90: New test.
+
+2024-07-20  Paul Thomas  <pault@gcc.gnu.org>
+
+	Backported from master:
+	2024-05-13  Paul Thomas  <pault@gcc.gnu.org>
+
+	PR fortran/113363
+	* gfortran.dg/pr113363.f90: New test.
+
+2024-07-20  René Rebe  <rene@exactcode.de>
+
+	Backported from master:
+	2024-07-18  René Rebe  <rene@exactcode.de>
+		    Peter Bergner  <bergner@linux.ibm.com>
+
+	PR target/97367
+	* gcc.target/powerpc/pr97367.c: New test.
+
+2024-07-17  Uros Bizjak  <ubizjak@gmail.com>
+
+	Backported from master:
+	2024-07-17  Uros Bizjak  <ubizjak@gmail.com>
+
+	PR target/115526
+	* gcc.target/alpha/pr115526.c: New test.
+
+2024-07-15  liuhongt  <hongtao.liu@intel.com>
+
+	Backported from master:
+	2024-07-15  liuhongt  <hongtao.liu@intel.com>
+
+	* gcc.target/i386/pr115872.c: New test.
+
+2024-07-13  Lulu Cheng  <chenglulu@loongson.cn>
+
+	Backported from master:
+	2024-07-12  Lulu Cheng  <chenglulu@loongson.cn>
+
+	PR target/115752
+	* gcc.target/loongarch/pr115752.c: New test.
+
+2024-07-12  Paul Thomas  <pault@gcc.gnu.org>
+
+	Backported from master:
+	2024-05-23  Paul Thomas  <pault@gcc.gnu.org>
+
+	PR fortran/103312
+	* gfortran.dg/pr103312.f90: New test.
+
+2024-07-11  Andre Vieira  <andre.simoesdiasvieira@arm.com>
+
+	Backported from master:
+	2024-07-11  Andre Vieira  <andre.simoesdiasvieira@arm.com>
+
+	* gcc.target/arm/mve/intrinsics/vsetq_lane_su64.c: New test.
+
+2024-07-10  Torbjörn SVENSSON  <torbjorn.svensson@foss.st.com>
+
+	Backported from master:
+	2024-07-10  Torbjörn SVENSSON  <torbjorn.svensson@foss.st.com>
+
+	PR target/105090
+	* gcc.target/arm/copysign_softfloat_1.c: Drop check for lsr
+
+2024-07-08  Paul Thomas  <pault@gcc.gnu.org>
+
+	Backported from master:
+	2024-05-12  Paul Thomas  <pault@gcc.gnu.org>
+
+	PR fortran/84006
+	PR fortran/100027
+	PR fortran/98534
+	* gfortran.dg/storage_size_7.f90: New test.
+	* gfortran.dg/transfer_class_4.f90: New test.
+
+2024-07-05  Georg-Johann Lay  <avr@gjlay.de>
+
+	Backported from master:
+	2024-07-05  Georg-Johann Lay  <avr@gjlay.de>
+
+	PR target/87376
+	* gcc.target/avr/torture/pr87376.c: New test.
+
+2024-07-04  Kyrylo Tkachov  <ktkachov@nvidia.com>
+
+	Backported from master:
+	2024-07-03  Kyrylo Tkachov  <ktkachov@nvidia.com>
+
+	PR target/115475
+	* gcc.target/aarch64/acle/bf16_sve_feature.c: New test.
+
+2024-07-04  Kyrylo Tkachov  <ktkachov@nvidia.com>
+
+	Backported from master:
+	2024-07-03  Kyrylo Tkachov  <ktkachov@nvidia.com>
+
+	PR target/115457
+	* gcc.target/aarch64/acle/bf16_feature.c: New test.
+
+2024-07-03  Georg-Johann Lay  <avr@gjlay.de>
+
+	Backported from master:
+	2024-07-03  Georg-Johann Lay  <avr@gjlay.de>
+
+	PR target/98762
+	* gcc.target/avr/torture/pr98762.c: New test.
+
+2024-07-03  Kewen Lin  <linkw@linux.ibm.com>
+
+	Backported from master:
+	2024-06-26  Kewen Lin  <linkw@linux.ibm.com>
+		    Xionghu Luo  <xionghuluo@tencent.com>
+
+	PR target/106069
+	PR target/115355
+	* gcc.target/powerpc/pr106069-2.c: New test.
+
+2024-07-03  Kewen Lin  <linkw@linux.ibm.com>
+
+	Backported from master:
+	2024-06-26  Kewen Lin  <linkw@linux.ibm.com>
+		    Xionghu Luo  <xionghuluo@tencent.com>
+
+	PR target/106069
+	PR target/115355
+	* gcc.target/powerpc/pr106069-1.c: New test.
+
+2024-07-01  Georg-Johann Lay  <avr@gjlay.de>
+
+	Backported from master:
+	2024-07-01  Georg-Johann Lay  <avr@gjlay.de>
+
+	PR target/88236
+	PR target/115726
+	* gcc.target/avr/torture/pr88236-pr115726.c: New test.
+
+2024-06-28  Kewen Lin  <linkw@linux.ibm.com>
+
+	Backported from master:
+	2024-06-21  Kewen Lin  <linkw@linux.ibm.com>
+		    Xionghu Luo  <xionghuluo@tencent.com>
+
+	PR target/106069
+	PR target/115355
+	* g++.target/powerpc/pr106069.C: New test.
+	* gcc.target/powerpc/pr115355.c: New test.
+
+2024-06-27  Andrew Carlotti  <andrew.carlotti@arm.com>
+
+	Backported from master:
+	2023-12-16  Andrew Carlotti  <andrew.carlotti@arm.com>
+
+	PR target/115618
+	* gcc.target/aarch64/options_set_4.c: Add terminating newline.
+	* gcc.target/aarch64/options_set_27.c: New test.
+
+2024-06-24  Kewen Lin  <linkw@linux.ibm.com>
+
+	Backported from master:
+	2024-05-29  Kewen Lin  <linkw@linux.ibm.com>
+
+	PR target/114846
+	* gcc.target/powerpc/pr114846.c: New test.
+
+2024-06-20  Jakub Jelinek  <jakub@redhat.com>
+
+	Backported from master:
+	2024-06-17  Jakub Jelinek  <jakub@redhat.com>
+
+	PR driver/115440
+	* g++.dg/cpp1z/pr115440.C: New test.
+
+2024-06-19  Harald Anlauf  <anlauf@gmx.de>
+
+	Backported from master:
+	2024-06-04  Harald Anlauf  <anlauf@gmx.de>
+
+	PR fortran/83865
+	* gfortran.dg/allocate_with_source_32.f90: New test.
+
+2024-06-17  Jakub Jelinek  <jakub@redhat.com>
+
+	Backported from master:
+	2024-06-17  Jakub Jelinek  <jakub@redhat.com>
+
+	PR c/115290
+	* c-c++-common/Warray-compare-3.c: New test.
+
+2024-06-17  Jakub Jelinek  <jakub@redhat.com>
+
+	Backported from master:
+	2024-06-17  Jakub Jelinek  <jakub@redhat.com>
+
+	PR target/111343
+	PR c++/115511
+	* g++.dg/cpp23/ext-floating18.C: New test.
+
+2024-06-12  Torbjörn SVENSSON  <torbjorn.svensson@foss.st.com>
+
+	Backported from master:
+	2024-06-12  Torbjörn SVENSSON  <torbjorn.svensson@foss.st.com>
+		    Yvan ROUX  <yvan.roux@foss.st.com>
+
+	PR target/115253
+	* gcc.target/arm/cmse/extend-return.c: Update test case
+	condition for Armv8.1-M.
+
+2024-06-11  Jakub Jelinek  <jakub@redhat.com>
+
+	Backported from master:
+	2024-06-06  Jakub Jelinek  <jakub@redhat.com>
+
+	PR c/114493
+	* gcc.dg/pr114493-1.c: New test.
+	* gcc.dg/pr114493-2.c: New test.
+
+2024-06-11  Jakub Jelinek  <jakub@redhat.com>
+
+	Backported from master:
+	2024-06-04  Jakub Jelinek  <jakub@redhat.com>
+
+	PR middle-end/108789
+	* gcc.c-torture/execute/pr108789.c: New test.
+
+2024-06-11  Jakub Jelinek  <jakub@redhat.com>
+
+	Backported from master:
+	2024-05-15  Jakub Jelinek  <jakub@redhat.com>
+
+	PR rtl-optimization/114902
+	PR rtl-optimization/115092
+	* gcc.dg/pr114902.c: New test.
+	* gcc.dg/pr115092.c: New test.
+
+2024-06-10  Eric Botcazou  <ebotcazou@adacore.com>
+
+	* gnat.dg/incomplete8.adb: New test.
+
+2024-06-10  Eric Botcazou  <ebotcazou@adacore.com>
+
+	PR ada/114398
+	* gnat.dg/access11.adb: New test.
+
+2024-06-03  Uros Bizjak  <ubizjak@gmail.com>
+
+	Backported from master:
+	2024-05-31  Uros Bizjak  <ubizjak@gmail.com>
+
+	PR target/115297
+	* gcc.target/alpha/pr115297.c: New test.
+
+2024-06-01  Georg-Johann Lay  <avr@gjlay.de>
+
+	Backported from master:
+	2024-06-01  Georg-Johann Lay  <avr@gjlay.de>
+
+	PR tree-optimization/115307
+	* gcc.target/avr/torture/pr115307-isinf.c: New test.
+
+2024-06-01  Georg-Johann Lay  <avr@gjlay.de>
+
+	Backported from master:
+	2024-06-01  Georg-Johann Lay  <avr@gjlay.de>
+
+	PR target/115317
+	* gcc.target/avr/torture/pr115317-isinf.c: New test.
+
+2024-05-31  Richard Sandiford  <richard.sandiford@arm.com>
+
+	Backported from master:
+	2024-01-29  Richard Sandiford  <richard.sandiford@arm.com>
+
+	PR target/113281
+	* gcc.dg/vect/pr113281-1.c: New test.
+	* gcc.dg/vect/pr113281-2.c: Likewise.
+	* gcc.dg/vect/pr113281-3.c: Likewise.
+	* gcc.dg/vect/pr113281-4.c: Likewise.
+	* gcc.dg/vect/pr113281-5.c: Likewise.
+
+2024-05-31  Richard Sandiford  <richard.sandiford@arm.com>
+
+	Backported from master:
+	2024-05-24  Richard Sandiford  <richard.sandiford@arm.com>
+
+	PR tree-optimization/115192
+	* gcc.dg/vect/pr115192.c: New test.
+
+2024-05-28  Tobias Burnus  <tburnus@baylibre.com>
+
+	Backported from master:
+	2024-05-20  Tobias Burnus  <tburnus@baylibre.com>
+
+	PR fortran/115150
+	* gfortran.dg/shape_12.f90: New test.
+
+2024-05-24  Jason Merrill  <jason@redhat.com>
+
+	Backported from master:
+	2023-09-22  Jason Merrill  <jason@redhat.com>
+
+	PR c++/111529
+	* g++.dg/ext/unroll-4.C: New test.
+
+2024-05-24  Jason Merrill  <jason@redhat.com>
+
+	Backported from master:
+	2024-01-25  Jason Merrill  <jason@redhat.com>
+
+	PR c++/113598
+	* g++.dg/cpp0x/initlist-pmf2.C: New test.
+
+2024-05-22  Torbjörn SVENSSON  <torbjorn.svensson@foss.st.com>
+
+	Backported from master:
+	2024-05-22  Torbjörn SVENSSON  <torbjorn.svensson@foss.st.com>
+
+	* gcc.target/arm/cmse/extend-param.c: Add regression test. Add
+	-fshort-enums.
+	* gcc.target/arm/cmse/extend-return.c: Add -fshort-enums option.
+
+2024-05-22  Harald Anlauf  <anlauf@gmx.de>
+
+	Backported from master:
+	2024-05-05  Harald Anlauf  <anlauf@gmx.de>
+
+	PR fortran/114827
+	* gfortran.dg/asan/unlimited_polymorphic_34.f90: New test.
+
+2024-05-22  Andrew Jenner  <andrew@codesourcery.com>
+
+	Backported from master:
+	2023-11-28  Andrew Jenner  <andrew@codesourcery.com>
+		    Tobias Burnus   <tobias@codesourcery.com>
+
+	PR fortran/110415
+	* gfortran.dg/pr110415.f90: New test.
+	* gfortran.dg/asan/pr110415-2.f90: New test.
+	* gfortran.dg/asan/pr110415-3.f90: New test.
+
+2024-05-22  Jakub Jelinek  <jakub@redhat.com>
+
+	Backported from master:
+	2024-05-22  Jakub Jelinek  <jakub@redhat.com>
+
+	PR tree-optimization/115152
+	* gcc.dg/pr115152.c: New test.
+
+2024-05-22  Jakub Jelinek  <jakub@redhat.com>
+
+	Backported from master:
+	2024-05-22  Jakub Jelinek  <jakub@redhat.com>
+
+	PR sanitizer/115172
+	* gcc.dg/asan/pr115172.c: New test.
+
+2024-05-21  Harald Anlauf  <anlauf@gmx.de>
+
+	Backported from master:
+	2024-05-11  Harald Anlauf  <anlauf@gmx.de>
+
+	PR fortran/115039
+	* gfortran.dg/statement_function_5.f90: New test.
+
+2024-05-21  Kewen Lin  <linkw@linux.ibm.com>
+
+	Backported from master:
+	2024-04-10  Kewen Lin  <linkw@linux.ibm.com>
+
+	PR testsuite/114662
+	* gcc.dg/lto/pr113359-2_0.c: Use unsigned long long instead of
+	unsigned long.
+	* gcc.dg/lto/pr113359-2_1.c: Likewise.
+
+2024-05-21  Andrew Pinski  <quic_apinski@quicinc.com>
+
+	Backported from master:
+	2024-05-20  Andrew Pinski  <quic_apinski@quicinc.com>
+
+	PR tree-optimization/115143
+	* gcc.c-torture/compile/pr115143-1.c: New test.
+	* gcc.c-torture/compile/pr115143-2.c: New test.
+	* gcc.c-torture/compile/pr115143-3.c: New test.
+
+2024-05-21  Andrew Pinski  <quic_apinski@quicinc.com>
+
+	Backported from master:
+	2024-05-21  Andrew Pinski  <quic_apinski@quicinc.com>
+
+	PR tree-optimization/115154
+	* c-c++-common/ubsan/signed1bitfield-1.c: New test.
+	* gcc.c-torture/execute/signed1bitfield-1.c: New test.
+
 2024-05-21  Release Manager
 
 	* GCC 13.3.0 released.
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/c-c++-common/Warray-compare-3.c
@@ -0,0 +1,13 @@
+/* PR c/115290 */
+/* { dg-do compile } */
+/* { dg-options "-Warray-compare" } */
+
+int a[32][32], b[32][32];
+
+int
+foo (int x, int y)
+{
+  return (x ? a : b) == (y ? a : b); /* { dg-warning "comparison between two arrays" } */
+/* { dg-message "use '&\\\(\[^\n\r]*\\\)\\\[0\\\] == &\\\(\[^\n\r]*\\\)\\\[0\\\]' to compare the addresses" "" { target c } .-1 } */
+/* { dg-message "use unary '\\\+' which decays operands to pointers or '&\\\(\[^\n\r]*\\\)\\\[0\\\] == &\\\(\[^\n\r]*\\\)\\\[0\\\]' to compare the addresses" "" { target c++ } .-2 } */
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/c-c++-common/torture/pr116189-1.c
@@ -0,0 +1,30 @@
+/* { dg-additional-options "-fcompare-debug" } */
+
+/* PR target/116189 */
+
+/* In the sh backend, we used to create insn in the path of rtx_costs.
+   This means sometimes the max uid for insns would be different between
+   debugging and non debugging which then would cause gcse's hashtable
+   to have different number of slots which would cause a different walk
+   for that hash table.  */
+
+extern void ff(void);
+extern short nn[8][4];
+typedef unsigned short move_table[4];
+extern signed long long ira_overall_cost;
+extern signed long long ira_load_cost;
+extern move_table *x_ira_register_move_cost[1];
+struct move { struct move *next; };
+unsigned short t;
+void emit_move_list(struct move * list, int freq, unsigned char mode, int regno) {
+  int cost;
+  for (; list != 0; list = list->next)
+  {
+    ff();
+    unsigned short aclass = t;
+    cost = (nn)[mode][aclass] ;
+    ira_load_cost = cost;
+    cost = x_ira_register_move_cost[mode][aclass][aclass] * freq ;
+    ira_overall_cost = cost;
+  }
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/c-c++-common/ubsan/signed1bitfield-1.c
@@ -0,0 +1,25 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fsanitize=undefined" } */
+
+/* PR tree-optimization/115154 */
+/* This was being miscompiled with -fsanitize=undefined due to
+   `(signed:1)(t*5)` being transformed into `-((signed:1)t)` which
+   is undefined. */
+
+struct s {
+  signed b : 1;
+} f;
+int i = 55;
+__attribute__((noinline))
+void check(int a)
+{
+        if (!a)
+        __builtin_abort();
+}
+int main() {
+    int t = i != 5;
+    t = t*5;
+    f.b = t;
+    int tt = f.b;
+    check(f.b);
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/g++.dg/cpp0x/initlist-pmf2.C
@@ -0,0 +1,12 @@
+// PR c++/113598
+// { dg-additional-options -Wno-c++11-extensions }
+
+struct Cpu
+{
+  int op_nop();
+};
+typedef int(Cpu::*OpCode)();
+void f()
+{
+  new OpCode[256]{&Cpu::op_nop};
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/g++.dg/cpp1z/pr115440.C
@@ -0,0 +1,8 @@
+// PR driver/115440
+// { dg-do compile { target c++17_only } }
+// { dg-options "--c++17" }
+
+int i;
+
+// { dg-bogus "unrecognized command-line option '--c\\\+\\\+17'; did you mean '--stdc\\\+\\\+17'" "" { target *-*-* } 0 }
+// { dg-error "unrecognized command-line option '--c\\\+\\\+17'" "" { target *-*-* } 0 }
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/g++.dg/cpp23/ext-floating18.C
@@ -0,0 +1,26 @@
+// P1467R9 - Extended floating-point types and standard names.
+// { dg-do compile { target c++23 } }
+// { dg-options "" }
+// { dg-add-options float32 }
+
+constexpr int foo (float) { return 1; }
+constexpr int foo (double) { return 2; }
+constexpr int foo (long double) { return 3; }
+
+#ifdef __STDCPP_FLOAT32_T__
+#if __FLT_MAX_EXP__ == __FLT32_MAX_EXP__ \
+    && __FLT_MAX_DIG__ == __FLT32_MAX_DIG__
+#if __FLT_MAX_EXP__ == __DBL_MAX_EXP__ \
+    && __FLT_MAX_DIG__ == __DBL_MAX_DIG__
+static_assert (foo (1.0f32) == 2);
+#else
+static_assert (foo (1.0f32) == 1);
+#endif
+#endif
+#endif
+#ifdef __STDCPP_FLOAT64_T__
+#if __DBL_MAX_EXP__ == __FLT64_MAX_EXP__ \
+    && __DBL_MAX_DIG__ == __FLT64_MAX_DIG__
+static_assert (foo (1.0f64) == 2);
+#endif
+#endif
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/g++.dg/cpp2a/spaceship-synth16.C
@@ -0,0 +1,13 @@
+// PR c++/113063
+// { dg-do link { target c++20 } }
+
+#include <compare>
+
+int main() {
+  struct X {
+    auto operator<=>(const X&) const = default;
+  };
+  X x;
+  static_assert(noexcept(x <=> x));
+  x <=> x;
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/g++.dg/cpp2a/spaceship-synth16a.C
@@ -0,0 +1,16 @@
+// PR c++/116289
+// PR c++/113063
+// { dg-do link { target c++20 } }
+// A version of spaceship-synth16.C where the local class isn't empty.
+
+#include <compare>
+
+int main() {
+  struct X {
+    int m = 0;
+    auto operator<=>(const X&) const = default;
+  };
+  X x;
+  static_assert(noexcept(x <=> x));
+  x <=> x;
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/g++.dg/ext/unroll-4.C
@@ -0,0 +1,16 @@
+// PR c++/111529
+// { dg-do compile { target c++11 } }
+// { dg-additional-options -Wno-c++20-extensions }
+
+template <int>
+void f() {
+  []<int>() {
+    #pragma GCC unroll 9
+    for (int i = 1; i; --i) {
+    }
+  };
+}
+
+int main() {
+  f<0>();
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/g++.target/powerpc/pr106069.C
@@ -0,0 +1,119 @@
+/* { dg-do run } */
+/* { dg-options "-O -fno-tree-forwprop -maltivec" } */
+/* { dg-require-effective-target vmx_hw } */
+
+typedef __attribute__ ((altivec (vector__))) unsigned native_simd_type;
+
+union
+{
+  native_simd_type V;
+  int R[4];
+} store_le_vec;
+
+struct S
+{
+  S () = default;
+  S (unsigned B0)
+  {
+    native_simd_type val{B0};
+    m_simd = val;
+  }
+  void store_le (unsigned int out[])
+  {
+    store_le_vec.V = m_simd;
+    unsigned int x0 = store_le_vec.R[0];
+    __builtin_memcpy (out, &x0, 4);
+  }
+  S rotl (unsigned int r)
+  {
+    native_simd_type rot{r};
+    return __builtin_vec_rl (m_simd, rot);
+  }
+  void operator+= (S other)
+  {
+    m_simd = __builtin_vec_add (m_simd, other.m_simd);
+  }
+  void operator^= (S other)
+  {
+    m_simd = __builtin_vec_xor (m_simd, other.m_simd);
+  }
+  static void transpose (S &B0, S B1, S B2, S B3)
+  {
+    native_simd_type T0 = __builtin_vec_mergeh (B0.m_simd, B2.m_simd);
+    native_simd_type T1 = __builtin_vec_mergeh (B1.m_simd, B3.m_simd);
+    native_simd_type T2 = __builtin_vec_mergel (B0.m_simd, B2.m_simd);
+    native_simd_type T3 = __builtin_vec_mergel (B1.m_simd, B3.m_simd);
+    B0 = __builtin_vec_mergeh (T0, T1);
+    B3 = __builtin_vec_mergel (T2, T3);
+  }
+  S (native_simd_type x) : m_simd (x) {}
+  native_simd_type m_simd;
+};
+
+void
+foo (unsigned int output[], unsigned state[])
+{
+  S R00 = state[0];
+  S R01 = state[0];
+  S R02 = state[2];
+  S R03 = state[0];
+  S R05 = state[5];
+  S R06 = state[6];
+  S R07 = state[7];
+  S R08 = state[8];
+  S R09 = state[9];
+  S R10 = state[10];
+  S R11 = state[11];
+  S R12 = state[12];
+  S R13 = state[13];
+  S R14 = state[4];
+  S R15 = state[15];
+  for (int r = 0; r != 10; ++r)
+    {
+      R09 += R13;
+      R11 += R15;
+      R05 ^= R09;
+      R06 ^= R10;
+      R07 ^= R11;
+      R07 = R07.rotl (7);
+      R00 += R05;
+      R01 += R06;
+      R02 += R07;
+      R15 ^= R00;
+      R12 ^= R01;
+      R13 ^= R02;
+      R00 += R05;
+      R01 += R06;
+      R02 += R07;
+      R15 ^= R00;
+      R12 = R12.rotl (8);
+      R13 = R13.rotl (8);
+      R10 += R15;
+      R11 += R12;
+      R08 += R13;
+      R09 += R14;
+      R05 ^= R10;
+      R06 ^= R11;
+      R07 ^= R08;
+      R05 = R05.rotl (7);
+      R06 = R06.rotl (7);
+      R07 = R07.rotl (7);
+    }
+  R00 += state[0];
+  S::transpose (R00, R01, R02, R03);
+  R00.store_le (output);
+}
+
+unsigned int res[1];
+unsigned main_state[]{1634760805, 60878,      2036477234, 6,
+		      0,	  825562964,  1471091955, 1346092787,
+		      506976774,  4197066702, 518848283,  118491664,
+		      0,	  0,	      0,	  0};
+int
+main ()
+{
+  foo (res, main_state);
+  if (res[0] != 0x41fcef98)
+    __builtin_abort ();
+  return 0;
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.c-torture/compile/pr115143-1.c
@@ -0,0 +1,21 @@
+/* PR tree-optimization/115143 */
+/* This used to ICE.
+   minmax part of phiopt would transform,
+   would transform `a!=0?min(a, b) : 0` into `min(a,b)`
+   which was correct except b was defined by a phi in the inner
+   bb which was not handled. */
+short a, d;
+char b;
+long c;
+unsigned long e, f;
+void g(unsigned long h) {
+  if (c ? e : b)
+    if (e)
+      if (d) {
+        a = f ? ({
+          unsigned long i = d ? f : 0, j = e ? h : 0;
+          i < j ? i : j;
+        }) : 0;
+      }
+}
+
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.c-torture/compile/pr115143-2.c
@@ -0,0 +1,30 @@
+/* { dg-options "-fgimple" } */
+/* PR tree-optimization/115143 */
+/* This used to ICE.
+   minmax part of phiopt would transform,
+   would transform `a!=0?min(a, b) : 0` into `min(a,b)`
+   which was correct except b was defined by a phi in the inner
+   bb which was not handled. */
+unsigned __GIMPLE (ssa,startwith("phiopt"))
+foo (unsigned a, unsigned b)
+{
+  unsigned j;
+  unsigned _23;
+  unsigned _12;
+
+  __BB(2):
+  if (a_6(D) != 0u)
+    goto __BB3;
+  else
+    goto __BB4;
+
+  __BB(3):
+  j_10 = __PHI (__BB2: b_11(D));
+  _23 = __MIN (a_6(D), j_10);
+  goto __BB4;
+
+  __BB(4):
+  _12 = __PHI (__BB3: _23, __BB2: 0u);
+  return _12;
+
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.c-torture/compile/pr115143-3.c
@@ -0,0 +1,29 @@
+/* { dg-options "-fgimple" } */
+/* PR tree-optimization/115143 */
+/* This used to ICE.
+   minmax part of phiopt would transform,
+   would transform `a!=0?min(a, b) : 0` into `min(a,b)`
+   which was correct except b was defined by a phi in the inner
+   bb which was not handled. */
+unsigned __GIMPLE (ssa,startwith("phiopt"))
+foo (unsigned a, unsigned b)
+{
+  unsigned j;
+  unsigned _23;
+  unsigned _12;
+
+  __BB(2):
+  if (a_6(D) > 0u)
+    goto __BB3;
+  else
+    goto __BB4;
+
+  __BB(3):
+  j_10 = __PHI (__BB2: b_7(D));
+  _23 = __MIN (a_6(D), j_10);
+  goto __BB4;
+
+  __BB(4):
+  _12 = __PHI (__BB3: _23, __BB2: 0u);
+  return _12;
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.c-torture/compile/pr115277.c
@@ -0,0 +1,28 @@
+int array[1000];
+void
+test (int a)
+{
+        if (__builtin_expect (a > 3, 1))
+                return;
+        for (int i = 0; i < a; i++)
+                array[i]=i;
+}
+void
+test2 (int a)
+{
+        if (__builtin_expect (a > 10, 1))
+                return;
+        for (int i = 0; i < a; i++)
+                array[i]=i;
+}
+int
+main()
+{
+        test(1);
+        test(2);
+        test(3);
+        test2(10);
+        if (array[9] != 9)
+                __builtin_abort ();
+        return 0;
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.c-torture/execute/pr108789.c
@@ -0,0 +1,39 @@
+/* PR middle-end/108789 */
+
+int
+add (unsigned *r, const unsigned *a, const unsigned *b)
+{
+  return __builtin_add_overflow (*a, *b, r);
+}
+
+int
+mul (unsigned *r, const unsigned *a, const unsigned *b)
+{
+  return __builtin_mul_overflow (*a, *b, r);
+}
+
+int
+main ()
+{
+  unsigned x;
+
+  /* 1073741824U + 1073741824U should not overflow.  */
+  x = (__INT_MAX__ + 1U) / 2;
+  if (add (&x, &x, &x))
+    __builtin_abort ();
+
+  /* 256U * 256U should not overflow */
+  x = 1U << (sizeof (int) * __CHAR_BIT__ / 4);
+  if (mul (&x, &x, &x))
+    __builtin_abort ();
+
+  /* 2147483648U + 2147483648U should overflow */
+  x = __INT_MAX__ + 1U;
+  if (!add (&x, &x, &x))
+    __builtin_abort ();
+
+  /* 65536U * 65536U should overflow */
+  x = 1U << (sizeof (int) * __CHAR_BIT__ / 2);
+  if (!mul (&x, &x, &x))
+    __builtin_abort ();
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.c-torture/execute/signed1bitfield-1.c
@@ -0,0 +1,23 @@
+/* PR tree-optimization/115154 */
+/* This was being miscompiled to `(signed:1)(t*5)`
+   being transformed into `-((signed:1)t)` which is undefined.
+   Note there is a pattern which removes the negative in some cases
+   which works around the issue.  */
+
+struct {
+  signed b : 1;
+} f;
+int i = 55;
+__attribute__((noinline))
+void check(int a)
+{
+        if (!a)
+        __builtin_abort();
+}
+int main() {
+    int t = i != 5;
+    t = t*5;
+    f.b = t;
+    int tt = f.b;
+    check(f.b);
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.dg/asan/pr115172.c
@@ -0,0 +1,20 @@
+/* PR sanitizer/115172 */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -fsanitize=address,bool -ffat-lto-objects -fdump-tree-asan1" } */
+/* { dg-final { scan-tree-dump-not "\.ASAN_CHECK " "asan1" } } */
+
+#ifdef __x86_64__
+#define SEG __seg_gs
+#else
+#define SEG __seg_fs
+#endif
+
+extern struct S { _Bool b; } s;
+void bar (void);
+
+void
+foo (void)
+{
+  if (*(volatile _Bool SEG *) (__UINTPTR_TYPE__) &s.b)
+    bar ();
+}
--- a/src/gcc/testsuite/gcc.dg/lto/pr113359-2_0.c
+++ b/src/gcc/testsuite/gcc.dg/lto/pr113359-2_0.c
@@ -8,15 +8,15 @@
 struct SA
 {
   unsigned int ax;
-  unsigned long ay;
-  unsigned long az;
+  unsigned long long ay;
+  unsigned long long az;
 };
 
 struct SB
 {
   unsigned int bx;
-  unsigned long by;
-  unsigned long bz;
+  unsigned long long by;
+  unsigned long long bz;
 };
 
 struct ZA
--- a/src/gcc/testsuite/gcc.dg/lto/pr113359-2_1.c
+++ b/src/gcc/testsuite/gcc.dg/lto/pr113359-2_1.c
@@ -5,15 +5,15 @@
 struct SA
 {
   unsigned int ax;
-  unsigned long ay;
-  unsigned long az;
+  unsigned long long ay;
+  unsigned long long az;
 };
 
 struct SB
 {
   unsigned int bx;
-  unsigned long by;
-  unsigned long bz;
+  unsigned long long by;
+  unsigned long long bz;
 };
 
 struct ZA
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.dg/pr114493-1.c
@@ -0,0 +1,19 @@
+/* PR c/114493 */
+/* { dg-do compile { target lto } } */
+/* { dg-options "-O2 -flto" } */
+
+void foo (void);
+struct S;
+struct S bar (struct S **);
+struct S qux (const struct S **);
+
+struct __attribute__((__may_alias__)) S {
+  int s;
+};
+
+struct S
+baz (void)
+{
+  foo ();
+  return (struct S) {};
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.dg/pr114493-2.c
@@ -0,0 +1,26 @@
+/* PR c/114493 */
+/* { dg-do compile { target lto } } */
+/* { dg-options "-O2 -flto -std=c2x" } */
+
+void foo (void);
+struct S;
+struct S bar (struct S **);
+struct S qux (const struct S **);
+
+void
+corge (void)
+{
+  struct S { int s; } s;
+  s.s = 0;
+}
+
+struct __attribute__((__may_alias__)) S {
+  int s;
+};
+
+struct S
+baz (void)
+{
+  foo ();
+  return (struct S) {};
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.dg/pr114902.c
@@ -0,0 +1,23 @@
+/* PR rtl-optimization/114902 */
+/* { dg-do run } */
+/* { dg-options "-O1 -fno-tree-fre -fno-tree-forwprop -fno-tree-ccp -fno-tree-dominator-opts" } */
+
+__attribute__((noipa))
+int foo (int x)
+{
+  int a = ~x;
+  int t = a & 1;
+  int e = -t;
+  int b = e >= -1;
+  if (b)
+    return 0;
+  __builtin_trap ();
+}
+
+int
+main ()
+{
+  foo (-1);
+  foo (0);
+  foo (1);
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.dg/pr115092.c
@@ -0,0 +1,16 @@
+/* PR rtl-optimization/115092 */
+/* { dg-do run } */
+/* { dg-options "-O1 -fgcse -ftree-pre -fno-tree-dominator-opts -fno-tree-fre -fno-guess-branch-probability" } */
+
+int a, b, c = 1, d, e;
+
+int
+main ()
+{
+  int f, g = a;
+  b = -2;
+  f = -(1 >> ((c && b) & ~a));
+  if (f <= b)
+    d = g / e;
+  return 0;
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.dg/pr115152.c
@@ -0,0 +1,17 @@
+/* PR tree-optimization/115152 */
+/* { dg-do run } */
+/* { dg-options "-O3 -fno-tree-fre -fno-tree-dominator-opts -fno-tree-loop-im" } */
+
+int a, b, c, d;
+signed char e[1] = { 1 };
+
+int
+main ()
+{
+  for (a = 0; a < 3; a++)
+    for (b = 0; b < 2; b++)
+      c = e[0] = e[0] ^ d;
+  if (!c)
+    __builtin_abort ();
+  return 0;
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.dg/vect/pr113281-1.c
@@ -0,0 +1,17 @@
+#include "tree-vect.h"
+
+unsigned char a;
+
+int main() {
+  check_vect ();
+
+  short b = a = 0;
+  for (; a != 19; a++)
+    if (a)
+      b = 32872 >> a;
+
+  if (b == 0)
+    return 0;
+  else
+    return 1;
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.dg/vect/pr113281-2.c
@@ -0,0 +1,50 @@
+/* { dg-do compile } */
+
+#define N 128
+
+short x[N];
+short y[N];
+
+void
+f1 (void)
+{
+  for (int i = 0; i < N; ++i)
+    x[i] >>= y[i];
+}
+
+void
+f2 (void)
+{
+  for (int i = 0; i < N; ++i)
+    x[i] >>= (y[i] < 32 ? y[i] : 32);
+}
+
+void
+f3 (void)
+{
+  for (int i = 0; i < N; ++i)
+    x[i] >>= (y[i] < 31 ? y[i] : 31);
+}
+
+void
+f4 (void)
+{
+  for (int i = 0; i < N; ++i)
+    x[i] >>= (y[i] & 31);
+}
+
+void
+f5 (void)
+{
+  for (int i = 0; i < N; ++i)
+    x[i] >>= 0x8000 >> y[i];
+}
+
+void
+f6 (void)
+{
+  for (int i = 0; i < N; ++i)
+    x[i] >>= 0x8000 >> (y[i] & 31);
+}
+
+/* { dg-final { scan-tree-dump-not {can narrow[^\n]+>>} "vect" } } */
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.dg/vect/pr113281-3.c
@@ -0,0 +1,39 @@
+/* { dg-do compile } */
+
+#define N 128
+
+short x[N];
+short y[N];
+
+void
+f1 (void)
+{
+  for (int i = 0; i < N; ++i)
+    x[i] >>= (y[i] < 30 ? y[i] : 30);
+}
+
+void
+f2 (void)
+{
+  for (int i = 0; i < N; ++i)
+    x[i] >>= ((y[i] & 15) + 2);
+}
+
+void
+f3 (void)
+{
+  for (int i = 0; i < N; ++i)
+    x[i] >>= (y[i] < 16 ? y[i] : 16);
+}
+
+void
+f4 (void)
+{
+  for (int i = 0; i < N; ++i)
+    x[i] = 32768 >> ((y[i] & 15) + 3);
+}
+
+/* { dg-final { scan-tree-dump {can narrow to signed:31 without loss [^\n]+>>} "vect" } } */
+/* { dg-final { scan-tree-dump {can narrow to signed:18 without loss [^\n]+>>} "vect" } } */
+/* { dg-final { scan-tree-dump {can narrow to signed:17 without loss [^\n]+>>} "vect" } } */
+/* { dg-final { scan-tree-dump {can narrow to unsigned:19 without loss [^\n]+>>} "vect" } } */
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.dg/vect/pr113281-4.c
@@ -0,0 +1,55 @@
+/* { dg-do compile } */
+
+#define N 128
+
+short x[N];
+short y[N];
+
+void
+f1 (void)
+{
+  for (int i = 0; i < N; ++i)
+    x[i] >>= (y[i] & 15);
+}
+
+void
+f2 (void)
+{
+  for (int i = 0; i < N; ++i)
+    x[i] >>= ((y[i] & 7) + 8);
+}
+
+void
+f3 (void)
+{
+  for (int i = 0; i < N; ++i)
+    x[i] >>= ((y[i] & 7) ^ 11);
+}
+
+void
+f4 (void)
+{
+  for (int i = 0; i < N; ++i)
+    x[i] >>= (y[i] < 15 ? y[i] : 15);
+}
+
+void
+f5 (void)
+{
+  for (int i = 0; i < N; ++i)
+    x[i] >>= (y[i] < 15 ? y[i] : 1);
+}
+
+void
+f6 (void)
+{
+  for (int i = 0; i < N; ++i)
+    x[i] = 32768 >> (y[i] & 15);
+}
+
+/* { dg-final { scan-tree-dump {:11:[^\n]+can narrow to signed:16 without loss [^\n]+>>} "vect" } } */
+/* { dg-final { scan-tree-dump {:18:[^\n]+can narrow to signed:16 without loss [^\n]+>>} "vect" } } */
+/* { dg-final { scan-tree-dump {:25:[^\n]+can narrow to signed:16 without loss [^\n]+>>} "vect" } } */
+/* { dg-final { scan-tree-dump {:32:[^\n]+can narrow to signed:16 without loss [^\n]+>>} "vect" } } */
+/* { dg-final { scan-tree-dump {:39:[^\n]+can narrow to signed:16 without loss [^\n]+>>} "vect" } } */
+/* { dg-final { scan-tree-dump {can narrow to unsigned:16 without loss [^\n]+>>} "vect" } } */
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.dg/vect/pr113281-5.c
@@ -0,0 +1,66 @@
+/* { dg-do compile } */
+
+#define N 128
+
+short x[N];
+short y[N];
+
+void
+f1 (void)
+{
+  for (int i = 0; i < N; ++i)
+    {
+      int a = y[i];
+      int b = ~a;
+      x[i] = b;
+    }
+}
+
+void
+f2 (void)
+{
+  for (int i = 0; i < N; ++i)
+    {
+      int a = y[i];
+      int b = -a;
+      x[i] = b;
+    }
+}
+
+void
+f3 (void)
+{
+  for (int i = 0; i < N; ++i)
+    {
+      int a = x[i];
+      int b = a / y[i];
+      x[i] = b;
+    }
+}
+
+void
+f4 (void)
+{
+  for (int i = 0; i < N; ++i)
+    {
+      int a = x[i];
+      int b = a < y[i] ? a : y[i];
+      x[i] = b;
+    }
+}
+
+void
+f5 (void)
+{
+  for (int i = 0; i < N; ++i)
+    {
+      int a = x[i];
+      int b = a > y[i] ? a : y[i];
+      x[i] = b;
+    }
+}
+
+/* { dg-final { scan-tree-dump {can narrow to signed:17 without loss [^\n]+= -} "vect" } } */
+/* { dg-final { scan-tree-dump {can narrow to signed:16 without loss [^\n]+= ~} "vect" } } */
+/* { dg-final { scan-tree-dump {can narrow to signed:16 without loss [^\n]+ MIN_EXPR} "vect" } } */
+/* { dg-final { scan-tree-dump {can narrow to signed:16 without loss [^\n]+ MAX_EXPR} "vect" } } */
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.dg/vect/pr115192.c
@@ -0,0 +1,28 @@
+#include "tree-vect.h"
+
+int data[4 * 16 * 16] __attribute__((aligned(16)));
+
+__attribute__((noipa)) void
+foo (__SIZE_TYPE__ n)
+{
+  for (__SIZE_TYPE__ i = 1; i < n; ++i)
+    {
+      data[i * n * 4] = data[(i - 1) * n * 4] + 1;
+      data[i * n * 4 + 1] = data[(i - 1) * n * 4 + 1] + 2;
+    }
+}
+
+int
+main ()
+{
+  check_vect ();
+
+  data[0] = 10;
+  data[1] = 20;
+
+  foo (3);
+
+  if (data[24] != 12 || data[25] != 24)
+    __builtin_abort ();
+  return 0;
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/aarch64/acle/bf16_feature.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+
+#pragma GCC target "+bf16"
+#ifndef __ARM_FEATURE_BF16
+#error "__ARM_FEATURE_BF16 is not defined but should be!"
+#endif
+
+void
+foo (void) {}
+
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/aarch64/acle/bf16_sve_feature.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+
+#pragma GCC target "+sve+bf16"
+#ifndef __ARM_FEATURE_SVE_BF16
+#error "__ARM_FEATURE_SVE_BF16 is not defined but should be!"
+#endif
+
+void
+foo (void) {}
+
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/aarch64/options_set_27.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=armv8.2-a+aes+sha3" } */
+
+int main ()
+{
+  return 0;
+}
+
+/* { dg-final { scan-assembler-times {\.arch armv8\.2\-a\+crc\+aes\+sha3\n} 1 } } */
--- a/src/gcc/testsuite/gcc.target/aarch64/options_set_4.c
+++ b/src/gcc/testsuite/gcc.target/aarch64/options_set_4.c
@@ -6,7 +6,7 @@ int main ()
   return 0;
 }
 
-/* { dg-final { scan-assembler-times {\.arch armv8\.2\-a\+crc\+crypto} 1 } } */
+/* { dg-final { scan-assembler-times {\.arch armv8\.2\-a\+crc\+crypto\n} 1 } } */
 
 /* Check if individual bits that make up a grouping is specified that only the
    grouping is kept. */
--- a/src/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/sudot_s32.c
+++ b/src/gcc/testsuite/gcc.target/aarch64/sve/acle/asm/sudot_s32.c
@@ -6,7 +6,7 @@
 
 /*
 ** sudot_s32_tied1:
-**	usdot	z0\.s, z2\.b, z4\.b
+**	usdot	z0\.s, z4\.b, z2\.b
 **	ret
 */
 TEST_TRIPLE_Z (sudot_s32_tied1, svint32_t, svint8_t, svuint8_t,
@@ -17,7 +17,7 @@ TEST_TRIPLE_Z (sudot_s32_tied1, svint32_t, svint8_t, svuint8_t,
 ** sudot_s32_tied2:
 **	mov	(z[0-9]+)\.d, z0\.d
 **	movprfx	z0, z4
-**	usdot	z0\.s, z2\.b, \1\.b
+**	usdot	z0\.s, \1\.b, z2\.b
 **	ret
 */
 TEST_TRIPLE_Z_REV (sudot_s32_tied2, svint32_t, svint8_t, svuint8_t,
@@ -27,7 +27,7 @@ TEST_TRIPLE_Z_REV (sudot_s32_tied2, svint32_t, svint8_t, svuint8_t,
 /*
 ** sudot_w0_s32_tied:
 **	mov	(z[0-9]+\.b), w0
-**	usdot	z0\.s, z2\.b, \1
+**	usdot	z0\.s, \1, z2\.b
 **	ret
 */
 TEST_TRIPLE_ZX (sudot_w0_s32_tied, svint32_t, svint8_t, uint8_t,
@@ -37,7 +37,7 @@ TEST_TRIPLE_ZX (sudot_w0_s32_tied, svint32_t, svint8_t, uint8_t,
 /*
 ** sudot_9_s32_tied:
 **	mov	(z[0-9]+\.b), #9
-**	usdot	z0\.s, z2\.b, \1
+**	usdot	z0\.s, \1, z2\.b
 **	ret
 */
 TEST_TRIPLE_Z (sudot_9_s32_tied, svint32_t, svint8_t, uint8_t,
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/aarch64/sve/acle/general/cnot_1.c
@@ -0,0 +1,23 @@
+/* { dg-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include <arm_sve.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** foo:
+**	cmpeq	(p[0-7])\.s, p0/z, z0\.s, #0
+**	mov	z0\.s, \1/z, #1
+**	ret
+*/
+svint32_t foo(svbool_t pg, svint32_t y)
+{
+  return svsel(svcmpeq(pg, y, 0), svdup_s32(1), svdup_s32(0));
+}
+
+#ifdef __cplusplus
+}
+#endif
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/alpha/pr115297.c
@@ -0,0 +1,13 @@
+/* PR target/115297 */
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+enum { BPF_F_USER_BUILD_ID } __bpf_get_stack_size;
+long __bpf_get_stack_flags, bpf_get_stack___trans_tmp_2;
+
+void bpf_get_stack() {
+  unsigned elem_size;
+  int err = elem_size = __bpf_get_stack_flags ?: sizeof(long);
+  if (__builtin_expect(__bpf_get_stack_size % elem_size, 0))
+    bpf_get_stack___trans_tmp_2 = err;
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/alpha/pr115526.c
@@ -0,0 +1,46 @@
+/* PR target/115526 */
+/* { dg-do assemble } */
+/* { dg-options "-O2 -Wno-attributes -fvisibility=hidden -fPIC -mcpu=ev4" } */
+
+struct _ts {
+  struct _dtoa_state *interp;
+};
+struct Bigint {
+  int k;
+} *_Py_dg_strtod_bs;
+struct _dtoa_state {
+  struct Bigint p5s;
+  struct Bigint *freelist[];
+};
+extern _Thread_local struct _ts _Py_tss_tstate;
+typedef struct Bigint Bigint;
+int pow5mult_k;
+long _Py_dg_strtod_ndigits;
+void PyMem_Free();
+void Bfree(Bigint *v) {
+  if (v)
+    {
+      if (v->k)
+	PyMem_Free();
+      else {
+	struct _dtoa_state *interp = _Py_tss_tstate.interp;
+	interp->freelist[v->k] = v;
+      }
+    }
+}
+static Bigint *pow5mult(Bigint *b) {
+  for (;;) {
+    if (pow5mult_k & 1) {
+      Bfree(b);
+      if (b == 0)
+        return 0;
+    }
+    if (!(pow5mult_k >>= 1))
+      break;
+  }
+  return 0;
+}
+void _Py_dg_strtod() {
+  if (_Py_dg_strtod_ndigits)
+    pow5mult(_Py_dg_strtod_bs);
+}
--- a/src/gcc/testsuite/gcc.target/arm/cmse/extend-param.c
+++ b/src/gcc/testsuite/gcc.target/arm/cmse/extend-param.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-mcmse" } */
+/* { dg-options "-mcmse -fshort-enums" } */
 /* { dg-final { check-function-bodies "**" "" "" } } */
 
 #include <arm_cmse.h>
@@ -78,7 +78,6 @@ __attribute__((cmse_nonsecure_entry)) char enumSecureFunc (enum offset index) {
   if (index >= ARRAY_SIZE)
     return 0;
   return array[index];
-
 }
 
 /*
@@ -88,9 +87,23 @@ __attribute__((cmse_nonsecure_entry)) char enumSecureFunc (enum offset index) {
 **	...
 */
 __attribute__((cmse_nonsecure_entry)) char boolSecureFunc (bool index) {
-
   if (index >= ARRAY_SIZE)
     return 0;
   return array[index];
+}
 
-}
\ No newline at end of file
+/*
+**__acle_se_boolCharShortEnumSecureFunc:
+**	...
+**	uxtb	r0, r0
+**	uxtb	r1, r1
+**	uxth	r2, r2
+**	uxtb	r3, r3
+**	...
+*/
+__attribute__((cmse_nonsecure_entry,optimize(0))) char boolCharShortEnumSecureFunc (bool a, unsigned char b, unsigned short c, enum offset d) {
+  size_t index = a + b + c + d;
+  if (index >= ARRAY_SIZE)
+    return 0;
+  return array[index];
+}
--- a/src/gcc/testsuite/gcc.target/arm/cmse/extend-return.c
+++ b/src/gcc/testsuite/gcc.target/arm/cmse/extend-return.c
@@ -1,5 +1,7 @@
 /* { dg-do compile } */
-/* { dg-options "-mcmse" } */
+/* { dg-options "-mcmse -fshort-enums" } */
+/* ARMv8-M expectation with target { ! arm_cmse_clear_ok }.  */
+/* ARMv8.1-M expectation with target arm_cmse_clear_ok.  */
 /* { dg-final { check-function-bodies "**" "" "" } } */
 
 #include <arm_cmse.h>
@@ -20,7 +22,15 @@ typedef enum offset __attribute__ ((cmse_nonsecure_call)) ns_enum_foo_t (void);
 typedef bool __attribute__ ((cmse_nonsecure_call)) ns_bool_foo_t (void);
 
 /*
-**unsignNonsecure0:
+**unsignNonsecure0:  { target arm_cmse_clear_ok }
+**	...
+**	blxns	r[0-3]
+**	...
+**	uxtb	r0, r0
+**	...
+*/
+/*
+**unsignNonsecure0: { target { ! arm_cmse_clear_ok } }
 **	...
 **	bl	__gnu_cmse_nonsecure_call
 **	uxtb	r0, r0
@@ -32,7 +42,15 @@ unsigned char unsignNonsecure0 (ns_unsign_foo_t * ns_foo_p)
 }
 
 /*
-**signNonsecure0:
+**signNonsecure0:  { target arm_cmse_clear_ok }
+**	...
+**	blxns	r[0-3]
+**	...
+**	sxtb	r0, r0
+**	...
+*/
+/*
+**signNonsecure0: { target { ! arm_cmse_clear_ok } }
 **	...
 **	bl	__gnu_cmse_nonsecure_call
 **	sxtb	r0, r0
@@ -44,7 +62,15 @@ signed char signNonsecure0 (ns_sign_foo_t * ns_foo_p)
 }
 
 /*
-**shortUnsignNonsecure0:
+**shortUnsignNonsecure0:  { target arm_cmse_clear_ok }
+**	...
+**	blxns	r[0-3]
+**	...
+**	uxth	r0, r0
+**	...
+*/
+/*
+**shortUnsignNonsecure0: { target { ! arm_cmse_clear_ok } }
 **	...
 **	bl	__gnu_cmse_nonsecure_call
 **	uxth	r0, r0
@@ -56,7 +82,15 @@ unsigned short shortUnsignNonsecure0 (ns_short_unsign_foo_t * ns_foo_p)
 }
 
 /*
-**shortSignNonsecure0:
+**shortSignNonsecure0:  { target arm_cmse_clear_ok }
+**	...
+**	blxns	r[0-3]
+**	...
+**	sxth	r0, r0
+**	...
+*/
+/*
+**shortSignNonsecure0: { target { ! arm_cmse_clear_ok } }
 **	...
 **	bl	__gnu_cmse_nonsecure_call
 **	sxth	r0, r0
@@ -68,7 +102,15 @@ signed short shortSignNonsecure0 (ns_short_sign_foo_t * ns_foo_p)
 }
 
 /*
-**enumNonsecure0:
+**enumNonsecure0:  { target arm_cmse_clear_ok }
+**	...
+**	blxns	r[0-3]
+**	...
+**	uxtb	r0, r0
+**	...
+*/
+/*
+**enumNonsecure0: { target { ! arm_cmse_clear_ok } }
 **	...
 **	bl	__gnu_cmse_nonsecure_call
 **	uxtb	r0, r0
@@ -80,7 +122,15 @@ unsigned char __attribute__((noipa)) enumNonsecure0 (ns_enum_foo_t * ns_foo_p)
 }
 
 /*
-**boolNonsecure0:
+**boolNonsecure0:  { target arm_cmse_clear_ok }
+**	...
+**	blxns	r[0-3]
+**	...
+**	uxtb	r0, r0
+**	...
+*/
+/*
+**boolNonsecure0: { target { ! arm_cmse_clear_ok } }
 **	...
 **	bl	__gnu_cmse_nonsecure_call
 **	uxtb	r0, r0
@@ -89,4 +139,4 @@ unsigned char __attribute__((noipa)) enumNonsecure0 (ns_enum_foo_t * ns_foo_p)
 unsigned char boolNonsecure0 (ns_bool_foo_t * ns_foo_p)
 {
   return ns_foo_p ();
-}
\ No newline at end of file
+}
--- a/src/gcc/testsuite/gcc.target/arm/copysign_softfloat_1.c
+++ b/src/gcc/testsuite/gcc.target/arm/copysign_softfloat_1.c
@@ -42,7 +42,6 @@ main (int argc, char **argv)
   int index = 0;
 
 /* { dg-final { scan-assembler-times "bfi" 2 { target arm_softfloat } } } */
-/* { dg-final { scan-assembler-times "lsr" 1 { target arm_softfloat } } } */
   for (index; index < N; index++)
     {
       if (__builtin_copysignf (a_f[index], b_f[index]) != c_f[index])
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_su64.c
@@ -0,0 +1,63 @@
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-add-options arm_v8_1m_mve } */
+/* { dg-require-effective-target arm_hard_ok } */
+/* { dg-additional-options "-mfloat-abi=hard -O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "arm_mve.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+**fn1:
+**	vmov	d0, r0, r1
+**	bx	lr
+*/
+uint64x2_t
+fn1 (uint64_t a, uint64x2_t b)
+{
+  return vsetq_lane_u64 (a, b, 0);
+}
+
+/*
+**fn2:
+**	vmov	d1, r0, r1
+**	bx	lr
+*/
+uint64x2_t
+fn2 (uint64_t a, uint64x2_t b)
+{
+  return vsetq_lane_u64 (a, b, 1);
+}
+
+/*
+**fn3:
+**	vmov	d0, r0, r1
+**	bx	lr
+*/
+int64x2_t
+fn3 (int64_t a, int64x2_t b)
+{
+  return vsetq_lane_s64 (a, b, 0);
+}
+
+/*
+**fn4:
+**	vmov	d1, r0, r1
+**	bx	lr
+*/
+int64x2_t
+fn4 (int64_t a, int64x2_t b)
+{
+  return vsetq_lane_s64 (a, b, 1);
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
+
--- a/src/gcc/testsuite/gcc.target/arm/simd/mve-vshr.c
+++ b/src/gcc/testsuite/gcc.target/arm/simd/mve-vshr.c
@@ -9,6 +9,8 @@
   void test_ ## NAME ##_ ## SIGN ## BITS ## x ## NB (TYPE##BITS##_t * __restrict__ dest, TYPE##BITS##_t *a, TYPE##BITS##_t *b) { \
     int i;								\
     for (i=0; i<NB; i++) {						\
+      if ((unsigned)b[i] >= (unsigned)(BITS))				\
+	__builtin_unreachable();					\
       dest[i] = a[i] OP b[i];						\
     }									\
 }
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/avr/torture/pr115307-isinf.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+
+int call_isinff (float f)
+{
+    int isinff (float);
+    return isinff (f);
+}
+
+int call_isinf (double f)
+{
+    int isinf (double);
+    return isinf (f);
+}
+
+int call_isinfl (long double f)
+{
+    int isinfl (long double);
+    return isinfl (f);
+}
+
+/* { dg-final { scan-assembler-not "unord" } } */
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/avr/torture/pr115317-isinf.c
@@ -0,0 +1,55 @@
+/* { dg-do run { target { ! avr_tiny } } } */
+
+extern int isinff (float);
+extern int isinf (double);
+extern int isinfl (long double);
+
+int tst_isinf (float x, int val)
+{
+  double y;
+  long double z;
+
+  __asm ("" : "+r"(x));
+  if (isinff (x) != val)
+    __builtin_exit (__LINE__);
+
+  y = x;
+  __asm ("" : "+r"(y));
+  if (isinf (y) != val)
+  __builtin_exit (__LINE__);
+
+  z = x;
+  __asm ("" : "+r"(z));
+  if (isinfl (z) != val)
+  __builtin_exit (__LINE__);
+}
+
+static float make_f (__UINT32_TYPE__ i)
+{
+  float f;
+  __builtin_memcpy (&f, &i, 4);
+  return f;
+}
+
+int main (void)
+{
+  tst_isinf (__builtin_huge_valf(), 1);
+  tst_isinf (-__builtin_huge_valf(), -1);
+  tst_isinf (__builtin_nanf(""), 0);
+  tst_isinf (0.0f, 0);
+  tst_isinf (-0.0f, 0);
+  tst_isinf (1.0f, 0);
+  tst_isinf (-1.0f, 0);
+  tst_isinf (make_f (0x7f800000), 1);
+  tst_isinf (make_f (0xff800000), -1);
+  tst_isinf (make_f (0x7f7fffff), 0);
+  tst_isinf (make_f (0xff7fffff), 0);
+  tst_isinf (make_f (0x7f800001), 0);
+  tst_isinf (make_f (0xff800001), 0);
+  tst_isinf (make_f (0x00800000), 0);
+  tst_isinf (make_f (0x80800000), 0);
+  tst_isinf (make_f (0x00400000), 0);
+  tst_isinf (make_f (0x80400000), 0);
+  
+  return 0;
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/avr/torture/pr116407-2.c
@@ -0,0 +1,34 @@
+/* { dg-do link } */
+
+typedef __UINT16_TYPE__ u16;
+typedef __INT16_TYPE__  T;
+
+#ifdef __OPTIMIZE__
+
+static __inline__ __attribute__((always_inline))
+void delay (T x, u16 nops)
+{
+    do
+        __builtin_avr_nops (nops);
+    while (--x != -1);
+}
+
+#ifdef __AVR_HAVE_JMP_CALL__
+
+void delay_2043 (T x) { delay (x, 2043); }
+void delay_2044 (T x) { delay (x, 2044); }
+void delay_2045 (T x) { delay (x, 2045); }
+void delay_2046 (T x) { delay (x, 2046); }
+
+#endif /* have JUMP, CALL */
+
+void delay_61 (T x) { delay (x, 61); }
+void delay_62 (T x) { delay (x, 62); }
+void delay_63 (T x) { delay (x, 63); }
+
+#endif /* optimize */
+
+int main (void)
+{
+    return 0;
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/avr/torture/pr116407-4.c
@@ -0,0 +1,34 @@
+/* { dg-do link } */
+
+typedef __UINT16_TYPE__ u16;
+typedef __INT32_TYPE__  T;
+
+#ifdef __OPTIMIZE__
+
+static __inline__ __attribute__((always_inline))
+void delay (T x, u16 nops)
+{
+    do
+        __builtin_avr_nops (nops);
+    while (--x != -1);
+}
+
+#ifdef __AVR_HAVE_JMP_CALL__
+
+void delay_2043 (T x) { delay (x, 2043); }
+void delay_2044 (T x) { delay (x, 2044); }
+void delay_2045 (T x) { delay (x, 2045); }
+void delay_2046 (T x) { delay (x, 2046); }
+
+#endif /* have JUMP, CALL */
+
+void delay_61 (T x) { delay (x, 61); }
+void delay_62 (T x) { delay (x, 62); }
+void delay_63 (T x) { delay (x, 63); }
+
+#endif /* optimize */
+
+int main (void)
+{
+    return 0;
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/avr/torture/pr87376.c
@@ -0,0 +1,60 @@
+/* { dg-do run { target { ! avr_tiny } } } */
+/* { dg-additional-options "-std=gnu99" } */
+
+typedef __UINT64_TYPE__ uint64_t;
+
+extern const __memx uint64_t aa __asm ("real_aa");
+extern const uint64_t bb __asm ("real_bb");
+
+const __memx uint64_t real_aa = 0x1122334455667788;
+const uint64_t real_bb        = 0x0908070605040302;
+
+__attribute__((noinline,noclone))
+uint64_t add1 (void)
+{
+  return aa + bb;
+}
+
+__attribute__((noinline,noclone))
+uint64_t add2 (void)
+{
+  return bb + aa;
+}
+
+__attribute__((noinline,noclone))
+uint64_t sub1 (void)
+{
+  return aa - bb;
+}
+
+__attribute__((noinline,noclone))
+uint64_t sub2 (void)
+{
+  return bb - aa;
+}
+
+__attribute__((noinline,noclone))
+uint64_t neg1 (void)
+{
+  return -aa;
+}
+
+int main (void)
+{
+  if (neg1() != -real_aa)
+  __builtin_exit (__LINE__);
+
+  if (add1() != real_aa + real_bb)
+    __builtin_exit (__LINE__);
+
+  if (add2() != real_bb + real_aa)
+    __builtin_exit (__LINE__);
+
+  if (sub1() != real_aa - real_bb)
+    __builtin_exit (__LINE__);
+  
+  if (sub2() != real_bb - real_aa)
+    __builtin_exit (__LINE__);
+
+  return 0;
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/avr/torture/pr88236-pr115726.c
@@ -0,0 +1,115 @@
+/* { dg-do run { target { ! avr_tiny } } } */
+/* { dg-additional-options "-std=gnu99" } */
+
+const __flash char fvals8[] = { 1, 2, 3 };
+char rvals8[] = { 0, 2, 4 };
+
+const __flash int fvals16[] = { 1, 2, 3 };
+int rvals16[] = { 0, 2, 4 };
+
+__attribute__((noinline, noclone))
+char xload8_r30 (const __memx char *pc)
+{
+  register char c __asm ("r30");
+  c = *pc;
+  __asm (";;" : "+r" (c));
+  return c;
+}
+
+__attribute__((noinline, noclone))
+int xload16_r30 (const __memx int *pc)
+{
+  register int c __asm ("r30");
+  c = *pc;
+  __asm (";;" : "+r" (c));
+  return c;
+}
+
+__attribute__((noinline, noclone))
+char xload8_r22 (const __memx char *pc)
+{
+  register char c __asm ("r22");
+  c = *pc;
+  __asm (";;" : "+r" (c));
+  return c;
+}
+
+__attribute__((noinline, noclone))
+int xload16_r22 (const __memx int *pc)
+{
+  register int c __asm ("r22");
+  c = *pc;
+  __asm (";;" : "+r" (c));
+  return c;
+}
+
+__attribute__((noinline, noclone))
+int xload16_r20 (const __memx int *pc)
+{
+  register int c __asm ("r20");
+  c = *pc;
+  __asm (";;" : "+r" (c));
+  return c;
+}
+
+void test8 (void)
+{
+  char c;
+  for (int i = 0; i < 3; ++i)
+    {
+      c = xload8_r30 (fvals8 + i);
+      if (c != 1 + i)
+	__builtin_exit (__LINE__);
+
+      c = xload8_r22 (fvals8 + i);
+      if (c != 1 + i)
+	__builtin_exit (__LINE__);
+
+      c = xload8_r30 (rvals8 + i);
+      if (c != 2 * i)
+	__builtin_exit (__LINE__);
+
+      c = xload8_r22 (rvals8 + i);
+      if (c != 2 * i)
+	__builtin_exit (__LINE__);
+    }
+}
+
+void test16 (void)
+{
+  int c;
+  for (int i = 0; i < 3; ++i)
+    {
+      c = xload16_r30 (fvals16 + i);
+      if (c != 1 + i)
+	__builtin_exit (__LINE__);
+
+      c = xload16_r22 (fvals16 + i);
+      if (c != 1 + i)
+	__builtin_exit (__LINE__);
+
+      c = xload16_r20 (fvals16 + i);
+      if (c != 1 + i)
+	__builtin_exit (__LINE__);
+
+      c = xload16_r30 (rvals16 + i);
+      if (c != 2 * i)
+	__builtin_exit (__LINE__);
+
+      c = xload16_r22 (rvals16 + i);
+      if (c != 2 * i)
+	__builtin_exit (__LINE__);
+
+      c = xload16_r20 (rvals16 + i);
+      if (c != 2 * i)
+	__builtin_exit (__LINE__);
+    }
+}
+
+int main (void)
+{
+  test8();
+  test16();
+
+  return 0;
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/avr/torture/pr98762.c
@@ -0,0 +1,19 @@
+/* { dg-do run } */
+/* { dg-additional-options "-std=c99" } */
+
+long long acc = 0x1122334455667788;
+
+__attribute__((noinline,noclone))
+void addhi (short a)
+{
+  acc += (long long) a << 32;
+}
+
+int main (void)
+{
+  addhi (0x0304);
+  if (acc != 0x1122364855667788)
+    __builtin_abort();
+
+  return 0;
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/i386/avx512bw-vpalignr-1b.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O0 -mavx512bw -mavx512vl" } */
+/* { dg-final { scan-assembler-times "vpalignr\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
+/* { dg-final { scan-assembler-times "vpalignr\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
+
+#include <immintrin.h>
+
+volatile __m256i y;
+volatile __m128i x;
+volatile __mmask32 m2;
+volatile __mmask16 m3;
+
+void extern
+avx512bw_test (void)
+{
+  y = _mm256_mask_alignr_epi8 (y, m2, y, y, 10);
+  x = _mm_mask_alignr_epi8 (x, m3, x, x, 10);
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/i386/avx512dq-vfpclasssd-1b.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-mavx512dq -O0" } */
+/* { dg-final { scan-assembler-times "vfpclasssd\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n^k\]*%k\[0-7\]\{%k\[0-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
+
+#include <immintrin.h>
+
+volatile __m128d x128;
+volatile __mmask8 m8;
+
+void extern
+avx512dq_test (void)
+{
+  m8 = _mm_mask_fpclass_sd_mask (m8, x128, 13);
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/i386/avx512dq-vfpclassss-1b.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-mavx512dq -O0" } */
+/* { dg-final { scan-assembler-times "vfpclassss\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n^k\]*%k\[0-7\]\{%k\[0-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
+
+#include <immintrin.h>
+
+volatile __m128 x128;
+volatile __mmask8 m8;
+
+void extern
+avx512dq_test (void)
+{
+  m8 = _mm_mask_fpclass_ss_mask (m8, x128, 13);
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/i386/avx512dq-vreducesd-1b.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-mavx512dq -O0" } */
+/* { dg-final { scan-assembler-times "vreducesd\[ \\t\]+\[^\{\n\]*\{sae\}\[^\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
+
+#include <immintrin.h>
+
+#define IMM 123
+
+volatile __m128d x1, x2, xx1, xx2;
+volatile __mmask8 m;
+
+void extern
+avx512dq_test (void)
+{
+  xx1 = _mm_reduce_round_sd (xx1, xx2, IMM, _MM_FROUND_NO_EXC);
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/i386/avx512dq-vreducess-1b.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-mavx512dq -O0" } */
+/* { dg-final { scan-assembler-times "vreducess\[ \\t\]+\[^\{\n\]*\{sae\}\[^\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]+\[^\n\]*%xmm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
+
+#include <immintrin.h>
+
+#define IMM 123
+
+volatile __m128 x1, x2, xx1, xx2;
+volatile __mmask8 m;
+
+void extern
+avx512dq_test (void)
+{
+  xx1 = _mm_reduce_round_ss (xx1, xx2, IMM, _MM_FROUND_NO_EXC);
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/i386/avx512fp16-vfpclassph-1c.c
@@ -0,0 +1,77 @@
+/* { dg-do run } */
+/* { dg-options "-O0 -mavx512fp16" } */
+/* { dg-require-effective-target avx512fp16 } */
+
+#define AVX512FP16
+#include "avx512f-helper.h"
+
+#include <math.h>
+#include <limits.h>
+#include <float.h>
+#define SIZE (AVX512F_LEN / 16)
+#include "avx512f-mask-type.h"
+
+#ifndef __FPCLASSPH__
+#define __FPCLASSPH__
+int check_fp_class_hp (_Float16 src, int imm)
+{
+  int qNaN_res = isnan (src);
+  int sNaN_res = isnan (src);
+  int Pzero_res = (src == 0.0);
+  int Nzero_res = (src == -0.0);
+  int PInf_res = (isinf (src) == 1);
+  int NInf_res = (isinf (src) == -1);
+  int Denorm_res = (fpclassify (src) == FP_SUBNORMAL);
+  int FinNeg_res = __builtin_finite (src) && (src < 0);
+
+  int result = (((imm & 1) && qNaN_res)
+		|| (((imm >> 1) & 1) && Pzero_res)
+		|| (((imm >> 2) & 1) && Nzero_res)
+		|| (((imm >> 3) & 1) && PInf_res)
+		|| (((imm >> 4) & 1) && NInf_res)
+		|| (((imm >> 5) & 1) && Denorm_res)
+		|| (((imm >> 6) & 1) && FinNeg_res)
+		|| (((imm >> 7) & 1) && sNaN_res));
+  return result;
+}
+#endif
+
+MASK_TYPE
+CALC (_Float16 *s1, int imm)
+{
+  int i;
+  MASK_TYPE res = 0;
+
+  for (i = 0; i < SIZE; i++)
+    if (check_fp_class_hp(s1[i], imm))
+      res = res | (1 << i);
+
+  return res;
+}
+
+void
+TEST (void)
+{
+  int i;
+  UNION_TYPE (AVX512F_LEN, h) src;
+  MASK_TYPE res1, res2, res_ref = 0;
+  MASK_TYPE mask = MASK_VALUE;
+
+  src.a[SIZE - 1] = NAN;
+  src.a[SIZE - 2] = 1.0 / 0.0;
+  for (i = 0; i < SIZE - 2; i++)
+    {
+      src.a[i] = -24.43 + 0.6 * i;
+    }
+
+  res1 = INTRINSIC (_fpclass_ph_mask) (src.x, 0xFF);
+  res2 = INTRINSIC (_mask_fpclass_ph_mask) (mask, src.x, 0xFF);
+
+  res_ref = CALC (src.a, 0xFF);
+
+  if (res_ref != res1)
+    abort ();
+
+  if ((mask & res_ref) != res2)
+    abort ();
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/i386/avx512vl-valignq-1b.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O0 -mavx512vl" } */
+/* { dg-final { scan-assembler-times "valignq\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\{%k\[1-7\]\}(?:\n|\[ \\t\]+#)" 1 } } */
+
+#include <immintrin.h>
+
+volatile __m256i y;
+volatile __m128i x;
+volatile __mmask8 m;
+
+void extern
+avx512vl_test (void)
+{
+  x = _mm_mask_alignr_epi64 (x, m, x, x, 1);
+}
--- a/src/gcc/testsuite/gcc.target/i386/pieces-memcpy-10.c
+++ b/src/gcc/testsuite/gcc.target/i386/pieces-memcpy-10.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -mno-avx2 -mavx -mtune=sandybridge" } */
+/* { dg-options "-O2 -mno-avx2 -mavx -mmove-max=128 -mstore-max=128 -mtune=sandybridge" } */
 
 extern char *dst, *src;
 
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/i386/pieces-memcpy-22.c
@@ -0,0 +1,12 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mno-avx2 -mavx -mtune=generic" } */
+
+extern char *dst, *src;
+
+void
+foo (void)
+{
+  __builtin_memcpy (dst, src, 33);
+}
+
+/* { dg-final { scan-assembler-times "vmovdqu\[ \\t\]+\[^\n\]*%ymm" 2 } } */
--- a/src/gcc/testsuite/gcc.target/i386/pieces-memcpy-6.c
+++ b/src/gcc/testsuite/gcc.target/i386/pieces-memcpy-6.c
@@ -1,5 +1,5 @@
 /* { dg-do compile { target { ! ia32 } } } */
-/* { dg-options "-O2 -mno-avx2 -mavx -mtune=sandybridge" } */
+/* { dg-options "-O2 -mno-avx2 -mavx -mmove-max=128 -mstore-max=128 -mtune=sandybridge" } */
 
 extern char *dst, *src;
 
--- a/src/gcc/testsuite/gcc.target/i386/pieces-memset-38.c
+++ b/src/gcc/testsuite/gcc.target/i386/pieces-memset-38.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -mno-avx512f -mavx2 -mtune=sandybridge" } */
+/* { dg-options "-O2 -mno-avx512f -mavx2 -mmove-max=128 -mstore-max=128 -mtune=sandybridge" } */
 
 extern char *dst;
 
--- a/src/gcc/testsuite/gcc.target/i386/pieces-memset-40.c
+++ b/src/gcc/testsuite/gcc.target/i386/pieces-memset-40.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -mno-avx512f -mavx2 -mtune=sandybridge" } */
+/* { dg-options "-O2 -mno-avx512f -mavx2 -mmove-max=128 -mstore-max=128 -mtune=sandybridge" } */
 
 extern char *dst;
 
--- a/src/gcc/testsuite/gcc.target/i386/pieces-memset-41.c
+++ b/src/gcc/testsuite/gcc.target/i386/pieces-memset-41.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -mno-avx2 -mavx -mtune=sandybridge -mno-stackrealign" } */
+/* { dg-options "-O2 -mno-avx2 -mavx -mmove-max=128 -mstore-max=128 -mtune=sandybridge -mno-stackrealign" } */
 
 extern char *dst;
 
--- a/src/gcc/testsuite/gcc.target/i386/pieces-memset-42.c
+++ b/src/gcc/testsuite/gcc.target/i386/pieces-memset-42.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -mno-avx2 -mavx -mtune=sandybridge" } */
+/* { dg-options "-O2 -mno-avx2 -mavx -mmove-max=128 -mstore-max=128 -mtune=sandybridge" } */
 
 extern char *dst;
 
--- a/src/gcc/testsuite/gcc.target/i386/pieces-memset-43.c
+++ b/src/gcc/testsuite/gcc.target/i386/pieces-memset-43.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -mno-avx2 -mavx -mtune=sandybridge" } */
+/* { dg-options "-O2 -mno-avx2 -mavx -mmove-max=128 -mstore-max=128 -mtune=sandybridge" } */
 
 extern char *dst;
 
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/i386/pieces-memset-51.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mno-avx2 -mavx -mtune=generic" } */
+
+extern char *dst;
+
+void
+foo (int x)
+{
+  __builtin_memset (dst, x, 64);
+}
+
+/* { dg-final { scan-assembler-times "vmovdqu\[ \\t\]+\[^\n\]*%ymm" 2 } } */
--- a/src/gcc/testsuite/gcc.target/i386/pieces-strcpy-2.c
+++ b/src/gcc/testsuite/gcc.target/i386/pieces-strcpy-2.c
@@ -1,5 +1,5 @@
 /* { dg-do compile { target { ! ia32 } } } */
-/* { dg-options "-O2 -mno-avx2 -mavx -mtune=sandybridge" } */
+/* { dg-options "-O2 -mno-avx2 -mavx -mmove-max=128 -mstore-max=128 -mtune=sandybridge" } */
 
 extern char *strcpy (char *, const char *);
 
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/i386/pieces-strcpy-3.c
@@ -0,0 +1,15 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mno-avx2 -mavx -mtune=generic" } */
+
+extern char *strcpy (char *, const char *);
+
+void
+foo (char *s)
+{
+  strcpy (s,
+	  "1234567890abcdef123456abcdef5678123456abcdef567abcdef678"
+	  "1234567");
+}
+
+/* { dg-final { scan-assembler-times "vmovdqa\[ \\t\]+\[^\n\]*%ymm" 2 } } */
+/* { dg-final { scan-assembler-times "vmovdqu\[ \\t\]+\[^\n\]*%ymm" 2 } } */
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/i386/pr115872.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -g" } */
+
+long set_work_pending_p;
+_Bool set_work_pending() {
+  _Bool __trans_tmp_1;
+  long mask = 1, old = __atomic_fetch_or(&set_work_pending_p, mask, 0);
+  __trans_tmp_1 = old & mask;
+  return !__trans_tmp_1;
+}
+void __queue_work() {
+  _Bool ret = set_work_pending();
+  if (ret)
+    __queue_work();
+}
+
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/i386/pr116043.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-mavx512bf16 -O3" } */
+/* { dg-final { scan-assembler-not {(?n)lea.*@gottpoff} } } */
+
+extern __thread int a, c, i, j, k, l;
+int *b;
+struct d {
+  int e;
+} f, g;
+char *h;
+
+void m(struct d *n) {
+  b = &k;
+  for (; n->e; b++, n--) {
+    i = b && a;
+    if (i)
+      j = c;
+  }
+}
+
+char *o(struct d *n) {
+  for (; n->e;)
+    return h;
+}
+
+int q() {
+  if (l)
+    return 1;
+  int p = *o(&g);
+  m(&f);
+  m(&g);
+  l = p;
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/i386/pr116512.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-march=x86-64-v4 -O2" } */
+/* { dg-final { scan-assembler-not "vzeroupper" { target { ! ia32 } } } } */
+
+#include <immintrin.h>
+
+struct B {
+  union {
+    __m512 f;
+    __m512i s;
+  };
+};
+
+struct B foo(int n) {
+  struct B res;
+  res.s = _mm512_set1_epi32(n);
+
+  return res;
+}
+
+__m512i bar(int n) {
+  struct B res;
+  res.s = _mm512_set1_epi32(n);
+
+  return res.s;
+}
--- a/src/gcc/testsuite/gcc.target/i386/prefetchi-1.c
+++ b/src/gcc/testsuite/gcc.target/i386/prefetchi-1.c
@@ -1,7 +1,7 @@
 /* { dg-do compile { target { ! ia32 } } } */
 /* { dg-options "-mprefetchi -O2" } */
-/* { dg-final { scan-assembler-times "\[ \\t\]+prefetchit0\[ \\t\]+" 2 } } */
-/* { dg-final { scan-assembler-times "\[ \\t\]+prefetchit1\[ \\t\]+" 2 } } */
+/* { dg-final { scan-assembler-times "\[ \\t\]+prefetchit0\[ \\t\]+bar\\(%rip\\)" 2 } } */
+/* { dg-final { scan-assembler-times "\[ \\t\]+prefetchit1\[ \\t\]+bar\\(%rip\\)" 2 } } */
 
 #include <x86intrin.h>
 
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/i386/prefetchi-1b.c
@@ -0,0 +1,26 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-mprefetchi -O0" } */
+/* { dg-final { scan-assembler-times "\[ \\t\]+prefetchit0\[ \\t\]+bar\\(%rip\\)" 1 } } */
+/* { dg-final { scan-assembler-times "\[ \\t\]+prefetchit1\[ \\t\]+bar\\(%rip\\)" 1 } } */
+
+#include <x86intrin.h>
+
+int
+bar (int a)
+{
+  return a + 1;
+}
+
+int
+foo1 (int b)
+{
+  _m_prefetchit0 (bar);
+  return bar (b) + 1;
+}
+
+int
+foo2 (int b)
+{
+  _m_prefetchit1 (bar);
+  return bar (b) + 1;
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/loongarch/pr115752.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+
+long double
+test (long double xx)
+{
+   __asm ("" :: "f"(xx)); /* { dg-error "inconsistent operand constraints in an 'asm'" } */
+   return xx + 1;
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/powerpc/pr106069-1.c
@@ -0,0 +1,39 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-require-effective-target vmx_hw } */
+
+/* Test vector merge for 8-bit element size,
+   it will abort if the RTL pattern isn't expected.  */
+
+#include "altivec.h"
+
+__attribute__((noipa))
+signed char elem_6 (vector signed char a, vector signed char b)
+{
+  vector signed char c = vec_mergeh (a,b);
+  return vec_extract (c, 6);
+}
+
+__attribute__((noipa))
+unsigned char elem_15 (vector unsigned char a, vector unsigned char b)
+{
+  vector unsigned char c = vec_mergel (a,b);
+  return vec_extract (c, 15);
+}
+
+int
+main ()
+{
+  vector unsigned char v1
+    = {3, 33, 22, 12, 34, 14, 5, 25, 30, 11, 0, 21, 17, 27, 38, 8};
+  vector unsigned char v2
+    = {81, 82, 83, 84, 68, 67, 66, 65, 99, 100, 101, 102, 250, 125, 0, 6};
+  signed char x1 = elem_6 ((vector signed char) v1, (vector signed char) v2);
+  unsigned char x2 = elem_15 (v1, v2);
+
+  if (x1 != 12 || x2 != 6)
+    __builtin_abort ();
+
+  return 0;
+}
+
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/powerpc/pr106069-2.c
@@ -0,0 +1,37 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-require-effective-target vmx_hw } */
+
+/* Test vector merge for 16-bit element size,
+   it will abort if the RTL pattern isn't expected.  */
+
+#include "altivec.h"
+
+__attribute__((noipa))
+signed short elem_2 (vector signed short a, vector signed short b)
+{
+  vector signed short c = vec_mergeh (a,b);
+  return vec_extract (c, 2);
+}
+
+__attribute__((noipa))
+unsigned short elem_7 (vector unsigned short a, vector unsigned short b)
+{
+  vector unsigned short c = vec_mergel (a,b);
+  return vec_extract (c, 7);
+}
+
+int
+main ()
+{
+  vector unsigned short v1 = {3, 22, 12, 34, 5, 25, 30, 11};
+  vector unsigned short v2 = {84, 168, 267, 966, 65, 399, 999, 99};
+  signed short x1 = elem_2 ((vector signed short) v1, (vector signed short) v2);
+  unsigned short x2 = elem_7 (v1, v2);
+
+  if (x1 != 22 || x2 != 99)
+    __builtin_abort ();
+
+  return 0;
+}
+
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/powerpc/pr114759-2.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mdejagnu-cpu=power8 -mrop-protect" } */
+/* { dg-require-effective-target rop_ok } Only enable on supported ABIs.  */
+
+/* Verify we generate ROP-protect hash insns when compiling for Power8.  */
+
+extern void foo (void);
+
+int
+bar (void)
+{
+  foo ();
+  return 5;
+}
+
+/* { dg-final { scan-assembler-times {\mhashst\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mhashchk\M} 1 } } */
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/powerpc/pr114759-3.c
@@ -0,0 +1,21 @@
+/* PR target/114759 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mdejagnu-cpu=power7 -mrop-protect" } */
+
+/* Verify we emit an error if we use -mrop-protect with an unsupported cpu
+   or ABI.  */
+
+extern void foo (void);
+
+int
+bar (void)
+{
+  foo ();
+  return 5;
+}
+
+/* The correct line number is in the preamble to the error message, not
+   in the final line (which is all that dg-error inspects). Hence, we have
+   to tell dg-error to ignore the line number.  */
+/* { dg-error "'-mrop-protect' requires '-mcpu=power8'" "PR114759" { target *-*-* } 0 } */
+/* { dg-error "'-mrop-protect' requires the ELFv2 ABI" "PR114759" { target { ! rop_ok } } 0 } */
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/powerpc/pr114846.c
@@ -0,0 +1,20 @@
+/* { dg-do run } */
+/* { dg-require-effective-target builtin_eh_return } */
+
+/* Ensure it runs successfully.  */
+
+__attribute__ ((noipa))
+int f (int *a, long offset, void *handler)
+{
+  if (*a == 5)
+    return 5;
+  __builtin_eh_return (offset, handler);
+}
+
+int main ()
+{
+  int t = 5;
+  if (f (&t, 0, 0) != 5)
+    __builtin_abort ();
+  return 0;
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/powerpc/pr115355.c
@@ -0,0 +1,37 @@
+/* { dg-do run } */
+/* { dg-require-effective-target p9vector_hw } */
+/* Force vectorization with -fno-vect-cost-model to have vector unpack
+   which exposes the issue in PR115355.  */
+/* { dg-options "-O2 -mdejagnu-cpu=power9 -fno-vect-cost-model" } */
+
+/* Verify it runs successfully.  */
+
+__attribute__((noipa))
+void setToIdentityGOOD(unsigned long long *mVec, unsigned int mLen)
+{
+  #pragma GCC novector
+  for (unsigned int i = 0; i < mLen; i++)
+    mVec[i] = i;
+}
+
+__attribute__((noipa))
+void setToIdentityBAD(unsigned long long *mVec, unsigned int mLen)
+{
+  for (unsigned int i = 0; i < mLen; i++)
+    mVec[i] = i;
+}
+
+unsigned long long vec1[100];
+unsigned long long vec2[100];
+
+int main()
+{
+  unsigned int l = 29;
+  setToIdentityGOOD (vec1, 29);
+  setToIdentityBAD (vec2, 29);
+
+  if (__builtin_memcmp (vec1, vec2, l * sizeof (vec1[0])) != 0)
+    __builtin_abort ();
+
+  return 0;
+}
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/powerpc/pr115389.c
@@ -0,0 +1,17 @@
+/* PR target/115389 */
+/* { dg-do assemble } */
+/* { dg-options "-O2 -mdejagnu-cpu=power10 -mrop-protect -mno-vsx -mno-altivec -mabi=no-altivec -save-temps" } */
+/* { dg-require-effective-target rop_ok } */
+
+/* Verify we do not emit invalid offsets for our ROP insns.  */
+
+extern void foo (void);
+long
+bar (void)
+{
+  foo ();
+  return 0;
+}
+
+/* { dg-final { scan-assembler-times {\mhashst\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mhashchk\M} 1 } } */
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gcc.target/powerpc/pr97367.c
@@ -0,0 +1,13 @@
+/* PR target/97367 */
+/* { dg-options "-mdejagnu-cpu=G5" } */
+
+/* Verify we emit a ".machine power4" and ".machine altivec" rather
+   than a ".machine power7".  */
+
+int dummy (void)
+{
+  return 0;
+}
+
+/* { dg-final { scan-assembler {\.machine power4\M} } } */
+/* { dg-final { scan-assembler {\.machine altivec\M} } } */
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gfortran.dg/allocate_with_source_32.f90
@@ -0,0 +1,33 @@
+! { dg-do run }
+!
+! PR fortran/83865
+!
+! Test ALLOCATE with SOURCE= of deferred length character, where
+! the source-expression is an array of character with length 0.
+
+program p
+  implicit none
+  character(:), allocatable :: z(:)
+  character(1) :: cc(4) = ""
+  allocate (z, source=[''])
+  if (len (z) /= 0 .or. size (z) /= 1) stop 1
+  deallocate (z)
+  allocate (z, source=['',''])
+  if (len (z) /= 0 .or. size (z) /= 2) stop 2
+  deallocate (z)
+  allocate (z, source=[ character(0) :: 'a','b','c'])
+  if (len (z) /= 0 .or. size (z) /= 3) stop 3
+  deallocate (z)
+  allocate (z, source=[ character(0) :: cc ])
+  if (len (z) /= 0 .or. size (z) /= 4) stop 4
+  deallocate (z)
+  associate (x => f())
+    if (len (x) /= 0 .or. size (x) /= 1) stop 5
+    if (x(1) /= '') stop 6
+  end associate
+contains
+  function f() result(z)
+    character(:), allocatable :: z(:)
+    allocate (z, source=[''])
+  end function f
+end
new file mode 100755
--- /dev/null
+++ b/src/gcc/testsuite/gfortran.dg/asan/pr110415-2.f90
@@ -0,0 +1,45 @@
+! { dg-do run }
+!
+! Contributed by Brad Richardson <everythingfunctional@protonmail.com>
+!
+implicit none
+  type, abstract :: p
+    integer :: a = 4
+  end type p
+
+  type, extends(p) :: c
+    integer :: b = 7
+    character(len=:), allocatable :: str, str2(:)
+  end type c
+
+  type, extends(p) :: d
+    integer :: ef = 7
+  end type d
+
+  class(p), allocatable :: a
+
+  a = func()
+
+  a = func2()
+
+  a = func()
+
+  deallocate(a)
+
+contains
+  function func2() result(a)
+    class(p), allocatable :: a
+    a = d()
+  end function func2
+
+  function func() result(a)
+    class(p), allocatable :: a
+
+    a = c()
+    select type(a)
+    type is (c)
+      a%str = 'abcd'
+      a%str2 = ['abcd','efgh']
+    end select
+  end function func
+end program
new file mode 100755
--- /dev/null
+++ b/src/gcc/testsuite/gfortran.dg/asan/pr110415-3.f90
@@ -0,0 +1,49 @@
+! { dg-do run }
+!
+! Contributed by Brad Richardson <everythingfunctional@protonmail.com>
+!
+implicit none
+  type, abstract :: p
+    integer :: a = 4
+  end type p
+
+  type, extends(p) :: c
+    integer :: b = 7
+    character(len=:), allocatable :: str, str2(:)
+  end type c
+
+  type, extends(p) :: d
+    integer :: ef = 7
+  end type d
+
+  class(p), allocatable :: a(:)
+
+  a = func()
+
+  a = func2()
+
+  a = func()
+
+  deallocate(a)
+
+contains
+  function func2() result(a)
+    class(p), allocatable :: a(:)
+    a = [d(),d()]
+  end function func2
+
+  function func() result(a)
+    class(p), allocatable :: a(:)
+
+    a = [c(),c(),c()]
+    select type(a)
+    type is (c)
+      a(1)%str = 'abcd'
+      a(2)%str = 'abc'
+      a(3)%str = 'abcd4'
+      a(1)%str2 = ['abcd','efgh']
+      a(2)%str2 = ['bcd','fgh']
+      a(3)%str2 = ['abcd6','efgh7']
+    end select
+  end function func
+end program
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gfortran.dg/asan/unlimited_polymorphic_34.f90
@@ -0,0 +1,135 @@
+! { dg-do run }
+! PR fortran/114827 - issues with class(*) assignment found by valgrind
+!
+! Contributed by Neil Carlson <neil.n.carlson@gmail.com>
+
+program main
+  implicit none
+  call run
+  call run1
+  call run2
+contains
+  ! Scalar tests
+  subroutine run ()
+    character(*),        parameter :: c = 'fubarfubarfubarfubarfubarfu'
+    character(*,kind=4), parameter :: d = 4_"abcdef"
+    complex,             parameter :: z = (1.,2.)
+    class(*),          allocatable :: y
+
+    call foo (c, y)
+    select type (y)
+    type is (character(*))
+!      print *, y(5:6)                  ! ICE (-> pr114874)
+       if (y /= c) stop 1
+    class default
+       stop 2
+    end select
+
+    call foo (z, y)
+    select type (y)
+    type is (complex)
+       if (y /= z) stop 3
+    class default
+       stop 4
+    end select
+
+    call foo (d, y)
+    select type (y)
+    type is (character(*,kind=4))
+!      print *, y                       ! NAG fails here
+       if (y /= d) stop 5
+    class default
+       stop 6
+    end select
+  end subroutine 
+  !
+  subroutine foo (a, b)
+    class(*), intent(in)  :: a
+    class(*), allocatable :: b
+    b = a
+  end subroutine
+
+  ! Rank-1 tests
+  subroutine run1 ()
+    character(*),        parameter :: c(*) = ['fubar','snafu']
+    character(*,kind=4), parameter :: d(*) = [4_"abc",4_"def"]
+    real,                parameter :: r(*) = [1.,2.,3.]
+    class(*),          allocatable :: y(:)
+
+    call foo1 (c, y)
+    select type (y)
+    type is (character(*))
+!      print *, ">",y(2)(1:3),"<  >", c(2)(1:3), "<"
+       if (any (y    /= c))        stop 11
+       if (y(2)(1:3) /= c(2)(1:3)) stop 12
+    class default
+       stop 13
+    end select
+
+    call foo1 (r, y)
+    select type (y)
+    type is (real)
+       if (any (y /= r)) stop 14
+    class default
+       stop 15
+    end select
+
+    call foo1 (d, y)
+    select type (y)
+    type is (character(*,kind=4))
+!      print *, ">",y(2)(2:3),"<  >", d(2)(2:3), "<"
+       if (any (y /= d)) stop 16
+    class default
+       stop 17
+    end select
+  end subroutine 
+  !
+  subroutine foo1 (a, b)
+    class(*), intent(in)  :: a(:)
+    class(*), allocatable :: b(:)
+    b = a
+  end subroutine
+
+  ! Rank-2 tests
+  subroutine run2 ()
+    character(7) :: c(2,3)
+    complex      :: z(3,3)
+    integer      :: i, j
+    class(*), allocatable :: y(:,:)
+
+    c = reshape (['fubar11','snafu21',&
+                  'fubar12','snafu22',&
+                  'fubar13','snafu23'],shape(c))
+    call foo2 (c, y)
+    select type (y)
+    type is (character(*))
+!      print *, y(2,1)
+       if (y(2,1) /= c(2,1)) stop 21
+       if (any (y /= c))     stop 22
+    class default
+       stop 23
+    end select
+
+    do    j = 1, size (z,2)
+       do i = 1, size (z,1)
+          z(i,j) = cmplx (i,j)
+       end do
+    end do
+    call foo2 (z, y)
+    select type (y)
+    type is (complex)
+!      print *, y(2,1)
+       if (any (y%re /= z%re)) stop 24
+       if (any (y%im /= z%im)) stop 25
+    class default
+       stop 26
+    end select
+  end subroutine 
+  !
+  subroutine foo2 (a, b)
+    class(*), intent(in)  :: a(:,:)
+    class(*), allocatable :: b(:,:)
+    b = a
+  end subroutine
+
+end program
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gfortran.dg/pr103312.f90
@@ -0,0 +1,87 @@
+! { dg-do run }
+!
+! Test the fix for pr103312, in which the use of a component call in
+! initialization expressions, eg. character(this%size()), caused ICEs.
+!
+! Contributed by Arseny Solokha  <asolokha@gmx.com>
+!
+module example
+
+  type, abstract :: foo
+    integer :: i
+  contains
+    procedure(foo_size), deferred :: size
+    procedure(foo_func), deferred :: func
+  end type
+
+  interface
+    function foo_func (this) result (string)
+      import :: foo
+      class(foo) :: this
+      character(this%size()) :: string
+    end function
+    pure integer function foo_size (this)
+      import foo
+      class(foo), intent(in) :: this
+    end function
+  end interface
+
+end module
+
+module extension
+  use example
+  implicit none
+  type, extends(foo) :: bar
+  contains
+    procedure :: size
+    procedure :: func
+  end type
+
+contains
+    pure integer function size (this)
+      class(bar), intent(in) :: this
+      size = this%i
+    end function
+    function func (this) result (string)
+      class(bar) :: this
+      character(this%size()) :: string
+      string = repeat ("x", len (string))
+    end function
+
+end module
+
+module unextended
+  implicit none
+  type :: foobar
+    integer :: i
+  contains
+    procedure :: size
+    procedure :: func
+  end type
+
+contains
+    pure integer function size (this)
+      class(foobar), intent(in) :: this
+      size = this%i
+    end function
+    function func (this) result (string)
+      class(foobar) :: this
+      character(this%size()) :: string
+      character(:), allocatable :: chr
+      string = repeat ("y", len (string))
+      allocate (character(this%size()) :: chr)
+      if (len (string) .ne. len (chr)) stop 1
+    end function
+
+end module
+
+  use example
+  use extension
+  use unextended
+  type(bar) :: a
+  type(foobar) :: b
+  a%i = 5
+  if (a%func() .ne. 'xxxxx') stop 2
+  b%i = 7
+  if (b%func() .ne. 'yyyyyyy') stop 3
+end
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gfortran.dg/pr108889.f90
@@ -0,0 +1,43 @@
+! { dg-do compile }
+! { dg-options "-Wall -fdump-tree-original" }
+!
+! Contributed by Tobias Burnus  <burnus@gcc.gnu.org>
+!
+program main
+  implicit none
+
+  type :: struct
+    real, allocatable :: var(:)
+  end type struct
+
+  type(struct) :: single
+  real, allocatable :: ref1(:), ref2(:), ref3(:), ref4(:)
+
+  ref2 = [1,2,3,4,5]    ! Warnings here
+
+  single%var = ref2     ! No warnings for components
+  ref1 = single%var     ! Warnings here
+  ref1 = [1,2,3,4,5]    ! Should not add to tree dump count
+
+  allocate (ref3(5))
+  ref3 = single%var     ! No warnings following allocation
+
+  call set_ref4
+
+  call test (ref1)
+  call test (ref2)
+  call test (ref3)
+  call test (ref4)
+
+contains
+  subroutine test (arg)
+    real, allocatable :: arg(:)
+    if (size(arg) /= size(single%var)) stop 1
+    if (lbound(arg, 1) /= 1) stop 2
+    if (any (arg /= single%var)) stop 3
+  end
+  subroutine set_ref4
+    ref4 = single%var   ! Warnings in contained scope
+  end
+end
+! { df-final { scan-tree-dump-times "ubound = 0" 3 "original" } }
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gfortran.dg/pr110415.f90
@@ -0,0 +1,20 @@
+! { dg-do run }
+!
+! Contributed by Brad Richardson <everythingfunctional@protonmail.com>
+!
+  type, abstract :: p
+  end type p
+
+  type, extends(p) :: c
+  end type c
+
+  class(p), allocatable :: a
+
+  a = func()
+contains
+  function func() result(a)
+    class(p), allocatable :: a
+
+    a = c()
+  end function func
+end program
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gfortran.dg/pr113363.f90
@@ -0,0 +1,86 @@
+! { dg-do run }
+! Test the fix for comment 1 in PR113363, which failed as in comments below.
+! Contributed by Harald Anlauf  <anlauf@gcc.gnu.org>
+program p
+  implicit none
+  class(*), allocatable :: x(:), y
+  character(*), parameter :: arr(2) = ["hello ","bye   "], &
+                             sca = "Have a nice day"
+  character(10) :: const
+
+! Bug was detected in polymorphic array function results
+  allocate(x, source = foo ())
+  call check1 (x, arr)              ! Wrong output "6 hello e"
+  deallocate (x)
+  x = foo ()
+  call check1 (x, arr)              ! Wrong output "0  "
+  associate (var => foo ())         ! OK after r14-9489-g3fd46d859cda10
+    call check1 (var, arr)          ! Now OK - outputs: "6 hello bye   "
+  end associate
+
+! Check scalar function results     ! All OK
+  allocate (y, source = bar())
+  call check2 (y, sca)
+  deallocate (y)
+  y = bar ()
+  call check2 (y, sca)
+  deallocate (y)
+  associate (var => bar ())
+    call check2 (var, sca)
+  end associate
+
+! Finally variable expressions...
+  allocate (y, source = x(1))       ! Gave zero length here
+  call check2 (y, "hello")
+  y = x(2)                          ! Segfaulted here
+  call check2 (y, "bye   ")
+  associate (var => x(2))           ! Gave zero length here
+    call check2 (var, "bye   ")
+  end associate
+
+! ...and constant expressions       ! All OK
+  deallocate(y)
+  allocate (y, source = "abcde")
+  call check2 (y, "abcde")
+  const = "hijklmnopq"
+  y = const
+  call check2 (y, "hijklmnopq")
+  associate (var => "mnopq")
+    call check2 (var, "mnopq")
+  end associate
+  deallocate (x, y)
+
+contains
+
+  function foo() result(res)
+    class(*), allocatable :: res(:)
+    res = arr
+  end function foo
+
+  function bar() result(res)
+    class(*), allocatable :: res
+    res = sca
+  end function bar
+
+  subroutine check1 (x, carg)
+    class(*), intent(in) :: x(:)
+    character(*) :: carg(:)
+    select type (x)
+    type is (character(*))
+      if (any (x .ne. carg)) stop 1
+    class default
+       stop 2
+    end select
+  end subroutine check1
+
+  subroutine check2 (x, carg)
+    class(*), intent(in) :: x
+    character(*) :: carg
+    select type (x)
+    type is (character(*))
+      if (x .ne. carg) stop 3
+    class default
+       stop 4
+    end select
+  end subroutine check2
+end
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gfortran.dg/shape_12.f90
@@ -0,0 +1,51 @@
+! { dg-do run }
+!
+! PR fortran/115150
+!
+! Check that SHAPE handles zero-sized arrays correctly
+!
+implicit none
+call one
+call two
+
+contains
+
+subroutine one
+  real,allocatable :: A(:),B(:,:)
+  allocate(a(3:0), b(5:1, 2:5))
+
+  if (any (shape(a) /= [0])) stop 1
+  if (any (shape(b) /= [0, 4])) stop 2
+  if (size(a) /= 0) stop 3
+  if (size(b) /= 0) stop 4
+  if (any (lbound(a) /= [1])) stop 5
+  if (any (lbound(b) /= [1, 2])) stop 6
+  if (any (ubound(a) /= [0])) stop 5
+  if (any (ubound(b) /= [0,5])) stop 6
+end
+
+subroutine two
+integer :: x1(10), x2(10,10)
+call f(x1, x2, -3)
+end
+
+subroutine f(y1, y2, n)
+  integer, value :: n
+  integer :: y1(1:n)
+  integer :: y2(1:n,4,2:*)
+  call g(y1, y2)
+end
+
+subroutine g(z1, z2)
+  integer :: z1(..), z2(..)
+
+  if (any (shape(z1) /= [0])) stop 1
+  if (any (shape(z2) /= [0, 4, -1])) stop 2
+  if (size(z1) /= 0) stop 3
+  if (size(z2) /= 0) stop 4
+  if (any (lbound(z1) /= [1])) stop 5
+  if (any (lbound(z2) /= [1, 1, 1])) stop 6
+  if (any (ubound(z1) /= [0])) stop 5
+  if (any (ubound(z2) /= [0, 4, -1])) stop 6
+end
+end
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gfortran.dg/statement_function_5.f90
@@ -0,0 +1,20 @@
+! { dg-do compile }
+! PR fortran/115039
+!
+! Check that inquiry refs work with statement functions
+!
+! { dg-additional-options "-std=legacy -fdump-tree-optimized" }
+! { dg-prune-output " Obsolescent feature" }
+! { dg-final { scan-tree-dump-not "_gfortran_stop_numeric" "optimized" } }
+
+program testit
+  implicit none
+  complex :: x
+  real    :: im
+  integer :: slen
+  character(5) :: s
+  im(x)   = x%im + x%re + x%kind
+  slen(s) = s%len
+  if (im((1.0,3.0) + (2.0,4.0)) /= 14.) stop 1
+  if (slen('abcdef') /= 5)              stop 2
+end program testit
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gfortran.dg/storage_size_7.f90
@@ -0,0 +1,91 @@
+! { dg-do run }
+! Fix STORAGE_SIZE intrinsic for polymorphic arguments PR84006 and PR100027.
+! Contributed by Steve Kargl  <kargls@comcast.net>
+!            and José Rui Faustino de Sousa  <jrfsousa@gcc.gnu.org>
+program p
+  use, intrinsic :: ISO_FORTRAN_ENV, only: int64
+  type t
+    integer i
+  end type
+  type s
+    class(t), allocatable :: c(:)
+  end type
+  integer :: rslt, class_rslt
+  integer(kind=int64), target :: tgt
+  class(t), allocatable, target :: t_alloc(:)
+  class(s), allocatable, target :: s_alloc(:)
+  character(:), allocatable, target :: chr(:)
+  class(*), pointer :: ptr_s, ptr_a(:)
+
+  allocate (t_alloc(2), source=t(1))
+  rslt = storage_size(t_alloc(1))      ! Scalar arg - the original testcase
+  if (rslt .ne. 32) stop 1
+
+  rslt = storage_size(t_alloc)         ! Array arg
+  if (rslt .ne. 32) stop 2
+
+  call pr100027
+
+  allocate (s_alloc(2), source=s([t(1), t(2)]))
+! This, of course, is processor dependent: gfortran gives 576, NAG 448
+! and Intel 1216.
+  class_rslt = storage_size(s_alloc)   ! Type with a class component
+  ptr_s => s_alloc(2)
+! However, the unlimited polymorphic result should be the same
+  if (storage_size (ptr_s) .ne. class_rslt) stop 3
+  ptr_a => s_alloc
+  if (storage_size (ptr_a) .ne. class_rslt) stop 4
+
+  rslt = storage_size(s_alloc(1)%c(2)) ! Scalar component arg
+  if (rslt .ne. 32) stop 5
+
+  rslt = storage_size(s_alloc(1)%c)    ! Scalar component of array arg
+  if (rslt .ne. 32) stop 6
+
+  ptr_s => tgt
+  rslt = storage_size (ptr_s)          ! INTEGER(8) target
+  if (rslt .ne. 64) stop 7
+
+  allocate (chr(2), source = ["abcde", "fghij"])
+  ptr_s => chr(2)
+  rslt = storage_size (ptr_s)          ! CHARACTER(5) scalar
+  if (rslt .ne. 40) stop 8
+
+  ptr_a => chr
+  rslt = storage_size (ptr_a)          ! CHARACTER(5) array
+  if (rslt .ne. 40) stop 9
+
+  deallocate (t_alloc, s_alloc, chr)   ! For valgrind check
+
+contains
+
+! Original testcase from José Rui Faustino de Sousa
+  subroutine pr100027
+    implicit none
+
+    integer, parameter :: n = 11
+
+    type :: foo_t
+    end type foo_t
+
+    type, extends(foo_t) :: bar_t
+    end type bar_t
+
+    class(*),     pointer :: apu(:)
+    class(foo_t), pointer :: apf(:)
+    class(bar_t), pointer :: apb(:)
+    type(bar_t),   target :: atb(n)
+
+    integer :: m
+
+    apu => atb
+    m = storage_size(apu)
+    if (m .ne. 0) stop 10
+    apf => atb
+    m = storage_size(apf)
+    if (m .ne. 0) stop 11
+    apb => atb
+    m = storage_size(apb)
+    if (m .ne. 0) stop 12
+  end
+end program p
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gfortran.dg/string_array_constructor_4.f90
@@ -0,0 +1,59 @@
+! { dg-do run }
+! PR fortran/103115 - character array constructor with >= 4 constant elements
+!
+! This used to ICE when the first element is deferred-length character
+! or could lead to wrong results.
+
+program pr103115
+  implicit none
+  integer :: i
+  character(*), parameter :: expect(*) = [ "1","2","3","4","5" ]
+  character(5)            :: abc = "12345"
+  character(5), parameter :: def = "12345"
+  character(:), dimension(:), allocatable :: list
+  character(:), dimension(:), allocatable :: titles
+  titles = ["1"]
+  titles = [ titles&
+            ,"2"&
+            ,"3"&
+            ,"4"&
+            ,"5"&  ! used to ICE
+            ]
+  if (len (titles) /= 1 .or. size (titles) /= 5) stop 1
+  if (any (titles  /= expect))                   stop 2
+  titles = ["1"]
+  titles = [ titles, (char(48+i),i=2,5) ]
+  if (len (titles) /= 1 .or. size (titles) /= 5) stop 3
+  if (any (titles  /= expect))                   stop 4
+  titles = ["1"]
+  titles = [ titles, ("2345"(i:i),i=1,4) ]
+  if (len (titles) /= 1 .or. size (titles) /= 5) stop 5
+  if (any (titles  /= expect))                   stop 6
+  titles = ["1"]
+  titles = [ titles, (def(i:i),i=2,5) ]
+  if (len (titles) /= 1 .or. size (titles) /= 5) stop 7
+  if (any (titles  /= expect))                   stop 8
+  list = [ (char(48+i),i=1,5) ]
+  titles = [ list(1), (char(48+i),i=2,5) ]
+  if (len (titles) /= 1 .or. size (titles) /= 5) stop 9
+  if (any (titles  /= expect))                   stop 10
+  titles = ["1"]
+  titles = [ titles, (abc(i:i),i=2,5) ]
+  if (len (titles) /= 1 .or. size (titles) /= 5) stop 11
+  if (any (titles  /= expect))                   stop 12
+
+  ! with typespec:
+  list = [ (char(48+i),i=1,5) ]
+  titles = [ character(2) :: list(1), (char(48+i),i=2,5) ]
+  if (len (titles) /= 2 .or. size (titles) /= 5) stop 13
+  if (any (titles  /= expect))                   stop 14
+  titles = ["1"]
+  titles = [ character(2) :: titles, (char(48+i),i=2,5) ]
+  if (len (titles) /= 2 .or. size (titles) /= 5) stop 15
+  if (any (titles  /= expect))                   stop 16
+  titles = ["1"]
+  titles = [ character(2) :: titles, (def(i:i),i=2,5) ]
+  if (len (titles) /= 2 .or. size (titles) /= 5) stop 17
+  if (any (titles  /= expect))                   stop 18
+  deallocate (titles, list)
+end
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gfortran.dg/transfer_class_4.f90
@@ -0,0 +1,87 @@
+! { dg-do run }
+!
+! Fix TRANSFER intrinsic for unlimited polymorphic SOURCEs - PR98534
+! Note that unlimited polymorphic MOLD is a TODO.
+!
+! Contributed by Paul Thomas  <pault@gcc.gnu.org>
+!
+  use, intrinsic :: ISO_FORTRAN_ENV, only: real32
+  implicit none
+  character(*), parameter :: string = "abcdefgh"
+  character(len=:), allocatable :: string_a(:)
+  class(*), allocatable :: star
+  class(*), allocatable :: star_a(:)
+  character(len=:), allocatable :: chr
+  character(len=:), allocatable :: chr_a(:)
+  integer :: sz, sum1, sum2, i
+  real(real32) :: r = 1.0
+
+! Part 1: worked correctly
+  star = r
+  sz = storage_size (star)/8
+  allocate (character(len=sz) :: chr)
+  chr = transfer (star, chr)
+  sum1 = sum ([(ichar(chr(i:i)), i = 1, sz)])
+  chr = transfer(1.0, chr)
+  sum2 = sum ([(ichar(chr(i:i)), i = 1, sz)])
+
+  if (sz /= storage_size (r)/8) stop 1
+  if (sum1 /= sum2) stop 2
+
+  deallocate (star) ! The automatic reallocation causes invalid writes
+                    ! and memory leaks. Even with this deallocation
+                    ! The invalid writes still occur.
+  deallocate (chr)
+
+! Part 2: Got everything wrong because '_len' field of unlimited polymorphic
+! expressions was not used.
+  star = string
+  sz = storage_size (star)/8
+  if (sz /= len (string)) stop 3 ! storage_size failed
+
+  sz = len (string) ! Ignore previous error in storage_size
+  allocate (character(len=sz) :: chr)
+  chr = transfer (star, chr)
+  sum1 = sum ([(ichar(chr(i:i)), i = 1, sz)])
+  chr = transfer(string, chr)
+  sum2 = sum ([(ichar(chr(i:i)), i = 1, sz)])
+  if (sum1 /= sum2) stop 4       ! transfer failed
+
+! Check that arrays are OK for transfer
+  star_a = ['abcde','fghij']
+  allocate (character (len = 5) :: chr_a(2))
+  chr_a = transfer (star_a, chr_a)
+  if (any (chr_a .ne. ['abcde','fghij'])) stop 5
+
+! Check that string length and size are correctly handled
+  string_a = ["abcdefgh", "ijklmnop"]
+  star_a = string_a;
+  chr_a = transfer (star_a, chr_a) ! Old string length used for size
+  if (size(chr_a) .ne. 4) stop 6
+  if (len(chr_a) .ne. 5) stop 7
+  if (trim (chr_a(3)) .ne. "klmno") stop 8
+  if (chr_a(4)(1:1) .ne. "p") stop 9
+
+  chr_a = transfer (star_a, string_a) ! Use correct string_length for payload
+  if (size(chr_a) .ne. 2) stop 10
+  if (len(chr_a) .ne. 8) stop 11
+  if (any (chr_a .ne. string_a)) stop 12
+
+! Check that an unlimited polymorphic function result is transferred OK
+  deallocate (chr_a)
+  string_a = ['abc', 'def', 'hij']
+  chr_a = transfer (foo (string_a), string_a)
+  if (any (chr_a .ne. string_a)) stop 13
+
+! Finally, check that the SIZE gives correct results with unlimited sources.
+  chr_a = transfer (star_a, chr_a, 4)
+  if (chr_a (4) .ne. 'jkl') stop 14
+
+  deallocate (star, chr, star_a, chr_a, string_a)
+contains
+  function foo (arg) result(res)
+    character(*), intent(in) :: arg(:)
+    class(*), allocatable :: res(:)
+    res = arg
+  end
+end
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gnat.dg/access11.adb
@@ -0,0 +1,80 @@
+--  PR ada/114398
+--  Testcase by Dennis van Raaij <d.van.raaij@gmail.com>
+
+--  { dg-do run }
+
+with Ada.Finalization;
+
+procedure Access11 is
+
+   package Pkg is
+
+      type Int is
+        new Ada.Finalization.Limited_Controlled
+      with record
+         Value : Integer;
+      end record;
+
+      procedure Set (This : out Int; To : Integer);
+      procedure Set (This : out Int; To : Int);
+
+      function "+" (Left, Right : Int) return Int;
+
+      overriding procedure Initialize (This : in out Int);
+      overriding procedure Finalize   (This : in out Int);
+
+   end Pkg;
+
+   package body Pkg is
+
+      procedure Set (This : out Int; To : Integer) is
+      begin
+         This.Value := To;
+      end Set;
+
+      procedure Set (This  : out Int; To : Int) is
+      begin
+         This.Value := To.Value;
+      end Set;
+
+      function "+" (Left, Right : Int) return Int is
+      begin
+         return Result : Int do
+            Result.Value := Left.Value + Right.Value;
+         end return;
+      end "+";
+
+      overriding procedure Initialize (This : in out Int) is
+      begin
+         This.Value := 42;
+      end Initialize;
+
+      overriding procedure Finalize (This : in out Int) is
+      begin
+         This.Value := 0;
+      end Finalize;
+
+   end Pkg;
+
+   use Pkg;
+
+   type Binary_Operator is access
+     function (Left, Right : Int) return Int;
+
+   procedure Test
+     (Op          : Binary_Operator;
+      Left, Right : Int)
+   is
+      Result : Int;
+   begin
+      Result.Set (Op (Left, Right));
+   end Test;
+
+   A, B : Int;
+
+begin
+   A.Set (7);
+   B.Set (9);
+
+   Test ("+"'Access, A, B);
+end;
new file mode 100644
--- /dev/null
+++ b/src/gcc/testsuite/gnat.dg/incomplete8.adb
@@ -0,0 +1,22 @@
+-- PR ada/114708
+-- Reported by Jere <jhb.chat@gmail.com>
+
+-- { dg-do compile }
+
+procedure Incomplete8 is
+
+  generic
+    type Element_Type(<>);
+  package Test_Incomplete_Formal is
+    type Element_Access is access Element_Type;
+  end Test_Incomplete_Formal;
+
+  type Node;
+
+  package P is new Test_Incomplete_Formal(Node);
+
+  type Node is limited null record;
+   
+begin
+  null;
+end;
--- a/src/gcc/testsuite/lib/target-supports.exp
+++ b/src/gcc/testsuite/lib/target-supports.exp
@@ -6919,7 +6919,7 @@ proc check_effective_target_powerpc_elfv2 { } {
 # Return 1 if this is a PowerPC target supporting -mrop-protect
 
 proc check_effective_target_rop_ok { } {
-    return [check_effective_target_power10_ok] && [check_effective_target_powerpc_elfv2]
+    return [check_effective_target_has_arch_pwr8] && [check_effective_target_powerpc_elfv2]
 }
 
 # The VxWorks SPARC simulator accepts only EM_SPARC executables and
--- a/src/gcc/tree-data-ref.cc
+++ b/src/gcc/tree-data-ref.cc
@@ -73,6 +73,7 @@ along with GCC; see the file COPYING3.  If not see
 
 */
 
+#define INCLUDE_ALGORITHM
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
@@ -2629,7 +2630,9 @@ create_intersect_range_checks (class loop *loop, tree *cond_expr,
 	 Because the maximum values are inclusive, there is an alias
 	 if the maximum value of one segment is equal to the minimum
 	 value of the other.  */
-      min_align = MIN (dr_a.align, dr_b.align);
+      min_align = std::min (dr_a.align, dr_b.align);
+      min_align = std::min (min_align, known_alignment (dr_a.access_size));
+      min_align = std::min (min_align, known_alignment (dr_b.access_size));
       cmp_code = LT_EXPR;
     }
 
--- a/src/gcc/tree-ssa-ccp.cc
+++ b/src/gcc/tree-ssa-ccp.cc
@@ -3321,9 +3321,10 @@ convert_atomic_bit_not (enum internal_fn fn, gimple *use_stmt,
     return nullptr;
 
   gimple_stmt_iterator gsi;
-  gsi = gsi_for_stmt (use_stmt);
-  gsi_remove (&gsi, true);
   tree var = make_ssa_name (TREE_TYPE (lhs));
+  /* use_stmt need to be removed after use_nop_stmt,
+     so use_lhs can be released.  */
+  gimple *use_stmt_removal = use_stmt;
   use_stmt = gimple_build_assign (var, BIT_AND_EXPR, lhs, and_mask);
   gsi = gsi_for_stmt (use_not_stmt);
   gsi_insert_before (&gsi, use_stmt, GSI_NEW_STMT);
@@ -3333,6 +3334,8 @@ convert_atomic_bit_not (enum internal_fn fn, gimple *use_stmt,
   gsi_insert_after (&gsi, g, GSI_NEW_STMT);
   gsi = gsi_for_stmt (use_not_stmt);
   gsi_remove (&gsi, true);
+  gsi = gsi_for_stmt (use_stmt_removal);
+  gsi_remove (&gsi, true);
   return use_stmt;
 }
 
@@ -3635,8 +3638,7 @@ optimize_atomic_bit_test_and (gimple_stmt_iterator *gsip,
 		       */
 		    }
 		  var = make_ssa_name (TREE_TYPE (use_rhs));
-		  gsi = gsi_for_stmt (use_stmt);
-		  gsi_remove (&gsi, true);
+		  gimple* use_stmt_removal = use_stmt;
 		  g = gimple_build_assign (var, BIT_AND_EXPR, use_rhs,
 					   and_mask);
 		  gsi = gsi_for_stmt (use_nop_stmt);
@@ -3653,6 +3655,8 @@ optimize_atomic_bit_test_and (gimple_stmt_iterator *gsip,
 		  gsi_insert_after (&gsi, g, GSI_NEW_STMT);
 		  gsi = gsi_for_stmt (use_nop_stmt);
 		  gsi_remove (&gsi, true);
+		  gsi = gsi_for_stmt (use_stmt_removal);
+		  gsi_remove (&gsi, true);
 		}
 	    }
 	  else
--- a/src/gcc/tree-ssa-phiopt.cc
+++ b/src/gcc/tree-ssa-phiopt.cc
@@ -2106,6 +2106,10 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb, basic_block alt_
 	  || gimple_code (assign) != GIMPLE_ASSIGN)
 	return false;
 
+      /* There cannot be any phi nodes in the middle bb. */
+      if (!gimple_seq_empty_p (phi_nodes (middle_bb)))
+	return false;
+
       lhs = gimple_assign_lhs (assign);
       ass_code = gimple_assign_rhs_code (assign);
       if (ass_code != MAX_EXPR && ass_code != MIN_EXPR)
@@ -2119,6 +2123,10 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb, basic_block alt_
 	  || gimple_code (assign) != GIMPLE_ASSIGN)
 	return false;
 
+      /* There cannot be any phi nodes in the alt middle bb. */
+      if (!gimple_seq_empty_p (phi_nodes (alt_middle_bb)))
+	return false;
+
       alt_lhs = gimple_assign_lhs (assign);
       if (ass_code != gimple_assign_rhs_code (assign))
 	return false;
@@ -2229,6 +2237,10 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb, basic_block alt_
 	  || gimple_code (assign) != GIMPLE_ASSIGN)
 	return false;
 
+      /* There cannot be any phi nodes in the middle bb. */
+      if (!gimple_seq_empty_p (phi_nodes (middle_bb)))
+	return false;
+
       lhs = gimple_assign_lhs (assign);
       ass_code = gimple_assign_rhs_code (assign);
       if (ass_code != MAX_EXPR && ass_code != MIN_EXPR)
--- a/src/gcc/tree-ssa-strlen.cc
+++ b/src/gcc/tree-ssa-strlen.cc
@@ -4836,7 +4836,7 @@ strlen_pass::count_nonzero_bytes_addr (tree exp, tree vuse, gimple *stmt,
       if (maxlen + 1 < nbytes)
 	return false;
 
-      if (nbytes <= minlen)
+      if (nbytes <= minlen || !si->full_string_p)
 	*nulterm = false;
 
       if (nbytes < minlen)
@@ -4846,6 +4846,9 @@ strlen_pass::count_nonzero_bytes_addr (tree exp, tree vuse, gimple *stmt,
 	    maxlen = nbytes;
 	}
 
+      if (!si->full_string_p)
+	maxlen = nbytes;
+
       if (minlen < lenrange[0])
 	lenrange[0] = minlen;
       if (lenrange[1] < maxlen)
--- a/src/gcc/tree-vect-patterns.cc
+++ b/src/gcc/tree-vect-patterns.cc
@@ -5491,9 +5491,11 @@ vect_truncatable_operation_p (tree_code code)
 {
   switch (code)
     {
+    case NEGATE_EXPR:
     case PLUS_EXPR:
     case MINUS_EXPR:
     case MULT_EXPR:
+    case BIT_NOT_EXPR:
     case BIT_AND_EXPR:
     case BIT_IOR_EXPR:
     case BIT_XOR_EXPR:
@@ -5652,38 +5654,85 @@ vect_determine_precisions_from_range (stmt_vec_info stmt_info, gassign *stmt)
   unsigned int nops = gimple_num_ops (stmt);
 
   if (!vect_truncatable_operation_p (code))
-    /* Check that all relevant input operands are compatible, and update
-       [MIN_VALUE, MAX_VALUE] to include their ranges.  */
-    for (unsigned int i = 1; i < nops; ++i)
-      {
-	tree op = gimple_op (stmt, i);
-	if (TREE_CODE (op) == INTEGER_CST)
-	  {
-	    /* Don't require the integer to have RHS_TYPE (which it might
-	       not for things like shift amounts, etc.), but do require it
-	       to fit the type.  */
-	    if (!int_fits_type_p (op, type))
-	      return;
-
-	    min_value = wi::min (min_value, wi::to_wide (op, precision), sign);
-	    max_value = wi::max (max_value, wi::to_wide (op, precision), sign);
-	  }
-	else if (TREE_CODE (op) == SSA_NAME)
-	  {
-	    /* Ignore codes that don't take uniform arguments.  */
-	    if (!types_compatible_p (TREE_TYPE (op), type))
-	      return;
+    {
+      /* Handle operations that can be computed in type T if all inputs
+	 and outputs can be represented in type T.  Also handle left and
+	 right shifts, where (in addition) the maximum shift amount must
+	 be less than the number of bits in T.  */
+      bool is_shift;
+      switch (code)
+	{
+	case LSHIFT_EXPR:
+	case RSHIFT_EXPR:
+	  is_shift = true;
+	  break;
 
-	    wide_int op_min_value, op_max_value;
-	    if (!vect_get_range_info (op, &op_min_value, &op_max_value))
-	      return;
+	case ABS_EXPR:
+	case MIN_EXPR:
+	case MAX_EXPR:
+	case TRUNC_DIV_EXPR:
+	case CEIL_DIV_EXPR:
+	case FLOOR_DIV_EXPR:
+	case ROUND_DIV_EXPR:
+	case EXACT_DIV_EXPR:
+	  /* Modulus is excluded because it is typically calculated by doing
+	     a division, for which minimum signed / -1 isn't representable in
+	     the original signed type.  We could take the division range into
+	     account instead, if handling modulus ever becomes important.  */
+	  is_shift = false;
+	  break;
 
-	    min_value = wi::min (min_value, op_min_value, sign);
-	    max_value = wi::max (max_value, op_max_value, sign);
-	  }
-	else
+	default:
 	  return;
-      }
+	}
+      for (unsigned int i = 1; i < nops; ++i)
+	{
+	  tree op = gimple_op (stmt, i);
+	  wide_int op_min_value, op_max_value;
+	  if (TREE_CODE (op) == INTEGER_CST)
+	    {
+	      unsigned int op_precision = TYPE_PRECISION (TREE_TYPE (op));
+	      op_min_value = op_max_value = wi::to_wide (op, op_precision);
+	    }
+	  else if (TREE_CODE (op) == SSA_NAME)
+	    {
+	      if (!vect_get_range_info (op, &op_min_value, &op_max_value))
+		return;
+	    }
+	  else
+	    return;
+
+	  if (is_shift && i == 2)
+	    {
+	      /* There needs to be one more bit than the maximum shift amount.
+
+		 If the maximum shift amount is already 1 less than PRECISION
+		 then we can't narrow the shift further.  Dealing with that
+		 case first ensures that we can safely use an unsigned range
+		 below.
+
+		 op_min_value isn't relevant, since shifts by negative amounts
+		 are UB.  */
+	      if (wi::geu_p (op_max_value, precision - 1))
+		return;
+	      unsigned int min_bits = op_max_value.to_uhwi () + 1;
+
+	      /* As explained below, we can convert a signed shift into an
+		 unsigned shift if the sign bit is always clear.  At this
+		 point we've already processed the ranges of the output and
+		 the first input.  */
+	      auto op_sign = sign;
+	      if (sign == SIGNED && !wi::neg_p (min_value))
+		op_sign = UNSIGNED;
+	      op_min_value = wide_int::from (wi::min_value (min_bits, op_sign),
+					     precision, op_sign);
+	      op_max_value = wide_int::from (wi::max_value (min_bits, op_sign),
+					     precision, op_sign);
+	    }
+	  min_value = wi::min (min_value, op_min_value, sign);
+	  max_value = wi::max (max_value, op_max_value, sign);
+	}
+    }
 
   /* Try to switch signed types for unsigned types if we can.
      This is better for two reasons.  First, unsigned ops tend
--- a/src/gcc/ubsan.cc
+++ b/src/gcc/ubsan.cc
@@ -1719,13 +1719,17 @@ instrument_bool_enum_load (gimple_stmt_iterator *gsi)
       || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
     return;
 
+  addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (rhs));
+  if (as != TYPE_ADDR_SPACE (utype))
+    utype = build_qualified_type (utype, TYPE_QUALS (utype)
+					 | ENCODE_QUAL_ADDR_SPACE (as));
   bool ends_bb = stmt_ends_bb_p (stmt);
   location_t loc = gimple_location (stmt);
   tree lhs = gimple_assign_lhs (stmt);
   tree ptype = build_pointer_type (TREE_TYPE (rhs));
   tree atype = reference_alias_ptr_type (rhs);
   gimple *g = gimple_build_assign (make_ssa_name (ptype),
-				  build_fold_addr_expr (rhs));
+				   build_fold_addr_expr (rhs));
   gimple_set_location (g, loc);
   gsi_insert_before (gsi, g, GSI_SAME_STMT);
   tree mem = build2 (MEM_REF, utype, gimple_assign_lhs (g),
--- a/src/gcc/varasm.cc
+++ b/src/gcc/varasm.cc
@@ -7632,6 +7632,8 @@ decl_binds_to_current_def_p (const_tree decl)
      for all other declaration types.  */
   if (DECL_WEAK (decl))
     return false;
+  if (DECL_COMDAT_GROUP (decl))
+    return false;
   if (DECL_COMMON (decl)
       && (DECL_INITIAL (decl) == NULL
 	  || (!in_lto_p && DECL_INITIAL (decl) == error_mark_node)))
--- a/src/libgcc/ChangeLog
+++ b/src/libgcc/ChangeLog
@@ -1,3 +1,11 @@
+2024-06-12  Andre Vieira  <andre.simoesdiasvieira@arm.com>
+
+	Backported from master:
+	2024-06-06  Andre Vieira  <andre.simoesdiasvieira@arm.com>
+
+	PR target/115360
+	* config/arm/cmse_nonsecure_call.S: Add .type and .size directives.
+
 2024-05-21  Release Manager
 
 	* GCC 13.3.0 released.
--- a/src/libgcc/config/arm/cmse_nonsecure_call.S
+++ b/src/libgcc/config/arm/cmse_nonsecure_call.S
@@ -33,6 +33,7 @@
 #endif
 
 .thumb
+.type __gnu_cmse_nonsecure_call, %function
 .global __gnu_cmse_nonsecure_call
 __gnu_cmse_nonsecure_call:
 #if defined(__ARM_ARCH_8M_MAIN__)
@@ -142,3 +143,4 @@ pop	    {r5-r7, pc}
 #else
 #error "This should only be used for armv8-m base- and mainline."
 #endif
+.size __gnu_cmse_nonsecure_call, .-__gnu_cmse_nonsecure_call
--- a/src/libgcc/config/avr/libf7/ChangeLog
+++ b/src/libgcc/config/avr/libf7/ChangeLog
@@ -1,3 +1,11 @@
+2024-06-01  Georg-Johann Lay  <avr@gjlay.de>
+
+	Backported from master:
+	2024-06-01  Georg-Johann Lay  <avr@gjlay.de>
+
+	PR target/115317
+	* libf7-asm.sx (__isinf): Map -Inf to -1.
+
 2024-05-21  Release Manager
 
 	* GCC 13.3.0 released.
--- a/src/libgcc/config/avr/libf7/libf7-asm.sx
+++ b/src/libgcc/config/avr/libf7/libf7-asm.sx
@@ -1639,19 +1639,24 @@ _ENDF __copysign
 
 
 #ifdef F7MOD_D_isinf_
+;;; +Inf  ->  +1
+;;; -Inf  ->  -1
 _DEFUN __isinf
     DALIAS isinf
     LALIAS isinfl
+    ;; Save sign for later
+    push    R25
     F7call  class_D
+    pop     TMP
+    ldi     R24,    0
+    ldi     R25,    0
     ;; Inf: T = Z = 1.
-    brtc 0f
+    brtc 0f                     ; ordinary number
+    brne 0f                     ; Nan
     ldi     R24,    1
-    breq 1f
-0:
-    clr     R24
-1:
-    clr     R25
-    ret
+    sbrc    TMP,    7
+    sbiw    R24,    2
+0:  ret
 _ENDF __isinf
 #endif /* F7MOD_D_isinf_ */
 
--- a/src/libgomp/ChangeLog
+++ b/src/libgomp/ChangeLog
@@ -1,3 +1,12 @@
+2024-08-05  Paul Thomas  <pault@gcc.gnu.org>
+
+	Backported from master:
+	2024-07-19  Paul Thomas  <pault@gcc.gnu.org>
+
+	* testsuite/libgomp.oacc-fortran/privatized-ref-2.f90: Cut
+	dg-note about 'a' and remove bogus warnings about its array
+	descriptor components being used uninitialized.
+
 2024-05-21  Release Manager
 
 	* GCC 13.3.0 released.
--- a/src/libgomp/testsuite/libgomp.oacc-fortran/privatized-ref-2.f90
+++ b/src/libgomp/testsuite/libgomp.oacc-fortran/privatized-ref-2.f90
@@ -29,16 +29,10 @@ program main
   implicit none (type, external)
   integer :: j
   integer, allocatable :: A(:)
-  ! { dg-note {'a' declared here} {} { target *-*-* } .-1 }
   character(len=:), allocatable :: my_str
   character(len=15), allocatable :: my_str15
 
   A = [(3*j, j=1, 10)]
-  ! { dg-bogus {'a\.offset' is used uninitialized} {PR77504 etc.} { xfail *-*-* } .-1 }
-  ! { dg-bogus {'a\.dim\[0\]\.lbound' is used uninitialized} {PR77504 etc.} { xfail *-*-* } .-2 }
-  ! { dg-bogus {'a\.dim\[0\]\.ubound' is used uninitialized} {PR77504 etc.} { xfail *-*-* } .-3 }
-  ! { dg-bogus {'a\.dim\[0\]\.lbound' may be used uninitialized} {PR77504 etc.} { xfail { ! __OPTIMIZE__ } } .-4 }
-  ! { dg-bogus {'a\.dim\[0\]\.ubound' may be used uninitialized} {PR77504 etc.} { xfail { ! __OPTIMIZE__ } } .-5 }
   call foo (A, size(A))
   call bar (A)
   my_str = "1234567890"
--- a/src/libstdc++-v3/ChangeLog
+++ b/src/libstdc++-v3/ChangeLog
@@ -1,3 +1,224 @@
+2024-07-24  Jonathan Wakely  <jwakely@redhat.com>
+
+	Backported from master:
+	2024-07-24  Jonathan Wakely  <jwakely@redhat.com>
+
+	PR libstdc++/116070
+	* include/bits/stl_bvector.h: Check feature test macro before
+	using is_default_constructible_v.
+
+2024-07-12  Jonathan Wakely  <jwakely@redhat.com>
+
+	Backported from master:
+	2024-06-21  Jonathan Wakely  <jwakely@redhat.com>
+
+	PR libstdc++/115522
+	* include/std/array (to_array): Workaround the fact that
+	std::is_trivial is not sufficient to check that a type is
+	trivially default constructible and assignable.
+	* testsuite/23_containers/array/creation/115522.cc: New test.
+
+2024-07-09  Jonathan Wakely  <jwakely@redhat.com>
+
+	Backported from master:
+	2024-07-08  Jonathan Wakely  <jwakely@redhat.com>
+
+	PR libstdc++/115807
+	* include/c_compatibility/stdatomic.h (_Atomic): Ensure it
+	refers to std::atomic in the global namespace.
+	* testsuite/29_atomics/headers/stdatomic.h/115807.cc: New test.
+
+2024-07-09  Jonathan Wakely  <jwakely@redhat.com>
+
+	Backported from master:
+	2024-06-28  Jonathan Wakely  <jwakely@redhat.com>
+
+	PR libstdc++/115585
+	* src/c++11/assert_fail.cc (__glibcxx_assert_fail): Add
+	definition for non-verbose builds.
+
+2024-06-28  Jonathan Wakely  <jwakely@redhat.com>
+
+	Backported from master:
+	2024-06-25  Jonathan Wakely  <jwakely@redhat.com>
+
+	* doc/xml/faq.xml: Replace viewcvs links with cgit links.
+	* doc/xml/manual/allocator.xml: Likewise.
+	* doc/xml/manual/mt_allocator.xml: Likewise.
+	* doc/html/*: Regenerate.
+
+2024-06-28  Jonathan Wakely  <jwakely@redhat.com>
+
+	Backported from master:
+	2024-06-27  Jonathan Wakely  <jwakely@redhat.com>
+
+	PR libstdc++/115668
+	* include/bits/chrono_io.h (formatter<duration<R,P, C>::format):
+	Do not use chrono::abs.
+	* testsuite/20_util/duration/io.cc: Check formatting a duration
+	with unsigned rep.
+
+2024-06-27  Alexandre Oliva  <oliva@adacore.com>
+
+	Backported from master:
+	2024-06-27  Alexandre Oliva  <oliva@adacore.com>
+
+	PR libstdc++/115454
+	* testsuite/experimental/simd/pr115454_find_last_set.cc: Defer
+	to check_vect_support_and_set_flags's default dg-do action.
+
+2024-06-25  Jonathan Wakely  <jwakely@redhat.com>
+
+	* doc/xml/manual/status_cxx1998.xml: Remove confusing "not in
+	any particular release" text.
+	* doc/xml/manual/status_cxx2011.xml: Likewise.
+	* doc/xml/manual/status_cxx2014.xml: Likewise.
+	* doc/xml/manual/status_cxx2017.xml: Likewise.
+	* doc/xml/manual/status_cxx2020.xml: Likewise.
+	* doc/xml/manual/status_cxx2023.xml: Likewise.
+	* doc/xml/manual/status_cxxtr1.xml: Likewise.
+	* doc/xml/manual/status_cxxtr24733.xml: Likewise.
+	* doc/html/manual/status.html: Regenerate.
+
+2024-06-21  Matthias Kretz  <m.kretz@gsi.de>
+
+	Backported from master:
+	2024-06-21  Matthias Kretz  <m.kretz@gsi.de>
+
+	PR libstdc++/115575
+	* testsuite/experimental/simd/pr115454_find_last_set.cc: Require
+	avx512f_runtime. Don't memcpy fixed_size masks.
+
+2024-06-21  Matthias Kretz  <m.kretz@gsi.de>
+
+	Backported from master:
+	2024-06-20  Matthias Kretz  <m.kretz@gsi.de>
+
+	PR libstdc++/115454
+	* include/experimental/bits/simd_x86.h (_S_not_equal_to): Use
+	neq comparison instead of bitwise negation after eq.
+	(_S_find_last_set): Clear unused high bits before computing
+	bit_width.
+	* testsuite/experimental/simd/pr115454_find_last_set.cc: New
+	test.
+
+2024-06-14  Jonathan Wakely  <jwakely@redhat.com>
+
+	Backported from master:
+	2024-06-14  Jonathan Wakely  <jwakely@redhat.com>
+
+	* libsupc++/new_opa.cc [!_GLIBCXX_HOSTED]: Fix declaration of
+	posix_memalign.
+
+2024-06-11  Matthias Kretz  <m.kretz@gsi.de>
+
+	Backported from master:
+	2024-06-04  Matthias Kretz  <m.kretz@gsi.de>
+
+	PR libstdc++/115308
+	* include/experimental/bits/simd.h (__int_for_sizeof): Remove
+	special cases for __clang__.
+	(_SimdWrapper): Change constructor overload set to allow
+	conversion from vector types with integral conversions via bit
+	reinterpretation.
+
+2024-06-11  Matthias Kretz  <m.kretz@gsi.de>
+
+	Backported from master:
+	2024-05-29  Matthias Kretz  <m.kretz@gsi.de>
+
+	PR libstdc++/115247
+	* include/experimental/bits/simd.h (__as_vector): Don't use
+	vector_size(8) on __i386__.
+	(__vec_shuffle): Never return MMX vectors, widen to 16 bytes
+	instead.
+	(concat): Fix padding calculation to pick up widening logic from
+	__as_vector.
+
+2024-06-11  Matthias Kretz  <m.kretz@gsi.de>
+
+	Backported from master:
+	2024-05-13  Matthias Kretz  <m.kretz@gsi.de>
+
+	PR libstdc++/114958
+	* include/experimental/bits/simd.h (__as_vector): Return scalar
+	simd as one-element vector. Return vector from single-vector
+	fixed_size simd.
+	(__vec_shuffle): New.
+	(__extract_part): Adjust return type signature.
+	(split): Use __extract_part for any split into non-fixed_size
+	simds.
+	(concat): If the return type stores a single vector, use
+	__vec_shuffle (which calls __builtin_shufflevector) to produce
+	the return value.
+	* include/experimental/bits/simd_builtin.h
+	(__shift_elements_right): Removed.
+	(__extract_part): Return single elements directly. Use
+	__vec_shuffle (which calls __builtin_shufflevector) to for all
+	non-trivial cases.
+	* include/experimental/bits/simd_fixed_size.h (__extract_part):
+	Return single elements directly.
+	* testsuite/experimental/simd/pr114958.cc: New test.
+
+2024-06-01  Jonathan Wakely  <jwakely@redhat.com>
+
+	Backported from master:
+	2024-06-01  Jonathan Wakely  <jwakely@redhat.com>
+
+	PR libstdc++/115269
+	* doc/xml/manual/using.xml: Replace link to gcc-4.3.2 docs.
+	Replace list of -std=... options with a single entry for -std.
+	* doc/html/manual/using.html: Regenerate.
+
+2024-05-28  Jakub Jelinek  <jakub@redhat.com>
+
+	* testsuite/19_diagnostics/stacktrace/hash.cc: Adjust
+	dg-options to use -lstdc++exp.
+
+2024-05-28  Jonathan Wakely  <jwakely@redhat.com>
+
+	Backported from master:
+	2024-05-22  Jonathan Wakely  <jwakely@redhat.com>
+
+	PR libstdc++/114940
+	* include/std/stacktrace (_GLIBCXX_SIZED_DELETE): New macro.
+	(basic_stacktrace::_Impl::_M_deallocate): Use it.
+
+2024-05-21  Dimitrij Mijoski  <dmjpp@hotmail.com>
+
+	Backported from master:
+	2023-10-21  Dimitrij Mijoski  <dmjpp@hotmail.com>
+
+	* testsuite/22_locale/codecvt/codecvt_unicode.h: Test length()
+
+2024-05-21  Dimitrij Mijoski  <dmjpp@hotmail.com>
+
+	Backported from master:
+	2023-09-29  Dimitrij Mijoski  <dmjpp@hotmail.com>
+
+	PR libstdc++/108976
+	* src/c++11/codecvt.cc (read_utf8_code_point): Fix handing of
+	surrogates in UTF-8.
+	(ucs4_out): Fix handling of surrogates in UCS-4 -> UTF-8.
+	(ucs4_in): Fix handling of range with odd number of bytes.
+	(ucs4_out): Fix handling of surrogates in UCS-4 -> UTF-16.
+	(ucs2_out): Fix handling of surrogates in UCS-2 -> UTF-16.
+	(ucs2_in): Fix handling of range with odd number of bytes.
+	(__codecvt_utf16_base<char16_t>::do_in): Likewise.
+	(__codecvt_utf16_base<char32_t>::do_in): Likewise.
+	(__codecvt_utf16_base<wchar_t>::do_in): Likewise.
+	* testsuite/22_locale/codecvt/codecvt_unicode.cc: Renames, add
+	tests for codecvt_utf16<char16_t> and codecvt_utf16<char32_t>.
+	* testsuite/22_locale/codecvt/codecvt_unicode.h: Refactor UTF-8
+	testing functions for char8_t, add more test cases for errors,
+	add testing functions for codecvt_utf16.
+	* testsuite/22_locale/codecvt/codecvt_unicode_wchar_t.cc:
+	Renames, add tests for codecvt_utf16<whchar_t>.
+	* testsuite/22_locale/codecvt/codecvt_utf16/79980.cc (test06):
+	Fix test.
+	* testsuite/22_locale/codecvt/codecvt_unicode_char8_t.cc: New
+	test.
+
 2024-05-21  Release Manager
 
 	* GCC 13.3.0 released.
--- a/src/libstdc++-v3/doc/html/faq.html
+++ b/src/libstdc++-v3/doc/html/faq.html
@@ -148,7 +148,7 @@
      The libstdc++ project is contributed to by several developers
      all over the world, in the same way as GCC or the Linux kernel.
      The current maintainers are listed in the
-     <a class="link" href="https://gcc.gnu.org/viewcvs/gcc/trunk/MAINTAINERS?view=co" target="_top"><code class="filename">MAINTAINERS</code></a>
+     <a class="link" href="https://gcc.gnu.org/cgit/gcc/tree/MAINTAINERS" target="_top"><code class="filename">MAINTAINERS</code></a>
      file (look for "c++ runtime libs").
     </p><p>
     Development and discussion is held on the libstdc++ mailing
--- a/src/libstdc++-v3/doc/html/manual/memory.html
+++ b/src/libstdc++-v3/doc/html/manual/memory.html
@@ -120,8 +120,8 @@
        Over multiple iterations, various STL container
      objects have elements inserted to some maximum amount. A variety
      of allocators are tested.
-     Test source for <a class="link" href="http://gcc.gnu.org/viewcvs/gcc/trunk/libstdc%2B%2B-v3/testsuite/performance/23_containers/insert/sequence.cc?view=markup" target="_top">sequence</a>
-     and <a class="link" href="http://gcc.gnu.org/viewcvs/gcc/trunk/libstdc%2B%2B-v3/testsuite/performance/23_containers/insert/associative.cc?view=markup" target="_top">associative</a>
+     Test source for <a class="link" href="https://gcc.gnu.org/cgit/gcc/tree/libstdc++-v3/testsuite/performance/23_containers/insert/sequence.cc?h=releases%2Fgcc-13" target="_top">sequence</a>
+     and <a class="link" href="https://gcc.gnu.org/cgit/gcc/tree/libstdc++-v3/testsuite/performance/23_containers/insert/associative.cc?h=releases%2Fgcc-13" target="_top">associative</a>
      containers.
        </p></li><li class="listitem"><p>
        Insertion and erasure in a multi-threaded environment.
@@ -130,14 +130,14 @@
      on a per-thread basis, as well as measuring thread contention
      for memory resources.
      Test source
-    <a class="link" href="http://gcc.gnu.org/viewcvs/gcc/trunk/libstdc%2B%2B-v3/testsuite/performance/23_containers/insert_erase/associative.cc?view=markup" target="_top">here</a>.
+    <a class="link" href="https://gcc.gnu.org/cgit/gcc/tree/libstdc++-v3/testsuite/performance/23_containers/insert_erase/associative.cc?h=releases%2Fgcc-13" target="_top">here</a>.
        </p></li><li class="listitem"><p>
 	 A threaded producer/consumer model.
        </p><p>
        Test source for
-     <a class="link" href="http://gcc.gnu.org/viewcvs/gcc/trunk/libstdc++-v3/testsuite/performance/23_containers/producer_consumer/sequence.cc?view=markup" target="_top">sequence</a>
+     <a class="link" href="https://gcc.gnu.org/cgit/gcc/tree/libstdc++-v3/testsuite/performance/23_containers/producer_consumer/sequence.cc?h=releases%2Fgcc-13" target="_top">sequence</a>
      and
-     <a class="link" href="http://gcc.gnu.org/viewcvs/gcc/trunk/libstdc++-v3/testsuite/performance/23_containers/producer_consumer/associative.cc?view=markup" target="_top">associative</a>
+     <a class="link" href="https://gcc.gnu.org/cgit/gcc/tree/libstdc++-v3/testsuite/performance/23_containers/producer_consumer/associative.cc?h=releases%2Fgcc-13" target="_top">associative</a>
      containers.
      </p></li></ol></div><p>
      Since GCC 12 the default choice for
--- a/src/libstdc++-v3/doc/html/manual/mt_allocator_impl.html
+++ b/src/libstdc++-v3/doc/html/manual/mt_allocator_impl.html
@@ -155,7 +155,7 @@ that uses it is fully constructed. For most (but not all) STL
 containers, this works, as an instance of the allocator is constructed
 as part of a container's constructor. However, this assumption is
 implementation-specific, and subject to change. For an example of a
-pool that frees memory, see the following
-    <a class="link" href="http://gcc.gnu.org/viewcvs/gcc/trunk/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local-6.cc?view=markup" target="_top">
-    example.</a>
+pool that frees memory, see the
+    <a class="link" href="https://gcc.gnu.org/cgit/gcc/tree/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local-6.cc?h=releases%2Fgcc-13" target="_top"><code class="filename">ext/mt_allocator/deallocate_local-6.cc</code></a>
+    example.
 </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="mt_allocator_design.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="mt_allocator.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="mt_allocator_ex_single.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Design Issues </td><td width="20%" align="center"><a accesskey="h" href="../index.html">Home</a></td><td width="40%" align="right" valign="top"> Single Thread Example</td></tr></table></div></body></html>
\ No newline at end of file
--- a/src/libstdc++-v3/doc/html/manual/status.html
+++ b/src/libstdc++-v3/doc/html/manual/status.html
@@ -6,7 +6,7 @@
 This status table is based on the table of contents of ISO/IEC 14882:2003.
 </p><p>
 This section describes the C++ support in
-the GCC 13 release series, not in any particular release.
+the GCC 13 release series.
 </p><div class="table"><a id="table.cxx98_status"></a><p class="title"><strong>Table 1.1. C++ 1998/2003 Implementation Status</strong></p><div class="table-contents"><table class="table" summary="C++ 1998/2003 Implementation Status" border="1"><colgroup><col align="left" class="c1" /><col align="left" class="c2" /><col align="left" class="c3" /><col align="left" class="c4" /></colgroup><thead><tr><th align="left">Section</th><th align="left">Description</th><th align="left">Status</th><th align="left">Comments</th></tr></thead><tbody><tr><td align="left">
 	<span class="emphasis"><em>18</em></span>
       </td><td colspan="3" align="left">
@@ -161,7 +161,7 @@ since that release.
 This status table is based on the table of contents of ISO/IEC 14882:2011.
 </p><p>
 This section describes the C++11 support in
-the GCC 13 release series, not in any particular release.
+the GCC 13 release series.
 </p><div class="table"><a id="table.cxx11_status"></a><p class="title"><strong>Table 1.2. C++ 2011 Implementation Status</strong></p><div class="table-contents"><table class="table" summary="C++ 2011 Implementation Status" border="1"><colgroup><col align="left" class="c1" /><col align="left" class="c2" /><col align="left" class="c3" /><col align="left" class="c4" /></colgroup><thead><tr><th align="left">Section</th><th align="left">Description</th><th align="left">Status</th><th align="left">Comments</th></tr></thead><tbody><tr><td align="left">
 	<span class="emphasis"><em>18</em></span>
       </td><td colspan="3" align="left">
@@ -434,7 +434,7 @@ Some subclauses are not shown in the table where the content is unchanged
 since C++11 and the implementation is complete.
 </p><p>
 This section describes the C++14 and library TS support in
-the GCC 13 release series, not in any particular release.
+the GCC 13 release series.
 </p><div class="table"><a id="table.cxx14_status"></a><p class="title"><strong>Table 1.3. C++ 2014 Implementation Status</strong></p><div class="table-contents"><table class="table" summary="C++ 2014 Implementation Status" border="1"><colgroup><col align="left" class="c1" /><col align="left" class="c2" /><col align="left" class="c3" /><col align="left" class="c4" /></colgroup><thead><tr><th align="left">Section</th><th align="left">Description</th><th align="left">Status</th><th align="left">Comments</th></tr></thead><tbody><tr><td align="left">
 	<span class="emphasis"><em>18</em></span>
       </td><td colspan="3" align="left">
@@ -579,7 +579,7 @@ so the API and ABI of features added in C++17 is only stable
 since that release.
 </p><p>
 This section describes the C++17 and library TS support in
-the GCC 13 release series, not in any particular release.
+the GCC 13 release series.
 </p><p>
 The following table lists new library features that are included in
 the C++17 standard. The "Proposal" column provides a link to the
@@ -1255,7 +1255,7 @@ options. The pre-defined symbol
 presence of the required flag.
 </p><p>
 This section describes the C++20 and library TS support in
-the GCC 13 release series, not in any particular release.
+the GCC 13 release series.
 </p><p>
 The following table lists new library features that are included in
 the C++20 standard. The "Proposal" column provides a link to the
@@ -1725,7 +1725,7 @@ options. The pre-defined symbol
 presence of the required flag.
 </p><p>
 This section describes the C++23 and library TS support in
-the GCC 13 release series, not in any particular release.
+the GCC 13 release series.
 </p><p>
 The following table lists new library features that have been accepted into
 the C++23 working draft. The "Proposal" column provides a link to the
@@ -2123,7 +2123,7 @@ In this implementation the header names are prefixed by
 <code class="code">&lt;tr1/memory&gt;</code>, and so on.
 </p><p>
 This page describes the TR1 support in
-the GCC 13 release series, not in any particular release.
+the GCC 13 release series.
 </p><div class="table"><a id="table.tr1_status"></a><p class="title"><strong>Table 1.11. C++ TR1 Implementation Status</strong></p><div class="table-contents"><table class="table" summary="C++ TR1 Implementation Status" border="1"><colgroup><col align="left" class="c1" /><col align="left" class="c2" /><col align="left" class="c3" /><col align="left" class="c4" /></colgroup><thead><tr><th align="left">Section</th><th align="left">Description</th><th align="left">Status</th><th align="left">Comments</th></tr></thead><tbody><tr><td align="left"><span class="emphasis"><em>2</em></span></td><td colspan="3" align="left"><span class="emphasis"><em>General Utilities</em></span></td></tr><tr><td align="left">2.1</td><td align="left">Reference wrappers</td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.1.1</td><td align="left">Additions to header <code class="code">&lt;functional&gt;</code> synopsis</td><td align="left">Y</td><td align="left"> </td></tr><tr><td align="left">2.1.2</td><td align="left">Class template <code class="code">reference_wrapper</code></td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.1.2.1</td><td align="left"><code class="code">reference_wrapper</code> construct/copy/destroy</td><td align="left">Y</td><td align="left"> </td></tr><tr><td align="left">2.1.2.2</td><td align="left"><code class="code">reference_wrapper</code> assignment</td><td align="left">Y</td><td align="left"> </td></tr><tr><td align="left">2.1.2.3</td><td align="left"><code class="code">reference_wrapper</code> access</td><td align="left">Y</td><td align="left"> </td></tr><tr><td align="left">2.1.2.4</td><td align="left"><code class="code">reference_wrapper</code> invocation</td><td align="left">Y</td><td align="left"> </td></tr><tr><td align="left">2.1.2.5</td><td align="left"><code class="code">reference_wrapper</code> helper functions</td><td align="left">Y</td><td align="left"> </td></tr><tr><td align="left">2.2</td><td align="left">Smart pointers</td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.1</td><td align="left">Additions to header <code class="code">&lt;memory&gt;</code> synopsis</td><td align="left">Y</td><td align="left"> </td></tr><tr><td align="left">2.2.2</td><td align="left">Class <code class="code">bad_weak_ptr</code></td><td align="left">Y</td><td align="left"> </td></tr><tr><td align="left">2.2.3</td><td align="left">Class template <code class="code">shared_ptr</code></td><td align="left"> </td><td align="left">
 	<p>
 	  Uses code from
@@ -2144,7 +2144,7 @@ ISO/IEC TR 24733:2011,
 decimal floating-point arithmetic".
 </p><p>
 This page describes the TR 24733 support in
-the GCC 13 release series, not in any particular release.
+the GCC 13 release series.
 </p><div class="table"><a id="table.decfp_status"></a><p class="title"><strong>Table 1.12. C++ TR 24733 Implementation Status</strong></p><div class="table-contents"><table class="table" summary="C++ TR 24733 Implementation Status" border="1"><colgroup><col align="left" class="c1" /><col align="left" class="c2" /><col align="left" class="c3" /><col align="left" class="c4" /></colgroup><thead><tr><th align="left">Section</th><th align="left">Description</th><th align="left">Status</th><th align="left">Comments</th></tr></thead><tbody><tr><td align="left">
 	<span class="emphasis"><em>0</em></span>
       </td><td colspan="3" align="left">
--- a/src/libstdc++-v3/doc/html/manual/using.html
+++ b/src/libstdc++-v3/doc/html/manual/using.html
@@ -4,7 +4,7 @@
   
 </th><td width="20%" align="right"> <a accesskey="n" href="using_headers.html">Next</a></td></tr></table><hr /></div><div class="chapter"><div class="titlepage"><div><div><h2 class="title"><a id="manual.intro.using"></a>Chapter 3. Using</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="section"><a href="using.html#manual.intro.using.flags">Command Options</a></span></dt><dt><span class="section"><a href="using_headers.html">Headers</a></span></dt><dd><dl><dt><span class="section"><a href="using_headers.html#manual.intro.using.headers.all">Header Files</a></span></dt><dt><span class="section"><a href="using_headers.html#manual.intro.using.headers.mixing">Mixing Headers</a></span></dt><dt><span class="section"><a href="using_headers.html#manual.intro.using.headers.cheaders">The C Headers and <code class="code">namespace std</code></a></span></dt><dt><span class="section"><a href="using_headers.html#manual.intro.using.headers.pre">Precompiled Headers</a></span></dt></dl></dd><dt><span class="section"><a href="using_macros.html">Macros</a></span></dt><dt><span class="section"><a href="using_dual_abi.html">Dual ABI</a></span></dt><dd><dl><dt><span class="section"><a href="using_dual_abi.html#manual.intro.using.abi.trouble">Troubleshooting</a></span></dt></dl></dd><dt><span class="section"><a href="using_namespaces.html">Namespaces</a></span></dt><dd><dl><dt><span class="section"><a href="using_namespaces.html#manual.intro.using.namespaces.all">Available Namespaces</a></span></dt><dt><span class="section"><a href="using_namespaces.html#manual.intro.using.namespaces.std">namespace std</a></span></dt><dt><span class="section"><a href="using_namespaces.html#manual.intro.using.namespaces.comp">Using Namespace Composition</a></span></dt></dl></dd><dt><span class="section"><a href="using_dynamic_or_shared.html">Linking</a></span></dt><dd><dl><dt><span class="section"><a href="using_dynamic_or_shared.html#manual.intro.using.linkage.freestanding">Almost Nothing</a></span></dt><dt><span class="section"><a href="using_dynamic_or_shared.html#manual.intro.using.linkage.dynamic">Finding Dynamic or Shared Libraries</a></span></dt><dt><span class="section"><a href="using_dynamic_or_shared.html#manual.intro.using.linkage.experimental">Experimental Library Extensions</a></span></dt></dl></dd><dt><span class="section"><a href="using_concurrency.html">Concurrency</a></span></dt><dd><dl><dt><span class="section"><a href="using_concurrency.html#manual.intro.using.concurrency.prereq">Prerequisites</a></span></dt><dt><span class="section"><a href="using_concurrency.html#manual.intro.using.concurrency.thread_safety">Thread Safety</a></span></dt><dt><span class="section"><a href="using_concurrency.html#manual.intro.using.concurrency.atomics">Atomics</a></span></dt><dt><span class="section"><a href="using_concurrency.html#manual.intro.using.concurrency.io">IO</a></span></dt><dd><dl><dt><span class="section"><a href="using_concurrency.html#concurrency.io.structure">Structure</a></span></dt><dt><span class="section"><a href="using_concurrency.html#concurrency.io.defaults">Defaults</a></span></dt><dt><span class="section"><a href="using_concurrency.html#concurrency.io.future">Future</a></span></dt><dt><span class="section"><a href="using_concurrency.html#concurrency.io.alt">Alternatives</a></span></dt></dl></dd><dt><span class="section"><a href="using_concurrency.html#manual.intro.using.concurrency.containers">Containers</a></span></dt></dl></dd><dt><span class="section"><a href="using_exceptions.html">Exceptions</a></span></dt><dd><dl><dt><span class="section"><a href="using_exceptions.html#intro.using.exception.safety">Exception Safety</a></span></dt><dt><span class="section"><a href="using_exceptions.html#intro.using.exception.propagating">Exception Neutrality</a></span></dt><dt><span class="section"><a href="using_exceptions.html#intro.using.exception.alloc">Memory allocation</a></span></dt><dt><span class="section"><a href="using_exceptions.html#intro.using.exception.no">Doing without</a></span></dt><dt><span class="section"><a href="using_exceptions.html#intro.using.exception.compat">Compatibility</a></span></dt><dd><dl><dt><span class="section"><a href="using_exceptions.html#using.exception.compat.c">With <code class="literal">C</code></a></span></dt><dt><span class="section"><a href="using_exceptions.html#using.exception.compat.posix">With <code class="literal">POSIX</code> thread cancellation</a></span></dt></dl></dd></dl></dd><dt><span class="section"><a href="debug.html">Debugging Support</a></span></dt><dd><dl><dt><span class="section"><a href="debug.html#debug.compiler">Using <span class="command"><strong>g++</strong></span></a></span></dt><dt><span class="section"><a href="debug.html#debug.req">Debug Versions of Library Binary Files</a></span></dt><dt><span class="section"><a href="debug.html#debug.memory">Memory Leak Hunting</a></span></dt><dd><dl><dt><span class="section"><a href="debug.html#debug.memory.mtalloc">Non-memory leaks in Pool and MT allocators</a></span></dt></dl></dd><dt><span class="section"><a href="debug.html#debug.races">Data Race Hunting</a></span></dt><dt><span class="section"><a href="debug.html#debug.gdb">Using <span class="command"><strong>gdb</strong></span></a></span></dt><dt><span class="section"><a href="debug.html#debug.exceptions">Tracking uncaught exceptions</a></span></dt><dt><span class="section"><a href="debug.html#debug.debug_mode">Debug Mode</a></span></dt><dt><span class="section"><a href="debug.html#debug.compile_time_checks">Compile Time Checking</a></span></dt></dl></dd></dl></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="manual.intro.using.flags"></a>Command Options</h2></div></div></div><p>
       The set of features available in the GNU C++ library is shaped by
-      several <a class="link" href="http://gcc.gnu.org/onlinedocs/gcc-4.3.2/gcc/Invoking-GCC.html" target="_top">GCC
+      several <a class="link" href="https://gcc.gnu.org/onlinedocs/gcc-13.1.0/gcc/Invoking-GCC.html" target="_top">GCC
       Command Options</a>. Options that impact libstdc++ are
       enumerated and detailed in the table below.
     </p><p>
@@ -14,9 +14,11 @@
       <span class="command"><strong>g++ -std=gnu++17</strong></span> since GCC 11, and
       <span class="command"><strong>g++ -std=gnu++14</strong></span> in GCC 6, 7, 8, 9, and 10, and
       <span class="command"><strong>g++ -std=gnu++98</strong></span> for older releases.
-    </p><div class="table"><a id="table.cmd_options"></a><p class="title"><strong>Table 3.1. C++ Command Options</strong></p><div class="table-contents"><table class="table" summary="C++ Command Options" border="1"><colgroup><col align="left" class="c1" /><col align="left" class="c2" /></colgroup><thead><tr><th align="left">Option Flags</th><th align="left">Description</th></tr></thead><tbody><tr><td align="left"><code class="literal">-std=c++98</code> or <code class="literal">-std=c++03</code>
-      </td><td align="left">Use the 1998 ISO C++ standard plus amendments.</td></tr><tr><td align="left"><code class="literal">-std=gnu++98</code> or <code class="literal">-std=gnu++03</code>
-      </td><td align="left">As directly above, with GNU extensions.</td></tr><tr><td align="left"><code class="literal">-std=c++11</code></td><td align="left">Use the 2011 ISO C++ standard.</td></tr><tr><td align="left"><code class="literal">-std=gnu++11</code></td><td align="left">As directly above, with GNU extensions.</td></tr><tr><td align="left"><code class="literal">-std=c++14</code></td><td align="left">Use the 2014 ISO C++ standard.</td></tr><tr><td align="left"><code class="literal">-std=gnu++14</code></td><td align="left">As directly above, with GNU extensions.</td></tr><tr><td align="left">
+    </p><div class="table"><a id="table.cmd_options"></a><p class="title"><strong>Table 3.1. C++ Command Options</strong></p><div class="table-contents"><table class="table" summary="C++ Command Options" border="1"><colgroup><col align="left" class="c1" /><col align="left" class="c2" /></colgroup><thead><tr><th align="left">Option Flags</th><th align="left">Description</th></tr></thead><tbody><tr><td align="left"><code class="literal">-std</code>
+      </td><td align="left">
+	Select the C++ standard, and whether to use the base standard
+	or GNU dialect.
+      </td></tr><tr><td align="left">
 	<code class="literal">-fno-exceptions</code>
       </td><td align="left">See <a class="link" href="using_exceptions.html#intro.using.exception.no" title="Doing without">exception-free dialect</a></td></tr><tr><td align="left">
 	<code class="literal">-fno-rtti</code>
--- a/src/libstdc++-v3/doc/xml/faq.xml
+++ b/src/libstdc++-v3/doc/xml/faq.xml
@@ -91,7 +91,7 @@
      The libstdc++ project is contributed to by several developers
      all over the world, in the same way as GCC or the Linux kernel.
      The current maintainers are listed in the
-     <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://gcc.gnu.org/viewcvs/gcc/trunk/MAINTAINERS?view=co"><filename>MAINTAINERS</filename></link>
+     <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://gcc.gnu.org/cgit/gcc/tree/MAINTAINERS"><filename>MAINTAINERS</filename></link>
      file (look for "c++ runtime libs").
     </para>
     <para>
--- a/src/libstdc++-v3/doc/xml/manual/allocator.xml
+++ b/src/libstdc++-v3/doc/xml/manual/allocator.xml
@@ -184,8 +184,8 @@
        Over multiple iterations, various STL container
      objects have elements inserted to some maximum amount. A variety
      of allocators are tested.
-     Test source for <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://gcc.gnu.org/viewcvs/gcc/trunk/libstdc%2B%2B-v3/testsuite/performance/23_containers/insert/sequence.cc?view=markup">sequence</link>
-     and <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://gcc.gnu.org/viewcvs/gcc/trunk/libstdc%2B%2B-v3/testsuite/performance/23_containers/insert/associative.cc?view=markup">associative</link>
+     Test source for <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://gcc.gnu.org/cgit/gcc/tree/libstdc++-v3/testsuite/performance/23_containers/insert/sequence.cc?h=releases%2Fgcc-13">sequence</link>
+     and <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://gcc.gnu.org/cgit/gcc/tree/libstdc++-v3/testsuite/performance/23_containers/insert/associative.cc?h=releases%2Fgcc-13">associative</link>
      containers.
        </para>
 
@@ -200,7 +200,7 @@
      on a per-thread basis, as well as measuring thread contention
      for memory resources.
      Test source
-    <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://gcc.gnu.org/viewcvs/gcc/trunk/libstdc%2B%2B-v3/testsuite/performance/23_containers/insert_erase/associative.cc?view=markup">here</link>.
+    <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://gcc.gnu.org/cgit/gcc/tree/libstdc++-v3/testsuite/performance/23_containers/insert_erase/associative.cc?h=releases%2Fgcc-13">here</link>.
        </para>
      </listitem>
 
@@ -210,9 +210,9 @@
        </para>
        <para>
        Test source for
-     <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://gcc.gnu.org/viewcvs/gcc/trunk/libstdc++-v3/testsuite/performance/23_containers/producer_consumer/sequence.cc?view=markup">sequence</link>
+     <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://gcc.gnu.org/cgit/gcc/tree/libstdc++-v3/testsuite/performance/23_containers/producer_consumer/sequence.cc?h=releases%2Fgcc-13">sequence</link>
      and
-     <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://gcc.gnu.org/viewcvs/gcc/trunk/libstdc++-v3/testsuite/performance/23_containers/producer_consumer/associative.cc?view=markup">associative</link>
+     <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://gcc.gnu.org/cgit/gcc/tree/libstdc++-v3/testsuite/performance/23_containers/producer_consumer/associative.cc?h=releases%2Fgcc-13">associative</link>
      containers.
      </para>
      </listitem>
--- a/src/libstdc++-v3/doc/xml/manual/mt_allocator.xml
+++ b/src/libstdc++-v3/doc/xml/manual/mt_allocator.xml
@@ -307,9 +307,9 @@ that uses it is fully constructed. For most (but not all) STL
 containers, this works, as an instance of the allocator is constructed
 as part of a container's constructor. However, this assumption is
 implementation-specific, and subject to change. For an example of a
-pool that frees memory, see the following
-    <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://gcc.gnu.org/viewcvs/gcc/trunk/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local-6.cc?view=markup">
-    example.</link>
+pool that frees memory, see the
+    <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://gcc.gnu.org/cgit/gcc/tree/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local-6.cc?h=releases%2Fgcc-13"><filename>ext/mt_allocator/deallocate_local-6.cc</filename></link>
+    example.
 </para>
 
 </section>
--- a/src/libstdc++-v3/doc/xml/manual/status_cxx1998.xml
+++ b/src/libstdc++-v3/doc/xml/manual/status_cxx1998.xml
@@ -19,7 +19,7 @@ This status table is based on the table of contents of ISO/IEC 14882:2003.
 
 <para>
 This section describes the C++ support in
-the GCC 13 release series, not in any particular release.
+the GCC 13 release series.
 </para>
 
 <!-- Status is Yes or No, Broken/Partial-->
--- a/src/libstdc++-v3/doc/xml/manual/status_cxx2011.xml
+++ b/src/libstdc++-v3/doc/xml/manual/status_cxx2011.xml
@@ -35,7 +35,7 @@ This status table is based on the table of contents of ISO/IEC 14882:2011.
 
 <para>
 This section describes the C++11 support in
-the GCC 13 release series, not in any particular release.
+the GCC 13 release series.
 </para>
 
 <!-- Status is Yes or No, Broken/Partial-->
--- a/src/libstdc++-v3/doc/xml/manual/status_cxx2014.xml
+++ b/src/libstdc++-v3/doc/xml/manual/status_cxx2014.xml
@@ -30,7 +30,7 @@ since C++11 and the implementation is complete.
 
 <para>
 This section describes the C++14 and library TS support in
-the GCC 13 release series, not in any particular release.
+the GCC 13 release series.
 </para>
 
 <!-- Status is Yes or No, Broken/Partial-->
--- a/src/libstdc++-v3/doc/xml/manual/status_cxx2017.xml
+++ b/src/libstdc++-v3/doc/xml/manual/status_cxx2017.xml
@@ -24,7 +24,7 @@ since that release.
 
 <para>
 This section describes the C++17 and library TS support in
-the GCC 13 release series, not in any particular release.
+the GCC 13 release series.
 </para>
 
 <para>
--- a/src/libstdc++-v3/doc/xml/manual/status_cxx2020.xml
+++ b/src/libstdc++-v3/doc/xml/manual/status_cxx2020.xml
@@ -21,7 +21,7 @@ presence of the required flag.
 
 <para>
 This section describes the C++20 and library TS support in
-the GCC 13 release series, not in any particular release.
+the GCC 13 release series.
 </para>
 
 <para>
--- a/src/libstdc++-v3/doc/xml/manual/status_cxx2023.xml
+++ b/src/libstdc++-v3/doc/xml/manual/status_cxx2023.xml
@@ -21,7 +21,7 @@ presence of the required flag.
 
 <para>
 This section describes the C++23 and library TS support in
-the GCC 13 release series, not in any particular release.
+the GCC 13 release series.
 </para>
 
 <para>
--- a/src/libstdc++-v3/doc/xml/manual/status_cxxtr1.xml
+++ b/src/libstdc++-v3/doc/xml/manual/status_cxxtr1.xml
@@ -23,7 +23,7 @@ In this implementation the header names are prefixed by
 
 <para>
 This page describes the TR1 support in
-the GCC 13 release series, not in any particular release.
+the GCC 13 release series.
 </para>
 
 <!-- Status is Yes or No, Broken/Partial-->
--- a/src/libstdc++-v3/doc/xml/manual/status_cxxtr24733.xml
+++ b/src/libstdc++-v3/doc/xml/manual/status_cxxtr24733.xml
@@ -18,7 +18,7 @@ decimal floating-point arithmetic".
 
 <para>
 This page describes the TR 24733 support in
-the GCC 13 release series, not in any particular release.
+the GCC 13 release series.
 </para>
 
 <!-- Status is Yes or No, Broken/Partial-->
--- a/src/libstdc++-v3/doc/xml/manual/using.xml
+++ b/src/libstdc++-v3/doc/xml/manual/using.xml
@@ -7,7 +7,7 @@
 
     <para>
       The set of features available in the GNU C++ library is shaped by
-      several <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://gcc.gnu.org/onlinedocs/gcc-4.3.2/gcc/Invoking-GCC.html">GCC
+      several <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://gcc.gnu.org/onlinedocs/gcc-13.1.0/gcc/Invoking-GCC.html">GCC
       Command Options</link>. Options that impact libstdc++ are
       enumerated and detailed in the table below.
     </para>
@@ -37,35 +37,12 @@
 
   <tbody>
     <row>
-      <entry><literal>-std=c++98</literal> or <literal>-std=c++03</literal>
+      <entry><literal>-std</literal>
       </entry>
-      <entry>Use the 1998 ISO C++ standard plus amendments.</entry>
-    </row>
-
-    <row>
-      <entry><literal>-std=gnu++98</literal> or <literal>-std=gnu++03</literal>
+      <entry>
+	Select the C++ standard, and whether to use the base standard
+	or GNU dialect.
       </entry>
-      <entry>As directly above, with GNU extensions.</entry>
-    </row>
-
-    <row>
-      <entry><literal>-std=c++11</literal></entry>
-      <entry>Use the 2011 ISO C++ standard.</entry>
-    </row>
-
-    <row>
-      <entry><literal>-std=gnu++11</literal></entry>
-      <entry>As directly above, with GNU extensions.</entry>
-    </row>
-
-    <row>
-      <entry><literal>-std=c++14</literal></entry>
-      <entry>Use the 2014 ISO C++ standard.</entry>
-    </row>
-
-    <row>
-      <entry><literal>-std=gnu++14</literal></entry>
-      <entry>As directly above, with GNU extensions.</entry>
     </row>
 
     <row>
--- a/src/libstdc++-v3/include/bits/chrono_io.h
+++ b/src/libstdc++-v3/include/bits/chrono_io.h
@@ -1608,7 +1608,10 @@ namespace __format
 	format(const chrono::duration<_Rep, _Period>& __d,
 	       basic_format_context<_Out, _CharT>& __fc) const
 	{
-	  return _M_f._M_format(chrono::abs(__d), __fc, __d < __d.zero());
+	  if constexpr (numeric_limits<_Rep>::is_signed)
+	    if (__d < __d.zero())
+	      return _M_f._M_format(-__d, __fc, true);
+	  return _M_f._M_format(__d, __fc, false);
 	}
 
     private:
--- a/src/libstdc++-v3/include/bits/stl_bvector.h
+++ b/src/libstdc++-v3/include/bits/stl_bvector.h
@@ -593,7 +593,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 	_GLIBCXX20_CONSTEXPR
 	_Bvector_impl() _GLIBCXX_NOEXCEPT_IF(
 	  is_nothrow_default_constructible<_Bit_alloc_type>::value)
-#if __cpp_concepts
+#if __cpp_concepts && __cpp_lib_type_trait_variable_templates
 	requires is_default_constructible_v<_Bit_alloc_type>
 #endif
 	: _Bit_alloc_type()
--- a/src/libstdc++-v3/include/c_compatibility/stdatomic.h
+++ b/src/libstdc++-v3/include/c_compatibility/stdatomic.h
@@ -34,7 +34,7 @@
 
 #define __cpp_lib_stdatomic_h 202011L
 
-#define _Atomic(_Tp) std::atomic<_Tp>
+#define _Atomic(_Tp) ::std::atomic<_Tp>
 
 using std::memory_order;
 using std::memory_order_relaxed;
--- a/src/libstdc++-v3/include/experimental/bits/simd.h
+++ b/src/libstdc++-v3/include/experimental/bits/simd.h
@@ -584,19 +584,12 @@ template <size_t _Bytes>
     static_assert(_Bytes > 0);
     if constexpr (_Bytes == sizeof(int))
       return int();
-  #ifdef __clang__
-    else if constexpr (_Bytes == sizeof(char))
-      return char();
-  #else
     else if constexpr (_Bytes == sizeof(_SChar))
       return _SChar();
-  #endif
     else if constexpr (_Bytes == sizeof(short))
       return short();
-  #ifndef __clang__
     else if constexpr (_Bytes == sizeof(long))
       return long();
-  #endif
     else if constexpr (_Bytes == sizeof(_LLong))
       return _LLong();
   #ifdef __SIZEOF_INT128__
@@ -1616,7 +1609,29 @@ template <typename _V>
     if constexpr (__is_vector_type_v<_V>)
       return __x;
     else if constexpr (is_simd<_V>::value || is_simd_mask<_V>::value)
-      return __data(__x)._M_data;
+      {
+	if constexpr (__is_fixed_size_abi_v<typename _V::abi_type>)
+	  {
+	    static_assert(is_simd<_V>::value);
+	    static_assert(_V::abi_type::template __traits<
+			    typename _V::value_type>::_SimdMember::_S_tuple_size == 1);
+	    return __as_vector(__data(__x).first);
+	  }
+	else if constexpr (_V::size() > 1)
+	  return __data(__x)._M_data;
+	else
+	  {
+	    static_assert(is_simd<_V>::value);
+	    using _Tp = typename _V::value_type;
+#ifdef __i386__
+	    constexpr auto __bytes = sizeof(_Tp) == 8 ? 16 : sizeof(_Tp);
+	    using _RV [[__gnu__::__vector_size__(__bytes)]] = _Tp;
+#else
+	    using _RV [[__gnu__::__vector_size__(sizeof(_Tp))]] = _Tp;
+#endif
+	    return _RV{__data(__x)};
+	  }
+      }
     else if constexpr (__is_vectorizable_v<_V>)
       return __vector_type_t<_V, 2>{__x};
     else
@@ -2026,6 +2041,72 @@ template <typename _Tp, typename _TVT = _VectorTraits<_Tp>>
       return ~__a;
   }
 
+// }}}
+// __vec_shuffle{{{
+template <typename _T0, typename _T1, typename _Fun, size_t... _Is>
+  _GLIBCXX_SIMD_INTRINSIC constexpr
+  __vector_type_t<remove_reference_t<decltype(declval<_T0>()[0])>, sizeof...(_Is)>
+  __vec_shuffle(_T0 __x, _T1 __y, index_sequence<_Is...> __seq, _Fun __idx_perm)
+  {
+    constexpr int _N0 = sizeof(__x) / sizeof(__x[0]);
+    constexpr int _N1 = sizeof(__y) / sizeof(__y[0]);
+    using _Tp = remove_reference_t<decltype(declval<_T0>()[0])>;
+    using _RV [[maybe_unused]] = __vector_type_t<_Tp, sizeof...(_Is)>;
+#if __has_builtin(__builtin_shufflevector)
+#ifdef __clang__
+    // Clang requires _T0 == _T1
+    if constexpr (sizeof(__x) > sizeof(__y) and _N1 == 1)
+      return __vec_shuffle(__x, _T0{__y[0]}, __seq, __idx_perm);
+    else if constexpr (sizeof(__x) > sizeof(__y))
+      return __vec_shuffle(__x, __intrin_bitcast<_T0>(__y), __seq, __idx_perm);
+    else if constexpr (sizeof(__x) < sizeof(__y) and _N0 == 1)
+      return __vec_shuffle(_T1{__x[0]}, __y, __seq, [=](int __i) {
+	       __i = __idx_perm(__i);
+	       return __i < _N0 ? __i : __i - _N0 + _N1;
+	     });
+    else if constexpr (sizeof(__x) < sizeof(__y))
+      return __vec_shuffle(__intrin_bitcast<_T1>(__x), __y, __seq, [=](int __i) {
+	       __i = __idx_perm(__i);
+	       return __i < _N0 ? __i : __i - _N0 + _N1;
+	     });
+    else
+#endif
+      {
+	const auto __r = __builtin_shufflevector(__x, __y, [=] {
+			   constexpr int __j = __idx_perm(_Is);
+			   static_assert(__j < _N0 + _N1);
+			   return __j;
+			 }()...);
+#ifdef __i386__
+	if constexpr (sizeof(__r) == sizeof(_RV))
+	  return __r;
+	else
+	  return _RV {__r[_Is]...};
+#else
+	return __r;
+#endif
+      }
+#else
+    return _RV {
+      [=]() -> _Tp {
+	constexpr int __j = __idx_perm(_Is);
+	static_assert(__j < _N0 + _N1);
+	if constexpr (__j < 0)
+	  return 0;
+	else if constexpr (__j < _N0)
+	  return __x[__j];
+	else
+	  return __y[__j - _N0];
+      }()...
+    };
+#endif
+  }
+
+template <typename _T0, typename _Fun, typename _Seq>
+  _GLIBCXX_SIMD_INTRINSIC constexpr auto
+  __vec_shuffle(_T0 __x, _Seq __seq, _Fun __idx_perm)
+  { return __vec_shuffle(__x, _T0(), __seq, __idx_perm); }
+
 // }}}
 // __concat{{{
 template <typename _Tp, typename _TVT = _VectorTraits<_Tp>,
@@ -2624,6 +2705,8 @@ template <typename _BuiltinType>
 
 // }}}
 // _SimdWrapper{{{
+struct _DisabledSimdWrapper;
+
 template <typename _Tp, size_t _Width>
   struct _SimdWrapper<
     _Tp, _Width,
@@ -2633,16 +2716,17 @@ template <typename _Tp, size_t _Width>
 			      == sizeof(__vector_type_t<_Tp, _Width>),
 		       __vector_type_t<_Tp, _Width>>
   {
-    using _Base
-      = _SimdWrapperBase<__has_iec559_behavior<__signaling_NaN, _Tp>::value
-			   && sizeof(_Tp) * _Width
-				== sizeof(__vector_type_t<_Tp, _Width>),
-			 __vector_type_t<_Tp, _Width>>;
+    static constexpr bool _S_need_default_init
+      = __has_iec559_behavior<__signaling_NaN, _Tp>::value
+	  and sizeof(_Tp) * _Width == sizeof(__vector_type_t<_Tp, _Width>);
+
+    using _BuiltinType = __vector_type_t<_Tp, _Width>;
+
+    using _Base = _SimdWrapperBase<_S_need_default_init, _BuiltinType>;
 
     static_assert(__is_vectorizable_v<_Tp>);
     static_assert(_Width >= 2); // 1 doesn't make sense, use _Tp directly then
 
-    using _BuiltinType = __vector_type_t<_Tp, _Width>;
     using value_type = _Tp;
 
     static inline constexpr size_t _S_full_size
@@ -2678,13 +2762,26 @@ template <typename _Tp, size_t _Width>
     _GLIBCXX_SIMD_INTRINSIC constexpr _SimdWrapper&
     operator=(_SimdWrapper&&) = default;
 
-    template <typename _V, typename = enable_if_t<disjunction_v<
-			     is_same<_V, __vector_type_t<_Tp, _Width>>,
-			     is_same<_V, __intrinsic_type_t<_Tp, _Width>>>>>
+    // Convert from exactly matching __vector_type_t
+    using _SimdWrapperBase<_S_need_default_init, _BuiltinType>::_SimdWrapperBase;
+
+    // Convert from __intrinsic_type_t if __intrinsic_type_t and __vector_type_t differ, otherwise
+    // this ctor should not exist. Making the argument type unusable is our next best solution.
+    _GLIBCXX_SIMD_INTRINSIC constexpr
+    _SimdWrapper(conditional_t<is_same_v<_BuiltinType, __intrinsic_type_t<_Tp, _Width>>,
+			       _DisabledSimdWrapper, __intrinsic_type_t<_Tp, _Width>> __x)
+    : _Base(__vector_bitcast<_Tp, _Width>(__x)) {}
+
+    // Convert from different __vector_type_t, but only if bit reinterpretation is a correct
+    // conversion of the value_type
+    template <typename _V, typename _TVT = _VectorTraits<_V>,
+	      typename = enable_if_t<sizeof(typename _TVT::value_type) == sizeof(_Tp)
+				       and sizeof(_V) == sizeof(_BuiltinType)
+				       and is_integral_v<_Tp>
+				       and is_integral_v<typename _TVT::value_type>>>
       _GLIBCXX_SIMD_INTRINSIC constexpr
       _SimdWrapper(_V __x)
-      // __vector_bitcast can convert e.g. __m128 to __vector(2) float
-      : _Base(__vector_bitcast<_Tp, _Width>(__x)) {}
+      : _Base(reinterpret_cast<_BuiltinType>(__x)) {}
 
     template <typename... _As,
 	      typename = enable_if_t<((is_same_v<simd_abi::scalar, _As> && ...)
@@ -3886,7 +3983,7 @@ template <size_t... _Sizes, typename _Tp, typename _Ap,
 // __extract_part {{{
 template <int _Index, int _Total, int _Combine = 1, typename _Tp, size_t _Np>
   _GLIBCXX_SIMD_INTRINSIC _GLIBCXX_CONST constexpr
-  _SimdWrapper<_Tp, _Np / _Total * _Combine>
+  conditional_t<_Np == _Total and _Combine == 1, _Tp, _SimdWrapper<_Tp, _Np / _Total * _Combine>>
   __extract_part(const _SimdWrapper<_Tp, _Np> __x);
 
 template <int _Index, int _Parts, int _Combine = 1, typename _Tp, typename _A0, typename... _As>
@@ -4150,48 +4247,21 @@ template <size_t... _Sizes, typename _Tp, typename _Ap, typename>
 			 __split_wrapper(_SL::template _S_pop_front<1>(),
 					 __data(__x).second));
       }
-    else if constexpr ((!is_same_v<simd_abi::scalar,
-				   simd_abi::deduce_t<_Tp, _Sizes>> && ...)
-		       && (!__is_fixed_size_abi_v<
-			     simd_abi::deduce_t<_Tp, _Sizes>> && ...))
+    else if constexpr ((!__is_fixed_size_abi_v<simd_abi::deduce_t<_Tp, _Sizes>> && ...))
       {
-	if constexpr (((_Sizes * 2 == _Np) && ...))
-	  return {{__private_init, __extract_part<0, 2>(__data(__x))},
-		  {__private_init, __extract_part<1, 2>(__data(__x))}};
-	else if constexpr (is_same_v<_SizeList<_Sizes...>,
-				     _SizeList<_Np / 3, _Np / 3, _Np / 3>>)
-	  return {{__private_init, __extract_part<0, 3>(__data(__x))},
-		  {__private_init, __extract_part<1, 3>(__data(__x))},
-		  {__private_init, __extract_part<2, 3>(__data(__x))}};
-	else if constexpr (is_same_v<_SizeList<_Sizes...>,
-				     _SizeList<2 * _Np / 3, _Np / 3>>)
-	  return {{__private_init, __extract_part<0, 3, 2>(__data(__x))},
-		  {__private_init, __extract_part<2, 3>(__data(__x))}};
-	else if constexpr (is_same_v<_SizeList<_Sizes...>,
-				     _SizeList<_Np / 3, 2 * _Np / 3>>)
-	  return {{__private_init, __extract_part<0, 3>(__data(__x))},
-		  {__private_init, __extract_part<1, 3, 2>(__data(__x))}};
-	else if constexpr (is_same_v<_SizeList<_Sizes...>,
-				     _SizeList<_Np / 2, _Np / 4, _Np / 4>>)
-	  return {{__private_init, __extract_part<0, 2>(__data(__x))},
-		  {__private_init, __extract_part<2, 4>(__data(__x))},
-		  {__private_init, __extract_part<3, 4>(__data(__x))}};
-	else if constexpr (is_same_v<_SizeList<_Sizes...>,
-				     _SizeList<_Np / 4, _Np / 4, _Np / 2>>)
-	  return {{__private_init, __extract_part<0, 4>(__data(__x))},
-		  {__private_init, __extract_part<1, 4>(__data(__x))},
-		  {__private_init, __extract_part<1, 2>(__data(__x))}};
-	else if constexpr (is_same_v<_SizeList<_Sizes...>,
-				     _SizeList<_Np / 4, _Np / 2, _Np / 4>>)
-	  return {{__private_init, __extract_part<0, 4>(__data(__x))},
-		  {__private_init, __extract_center(__data(__x))},
-		  {__private_init, __extract_part<3, 4>(__data(__x))}};
-	else if constexpr (((_Sizes * 4 == _Np) && ...))
-	  return {{__private_init, __extract_part<0, 4>(__data(__x))},
-		  {__private_init, __extract_part<1, 4>(__data(__x))},
-		  {__private_init, __extract_part<2, 4>(__data(__x))},
-		  {__private_init, __extract_part<3, 4>(__data(__x))}};
-	// else fall through
+	constexpr array<size_t, sizeof...(_Sizes)> __size = {_Sizes...};
+	return __generate_from_n_evaluations<sizeof...(_Sizes), _Tuple>(
+		 [&](auto __i) constexpr {
+		   constexpr size_t __offset = [&]() {
+		     size_t __r = 0;
+		     for (unsigned __j = 0; __j < __i; ++__j)
+		       __r += __size[__j];
+		     return __r;
+		   }();
+		   return __deduced_simd<_Tp, __size[__i]>(
+			    __private_init,
+			    __extract_part<__offset, _Np, __size[__i]>(__data(__x)));
+		 });
       }
 #ifdef _GLIBCXX_SIMD_USE_ALIASING_LOADS
     const __may_alias<_Tp>* const __element_ptr
@@ -4253,14 +4323,37 @@ template <typename _Tp, typename... _As, typename = __detail::__odr_helper>
   simd<_Tp, simd_abi::deduce_t<_Tp, (simd_size_v<_Tp, _As> + ...)>>
   concat(const simd<_Tp, _As>&... __xs)
   {
-    using _Rp = __deduced_simd<_Tp, (simd_size_v<_Tp, _As> + ...)>;
+    constexpr int _Np = (simd_size_v<_Tp, _As> + ...);
+    using _Abi = simd_abi::deduce_t<_Tp, _Np>;
+    using _Rp = simd<_Tp, _Abi>;
+    using _RW = typename _SimdTraits<_Tp, _Abi>::_SimdMember;
     if constexpr (sizeof...(__xs) == 1)
       return simd_cast<_Rp>(__xs...);
     else if ((... && __xs._M_is_constprop()))
-      return simd<_Tp,
-		  simd_abi::deduce_t<_Tp, (simd_size_v<_Tp, _As> + ...)>>(
-	       [&](auto __i) constexpr _GLIBCXX_SIMD_ALWAYS_INLINE_LAMBDA
+      return _Rp([&](auto __i) constexpr _GLIBCXX_SIMD_ALWAYS_INLINE_LAMBDA
 	       { return __subscript_in_pack<__i>(__xs...); });
+    else if constexpr (__is_simd_wrapper_v<_RW> and sizeof...(__xs) == 2)
+      {
+	return {__private_init,
+		__vec_shuffle(__as_vector(__xs)..., std::make_index_sequence<_RW::_S_full_size>(),
+			      [](int __i) {
+				constexpr int __sizes[2] = {int(simd_size_v<_Tp, _As>)...};
+				constexpr int __vsizes[2]
+				  = {int(sizeof(__as_vector(__xs)) / sizeof(_Tp))...};
+				constexpr int __padding0 = __vsizes[0] - __sizes[0];
+				return __i >= _Np ? -1 : __i < __sizes[0] ? __i : __i + __padding0;
+			      })};
+      }
+    else if constexpr (__is_simd_wrapper_v<_RW> and sizeof...(__xs) == 3)
+      return [](const auto& __x0, const auto& __x1, const auto& __x2)
+		 _GLIBCXX_SIMD_ALWAYS_INLINE_LAMBDA {
+	       return concat(concat(__x0, __x1), __x2);
+	     }(__xs...);
+    else if constexpr (__is_simd_wrapper_v<_RW> and sizeof...(__xs) > 3)
+      return [](const auto& __x0, const auto& __x1, const auto&... __rest)
+		 _GLIBCXX_SIMD_ALWAYS_INLINE_LAMBDA {
+	       return concat(concat(__x0, __x1), concat(__rest...));
+	     }(__xs...);
     else
       {
 	_Rp __r{};
--- a/src/libstdc++-v3/include/experimental/bits/simd_builtin.h
+++ b/src/libstdc++-v3/include/experimental/bits/simd_builtin.h
@@ -92,124 +92,16 @@ template <typename _Tp, size_t _ToN = 0, typename _Up, size_t _M,
     return __intrin_bitcast<__vector_type_t<_Tp, _Np>>(__x._M_data);
   }
 
-// }}}
-// __shift_elements_right{{{
-// if (__shift % 2ⁿ == 0) => the low n Bytes are correct
-template <unsigned __shift, typename _Tp, typename _TVT = _VectorTraits<_Tp>>
-  _GLIBCXX_SIMD_INTRINSIC _Tp
-  __shift_elements_right(_Tp __v)
-  {
-    [[maybe_unused]] const auto __iv = __to_intrin(__v);
-    static_assert(__shift <= sizeof(_Tp));
-    if constexpr (__shift == 0)
-      return __v;
-    else if constexpr (__shift == sizeof(_Tp))
-      return _Tp();
-#if _GLIBCXX_SIMD_X86INTRIN // {{{
-    else if constexpr (__have_sse && __shift == 8
-		       && _TVT::template _S_is<float, 4>)
-      return _mm_movehl_ps(__iv, __iv);
-    else if constexpr (__have_sse2 && __shift == 8
-		       && _TVT::template _S_is<double, 2>)
-      return _mm_unpackhi_pd(__iv, __iv);
-    else if constexpr (__have_sse2 && sizeof(_Tp) == 16)
-      return reinterpret_cast<typename _TVT::type>(
-	_mm_srli_si128(reinterpret_cast<__m128i>(__iv), __shift));
-    else if constexpr (__shift == 16 && sizeof(_Tp) == 32)
-      {
-	/*if constexpr (__have_avx && _TVT::template _S_is<double, 4>)
-	  return _mm256_permute2f128_pd(__iv, __iv, 0x81);
-	else if constexpr (__have_avx && _TVT::template _S_is<float, 8>)
-	  return _mm256_permute2f128_ps(__iv, __iv, 0x81);
-	else if constexpr (__have_avx)
-	  return reinterpret_cast<typename _TVT::type>(
-	    _mm256_permute2f128_si256(__iv, __iv, 0x81));
-	else*/
-	return __zero_extend(__hi128(__v));
-      }
-    else if constexpr (__have_avx2 && sizeof(_Tp) == 32 && __shift < 16)
-      {
-	const auto __vll = __vector_bitcast<_LLong>(__v);
-	return reinterpret_cast<typename _TVT::type>(
-	  _mm256_alignr_epi8(_mm256_permute2x128_si256(__vll, __vll, 0x81),
-			     __vll, __shift));
-      }
-    else if constexpr (__have_avx && sizeof(_Tp) == 32 && __shift < 16)
-      {
-	const auto __vll = __vector_bitcast<_LLong>(__v);
-	return reinterpret_cast<typename _TVT::type>(
-	  __concat(_mm_alignr_epi8(__hi128(__vll), __lo128(__vll), __shift),
-		   _mm_srli_si128(__hi128(__vll), __shift)));
-      }
-    else if constexpr (sizeof(_Tp) == 32 && __shift > 16)
-      return __zero_extend(__shift_elements_right<__shift - 16>(__hi128(__v)));
-    else if constexpr (sizeof(_Tp) == 64 && __shift == 32)
-      return __zero_extend(__hi256(__v));
-    else if constexpr (__have_avx512f && sizeof(_Tp) == 64)
-      {
-	if constexpr (__shift >= 48)
-	  return __zero_extend(
-	    __shift_elements_right<__shift - 48>(__extract<3, 4>(__v)));
-	else if constexpr (__shift >= 32)
-	  return __zero_extend(
-	    __shift_elements_right<__shift - 32>(__hi256(__v)));
-	else if constexpr (__shift % 8 == 0)
-	  return reinterpret_cast<typename _TVT::type>(
-	    _mm512_alignr_epi64(__m512i(), __intrin_bitcast<__m512i>(__v),
-				__shift / 8));
-	else if constexpr (__shift % 4 == 0)
-	  return reinterpret_cast<typename _TVT::type>(
-	    _mm512_alignr_epi32(__m512i(), __intrin_bitcast<__m512i>(__v),
-				__shift / 4));
-	else if constexpr (__have_avx512bw && __shift < 16)
-	  {
-	    const auto __vll = __vector_bitcast<_LLong>(__v);
-	    return reinterpret_cast<typename _TVT::type>(
-	      _mm512_alignr_epi8(_mm512_shuffle_i32x4(__vll, __vll, 0xf9),
-				 __vll, __shift));
-	  }
-	else if constexpr (__have_avx512bw && __shift < 32)
-	  {
-	    const auto __vll = __vector_bitcast<_LLong>(__v);
-	    return reinterpret_cast<typename _TVT::type>(
-	      _mm512_alignr_epi8(_mm512_shuffle_i32x4(__vll, __m512i(), 0xee),
-				 _mm512_shuffle_i32x4(__vll, __vll, 0xf9),
-				 __shift - 16));
-	  }
-	else
-	  __assert_unreachable<_Tp>();
-      }
-  /*
-      } else if constexpr (__shift % 16 == 0 && sizeof(_Tp) == 64)
-	  return __auto_bitcast(__extract<__shift / 16, 4>(__v));
-  */
-#endif // _GLIBCXX_SIMD_X86INTRIN }}}
-    else
-      {
-	constexpr int __chunksize = __shift % 8 == 0   ? 8
-				    : __shift % 4 == 0 ? 4
-				    : __shift % 2 == 0 ? 2
-						       : 1;
-	auto __w = __vector_bitcast<__int_with_sizeof_t<__chunksize>>(__v);
-	using _Up = decltype(__w);
-	return __intrin_bitcast<_Tp>(
-	  __call_with_n_evaluations<(sizeof(_Tp) - __shift) / __chunksize>(
-	    [](auto... __chunks) _GLIBCXX_SIMD_ALWAYS_INLINE_LAMBDA {
-	      return _Up{__chunks...};
-	    }, [&](auto __i) _GLIBCXX_SIMD_ALWAYS_INLINE_LAMBDA {
-	      return __w[__shift / __chunksize + __i];
-	    }));
-      }
-  }
-
 // }}}
 // __extract_part(_SimdWrapper<_Tp, _Np>) {{{
 template <int _Index, int _Total, int _Combine, typename _Tp, size_t _Np>
   _GLIBCXX_SIMD_INTRINSIC _GLIBCXX_CONST constexpr
-  _SimdWrapper<_Tp, _Np / _Total * _Combine>
+  conditional_t<_Np == _Total and _Combine == 1, _Tp, _SimdWrapper<_Tp, _Np / _Total * _Combine>>
   __extract_part(const _SimdWrapper<_Tp, _Np> __x)
   {
-    if constexpr (_Index % 2 == 0 && _Total % 2 == 0 && _Combine % 2 == 0)
+    if constexpr (_Np == _Total and _Combine == 1)
+      return __x[_Index];
+    else if constexpr (_Index % 2 == 0 && _Total % 2 == 0 && _Combine % 2 == 0)
       return __extract_part<_Index / 2, _Total / 2, _Combine / 2>(__x);
     else
       {
@@ -235,39 +127,11 @@ template <int _Index, int _Total, int _Combine, typename _Tp, size_t _Np>
 	  return __x;
 	else if constexpr (_Index == 0)
 	  return __intrin_bitcast<_R>(__as_vector(__x));
-#if _GLIBCXX_SIMD_X86INTRIN // {{{
-	else if constexpr (sizeof(__x) == 32
-			   && __return_size * sizeof(_Tp) <= 16)
-	  {
-	    constexpr size_t __bytes_to_skip = __values_to_skip * sizeof(_Tp);
-	    if constexpr (__bytes_to_skip == 16)
-	      return __vector_bitcast<_Tp, __return_size>(
-		__hi128(__as_vector(__x)));
-	    else
-	      return __vector_bitcast<_Tp, __return_size>(
-		_mm_alignr_epi8(__hi128(__vector_bitcast<_LLong>(__x)),
-				__lo128(__vector_bitcast<_LLong>(__x)),
-				__bytes_to_skip));
-	  }
-#endif // _GLIBCXX_SIMD_X86INTRIN }}}
-	else if constexpr (_Index > 0
-			   && (__values_to_skip % __return_size != 0
-			       || sizeof(_R) >= 8)
-			   && (__values_to_skip + __return_size) * sizeof(_Tp)
-				<= 64
-			   && sizeof(__x) >= 16)
-	  return __intrin_bitcast<_R>(
-	    __shift_elements_right<__values_to_skip * sizeof(_Tp)>(
-	      __as_vector(__x)));
 	else
-	  {
-	    _R __r = {};
-	    __builtin_memcpy(&__r,
-			     reinterpret_cast<const char*>(&__x)
-			       + sizeof(_Tp) * __values_to_skip,
-			     __return_size * sizeof(_Tp));
-	    return __r;
-	  }
+	  return __vec_shuffle(__as_vector(__x), make_index_sequence<__bit_ceil(__return_size)>(),
+			       [](size_t __i) {
+				 return __i + __values_to_skip;
+			       });
       }
   }
 
--- a/src/libstdc++-v3/include/experimental/bits/simd_fixed_size.h
+++ b/src/libstdc++-v3/include/experimental/bits/simd_fixed_size.h
@@ -927,7 +927,9 @@ template <int _Index, int _Total, int _Combine, typename _Tp, typename _A0, type
     using _RetAbi = simd_abi::deduce_t<_Tp, __return_size>;
 
     // handle (optimize) the simple cases
-    if constexpr (_Index == 0 && _Tuple::_S_first_size == __return_size)
+    if constexpr (__return_size == 1)
+      return __x[integral_constant<size_t, __values_to_skip>()];
+    else if constexpr (_Index == 0 && _Tuple::_S_first_size == __return_size)
       return __x.first._M_data;
     else if constexpr (_Index == 0 && _Total == _Combine)
       return __x;
--- a/src/libstdc++-v3/include/experimental/bits/simd_x86.h
+++ b/src/libstdc++-v3/include/experimental/bits/simd_x86.h
@@ -2339,29 +2339,29 @@ template <typename _Abi, typename>
 		  __assert_unreachable<_Tp>();
 	      }
 	    else if constexpr (sizeof(__xi) == 64 && sizeof(_Tp) == 8)
-	      return ~_mm512_mask_cmpeq_epi64_mask(__k1, __xi, __yi);
+	      return _mm512_mask_cmpneq_epi64_mask(__k1, __xi, __yi);
 	    else if constexpr (sizeof(__xi) == 64 && sizeof(_Tp) == 4)
-	      return ~_mm512_mask_cmpeq_epi32_mask(__k1, __xi, __yi);
+	      return _mm512_mask_cmpneq_epi32_mask(__k1, __xi, __yi);
 	    else if constexpr (sizeof(__xi) == 64 && sizeof(_Tp) == 2)
-	      return ~_mm512_mask_cmpeq_epi16_mask(__k1, __xi, __yi);
+	      return _mm512_mask_cmpneq_epi16_mask(__k1, __xi, __yi);
 	    else if constexpr (sizeof(__xi) == 64 && sizeof(_Tp) == 1)
-	      return ~_mm512_mask_cmpeq_epi8_mask(__k1, __xi, __yi);
+	      return _mm512_mask_cmpneq_epi8_mask(__k1, __xi, __yi);
 	    else if constexpr (sizeof(__xi) == 32 && sizeof(_Tp) == 8)
-	      return ~_mm256_mask_cmpeq_epi64_mask(__k1, __xi, __yi);
+	      return _mm256_mask_cmpneq_epi64_mask(__k1, __xi, __yi);
 	    else if constexpr (sizeof(__xi) == 32 && sizeof(_Tp) == 4)
-	      return ~_mm256_mask_cmpeq_epi32_mask(__k1, __xi, __yi);
+	      return _mm256_mask_cmpneq_epi32_mask(__k1, __xi, __yi);
 	    else if constexpr (sizeof(__xi) == 32 && sizeof(_Tp) == 2)
-	      return ~_mm256_mask_cmpeq_epi16_mask(__k1, __xi, __yi);
+	      return _mm256_mask_cmpneq_epi16_mask(__k1, __xi, __yi);
 	    else if constexpr (sizeof(__xi) == 32 && sizeof(_Tp) == 1)
-	      return ~_mm256_mask_cmpeq_epi8_mask(__k1, __xi, __yi);
+	      return _mm256_mask_cmpneq_epi8_mask(__k1, __xi, __yi);
 	    else if constexpr (sizeof(__xi) == 16 && sizeof(_Tp) == 8)
-	      return ~_mm_mask_cmpeq_epi64_mask(__k1, __xi, __yi);
+	      return _mm_mask_cmpneq_epi64_mask(__k1, __xi, __yi);
 	    else if constexpr (sizeof(__xi) == 16 && sizeof(_Tp) == 4)
-	      return ~_mm_mask_cmpeq_epi32_mask(__k1, __xi, __yi);
+	      return _mm_mask_cmpneq_epi32_mask(__k1, __xi, __yi);
 	    else if constexpr (sizeof(__xi) == 16 && sizeof(_Tp) == 2)
-	      return ~_mm_mask_cmpeq_epi16_mask(__k1, __xi, __yi);
+	      return _mm_mask_cmpneq_epi16_mask(__k1, __xi, __yi);
 	    else if constexpr (sizeof(__xi) == 16 && sizeof(_Tp) == 1)
-	      return ~_mm_mask_cmpeq_epi8_mask(__k1, __xi, __yi);
+	      return _mm_mask_cmpneq_epi8_mask(__k1, __xi, __yi);
 	    else
 	      __assert_unreachable<_Tp>();
 	  }                                                   // }}}
@@ -5292,7 +5292,7 @@ template <typename _Abi, typename>
       _S_find_last_set(simd_mask<_Tp, _Abi> __k)
       {
 	if constexpr (__is_avx512_abi<_Abi>())
-	  return std::__bit_width(__k._M_data._M_data) - 1;
+	  return std::__bit_width(_Abi::_S_masked(__k._M_data)._M_data) - 1;
 	else
 	  return _Base::_S_find_last_set(__k);
       }
--- a/src/libstdc++-v3/include/std/array
+++ b/src/libstdc++-v3/include/std/array
@@ -426,7 +426,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       static_assert(is_constructible_v<_Tp, _Tp&>);
       if constexpr (is_constructible_v<_Tp, _Tp&>)
 	{
-	  if constexpr (is_trivial_v<_Tp>)
+	  if constexpr (is_trivially_copyable_v<_Tp>
+			  && is_trivially_default_constructible_v<_Tp>
+			  && is_copy_assignable_v<_Tp>)
 	    {
 	      array<remove_cv_t<_Tp>, _Nm> __arr;
 	      if (!__is_constant_evaluated() && _Nm != 0)
@@ -455,7 +457,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       static_assert(is_move_constructible_v<_Tp>);
       if constexpr (is_move_constructible_v<_Tp>)
 	{
-	  if constexpr (is_trivial_v<_Tp>)
+	  if constexpr (is_trivially_copyable_v<_Tp>
+			  && is_trivially_default_constructible_v<_Tp>
+			  && is_copy_assignable_v<_Tp>)
 	    {
 	      array<remove_cv_t<_Tp>, _Nm> __arr;
 	      if (!__is_constant_evaluated() && _Nm != 0)
--- a/src/libstdc++-v3/include/std/stacktrace
+++ b/src/libstdc++-v3/include/std/stacktrace
@@ -600,6 +600,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #else
 # define _GLIBCXX_OPERATOR_NEW ::operator new
 # define _GLIBCXX_OPERATOR_DELETE ::operator delete
+#endif
+
+#if __cpp_sized_deallocation
+# define _GLIBCXX_SIZED_DELETE(T, p, n) \
+  _GLIBCXX_OPERATOR_DELETE((p), (n) * sizeof(T))
+#else
+# define _GLIBCXX_SIZED_DELETE(T, p, n) _GLIBCXX_OPERATOR_DELETE(p)
 #endif
 
 	// Precondition: _M_frames == nullptr && __n != 0
@@ -641,8 +648,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  if (_M_capacity)
 	    {
 	      if constexpr (is_same_v<allocator_type, allocator<value_type>>)
-		_GLIBCXX_OPERATOR_DELETE (static_cast<void*>(_M_frames),
-					  _M_capacity * sizeof(value_type));
+		_GLIBCXX_SIZED_DELETE(value_type,
+				      static_cast<void*>(_M_frames),
+				      _M_capacity);
 	      else
 		__alloc.deallocate(_M_frames, _M_capacity);
 	      _M_frames = nullptr;
@@ -650,6 +658,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	    }
 	}
 
+#undef _GLIBCXX_SIZED_DELETE
 #undef _GLIBCXX_OPERATOR_DELETE
 #undef _GLIBCXX_OPERATOR_NEW
 
--- a/src/libstdc++-v3/libsupc++/new_opa.cc
+++ b/src/libstdc++-v3/libsupc++/new_opa.cc
@@ -47,7 +47,7 @@ using std::size_t;
 extern "C"
 {
 # if _GLIBCXX_HAVE_POSIX_MEMALIGN
-  void *posix_memalign(void **, size_t alignment, size_t size);
+  int posix_memalign(void **, size_t alignment, size_t size);
 # elif _GLIBCXX_HAVE_ALIGNED_ALLOC
   void *aligned_alloc(size_t alignment, size_t size);
 # elif _GLIBCXX_HAVE__ALIGNED_MALLOC
--- a/src/libstdc++-v3/src/c++11/assert_fail.cc
+++ b/src/libstdc++-v3/src/c++11/assert_fail.cc
@@ -22,10 +22,10 @@
 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 // <http://www.gnu.org/licenses/>.
 
-#include <cstdio>	// for std::fprintf, stderr
 #include <cstdlib>	// for std::abort
 
 #ifdef _GLIBCXX_VERBOSE_ASSERT
+#include <cstdio>	// for std::fprintf, stderr
 namespace std
 {
   [[__noreturn__]]
@@ -41,4 +41,12 @@ namespace std
     abort();
   }
 }
+#else
+namespace std
+{
+  [[__noreturn__]]
+  void
+  __glibcxx_assert_fail(const char*, int, const char*, const char*) noexcept
+  { abort(); }
+}
 #endif
--- a/src/libstdc++-v3/src/c++11/codecvt.cc
+++ b/src/libstdc++-v3/src/c++11/codecvt.cc
@@ -284,6 +284,8 @@ namespace
 	return invalid_mb_sequence;
       if (c1 == 0xE0 && c2 < 0xA0) [[unlikely]] // overlong
 	return invalid_mb_sequence;
+      if (c1 == 0xED && c2 >= 0xA0) [[unlikely]] // surrogate
+	return invalid_mb_sequence;
       if (avail < 3) [[unlikely]]
 	return incomplete_mb_character;
       char32_t c3 = (unsigned char) from[2];
@@ -484,6 +486,8 @@ namespace
     while (from.size())
       {
 	const char32_t c = from[0];
+	if (0xD800 <= c && c <= 0xDFFF) [[unlikely]]
+	  return codecvt_base::error;
 	if (c > maxcode) [[unlikely]]
 	  return codecvt_base::error;
 	if (!write_utf8_code_point(to, c)) [[unlikely]]
@@ -508,7 +512,7 @@ namespace
 	  return codecvt_base::error;
 	to = codepoint;
       }
-    return from.size() ? codecvt_base::partial : codecvt_base::ok;
+    return from.nbytes() ? codecvt_base::partial : codecvt_base::ok;
   }
 
   // ucs4 -> utf16
@@ -521,6 +525,8 @@ namespace
     while (from.size())
       {
 	const char32_t c = from[0];
+	if (0xD800 <= c && c <= 0xDFFF) [[unlikely]]
+	  return codecvt_base::error;
 	if (c > maxcode) [[unlikely]]
 	  return codecvt_base::error;
 	if (!write_utf16_code_point(to, c, mode)) [[unlikely]]
@@ -653,7 +659,7 @@ namespace
     while (from.size() && to.size())
       {
 	char16_t c = from[0];
-	if (is_high_surrogate(c))
+	if (0xD800 <= c && c <= 0xDFFF)
 	  return codecvt_base::error;
 	if (c > maxcode)
 	  return codecvt_base::error;
@@ -680,7 +686,7 @@ namespace
 	  return codecvt_base::error;
 	to = c;
       }
-    return from.size() == 0 ? codecvt_base::ok : codecvt_base::partial;
+    return from.nbytes() == 0 ? codecvt_base::ok : codecvt_base::partial;
   }
 
   const char16_t*
@@ -1344,8 +1350,6 @@ do_in(state_type&, const extern_type* __from, const extern_type* __from_end,
   auto res = ucs2_in(from, to, _M_maxcode, _M_mode);
   __from_next = reinterpret_cast<const char*>(from.next);
   __to_next = to.next;
-  if (res == codecvt_base::ok && __from_next != __from_end)
-    res = codecvt_base::error;
   return res;
 }
 
@@ -1419,8 +1423,6 @@ do_in(state_type&, const extern_type* __from, const extern_type* __from_end,
   auto res = ucs4_in(from, to, _M_maxcode, _M_mode);
   __from_next = reinterpret_cast<const char*>(from.next);
   __to_next = to.next;
-  if (res == codecvt_base::ok && __from_next != __from_end)
-    res = codecvt_base::error;
   return res;
 }
 
@@ -1521,8 +1523,6 @@ do_in(state_type&, const extern_type* __from, const extern_type* __from_end,
 #endif
   __from_next = reinterpret_cast<const char*>(from.next);
   __to_next = reinterpret_cast<wchar_t*>(to.next);
-  if (res == codecvt_base::ok && __from_next != __from_end)
-    res = codecvt_base::error;
   return res;
 }
 
--- a/src/libstdc++-v3/testsuite/19_diagnostics/stacktrace/hash.cc
+++ b/src/libstdc++-v3/testsuite/19_diagnostics/stacktrace/hash.cc
@@ -1,4 +1,4 @@
-// { dg-options "-std=gnu++23 -lstdc++_libbacktrace" }
+// { dg-options "-std=gnu++23 -lstdc++exp" }
 // { dg-do run { target c++23 } }
 // { dg-require-effective-target stacktrace }
 
--- a/src/libstdc++-v3/testsuite/20_util/duration/io.cc
+++ b/src/libstdc++-v3/testsuite/20_util/duration/io.cc
@@ -101,6 +101,12 @@ test_format()
   std::chrono::duration<float, std::milli> d{0.5};
   s = std::format("{}", d);
   VERIFY( s == "0.5ms" );
+
+  std::chrono::duration<unsigned, std::milli> u{500}; // PR libstdc++/115668
+  s = std::format("{}", u);
+  VERIFY( s == "500ms" );
+  s = std::format("{:%Q %q}", u);
+  VERIFY( s == "500 ms" );
 }
 
 int main()
--- a/src/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_unicode.cc
+++ b/src/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_unicode.cc
@@ -27,38 +27,58 @@ void
 test_utf8_utf32_codecvts ()
 {
   using codecvt_c32 = codecvt<char32_t, char, mbstate_t>;
-  auto loc_c = locale::classic ();
+  auto &loc_c = locale::classic ();
   VERIFY (has_facet<codecvt_c32> (loc_c));
 
   auto &cvt = use_facet<codecvt_c32> (loc_c);
-  test_utf8_utf32_codecvts (cvt);
+  test_utf8_utf32_cvt (cvt);
 
   codecvt_utf8<char32_t> cvt2;
-  test_utf8_utf32_codecvts (cvt2);
+  test_utf8_utf32_cvt (cvt2);
 }
 
 void
 test_utf8_utf16_codecvts ()
 {
   using codecvt_c16 = codecvt<char16_t, char, mbstate_t>;
-  auto loc_c = locale::classic ();
+  auto &loc_c = locale::classic ();
   VERIFY (has_facet<codecvt_c16> (loc_c));
 
   auto &cvt = use_facet<codecvt_c16> (loc_c);
-  test_utf8_utf16_cvts (cvt);
+  test_utf8_utf16_cvt (cvt);
 
   codecvt_utf8_utf16<char16_t> cvt2;
-  test_utf8_utf16_cvts (cvt2);
+  test_utf8_utf16_cvt (cvt2);
 
   codecvt_utf8_utf16<char32_t> cvt3;
-  test_utf8_utf16_cvts (cvt3);
+  test_utf8_utf16_cvt (cvt3);
 }
 
 void
 test_utf8_ucs2_codecvts ()
 {
   codecvt_utf8<char16_t> cvt;
-  test_utf8_ucs2_cvts (cvt);
+  test_utf8_ucs2_cvt (cvt);
+}
+
+void
+test_utf16_utf32_codecvts ()
+{
+  codecvt_utf16<char32_t> cvt;
+  test_utf16_utf32_cvt (cvt, utf16_big_endian);
+
+  codecvt_utf16<char32_t, 0x10FFFF, codecvt_mode::little_endian> cvt2;
+  test_utf16_utf32_cvt (cvt2, utf16_little_endian);
+}
+
+void
+test_utf16_ucs2_codecvts ()
+{
+  codecvt_utf16<char16_t> cvt;
+  test_utf16_ucs2_cvt (cvt, utf16_big_endian);
+
+  codecvt_utf16<char16_t, 0x10FFFF, codecvt_mode::little_endian> cvt2;
+  test_utf16_ucs2_cvt (cvt2, utf16_little_endian);
 }
 
 int
@@ -67,4 +87,6 @@ main ()
   test_utf8_utf32_codecvts ();
   test_utf8_utf16_codecvts ();
   test_utf8_ucs2_codecvts ();
+  test_utf16_utf32_codecvts ();
+  test_utf16_ucs2_codecvts ();
 }
--- a/src/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_unicode.h
+++ b/src/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_unicode.h
@@ -17,7 +17,6 @@
 
 #include <algorithm>
 #include <locale>
-#include <string>
 #include <testsuite_hooks.h>
 
 struct test_offsets_ok
@@ -42,33 +41,33 @@ auto constexpr array_size (const T (&)[N]) -> size_t
   return N;
 }
 
-template <class CharT>
+template <class InternT, class ExternT>
 void
-utf8_to_utf32_in_ok (const std::codecvt<CharT, char, mbstate_t> &cvt)
+utf8_to_utf32_in_ok (const std::codecvt<InternT, ExternT, mbstate_t> &cvt)
 {
   using namespace std;
   // UTF-8 string of 1-byte CP, 2-byte CP, 3-byte CP and 4-byte CP
-  const char in[] = "bш\uAAAA\U0010AAAA";
-  const char32_t exp_literal[] = U"bш\uAAAA\U0010AAAA";
-  CharT exp[array_size (exp_literal)] = {};
-  std::copy (begin (exp_literal), end (exp_literal), begin (exp));
-
-  static_assert (array_size (in) == 11, "");
-  static_assert (array_size (exp_literal) == 5, "");
-  static_assert (array_size (exp) == 5, "");
-  VERIFY (char_traits<char>::length (in) == 10);
-  VERIFY (char_traits<char32_t>::length (exp_literal) == 4);
-  VERIFY (char_traits<CharT>::length (exp) == 4);
+  const unsigned char input[] = "b\u0448\uAAAA\U0010AAAA";
+  const char32_t expected[] = U"b\u0448\uAAAA\U0010AAAA";
+  static_assert (array_size (input) == 11, "");
+  static_assert (array_size (expected) == 5, "");
+
+  ExternT in[array_size (input)];
+  InternT exp[array_size (expected)];
+  copy (begin (input), end (input), begin (in));
+  copy (begin (expected), end (expected), begin (exp));
+  VERIFY (char_traits<ExternT>::length (in) == 10);
+  VERIFY (char_traits<InternT>::length (exp) == 4);
 
   test_offsets_ok offsets[] = {{0, 0}, {1, 1}, {3, 2}, {6, 3}, {10, 4}};
   for (auto t : offsets)
     {
-      CharT out[array_size (exp) - 1] = {};
+      InternT out[array_size (exp) - 1] = {};
       VERIFY (t.in_size <= array_size (in));
       VERIFY (t.out_size <= array_size (out));
       auto state = mbstate_t{};
-      auto in_next = (const char *) nullptr;
-      auto out_next = (CharT *) nullptr;
+      auto in_next = (const ExternT *) nullptr;
+      auto out_next = (InternT *) nullptr;
       auto res = codecvt_base::result ();
 
       res = cvt.in (state, in, in + t.in_size, in_next, out, out + t.out_size,
@@ -76,19 +75,24 @@ utf8_to_utf32_in_ok (const std::codecvt<CharT, char, mbstate_t> &cvt)
       VERIFY (res == cvt.ok);
       VERIFY (in_next == in + t.in_size);
       VERIFY (out_next == out + t.out_size);
-      VERIFY (char_traits<CharT>::compare (out, exp, t.out_size) == 0);
+      VERIFY (char_traits<InternT>::compare (out, exp, t.out_size) == 0);
       if (t.out_size < array_size (out))
 	VERIFY (out[t.out_size] == 0);
+
+      state = {};
+      auto len = cvt.length (state, in, in + t.in_size, t.out_size);
+      VERIFY (len >= 0);
+      VERIFY (static_cast<size_t> (len) == t.in_size);
     }
 
   for (auto t : offsets)
     {
-      CharT out[array_size (exp)] = {};
+      InternT out[array_size (exp)] = {};
       VERIFY (t.in_size <= array_size (in));
       VERIFY (t.out_size <= array_size (out));
       auto state = mbstate_t{};
-      auto in_next = (const char *) nullptr;
-      auto out_next = (CharT *) nullptr;
+      auto in_next = (const ExternT *) nullptr;
+      auto out_next = (InternT *) nullptr;
       auto res = codecvt_base::result ();
 
       res
@@ -96,29 +100,34 @@ utf8_to_utf32_in_ok (const std::codecvt<CharT, char, mbstate_t> &cvt)
       VERIFY (res == cvt.ok);
       VERIFY (in_next == in + t.in_size);
       VERIFY (out_next == out + t.out_size);
-      VERIFY (char_traits<CharT>::compare (out, exp, t.out_size) == 0);
+      VERIFY (char_traits<InternT>::compare (out, exp, t.out_size) == 0);
       if (t.out_size < array_size (out))
 	VERIFY (out[t.out_size] == 0);
+
+      state = {};
+      auto len = cvt.length (state, in, in + t.in_size, array_size (out));
+      VERIFY (len >= 0);
+      VERIFY (static_cast<size_t> (len) == t.in_size);
     }
 }
 
-template <class CharT>
+template <class InternT, class ExternT>
 void
-utf8_to_utf32_in_partial (const std::codecvt<CharT, char, mbstate_t> &cvt)
+utf8_to_utf32_in_partial (const std::codecvt<InternT, ExternT, mbstate_t> &cvt)
 {
   using namespace std;
   // UTF-8 string of 1-byte CP, 2-byte CP, 3-byte CP and 4-byte CP
-  const char in[] = "bш\uAAAA\U0010AAAA";
-  const char32_t exp_literal[] = U"bш\uAAAA\U0010AAAA";
-  CharT exp[array_size (exp_literal)] = {};
-  std::copy (begin (exp_literal), end (exp_literal), begin (exp));
-
-  static_assert (array_size (in) == 11, "");
-  static_assert (array_size (exp_literal) == 5, "");
-  static_assert (array_size (exp) == 5, "");
-  VERIFY (char_traits<char>::length (in) == 10);
-  VERIFY (char_traits<char32_t>::length (exp_literal) == 4);
-  VERIFY (char_traits<CharT>::length (exp) == 4);
+  const unsigned char input[] = "b\u0448\uAAAA\U0010AAAA";
+  const char32_t expected[] = U"b\u0448\uAAAA\U0010AAAA";
+  static_assert (array_size (input) == 11, "");
+  static_assert (array_size (expected) == 5, "");
+
+  ExternT in[array_size (input)];
+  InternT exp[array_size (expected)];
+  copy (begin (input), end (input), begin (in));
+  copy (begin (expected), end (expected), begin (exp));
+  VERIFY (char_traits<ExternT>::length (in) == 10);
+  VERIFY (char_traits<InternT>::length (exp) == 4);
 
   test_offsets_partial offsets[] = {
     {1, 0, 0, 0}, // no space for first CP
@@ -144,14 +153,14 @@ utf8_to_utf32_in_partial (const std::codecvt<CharT, char, mbstate_t> &cvt)
 
   for (auto t : offsets)
     {
-      CharT out[array_size (exp) - 1] = {};
+      InternT out[array_size (exp) - 1] = {};
       VERIFY (t.in_size <= array_size (in));
       VERIFY (t.out_size <= array_size (out));
       VERIFY (t.expected_in_next <= t.in_size);
       VERIFY (t.expected_out_next <= t.out_size);
       auto state = mbstate_t{};
-      auto in_next = (const char *) nullptr;
-      auto out_next = (CharT *) nullptr;
+      auto in_next = (const ExternT *) nullptr;
+      auto out_next = (InternT *) nullptr;
       auto res = codecvt_base::result ();
 
       res = cvt.in (state, in, in + t.in_size, in_next, out, out + t.out_size,
@@ -159,37 +168,63 @@ utf8_to_utf32_in_partial (const std::codecvt<CharT, char, mbstate_t> &cvt)
       VERIFY (res == cvt.partial);
       VERIFY (in_next == in + t.expected_in_next);
       VERIFY (out_next == out + t.expected_out_next);
-      VERIFY (char_traits<CharT>::compare (out, exp, t.expected_out_next) == 0);
+      VERIFY (char_traits<InternT>::compare (out, exp, t.expected_out_next)
+	      == 0);
       if (t.expected_out_next < array_size (out))
 	VERIFY (out[t.expected_out_next] == 0);
+
+      state = {};
+      auto len = cvt.length (state, in, in + t.in_size, t.out_size);
+      VERIFY (len >= 0);
+      VERIFY (static_cast<size_t> (len) == t.expected_in_next);
     }
 }
 
-template <class CharT>
+template <class InternT, class ExternT>
 void
-utf8_to_utf32_in_error (const std::codecvt<CharT, char, mbstate_t> &cvt)
+utf8_to_utf32_in_error (const std::codecvt<InternT, ExternT, mbstate_t> &cvt)
 {
   using namespace std;
-  // UTF-8 string of 1-byte CP, 2-byte CP, 3-byte CP and 4-byte CP
-  const char valid_in[] = "bш\uAAAA\U0010AAAA";
-  const char32_t exp_literal[] = U"bш\uAAAA\U0010AAAA";
-  CharT exp[array_size (exp_literal)] = {};
-  std::copy (begin (exp_literal), end (exp_literal), begin (exp));
+  // UTF-8 string of 1-byte CP, 2-byte CP, 3-byte CP, 4-byte CP
+  const unsigned char input[] = "b\u0448\uD700\U0010AAAA";
+  const char32_t expected[] = U"b\u0448\uD700\U0010AAAA";
+  static_assert (array_size (input) == 11, "");
+  static_assert (array_size (expected) == 5, "");
+
+  ExternT in[array_size (input)];
+  InternT exp[array_size (expected)];
+  copy (begin (input), end (input), begin (in));
+  copy (begin (expected), end (expected), begin (exp));
+  VERIFY (char_traits<ExternT>::length (in) == 10);
+  VERIFY (char_traits<InternT>::length (exp) == 4);
+
+  // There are 5 classes of errors in UTF-8 decoding
+  // 1. Missing leading byte
+  // 2. Missing trailing byte
+  // 3. Surrogate CP
+  // 4. Overlong sequence
+  // 5. CP out of Unicode range
+  test_offsets_error<unsigned char> offsets[] = {
+
+    // 1. Missing leading byte. We will replace the leading byte with
+    // non-leading byte, such as a byte that is always invalid or a trailing
+    // byte.
 
-  static_assert (array_size (valid_in) == 11, "");
-  static_assert (array_size (exp_literal) == 5, "");
-  static_assert (array_size (exp) == 5, "");
-  VERIFY (char_traits<char>::length (valid_in) == 10);
-  VERIFY (char_traits<char32_t>::length (exp_literal) == 4);
-  VERIFY (char_traits<CharT>::length (exp) == 4);
+    // replace leading byte with invalid byte
+    {1, 4, 0, 0, 0xFF, 0},
+    {3, 4, 1, 1, 0xFF, 1},
+    {6, 4, 3, 2, 0xFF, 3},
+    {10, 4, 6, 3, 0xFF, 6},
 
-  test_offsets_error<char> offsets[] = {
+    // replace leading byte with trailing byte
+    {1, 4, 0, 0, 0b10101010, 0},
+    {3, 4, 1, 1, 0b10101010, 1},
+    {6, 4, 3, 2, 0b10101010, 3},
+    {10, 4, 6, 3, 0b10101010, 6},
 
-    // replace leading byte with invalid byte
-    {1, 4, 0, 0, '\xFF', 0},
-    {3, 4, 1, 1, '\xFF', 1},
-    {6, 4, 3, 2, '\xFF', 3},
-    {10, 4, 6, 3, '\xFF', 6},
+    // 2. Missing trailing byte. We will replace the trailing byte with
+    // non-trailing byte, such as a byte that is always invalid or a leading
+    // byte (simple ASCII byte in our case).
 
     // replace first trailing byte with ASCII byte
     {3, 4, 1, 1, 'z', 2},
@@ -197,21 +232,27 @@ utf8_to_utf32_in_error (const std::codecvt<CharT, char, mbstate_t> &cvt)
     {10, 4, 6, 3, 'z', 7},
 
     // replace first trailing byte with invalid byte
-    {3, 4, 1, 1, '\xFF', 2},
-    {6, 4, 3, 2, '\xFF', 4},
-    {10, 4, 6, 3, '\xFF', 7},
+    {3, 4, 1, 1, 0xFF, 2},
+    {6, 4, 3, 2, 0xFF, 4},
+    {10, 4, 6, 3, 0xFF, 7},
 
     // replace second trailing byte with ASCII byte
     {6, 4, 3, 2, 'z', 5},
     {10, 4, 6, 3, 'z', 8},
 
     // replace second trailing byte with invalid byte
-    {6, 4, 3, 2, '\xFF', 5},
-    {10, 4, 6, 3, '\xFF', 8},
+    {6, 4, 3, 2, 0xFF, 5},
+    {10, 4, 6, 3, 0xFF, 8},
 
     // replace third trailing byte
     {10, 4, 6, 3, 'z', 9},
-    {10, 4, 6, 3, '\xFF', 9},
+    {10, 4, 6, 3, 0xFF, 9},
+
+    // 2.1 The following test-cases raise doubt whether error or partial should
+    // be returned. For example, we have 4-byte sequence with valid leading
+    // byte. If we hide the last byte we need to return partial. But, if the
+    // second or third byte, which are visible to the call to codecvt, are
+    // malformed then error should be returned.
 
     // replace first trailing byte with ASCII byte, also incomplete at end
     {5, 4, 3, 2, 'z', 4},
@@ -219,30 +260,51 @@ utf8_to_utf32_in_error (const std::codecvt<CharT, char, mbstate_t> &cvt)
     {9, 4, 6, 3, 'z', 7},
 
     // replace first trailing byte with invalid byte, also incomplete at end
-    {5, 4, 3, 2, '\xFF', 4},
-    {8, 4, 6, 3, '\xFF', 7},
-    {9, 4, 6, 3, '\xFF', 7},
+    {5, 4, 3, 2, 0xFF, 4},
+    {8, 4, 6, 3, 0xFF, 7},
+    {9, 4, 6, 3, 0xFF, 7},
 
     // replace second trailing byte with ASCII byte, also incomplete at end
     {9, 4, 6, 3, 'z', 8},
 
     // replace second trailing byte with invalid byte, also incomplete at end
-    {9, 4, 6, 3, '\xFF', 8},
+    {9, 4, 6, 3, 0xFF, 8},
+
+    // 3. Surrogate CP. We modify the second byte (first trailing) of the 3-byte
+    // CP U+D700
+    {6, 4, 3, 2, 0b10100000, 4}, // turn U+D700 into U+D800
+    {6, 4, 3, 2, 0b10101100, 4}, // turn U+D700 into U+DB00
+    {6, 4, 3, 2, 0b10110000, 4}, // turn U+D700 into U+DC00
+    {6, 4, 3, 2, 0b10111100, 4}, // turn U+D700 into U+DF00
+
+    // 4. Overlong sequence. The CPs in the input are chosen such as modifying
+    // just the leading byte is enough to make them overlong, i.e. for the
+    // 3-byte and 4-byte CP the second byte (first trailing) has enough leading
+    // zeroes.
+    {3, 4, 1, 1, 0b11000000, 1},  // make the 2-byte CP overlong
+    {3, 4, 1, 1, 0b11000001, 1},  // make the 2-byte CP overlong
+    {6, 4, 3, 2, 0b11100000, 3},  // make the 3-byte CP overlong
+    {10, 4, 6, 3, 0b11110000, 6}, // make the 4-byte CP overlong
+
+    // 5. CP above range
+    // turn U+10AAAA into U+14AAAA by changing its leading byte
+    {10, 4, 6, 3, 0b11110101, 6},
+    // turn U+10AAAA into U+11AAAA by changing its 2nd byte
+    {10, 4, 6, 3, 0b10011010, 7},
   };
   for (auto t : offsets)
     {
-      char in[array_size (valid_in)] = {};
-      CharT out[array_size (exp) - 1] = {};
+      InternT out[array_size (exp) - 1] = {};
       VERIFY (t.in_size <= array_size (in));
       VERIFY (t.out_size <= array_size (out));
       VERIFY (t.expected_in_next <= t.in_size);
       VERIFY (t.expected_out_next <= t.out_size);
-      char_traits<char>::copy (in, valid_in, array_size (valid_in));
+      auto old_char = in[t.replace_pos];
       in[t.replace_pos] = t.replace_char;
 
       auto state = mbstate_t{};
-      auto in_next = (const char *) nullptr;
-      auto out_next = (CharT *) nullptr;
+      auto in_next = (const ExternT *) nullptr;
+      auto out_next = (InternT *) nullptr;
       auto res = codecvt_base::result ();
 
       res = cvt.in (state, in, in + t.in_size, in_next, out, out + t.out_size,
@@ -250,48 +312,56 @@ utf8_to_utf32_in_error (const std::codecvt<CharT, char, mbstate_t> &cvt)
       VERIFY (res == cvt.error);
       VERIFY (in_next == in + t.expected_in_next);
       VERIFY (out_next == out + t.expected_out_next);
-      VERIFY (char_traits<CharT>::compare (out, exp, t.expected_out_next) == 0);
+      VERIFY (char_traits<InternT>::compare (out, exp, t.expected_out_next)
+	      == 0);
       if (t.expected_out_next < array_size (out))
 	VERIFY (out[t.expected_out_next] == 0);
+
+      state = {};
+      auto len = cvt.length (state, in, in + t.in_size, t.out_size);
+      VERIFY (len >= 0);
+      VERIFY (static_cast<size_t> (len) == t.expected_in_next);
+
+      in[t.replace_pos] = old_char;
     }
 }
 
-template <class CharT>
+template <class InternT, class ExternT>
 void
-utf8_to_utf32_in (const std::codecvt<CharT, char, mbstate_t> &cvt)
+utf8_to_utf32_in (const std::codecvt<InternT, ExternT, mbstate_t> &cvt)
 {
   utf8_to_utf32_in_ok (cvt);
   utf8_to_utf32_in_partial (cvt);
   utf8_to_utf32_in_error (cvt);
 }
 
-template <class CharT>
+template <class InternT, class ExternT>
 void
-utf32_to_utf8_out_ok (const std::codecvt<CharT, char, mbstate_t> &cvt)
+utf32_to_utf8_out_ok (const std::codecvt<InternT, ExternT, mbstate_t> &cvt)
 {
   using namespace std;
   // UTF-8 string of 1-byte CP, 2-byte CP, 3-byte CP and 4-byte CP
-  const char32_t in_literal[] = U"bш\uAAAA\U0010AAAA";
-  const char exp[] = "bш\uAAAA\U0010AAAA";
-  CharT in[array_size (in_literal)] = {};
-  copy (begin (in_literal), end (in_literal), begin (in));
-
-  static_assert (array_size (in_literal) == 5, "");
-  static_assert (array_size (in) == 5, "");
-  static_assert (array_size (exp) == 11, "");
-  VERIFY (char_traits<char32_t>::length (in_literal) == 4);
-  VERIFY (char_traits<CharT>::length (in) == 4);
-  VERIFY (char_traits<char>::length (exp) == 10);
-
-  const test_offsets_ok offsets[] = {{0, 0}, {1, 1}, {2, 3}, {3, 6}, {4, 10}};
+  const char32_t input[] = U"b\u0448\uAAAA\U0010AAAA";
+  const unsigned char expected[] = "b\u0448\uAAAA\U0010AAAA";
+  static_assert (array_size (input) == 5, "");
+  static_assert (array_size (expected) == 11, "");
+
+  InternT in[array_size (input)];
+  ExternT exp[array_size (expected)];
+  copy (begin (input), end (input), begin (in));
+  copy (begin (expected), end (expected), begin (exp));
+  VERIFY (char_traits<InternT>::length (in) == 4);
+  VERIFY (char_traits<ExternT>::length (exp) == 10);
+
+  test_offsets_ok offsets[] = {{0, 0}, {1, 1}, {2, 3}, {3, 6}, {4, 10}};
   for (auto t : offsets)
     {
-      char out[array_size (exp) - 1] = {};
+      ExternT out[array_size (exp) - 1] = {};
       VERIFY (t.in_size <= array_size (in));
       VERIFY (t.out_size <= array_size (out));
       auto state = mbstate_t{};
-      auto in_next = (const CharT *) nullptr;
-      auto out_next = (char *) nullptr;
+      auto in_next = (const InternT *) nullptr;
+      auto out_next = (ExternT *) nullptr;
       auto res = codecvt_base::result ();
 
       res = cvt.out (state, in, in + t.in_size, in_next, out, out + t.out_size,
@@ -299,31 +369,31 @@ utf32_to_utf8_out_ok (const std::codecvt<CharT, char, mbstate_t> &cvt)
       VERIFY (res == cvt.ok);
       VERIFY (in_next == in + t.in_size);
       VERIFY (out_next == out + t.out_size);
-      VERIFY (char_traits<char>::compare (out, exp, t.out_size) == 0);
+      VERIFY (char_traits<ExternT>::compare (out, exp, t.out_size) == 0);
       if (t.out_size < array_size (out))
 	VERIFY (out[t.out_size] == 0);
     }
 }
 
-template <class CharT>
+template <class InternT, class ExternT>
 void
-utf32_to_utf8_out_partial (const std::codecvt<CharT, char, mbstate_t> &cvt)
+utf32_to_utf8_out_partial (const std::codecvt<InternT, ExternT, mbstate_t> &cvt)
 {
   using namespace std;
   // UTF-8 string of 1-byte CP, 2-byte CP, 3-byte CP and 4-byte CP
-  const char32_t in_literal[] = U"bш\uAAAA\U0010AAAA";
-  const char exp[] = "bш\uAAAA\U0010AAAA";
-  CharT in[array_size (in_literal)] = {};
-  copy (begin (in_literal), end (in_literal), begin (in));
-
-  static_assert (array_size (in_literal) == 5, "");
-  static_assert (array_size (in) == 5, "");
-  static_assert (array_size (exp) == 11, "");
-  VERIFY (char_traits<char32_t>::length (in_literal) == 4);
-  VERIFY (char_traits<CharT>::length (in) == 4);
-  VERIFY (char_traits<char>::length (exp) == 10);
-
-  const test_offsets_partial offsets[] = {
+  const char32_t input[] = U"b\u0448\uAAAA\U0010AAAA";
+  const unsigned char expected[] = "b\u0448\uAAAA\U0010AAAA";
+  static_assert (array_size (input) == 5, "");
+  static_assert (array_size (expected) == 11, "");
+
+  InternT in[array_size (input)];
+  ExternT exp[array_size (expected)];
+  copy (begin (input), end (input), begin (in));
+  copy (begin (expected), end (expected), begin (exp));
+  VERIFY (char_traits<InternT>::length (in) == 4);
+  VERIFY (char_traits<ExternT>::length (exp) == 10);
+
+  test_offsets_partial offsets[] = {
     {1, 0, 0, 0}, // no space for first CP
 
     {2, 1, 1, 1}, // no space for second CP
@@ -340,14 +410,14 @@ utf32_to_utf8_out_partial (const std::codecvt<CharT, char, mbstate_t> &cvt)
   };
   for (auto t : offsets)
     {
-      char out[array_size (exp) - 1] = {};
+      ExternT out[array_size (exp) - 1] = {};
       VERIFY (t.in_size <= array_size (in));
       VERIFY (t.out_size <= array_size (out));
       VERIFY (t.expected_in_next <= t.in_size);
       VERIFY (t.expected_out_next <= t.out_size);
       auto state = mbstate_t{};
-      auto in_next = (const CharT *) nullptr;
-      auto out_next = (char *) nullptr;
+      auto in_next = (const InternT *) nullptr;
+      auto out_next = (ExternT *) nullptr;
       auto res = codecvt_base::result ();
 
       res = cvt.out (state, in, in + t.in_size, in_next, out, out + t.out_size,
@@ -355,44 +425,58 @@ utf32_to_utf8_out_partial (const std::codecvt<CharT, char, mbstate_t> &cvt)
       VERIFY (res == cvt.partial);
       VERIFY (in_next == in + t.expected_in_next);
       VERIFY (out_next == out + t.expected_out_next);
-      VERIFY (char_traits<char>::compare (out, exp, t.expected_out_next) == 0);
+      VERIFY (char_traits<ExternT>::compare (out, exp, t.expected_out_next)
+	      == 0);
       if (t.expected_out_next < array_size (out))
 	VERIFY (out[t.expected_out_next] == 0);
     }
 }
 
-template <class CharT>
+template <class InternT, class ExternT>
 void
-utf32_to_utf8_out_error (const std::codecvt<CharT, char, mbstate_t> &cvt)
+utf32_to_utf8_out_error (const std::codecvt<InternT, ExternT, mbstate_t> &cvt)
 {
   using namespace std;
-  const char32_t valid_in[] = U"bш\uAAAA\U0010AAAA";
-  const char exp[] = "bш\uAAAA\U0010AAAA";
-
-  static_assert (array_size (valid_in) == 5, "");
-  static_assert (array_size (exp) == 11, "");
-  VERIFY (char_traits<char32_t>::length (valid_in) == 4);
-  VERIFY (char_traits<char>::length (exp) == 10);
-
-  test_offsets_error<CharT> offsets[] = {{4, 10, 0, 0, 0x00110000, 0},
-					 {4, 10, 1, 1, 0x00110000, 1},
-					 {4, 10, 2, 3, 0x00110000, 2},
-					 {4, 10, 3, 6, 0x00110000, 3}};
+  // UTF-8 string of 1-byte CP, 2-byte CP, 3-byte CP and 4-byte CP
+  const char32_t input[] = U"b\u0448\uAAAA\U0010AAAA";
+  const unsigned char expected[] = "b\u0448\uAAAA\U0010AAAA";
+  static_assert (array_size (input) == 5, "");
+  static_assert (array_size (expected) == 11, "");
+
+  InternT in[array_size (input)];
+  ExternT exp[array_size (expected)];
+  copy (begin (input), end (input), begin (in));
+  copy (begin (expected), end (expected), begin (exp));
+  VERIFY (char_traits<InternT>::length (in) == 4);
+  VERIFY (char_traits<ExternT>::length (exp) == 10);
+
+  test_offsets_error<InternT> offsets[] = {
+
+    // Surrogate CP
+    {4, 10, 0, 0, 0xD800, 0},
+    {4, 10, 1, 1, 0xDBFF, 1},
+    {4, 10, 2, 3, 0xDC00, 2},
+    {4, 10, 3, 6, 0xDFFF, 3},
+
+    // CP out of range
+    {4, 10, 0, 0, 0x00110000, 0},
+    {4, 10, 1, 1, 0x00110000, 1},
+    {4, 10, 2, 3, 0x00110000, 2},
+    {4, 10, 3, 6, 0x00110000, 3}};
 
   for (auto t : offsets)
     {
-      CharT in[array_size (valid_in)] = {};
-      char out[array_size (exp) - 1] = {};
+      ExternT out[array_size (exp) - 1] = {};
       VERIFY (t.in_size <= array_size (in));
       VERIFY (t.out_size <= array_size (out));
       VERIFY (t.expected_in_next <= t.in_size);
       VERIFY (t.expected_out_next <= t.out_size);
-      copy (begin (valid_in), end (valid_in), begin (in));
+      auto old_char = in[t.replace_pos];
       in[t.replace_pos] = t.replace_char;
 
       auto state = mbstate_t{};
-      auto in_next = (const CharT *) nullptr;
-      auto out_next = (char *) nullptr;
+      auto in_next = (const InternT *) nullptr;
+      auto out_next = (ExternT *) nullptr;
       auto res = codecvt_base::result ();
 
       res = cvt.out (state, in, in + t.in_size, in_next, out, out + t.out_size,
@@ -400,56 +484,59 @@ utf32_to_utf8_out_error (const std::codecvt<CharT, char, mbstate_t> &cvt)
       VERIFY (res == cvt.error);
       VERIFY (in_next == in + t.expected_in_next);
       VERIFY (out_next == out + t.expected_out_next);
-      VERIFY (char_traits<char>::compare (out, exp, t.expected_out_next) == 0);
+      VERIFY (char_traits<ExternT>::compare (out, exp, t.expected_out_next)
+	      == 0);
       if (t.expected_out_next < array_size (out))
 	VERIFY (out[t.expected_out_next] == 0);
+
+      in[t.replace_pos] = old_char;
     }
 }
 
-template <class CharT>
+template <class InternT, class ExternT>
 void
-utf32_to_utf8_out (const std::codecvt<CharT, char, mbstate_t> &cvt)
+utf32_to_utf8_out (const std::codecvt<InternT, ExternT, mbstate_t> &cvt)
 {
   utf32_to_utf8_out_ok (cvt);
   utf32_to_utf8_out_partial (cvt);
   utf32_to_utf8_out_error (cvt);
 }
 
-template <class CharT>
+template <class InternT, class ExternT>
 void
-test_utf8_utf32_codecvts (const std::codecvt<CharT, char, mbstate_t> &cvt)
+test_utf8_utf32_cvt (const std::codecvt<InternT, ExternT, mbstate_t> &cvt)
 {
   utf8_to_utf32_in (cvt);
   utf32_to_utf8_out (cvt);
 }
 
-template <class CharT>
+template <class InternT, class ExternT>
 void
-utf8_to_utf16_in_ok (const std::codecvt<CharT, char, mbstate_t> &cvt)
+utf8_to_utf16_in_ok (const std::codecvt<InternT, ExternT, mbstate_t> &cvt)
 {
   using namespace std;
   // UTF-8 string of 1-byte CP, 2-byte CP, 3-byte CP and 4-byte CP
-  const char in[] = "bш\uAAAA\U0010AAAA";
-  const char16_t exp_literal[] = u"bш\uAAAA\U0010AAAA";
-  CharT exp[array_size (exp_literal)] = {};
-  copy (begin (exp_literal), end (exp_literal), begin (exp));
-
-  static_assert (array_size (in) == 11, "");
-  static_assert (array_size (exp_literal) == 6, "");
-  static_assert (array_size (exp) == 6, "");
-  VERIFY (char_traits<char>::length (in) == 10);
-  VERIFY (char_traits<char16_t>::length (exp_literal) == 5);
-  VERIFY (char_traits<CharT>::length (exp) == 5);
+  const unsigned char input[] = "b\u0448\uAAAA\U0010AAAA";
+  const char16_t expected[] = u"b\u0448\uAAAA\U0010AAAA";
+  static_assert (array_size (input) == 11, "");
+  static_assert (array_size (expected) == 6, "");
+
+  ExternT in[array_size (input)];
+  InternT exp[array_size (expected)];
+  copy (begin (input), end (input), begin (in));
+  copy (begin (expected), end (expected), begin (exp));
+  VERIFY (char_traits<ExternT>::length (in) == 10);
+  VERIFY (char_traits<InternT>::length (exp) == 5);
 
   test_offsets_ok offsets[] = {{0, 0}, {1, 1}, {3, 2}, {6, 3}, {10, 5}};
   for (auto t : offsets)
     {
-      CharT out[array_size (exp) - 1] = {};
+      InternT out[array_size (exp) - 1] = {};
       VERIFY (t.in_size <= array_size (in));
       VERIFY (t.out_size <= array_size (out));
       auto state = mbstate_t{};
-      auto in_next = (const char *) nullptr;
-      auto out_next = (CharT *) nullptr;
+      auto in_next = (const ExternT *) nullptr;
+      auto out_next = (InternT *) nullptr;
       auto res = codecvt_base::result ();
 
       res = cvt.in (state, in, in + t.in_size, in_next, out, out + t.out_size,
@@ -457,19 +544,24 @@ utf8_to_utf16_in_ok (const std::codecvt<CharT, char, mbstate_t> &cvt)
       VERIFY (res == cvt.ok);
       VERIFY (in_next == in + t.in_size);
       VERIFY (out_next == out + t.out_size);
-      VERIFY (char_traits<CharT>::compare (out, exp, t.out_size) == 0);
+      VERIFY (char_traits<InternT>::compare (out, exp, t.out_size) == 0);
       if (t.out_size < array_size (out))
 	VERIFY (out[t.out_size] == 0);
+
+      state = {};
+      auto len = cvt.length (state, in, in + t.in_size, t.out_size);
+      VERIFY (len >= 0);
+      VERIFY (static_cast<size_t> (len) == t.in_size);
     }
 
   for (auto t : offsets)
     {
-      CharT out[array_size (exp)] = {};
+      InternT out[array_size (exp)] = {};
       VERIFY (t.in_size <= array_size (in));
       VERIFY (t.out_size <= array_size (out));
       auto state = mbstate_t{};
-      auto in_next = (const char *) nullptr;
-      auto out_next = (CharT *) nullptr;
+      auto in_next = (const ExternT *) nullptr;
+      auto out_next = (InternT *) nullptr;
       auto res = codecvt_base::result ();
 
       res
@@ -477,29 +569,34 @@ utf8_to_utf16_in_ok (const std::codecvt<CharT, char, mbstate_t> &cvt)
       VERIFY (res == cvt.ok);
       VERIFY (in_next == in + t.in_size);
       VERIFY (out_next == out + t.out_size);
-      VERIFY (char_traits<CharT>::compare (out, exp, t.out_size) == 0);
+      VERIFY (char_traits<InternT>::compare (out, exp, t.out_size) == 0);
       if (t.out_size < array_size (out))
 	VERIFY (out[t.out_size] == 0);
+
+      state = {};
+      auto len = cvt.length (state, in, in + t.in_size, array_size (out));
+      VERIFY (len >= 0);
+      VERIFY (static_cast<size_t> (len) == t.in_size);
     }
 }
 
-template <class CharT>
+template <class InternT, class ExternT>
 void
-utf8_to_utf16_in_partial (const std::codecvt<CharT, char, mbstate_t> &cvt)
+utf8_to_utf16_in_partial (const std::codecvt<InternT, ExternT, mbstate_t> &cvt)
 {
   using namespace std;
   // UTF-8 string of 1-byte CP, 2-byte CP, 3-byte CP and 4-byte CP
-  const char in[] = "bш\uAAAA\U0010AAAA";
-  const char16_t exp_literal[] = u"bш\uAAAA\U0010AAAA";
-  CharT exp[array_size (exp_literal)] = {};
-  copy (begin (exp_literal), end (exp_literal), begin (exp));
-
-  static_assert (array_size (in) == 11, "");
-  static_assert (array_size (exp_literal) == 6, "");
-  static_assert (array_size (exp) == 6, "");
-  VERIFY (char_traits<char>::length (in) == 10);
-  VERIFY (char_traits<char16_t>::length (exp_literal) == 5);
-  VERIFY (char_traits<CharT>::length (exp) == 5);
+  const unsigned char input[] = "b\u0448\uAAAA\U0010AAAA";
+  const char16_t expected[] = u"b\u0448\uAAAA\U0010AAAA";
+  static_assert (array_size (input) == 11, "");
+  static_assert (array_size (expected) == 6, "");
+
+  ExternT in[array_size (input)];
+  InternT exp[array_size (expected)];
+  copy (begin (input), end (input), begin (in));
+  copy (begin (expected), end (expected), begin (exp));
+  VERIFY (char_traits<ExternT>::length (in) == 10);
+  VERIFY (char_traits<InternT>::length (exp) == 5);
 
   test_offsets_partial offsets[] = {
     {1, 0, 0, 0}, // no space for first CP
@@ -530,14 +627,14 @@ utf8_to_utf16_in_partial (const std::codecvt<CharT, char, mbstate_t> &cvt)
 
   for (auto t : offsets)
     {
-      CharT out[array_size (exp) - 1] = {};
+      InternT out[array_size (exp) - 1] = {};
       VERIFY (t.in_size <= array_size (in));
       VERIFY (t.out_size <= array_size (out));
       VERIFY (t.expected_in_next <= t.in_size);
       VERIFY (t.expected_out_next <= t.out_size);
       auto state = mbstate_t{};
-      auto in_next = (const char *) nullptr;
-      auto out_next = (CharT *) nullptr;
+      auto in_next = (const ExternT *) nullptr;
+      auto out_next = (InternT *) nullptr;
       auto res = codecvt_base::result ();
 
       res = cvt.in (state, in, in + t.in_size, in_next, out, out + t.out_size,
@@ -545,36 +642,63 @@ utf8_to_utf16_in_partial (const std::codecvt<CharT, char, mbstate_t> &cvt)
       VERIFY (res == cvt.partial);
       VERIFY (in_next == in + t.expected_in_next);
       VERIFY (out_next == out + t.expected_out_next);
-      VERIFY (char_traits<CharT>::compare (out, exp, t.expected_out_next) == 0);
+      VERIFY (char_traits<InternT>::compare (out, exp, t.expected_out_next)
+	      == 0);
       if (t.expected_out_next < array_size (out))
 	VERIFY (out[t.expected_out_next] == 0);
+
+      state = {};
+      auto len = cvt.length (state, in, in + t.in_size, t.out_size);
+      VERIFY (len >= 0);
+      VERIFY (static_cast<size_t> (len) == t.expected_in_next);
     }
 }
 
-template <class CharT>
+template <class InternT, class ExternT>
 void
-utf8_to_utf16_in_error (const std::codecvt<CharT, char, mbstate_t> &cvt)
+utf8_to_utf16_in_error (const std::codecvt<InternT, ExternT, mbstate_t> &cvt)
 {
   using namespace std;
-  const char valid_in[] = "bш\uAAAA\U0010AAAA";
-  const char16_t exp_literal[] = u"bш\uAAAA\U0010AAAA";
-  CharT exp[array_size (exp_literal)] = {};
-  copy (begin (exp_literal), end (exp_literal), begin (exp));
+  // UTF-8 string of 1-byte CP, 2-byte CP, 3-byte CP, 4-byte CP
+  const unsigned char input[] = "b\u0448\uD700\U0010AAAA";
+  const char16_t expected[] = u"b\u0448\uD700\U0010AAAA";
+  static_assert (array_size (input) == 11, "");
+  static_assert (array_size (expected) == 6, "");
+
+  ExternT in[array_size (input)];
+  InternT exp[array_size (expected)];
+  copy (begin (input), end (input), begin (in));
+  copy (begin (expected), end (expected), begin (exp));
+  VERIFY (char_traits<ExternT>::length (in) == 10);
+  VERIFY (char_traits<InternT>::length (exp) == 5);
+
+  // There are 5 classes of errors in UTF-8 decoding
+  // 1. Missing leading byte
+  // 2. Missing trailing byte
+  // 3. Surrogate CP
+  // 4. Overlong sequence
+  // 5. CP out of Unicode range
+  test_offsets_error<unsigned char> offsets[] = {
+
+    // 1. Missing leading byte. We will replace the leading byte with
+    // non-leading byte, such as a byte that is always invalid or a trailing
+    // byte.
 
-  static_assert (array_size (valid_in) == 11, "");
-  static_assert (array_size (exp_literal) == 6, "");
-  static_assert (array_size (exp) == 6, "");
-  VERIFY (char_traits<char>::length (valid_in) == 10);
-  VERIFY (char_traits<char16_t>::length (exp_literal) == 5);
-  VERIFY (char_traits<CharT>::length (exp) == 5);
+    // replace leading byte with invalid byte
+    {1, 5, 0, 0, 0xFF, 0},
+    {3, 5, 1, 1, 0xFF, 1},
+    {6, 5, 3, 2, 0xFF, 3},
+    {10, 5, 6, 3, 0xFF, 6},
 
-  test_offsets_error<char> offsets[] = {
+    // replace leading byte with trailing byte
+    {1, 5, 0, 0, 0b10101010, 0},
+    {3, 5, 1, 1, 0b10101010, 1},
+    {6, 5, 3, 2, 0b10101010, 3},
+    {10, 5, 6, 3, 0b10101010, 6},
 
-    // replace leading byte with invalid byte
-    {1, 5, 0, 0, '\xFF', 0},
-    {3, 5, 1, 1, '\xFF', 1},
-    {6, 5, 3, 2, '\xFF', 3},
-    {10, 5, 6, 3, '\xFF', 6},
+    // 2. Missing trailing byte. We will replace the trailing byte with
+    // non-trailing byte, such as a byte that is always invalid or a leading
+    // byte (simple ASCII byte in our case).
 
     // replace first trailing byte with ASCII byte
     {3, 5, 1, 1, 'z', 2},
@@ -582,21 +706,27 @@ utf8_to_utf16_in_error (const std::codecvt<CharT, char, mbstate_t> &cvt)
     {10, 5, 6, 3, 'z', 7},
 
     // replace first trailing byte with invalid byte
-    {3, 5, 1, 1, '\xFF', 2},
-    {6, 5, 3, 2, '\xFF', 4},
-    {10, 5, 6, 3, '\xFF', 7},
+    {3, 5, 1, 1, 0xFF, 2},
+    {6, 5, 3, 2, 0xFF, 4},
+    {10, 5, 6, 3, 0xFF, 7},
 
     // replace second trailing byte with ASCII byte
     {6, 5, 3, 2, 'z', 5},
     {10, 5, 6, 3, 'z', 8},
 
     // replace second trailing byte with invalid byte
-    {6, 5, 3, 2, '\xFF', 5},
-    {10, 5, 6, 3, '\xFF', 8},
+    {6, 5, 3, 2, 0xFF, 5},
+    {10, 5, 6, 3, 0xFF, 8},
 
     // replace third trailing byte
     {10, 5, 6, 3, 'z', 9},
-    {10, 5, 6, 3, '\xFF', 9},
+    {10, 5, 6, 3, 0xFF, 9},
+
+    // 2.1 The following test-cases raise doubt whether error or partial should
+    // be returned. For example, we have 4-byte sequence with valid leading
+    // byte. If we hide the last byte we need to return partial. But, if the
+    // second or third byte, which are visible to the call to codecvt, are
+    // malformed then error should be returned.
 
     // replace first trailing byte with ASCII byte, also incomplete at end
     {5, 5, 3, 2, 'z', 4},
@@ -604,30 +734,51 @@ utf8_to_utf16_in_error (const std::codecvt<CharT, char, mbstate_t> &cvt)
     {9, 5, 6, 3, 'z', 7},
 
     // replace first trailing byte with invalid byte, also incomplete at end
-    {5, 5, 3, 2, '\xFF', 4},
-    {8, 5, 6, 3, '\xFF', 7},
-    {9, 5, 6, 3, '\xFF', 7},
+    {5, 5, 3, 2, 0xFF, 4},
+    {8, 5, 6, 3, 0xFF, 7},
+    {9, 5, 6, 3, 0xFF, 7},
 
     // replace second trailing byte with ASCII byte, also incomplete at end
     {9, 5, 6, 3, 'z', 8},
 
     // replace second trailing byte with invalid byte, also incomplete at end
-    {9, 5, 6, 3, '\xFF', 8},
+    {9, 5, 6, 3, 0xFF, 8},
+
+    // 3. Surrogate CP. We modify the second byte (first trailing) of the 3-byte
+    // CP U+D700
+    {6, 5, 3, 2, 0b10100000, 4}, // turn U+D700 into U+D800
+    {6, 5, 3, 2, 0b10101100, 4}, // turn U+D700 into U+DB00
+    {6, 5, 3, 2, 0b10110000, 4}, // turn U+D700 into U+DC00
+    {6, 5, 3, 2, 0b10111100, 4}, // turn U+D700 into U+DF00
+
+    // 4. Overlong sequence. The CPs in the input are chosen such as modifying
+    // just the leading byte is enough to make them overlong, i.e. for the
+    // 3-byte and 4-byte CP the second byte (first trailing) has enough leading
+    // zeroes.
+    {3, 5, 1, 1, 0b11000000, 1},  // make the 2-byte CP overlong
+    {3, 5, 1, 1, 0b11000001, 1},  // make the 2-byte CP overlong
+    {6, 5, 3, 2, 0b11100000, 3},  // make the 3-byte CP overlong
+    {10, 5, 6, 3, 0b11110000, 6}, // make the 4-byte CP overlong
+
+    // 5. CP above range
+    // turn U+10AAAA into U+14AAAA by changing its leading byte
+    {10, 5, 6, 3, 0b11110101, 6},
+    // turn U+10AAAA into U+11AAAA by changing its 2nd byte
+    {10, 5, 6, 3, 0b10011010, 7},
   };
   for (auto t : offsets)
     {
-      char in[array_size (valid_in)] = {};
-      CharT out[array_size (exp) - 1] = {};
+      InternT out[array_size (exp) - 1] = {};
       VERIFY (t.in_size <= array_size (in));
       VERIFY (t.out_size <= array_size (out));
       VERIFY (t.expected_in_next <= t.in_size);
       VERIFY (t.expected_out_next <= t.out_size);
-      char_traits<char>::copy (in, valid_in, array_size (valid_in));
+      auto old_char = in[t.replace_pos];
       in[t.replace_pos] = t.replace_char;
 
       auto state = mbstate_t{};
-      auto in_next = (const char *) nullptr;
-      auto out_next = (CharT *) nullptr;
+      auto in_next = (const ExternT *) nullptr;
+      auto out_next = (InternT *) nullptr;
       auto res = codecvt_base::result ();
 
       res = cvt.in (state, in, in + t.in_size, in_next, out, out + t.out_size,
@@ -635,48 +786,56 @@ utf8_to_utf16_in_error (const std::codecvt<CharT, char, mbstate_t> &cvt)
       VERIFY (res == cvt.error);
       VERIFY (in_next == in + t.expected_in_next);
       VERIFY (out_next == out + t.expected_out_next);
-      VERIFY (char_traits<CharT>::compare (out, exp, t.expected_out_next) == 0);
+      VERIFY (char_traits<InternT>::compare (out, exp, t.expected_out_next)
+	      == 0);
       if (t.expected_out_next < array_size (out))
 	VERIFY (out[t.expected_out_next] == 0);
+
+      state = {};
+      auto len = cvt.length (state, in, in + t.in_size, t.out_size);
+      VERIFY (len >= 0);
+      VERIFY (static_cast<size_t> (len) == t.expected_in_next);
+
+      in[t.replace_pos] = old_char;
     }
 }
 
-template <class CharT>
+template <class InternT, class ExternT>
 void
-utf8_to_utf16_in (const std::codecvt<CharT, char, mbstate_t> &cvt)
+utf8_to_utf16_in (const std::codecvt<InternT, ExternT, mbstate_t> &cvt)
 {
   utf8_to_utf16_in_ok (cvt);
   utf8_to_utf16_in_partial (cvt);
   utf8_to_utf16_in_error (cvt);
 }
 
-template <class CharT>
+template <class InternT, class ExternT>
 void
-utf16_to_utf8_out_ok (const std::codecvt<CharT, char, mbstate_t> &cvt)
+utf16_to_utf8_out_ok (const std::codecvt<InternT, ExternT, mbstate_t> &cvt)
 {
   using namespace std;
   // UTF-8 string of 1-byte CP, 2-byte CP, 3-byte CP and 4-byte CP
-  const char16_t in_literal[] = u"bш\uAAAA\U0010AAAA";
-  const char exp[] = "bш\uAAAA\U0010AAAA";
-  CharT in[array_size (in_literal)];
-  copy (begin (in_literal), end (in_literal), begin (in));
-
-  static_assert (array_size (in_literal) == 6, "");
-  static_assert (array_size (exp) == 11, "");
-  static_assert (array_size (in) == 6, "");
-  VERIFY (char_traits<char16_t>::length (in_literal) == 5);
-  VERIFY (char_traits<char>::length (exp) == 10);
-  VERIFY (char_traits<CharT>::length (in) == 5);
-
-  const test_offsets_ok offsets[] = {{0, 0}, {1, 1}, {2, 3}, {3, 6}, {5, 10}};
+  const char16_t input[] = u"b\u0448\uAAAA\U0010AAAA";
+  const unsigned char expected[] = "b\u0448\uAAAA\U0010AAAA";
+  static_assert (array_size (input) == 6, "");
+  static_assert (array_size (expected) == 11, "");
+
+  InternT in[array_size (input)];
+  ExternT exp[array_size (expected)];
+  copy (begin (input), end (input), begin (in));
+  copy (begin (expected), end (expected), begin (exp));
+  VERIFY (char_traits<InternT>::length (in) == 5);
+  VERIFY (char_traits<ExternT>::length (exp) == 10);
+
+  test_offsets_ok offsets[] = {{0, 0}, {1, 1}, {2, 3}, {3, 6}, {5, 10}};
   for (auto t : offsets)
     {
-      char out[array_size (exp) - 1] = {};
+      ExternT out[array_size (exp) - 1] = {};
       VERIFY (t.in_size <= array_size (in));
       VERIFY (t.out_size <= array_size (out));
       auto state = mbstate_t{};
-      auto in_next = (const CharT *) nullptr;
-      auto out_next = (char *) nullptr;
+      auto in_next = (const InternT *) nullptr;
+      auto out_next = (ExternT *) nullptr;
       auto res = codecvt_base::result ();
 
       res = cvt.out (state, in, in + t.in_size, in_next, out, out + t.out_size,
@@ -684,31 +843,31 @@ utf16_to_utf8_out_ok (const std::codecvt<CharT, char, mbstate_t> &cvt)
       VERIFY (res == cvt.ok);
       VERIFY (in_next == in + t.in_size);
       VERIFY (out_next == out + t.out_size);
-      VERIFY (char_traits<char>::compare (out, exp, t.out_size) == 0);
+      VERIFY (char_traits<ExternT>::compare (out, exp, t.out_size) == 0);
       if (t.out_size < array_size (out))
 	VERIFY (out[t.out_size] == 0);
     }
 }
 
-template <class CharT>
+template <class InternT, class ExternT>
 void
-utf16_to_utf8_out_partial (const std::codecvt<CharT, char, mbstate_t> &cvt)
+utf16_to_utf8_out_partial (const std::codecvt<InternT, ExternT, mbstate_t> &cvt)
 {
   using namespace std;
   // UTF-8 string of 1-byte CP, 2-byte CP, 3-byte CP and 4-byte CP
-  const char16_t in_literal[] = u"bш\uAAAA\U0010AAAA";
-  const char exp[] = "bш\uAAAA\U0010AAAA";
-  CharT in[array_size (in_literal)];
-  copy (begin (in_literal), end (in_literal), begin (in));
-
-  static_assert (array_size (in_literal) == 6, "");
-  static_assert (array_size (exp) == 11, "");
-  static_assert (array_size (in) == 6, "");
-  VERIFY (char_traits<char16_t>::length (in_literal) == 5);
-  VERIFY (char_traits<char>::length (exp) == 10);
-  VERIFY (char_traits<CharT>::length (in) == 5);
-
-  const test_offsets_partial offsets[] = {
+  const char16_t input[] = u"b\u0448\uAAAA\U0010AAAA";
+  const unsigned char expected[] = "b\u0448\uAAAA\U0010AAAA";
+  static_assert (array_size (input) == 6, "");
+  static_assert (array_size (expected) == 11, "");
+
+  InternT in[array_size (input)];
+  ExternT exp[array_size (expected)];
+  copy (begin (input), end (input), begin (in));
+  copy (begin (expected), end (expected), begin (exp));
+  VERIFY (char_traits<InternT>::length (in) == 5);
+  VERIFY (char_traits<ExternT>::length (exp) == 10);
+
+  test_offsets_partial offsets[] = {
     {1, 0, 0, 0}, // no space for first CP
 
     {2, 1, 1, 1}, // no space for second CP
@@ -732,14 +891,14 @@ utf16_to_utf8_out_partial (const std::codecvt<CharT, char, mbstate_t> &cvt)
   };
   for (auto t : offsets)
     {
-      char out[array_size (exp) - 1] = {};
+      ExternT out[array_size (exp) - 1] = {};
       VERIFY (t.in_size <= array_size (in));
       VERIFY (t.out_size <= array_size (out));
       VERIFY (t.expected_in_next <= t.in_size);
       VERIFY (t.expected_out_next <= t.out_size);
       auto state = mbstate_t{};
-      auto in_next = (const CharT *) nullptr;
-      auto out_next = (char *) nullptr;
+      auto in_next = (const InternT *) nullptr;
+      auto out_next = (ExternT *) nullptr;
       auto res = codecvt_base::result ();
 
       res = cvt.out (state, in, in + t.in_size, in_next, out, out + t.out_size,
@@ -747,26 +906,34 @@ utf16_to_utf8_out_partial (const std::codecvt<CharT, char, mbstate_t> &cvt)
       VERIFY (res == cvt.partial);
       VERIFY (in_next == in + t.expected_in_next);
       VERIFY (out_next == out + t.expected_out_next);
-      VERIFY (char_traits<char>::compare (out, exp, t.expected_out_next) == 0);
+      VERIFY (char_traits<ExternT>::compare (out, exp, t.expected_out_next)
+	      == 0);
       if (t.expected_out_next < array_size (out))
 	VERIFY (out[t.expected_out_next] == 0);
     }
 }
 
-template <class CharT>
+template <class InternT, class ExternT>
 void
-utf16_to_utf8_out_error (const std::codecvt<CharT, char, mbstate_t> &cvt)
+utf16_to_utf8_out_error (const std::codecvt<InternT, ExternT, mbstate_t> &cvt)
 {
   using namespace std;
-  const char16_t valid_in[] = u"bш\uAAAA\U0010AAAA";
-  const char exp[] = "bш\uAAAA\U0010AAAA";
-
-  static_assert (array_size (valid_in) == 6, "");
-  static_assert (array_size (exp) == 11, "");
-  VERIFY (char_traits<char16_t>::length (valid_in) == 5);
-  VERIFY (char_traits<char>::length (exp) == 10);
-
-  test_offsets_error<CharT> offsets[] = {
+  // UTF-8 string of 1-byte CP, 2-byte CP, 3-byte CP and 4-byte CP
+  const char16_t input[] = u"b\u0448\uAAAA\U0010AAAA";
+  const unsigned char expected[] = "b\u0448\uAAAA\U0010AAAA";
+  static_assert (array_size (input) == 6, "");
+  static_assert (array_size (expected) == 11, "");
+
+  InternT in[array_size (input)];
+  ExternT exp[array_size (expected)];
+  copy (begin (input), end (input), begin (in));
+  copy (begin (expected), end (expected), begin (exp));
+  VERIFY (char_traits<InternT>::length (in) == 5);
+  VERIFY (char_traits<ExternT>::length (exp) == 10);
+
+  // The only possible error in UTF-16 is unpaired surrogate code units.
+  // So we replace valid code points (scalar values) with lone surrogate CU.
+  test_offsets_error<InternT> offsets[] = {
     {5, 10, 0, 0, 0xD800, 0},
     {5, 10, 0, 0, 0xDBFF, 0},
     {5, 10, 0, 0, 0xDC00, 0},
@@ -796,18 +963,17 @@ utf16_to_utf8_out_error (const std::codecvt<CharT, char, mbstate_t> &cvt)
 
   for (auto t : offsets)
     {
-      CharT in[array_size (valid_in)] = {};
-      char out[array_size (exp) - 1] = {};
+      ExternT out[array_size (exp) - 1] = {};
       VERIFY (t.in_size <= array_size (in));
       VERIFY (t.out_size <= array_size (out));
       VERIFY (t.expected_in_next <= t.in_size);
       VERIFY (t.expected_out_next <= t.out_size);
-      copy (begin (valid_in), end (valid_in), begin (in));
+      auto old_char = in[t.replace_pos];
       in[t.replace_pos] = t.replace_char;
 
       auto state = mbstate_t{};
-      auto in_next = (const CharT *) nullptr;
-      auto out_next = (char *) nullptr;
+      auto in_next = (const InternT *) nullptr;
+      auto out_next = (ExternT *) nullptr;
       auto res = codecvt_base::result ();
 
       res = cvt.out (state, in, in + t.in_size, in_next, out, out + t.out_size,
@@ -815,56 +981,59 @@ utf16_to_utf8_out_error (const std::codecvt<CharT, char, mbstate_t> &cvt)
       VERIFY (res == cvt.error);
       VERIFY (in_next == in + t.expected_in_next);
       VERIFY (out_next == out + t.expected_out_next);
-      VERIFY (char_traits<char>::compare (out, exp, t.expected_out_next) == 0);
+      VERIFY (char_traits<ExternT>::compare (out, exp, t.expected_out_next)
+	      == 0);
       if (t.expected_out_next < array_size (out))
 	VERIFY (out[t.expected_out_next] == 0);
+
+      in[t.replace_pos] = old_char;
     }
 }
 
-template <class CharT>
+template <class InternT, class ExternT>
 void
-utf16_to_utf8_out (const std::codecvt<CharT, char, mbstate_t> &cvt)
+utf16_to_utf8_out (const std::codecvt<InternT, ExternT, mbstate_t> &cvt)
 {
   utf16_to_utf8_out_ok (cvt);
   utf16_to_utf8_out_partial (cvt);
   utf16_to_utf8_out_error (cvt);
 }
 
-template <class CharT>
+template <class InternT, class ExternT>
 void
-test_utf8_utf16_cvts (const std::codecvt<CharT, char, mbstate_t> &cvt)
+test_utf8_utf16_cvt (const std::codecvt<InternT, ExternT, mbstate_t> &cvt)
 {
   utf8_to_utf16_in (cvt);
   utf16_to_utf8_out (cvt);
 }
 
-template <class CharT>
+template <class InternT, class ExternT>
 void
-utf8_to_ucs2_in_ok (const std::codecvt<CharT, char, mbstate_t> &cvt)
+utf8_to_ucs2_in_ok (const std::codecvt<InternT, ExternT, mbstate_t> &cvt)
 {
   using namespace std;
   // UTF-8 string of 1-byte CP, 2-byte CP and 3-byte CP
-  const char in[] = "bш\uAAAA";
-  const char16_t exp_literal[] = u"bш\uAAAA";
-  CharT exp[array_size (exp_literal)] = {};
-  copy (begin (exp_literal), end (exp_literal), begin (exp));
-
-  static_assert (array_size (in) == 7, "");
-  static_assert (array_size (exp_literal) == 4, "");
-  static_assert (array_size (exp) == 4, "");
-  VERIFY (char_traits<char>::length (in) == 6);
-  VERIFY (char_traits<char16_t>::length (exp_literal) == 3);
-  VERIFY (char_traits<CharT>::length (exp) == 3);
+  const unsigned char input[] = "b\u0448\uAAAA";
+  const char16_t expected[] = u"b\u0448\uAAAA";
+  static_assert (array_size (input) == 7, "");
+  static_assert (array_size (expected) == 4, "");
+
+  ExternT in[array_size (input)];
+  InternT exp[array_size (expected)];
+  copy (begin (input), end (input), begin (in));
+  copy (begin (expected), end (expected), begin (exp));
+  VERIFY (char_traits<ExternT>::length (in) == 6);
+  VERIFY (char_traits<InternT>::length (exp) == 3);
 
   test_offsets_ok offsets[] = {{0, 0}, {1, 1}, {3, 2}, {6, 3}};
   for (auto t : offsets)
     {
-      CharT out[array_size (exp) - 1] = {};
+      InternT out[array_size (exp) - 1] = {};
       VERIFY (t.in_size <= array_size (in));
       VERIFY (t.out_size <= array_size (out));
       auto state = mbstate_t{};
-      auto in_next = (const char *) nullptr;
-      auto out_next = (CharT *) nullptr;
+      auto in_next = (const ExternT *) nullptr;
+      auto out_next = (InternT *) nullptr;
       auto res = codecvt_base::result ();
 
       res = cvt.in (state, in, in + t.in_size, in_next, out, out + t.out_size,
@@ -872,19 +1041,24 @@ utf8_to_ucs2_in_ok (const std::codecvt<CharT, char, mbstate_t> &cvt)
       VERIFY (res == cvt.ok);
       VERIFY (in_next == in + t.in_size);
       VERIFY (out_next == out + t.out_size);
-      VERIFY (char_traits<CharT>::compare (out, exp, t.out_size) == 0);
+      VERIFY (char_traits<InternT>::compare (out, exp, t.out_size) == 0);
       if (t.out_size < array_size (out))
 	VERIFY (out[t.out_size] == 0);
+
+      state = {};
+      auto len = cvt.length (state, in, in + t.in_size, t.out_size);
+      VERIFY (len >= 0);
+      VERIFY (static_cast<size_t> (len) == t.in_size);
     }
 
   for (auto t : offsets)
     {
-      CharT out[array_size (exp)] = {};
+      InternT out[array_size (exp)] = {};
       VERIFY (t.in_size <= array_size (in));
       VERIFY (t.out_size <= array_size (out));
       auto state = mbstate_t{};
-      auto in_next = (const char *) nullptr;
-      auto out_next = (CharT *) nullptr;
+      auto in_next = (const ExternT *) nullptr;
+      auto out_next = (InternT *) nullptr;
       auto res = codecvt_base::result ();
 
       res
@@ -892,29 +1066,34 @@ utf8_to_ucs2_in_ok (const std::codecvt<CharT, char, mbstate_t> &cvt)
       VERIFY (res == cvt.ok);
       VERIFY (in_next == in + t.in_size);
       VERIFY (out_next == out + t.out_size);
-      VERIFY (char_traits<CharT>::compare (out, exp, t.out_size) == 0);
+      VERIFY (char_traits<InternT>::compare (out, exp, t.out_size) == 0);
       if (t.out_size < array_size (out))
 	VERIFY (out[t.out_size] == 0);
+
+      state = {};
+      auto len = cvt.length (state, in, in + t.in_size, array_size (out));
+      VERIFY (len >= 0);
+      VERIFY (static_cast<size_t> (len) == t.in_size);
     }
 }
 
-template <class CharT>
+template <class InternT, class ExternT>
 void
-utf8_to_ucs2_in_partial (const std::codecvt<CharT, char, mbstate_t> &cvt)
+utf8_to_ucs2_in_partial (const std::codecvt<InternT, ExternT, mbstate_t> &cvt)
 {
   using namespace std;
   // UTF-8 string of 1-byte CP, 2-byte CP and 3-byte CP
-  const char in[] = "bш\uAAAA";
-  const char16_t exp_literal[] = u"bш\uAAAA";
-  CharT exp[array_size (exp_literal)] = {};
-  copy (begin (exp_literal), end (exp_literal), begin (exp));
-
-  static_assert (array_size (in) == 7, "");
-  static_assert (array_size (exp_literal) == 4, "");
-  static_assert (array_size (exp) == 4, "");
-  VERIFY (char_traits<char>::length (in) == 6);
-  VERIFY (char_traits<char16_t>::length (exp_literal) == 3);
-  VERIFY (char_traits<CharT>::length (exp) == 3);
+  const unsigned char input[] = "b\u0448\uAAAA";
+  const char16_t expected[] = u"b\u0448\uAAAA";
+  static_assert (array_size (input) == 7, "");
+  static_assert (array_size (expected) == 4, "");
+
+  ExternT in[array_size (input)];
+  InternT exp[array_size (expected)];
+  copy (begin (input), end (input), begin (in));
+  copy (begin (expected), end (expected), begin (exp));
+  VERIFY (char_traits<ExternT>::length (in) == 6);
+  VERIFY (char_traits<InternT>::length (exp) == 3);
 
   test_offsets_partial offsets[] = {
     {1, 0, 0, 0}, // no space for first CP
@@ -932,14 +1111,14 @@ utf8_to_ucs2_in_partial (const std::codecvt<CharT, char, mbstate_t> &cvt)
 
   for (auto t : offsets)
     {
-      CharT out[array_size (exp) - 1] = {};
+      InternT out[array_size (exp) - 1] = {};
       VERIFY (t.in_size <= array_size (in));
       VERIFY (t.out_size <= array_size (out));
       VERIFY (t.expected_in_next <= t.in_size);
       VERIFY (t.expected_out_next <= t.out_size);
       auto state = mbstate_t{};
-      auto in_next = (const char *) nullptr;
-      auto out_next = (CharT *) nullptr;
+      auto in_next = (const ExternT *) nullptr;
+      auto out_next = (InternT *) nullptr;
       auto res = codecvt_base::result ();
 
       res = cvt.in (state, in, in + t.in_size, in_next, out, out + t.out_size,
@@ -947,36 +1126,62 @@ utf8_to_ucs2_in_partial (const std::codecvt<CharT, char, mbstate_t> &cvt)
       VERIFY (res == cvt.partial);
       VERIFY (in_next == in + t.expected_in_next);
       VERIFY (out_next == out + t.expected_out_next);
-      VERIFY (char_traits<CharT>::compare (out, exp, t.expected_out_next) == 0);
+      VERIFY (char_traits<InternT>::compare (out, exp, t.expected_out_next)
+	      == 0);
       if (t.expected_out_next < array_size (out))
 	VERIFY (out[t.expected_out_next] == 0);
+
+      state = {};
+      auto len = cvt.length (state, in, in + t.in_size, t.out_size);
+      VERIFY (len >= 0);
+      VERIFY (static_cast<size_t> (len) == t.expected_in_next);
     }
 }
 
-template <class CharT>
+template <class InternT, class ExternT>
 void
-utf8_to_ucs2_in_error (const std::codecvt<CharT, char, mbstate_t> &cvt)
+utf8_to_ucs2_in_error (const std::codecvt<InternT, ExternT, mbstate_t> &cvt)
 {
   using namespace std;
-  const char valid_in[] = "bш\uAAAA\U0010AAAA";
-  const char16_t exp_literal[] = u"bш\uAAAA\U0010AAAA";
-  CharT exp[array_size (exp_literal)] = {};
-  copy (begin (exp_literal), end (exp_literal), begin (exp));
+  const unsigned char input[] = "b\u0448\uD700\U0010AAAA";
+  const char16_t expected[] = u"b\u0448\uD700\U0010AAAA";
+  static_assert (array_size (input) == 11, "");
+  static_assert (array_size (expected) == 6, "");
+
+  ExternT in[array_size (input)];
+  InternT exp[array_size (expected)];
+  copy (begin (input), end (input), begin (in));
+  copy (begin (expected), end (expected), begin (exp));
+  VERIFY (char_traits<ExternT>::length (in) == 10);
+  VERIFY (char_traits<InternT>::length (exp) == 5);
+
+  // There are 5 classes of errors in UTF-8 decoding
+  // 1. Missing leading byte
+  // 2. Missing trailing byte
+  // 3. Surrogate CP
+  // 4. Overlong sequence
+  // 5. CP out of Unicode range
+  test_offsets_error<unsigned char> offsets[] = {
+
+    // 1. Missing leading byte. We will replace the leading byte with
+    // non-leading byte, such as a byte that is always invalid or a trailing
+    // byte.
 
-  static_assert (array_size (valid_in) == 11, "");
-  static_assert (array_size (exp_literal) == 6, "");
-  static_assert (array_size (exp) == 6, "");
-  VERIFY (char_traits<char>::length (valid_in) == 10);
-  VERIFY (char_traits<char16_t>::length (exp_literal) == 5);
-  VERIFY (char_traits<CharT>::length (exp) == 5);
+    // replace leading byte with invalid byte
+    {1, 5, 0, 0, 0xFF, 0},
+    {3, 5, 1, 1, 0xFF, 1},
+    {6, 5, 3, 2, 0xFF, 3},
+    {10, 5, 6, 3, 0xFF, 6},
 
-  test_offsets_error<char> offsets[] = {
+    // replace leading byte with trailing byte
+    {1, 5, 0, 0, 0b10101010, 0},
+    {3, 5, 1, 1, 0b10101010, 1},
+    {6, 5, 3, 2, 0b10101010, 3},
+    {10, 5, 6, 3, 0b10101010, 6},
 
-    // replace leading byte with invalid byte
-    {1, 5, 0, 0, '\xFF', 0},
-    {3, 5, 1, 1, '\xFF', 1},
-    {6, 5, 3, 2, '\xFF', 3},
-    {10, 5, 6, 3, '\xFF', 6},
+    // 2. Missing trailing byte. We will replace the trailing byte with
+    // non-trailing byte, such as a byte that is always invalid or a leading
+    // byte (simple ASCII byte in our case).
 
     // replace first trailing byte with ASCII byte
     {3, 5, 1, 1, 'z', 2},
@@ -984,72 +1189,90 @@ utf8_to_ucs2_in_error (const std::codecvt<CharT, char, mbstate_t> &cvt)
     {10, 5, 6, 3, 'z', 7},
 
     // replace first trailing byte with invalid byte
-    {3, 5, 1, 1, '\xFF', 2},
-    {6, 5, 3, 2, '\xFF', 4},
-    {10, 5, 6, 3, '\xFF', 7},
+    {3, 5, 1, 1, 0xFF, 2},
+    {6, 5, 3, 2, 0xFF, 4},
+    {10, 5, 6, 3, 0xFF, 7},
 
     // replace second trailing byte with ASCII byte
     {6, 5, 3, 2, 'z', 5},
     {10, 5, 6, 3, 'z', 8},
 
     // replace second trailing byte with invalid byte
-    {6, 5, 3, 2, '\xFF', 5},
-    {10, 5, 6, 3, '\xFF', 8},
+    {6, 5, 3, 2, 0xFF, 5},
+    {10, 5, 6, 3, 0xFF, 8},
 
     // replace third trailing byte
     {10, 5, 6, 3, 'z', 9},
-    {10, 5, 6, 3, '\xFF', 9},
-
-    // When we see a leading byte of 4-byte CP, we should return error, no
-    // matter if it is incomplete at the end or has errors in the trailing
-    // bytes.
-
-    // Don't replace anything, show full 4-byte CP
-    {10, 4, 6, 3, 'b', 0},
-    {10, 5, 6, 3, 'b', 0},
+    {10, 5, 6, 3, 0xFF, 9},
 
-    // Don't replace anything, show incomplete 4-byte CP at the end
-    {7, 4, 6, 3, 'b', 0}, // incomplete fourth CP
-    {8, 4, 6, 3, 'b', 0}, // incomplete fourth CP
-    {9, 4, 6, 3, 'b', 0}, // incomplete fourth CP
-    {7, 5, 6, 3, 'b', 0}, // incomplete fourth CP
-    {8, 5, 6, 3, 'b', 0}, // incomplete fourth CP
-    {9, 5, 6, 3, 'b', 0}, // incomplete fourth CP
+    // 2.1 The following test-cases raise doubt whether error or partial should
+    // be returned. For example, we have 4-byte sequence with valid leading
+    // byte. If we hide the last byte we need to return partial. But, if the
+    // second or third byte, which are visible to the call to codecvt, are
+    // malformed then error should be returned.
 
     // replace first trailing byte with ASCII byte, also incomplete at end
     {5, 5, 3, 2, 'z', 4},
-
-    // replace first trailing byte with invalid byte, also incomplete at end
-    {5, 5, 3, 2, '\xFF', 4},
-
-    // replace first trailing byte with ASCII byte, also incomplete at end
     {8, 5, 6, 3, 'z', 7},
     {9, 5, 6, 3, 'z', 7},
 
     // replace first trailing byte with invalid byte, also incomplete at end
-    {8, 5, 6, 3, '\xFF', 7},
-    {9, 5, 6, 3, '\xFF', 7},
+    {5, 5, 3, 2, 0xFF, 4},
+    {8, 5, 6, 3, 0xFF, 7},
+    {9, 5, 6, 3, 0xFF, 7},
 
     // replace second trailing byte with ASCII byte, also incomplete at end
     {9, 5, 6, 3, 'z', 8},
 
     // replace second trailing byte with invalid byte, also incomplete at end
-    {9, 5, 6, 3, '\xFF', 8},
+    {9, 5, 6, 3, 0xFF, 8},
+
+    // 3. Surrogate CP. We modify the second byte (first trailing) of the 3-byte
+    // CP U+D700
+    {6, 5, 3, 2, 0b10100000, 4}, // turn U+D700 into U+D800
+    {6, 5, 3, 2, 0b10101100, 4}, // turn U+D700 into U+DB00
+    {6, 5, 3, 2, 0b10110000, 4}, // turn U+D700 into U+DC00
+    {6, 5, 3, 2, 0b10111100, 4}, // turn U+D700 into U+DF00
+
+    // 4. Overlong sequence. The CPs in the input are chosen such as modifying
+    // just the leading byte is enough to make them overlong, i.e. for the
+    // 3-byte and 4-byte CP the second byte (first trailing) has enough leading
+    // zeroes.
+    {3, 5, 1, 1, 0b11000000, 1},  // make the 2-byte CP overlong
+    {3, 5, 1, 1, 0b11000001, 1},  // make the 2-byte CP overlong
+    {6, 5, 3, 2, 0b11100000, 3},  // make the 3-byte CP overlong
+    {10, 5, 6, 3, 0b11110000, 6}, // make the 4-byte CP overlong
+
+    // 5. CP above range
+    // turn U+10AAAA into U+14AAAA by changing its leading byte
+    {10, 5, 6, 3, 0b11110101, 6},
+    // turn U+10AAAA into U+11AAAA by changing its 2nd byte
+    {10, 5, 6, 3, 0b10011010, 7},
+    // Don't replace anything, show full 4-byte CP U+10AAAA
+    {10, 4, 6, 3, 'b', 0},
+    {10, 5, 6, 3, 'b', 0},
+    // Don't replace anything, show incomplete 4-byte CP at the end. It's still
+    // out of UCS2 range just by seeing the first byte.
+    {7, 4, 6, 3, 'b', 0}, // incomplete fourth CP
+    {8, 4, 6, 3, 'b', 0}, // incomplete fourth CP
+    {9, 4, 6, 3, 'b', 0}, // incomplete fourth CP
+    {7, 5, 6, 3, 'b', 0}, // incomplete fourth CP
+    {8, 5, 6, 3, 'b', 0}, // incomplete fourth CP
+    {9, 5, 6, 3, 'b', 0}, // incomplete fourth CP
   };
   for (auto t : offsets)
     {
-      char in[array_size (valid_in)] = {};
-      CharT out[array_size (exp) - 1] = {};
+      InternT out[array_size (exp) - 1] = {};
       VERIFY (t.in_size <= array_size (in));
       VERIFY (t.out_size <= array_size (out));
       VERIFY (t.expected_in_next <= t.in_size);
       VERIFY (t.expected_out_next <= t.out_size);
-      char_traits<char>::copy (in, valid_in, array_size (valid_in));
+      auto old_char = in[t.replace_pos];
       in[t.replace_pos] = t.replace_char;
 
       auto state = mbstate_t{};
-      auto in_next = (const char *) nullptr;
-      auto out_next = (CharT *) nullptr;
+      auto in_next = (const ExternT *) nullptr;
+      auto out_next = (InternT *) nullptr;
       auto res = codecvt_base::result ();
 
       res = cvt.in (state, in, in + t.in_size, in_next, out, out + t.out_size,
@@ -1057,48 +1280,56 @@ utf8_to_ucs2_in_error (const std::codecvt<CharT, char, mbstate_t> &cvt)
       VERIFY (res == cvt.error);
       VERIFY (in_next == in + t.expected_in_next);
       VERIFY (out_next == out + t.expected_out_next);
-      VERIFY (char_traits<CharT>::compare (out, exp, t.expected_out_next) == 0);
+      VERIFY (char_traits<InternT>::compare (out, exp, t.expected_out_next)
+	      == 0);
       if (t.expected_out_next < array_size (out))
 	VERIFY (out[t.expected_out_next] == 0);
+
+      state = {};
+      auto len = cvt.length (state, in, in + t.in_size, t.out_size);
+      VERIFY (len >= 0);
+      VERIFY (static_cast<size_t> (len) == t.expected_in_next);
+
+      in[t.replace_pos] = old_char;
     }
 }
 
-template <class CharT>
+template <class InternT, class ExternT>
 void
-utf8_to_ucs2_in (const std::codecvt<CharT, char, mbstate_t> &cvt)
+utf8_to_ucs2_in (const std::codecvt<InternT, ExternT, mbstate_t> &cvt)
 {
   utf8_to_ucs2_in_ok (cvt);
   utf8_to_ucs2_in_partial (cvt);
   utf8_to_ucs2_in_error (cvt);
 }
 
-template <class CharT>
+template <class InternT, class ExternT>
 void
-ucs2_to_utf8_out_ok (const std::codecvt<CharT, char, mbstate_t> &cvt)
+ucs2_to_utf8_out_ok (const std::codecvt<InternT, ExternT, mbstate_t> &cvt)
 {
   using namespace std;
   // UTF-8 string of 1-byte CP, 2-byte CP and 3-byte CP
-  const char16_t in_literal[] = u"bш\uAAAA";
-  const char exp[] = "bш\uAAAA";
-  CharT in[array_size (in_literal)] = {};
-  copy (begin (in_literal), end (in_literal), begin (in));
-
-  static_assert (array_size (in_literal) == 4, "");
-  static_assert (array_size (exp) == 7, "");
-  static_assert (array_size (in) == 4, "");
-  VERIFY (char_traits<char16_t>::length (in_literal) == 3);
-  VERIFY (char_traits<char>::length (exp) == 6);
-  VERIFY (char_traits<CharT>::length (in) == 3);
-
-  const test_offsets_ok offsets[] = {{0, 0}, {1, 1}, {2, 3}, {3, 6}};
+  const char16_t input[] = u"b\u0448\uAAAA";
+  const unsigned char expected[] = "b\u0448\uAAAA";
+  static_assert (array_size (input) == 4, "");
+  static_assert (array_size (expected) == 7, "");
+
+  InternT in[array_size (input)];
+  ExternT exp[array_size (expected)];
+  copy (begin (input), end (input), begin (in));
+  copy (begin (expected), end (expected), begin (exp));
+  VERIFY (char_traits<InternT>::length (in) == 3);
+  VERIFY (char_traits<ExternT>::length (exp) == 6);
+
+  test_offsets_ok offsets[] = {{0, 0}, {1, 1}, {2, 3}, {3, 6}};
   for (auto t : offsets)
     {
-      char out[array_size (exp) - 1] = {};
+      ExternT out[array_size (exp) - 1] = {};
       VERIFY (t.in_size <= array_size (in));
       VERIFY (t.out_size <= array_size (out));
       auto state = mbstate_t{};
-      auto in_next = (const CharT *) nullptr;
-      auto out_next = (char *) nullptr;
+      auto in_next = (const InternT *) nullptr;
+      auto out_next = (ExternT *) nullptr;
       auto res = codecvt_base::result ();
 
       res = cvt.out (state, in, in + t.in_size, in_next, out, out + t.out_size,
@@ -1106,31 +1337,31 @@ ucs2_to_utf8_out_ok (const std::codecvt<CharT, char, mbstate_t> &cvt)
       VERIFY (res == cvt.ok);
       VERIFY (in_next == in + t.in_size);
       VERIFY (out_next == out + t.out_size);
-      VERIFY (char_traits<char>::compare (out, exp, t.out_size) == 0);
+      VERIFY (char_traits<ExternT>::compare (out, exp, t.out_size) == 0);
       if (t.out_size < array_size (out))
 	VERIFY (out[t.out_size] == 0);
     }
 }
 
-template <class CharT>
+template <class InternT, class ExternT>
 void
-ucs2_to_utf8_out_partial (const std::codecvt<CharT, char, mbstate_t> &cvt)
+ucs2_to_utf8_out_partial (const std::codecvt<InternT, ExternT, mbstate_t> &cvt)
 {
   using namespace std;
   // UTF-8 string of 1-byte CP, 2-byte CP and 3-byte CP
-  const char16_t in_literal[] = u"bш\uAAAA";
-  const char exp[] = "bш\uAAAA";
-  CharT in[array_size (in_literal)] = {};
-  copy (begin (in_literal), end (in_literal), begin (in));
-
-  static_assert (array_size (in_literal) == 4, "");
-  static_assert (array_size (exp) == 7, "");
-  static_assert (array_size (in) == 4, "");
-  VERIFY (char_traits<char16_t>::length (in_literal) == 3);
-  VERIFY (char_traits<char>::length (exp) == 6);
-  VERIFY (char_traits<CharT>::length (in) == 3);
-
-  const test_offsets_partial offsets[] = {
+  const char16_t input[] = u"b\u0448\uAAAA";
+  const unsigned char expected[] = "b\u0448\uAAAA";
+  static_assert (array_size (input) == 4, "");
+  static_assert (array_size (expected) == 7, "");
+
+  InternT in[array_size (input)];
+  ExternT exp[array_size (expected)];
+  copy (begin (input), end (input), begin (in));
+  copy (begin (expected), end (expected), begin (exp));
+  VERIFY (char_traits<InternT>::length (in) == 3);
+  VERIFY (char_traits<ExternT>::length (exp) == 6);
+
+  test_offsets_partial offsets[] = {
     {1, 0, 0, 0}, // no space for first CP
 
     {2, 1, 1, 1}, // no space for second CP
@@ -1142,14 +1373,14 @@ ucs2_to_utf8_out_partial (const std::codecvt<CharT, char, mbstate_t> &cvt)
   };
   for (auto t : offsets)
     {
-      char out[array_size (exp) - 1] = {};
+      ExternT out[array_size (exp) - 1] = {};
       VERIFY (t.in_size <= array_size (in));
       VERIFY (t.out_size <= array_size (out));
       VERIFY (t.expected_in_next <= t.in_size);
       VERIFY (t.expected_out_next <= t.out_size);
       auto state = mbstate_t{};
-      auto in_next = (const CharT *) nullptr;
-      auto out_next = (char *) nullptr;
+      auto in_next = (const InternT *) nullptr;
+      auto out_next = (ExternT *) nullptr;
       auto res = codecvt_base::result ();
 
       res = cvt.out (state, in, in + t.in_size, in_next, out, out + t.out_size,
@@ -1157,43 +1388,45 @@ ucs2_to_utf8_out_partial (const std::codecvt<CharT, char, mbstate_t> &cvt)
       VERIFY (res == cvt.partial);
       VERIFY (in_next == in + t.expected_in_next);
       VERIFY (out_next == out + t.expected_out_next);
-      VERIFY (char_traits<char>::compare (out, exp, t.expected_out_next) == 0);
+      VERIFY (char_traits<ExternT>::compare (out, exp, t.expected_out_next)
+	      == 0);
       if (t.expected_out_next < array_size (out))
 	VERIFY (out[t.expected_out_next] == 0);
     }
 }
 
-template <class CharT>
+template <class InternT, class ExternT>
 void
-ucs2_to_utf8_out_error (const std::codecvt<CharT, char, mbstate_t> &cvt)
+ucs2_to_utf8_out_error (const std::codecvt<InternT, ExternT, mbstate_t> &cvt)
 {
   using namespace std;
-  const char16_t valid_in[] = u"bш\uAAAA\U0010AAAA";
-  const char exp[] = "bш\uAAAA\U0010AAAA";
-
-  static_assert (array_size (valid_in) == 6, "");
-  static_assert (array_size (exp) == 11, "");
-  VERIFY (char_traits<char16_t>::length (valid_in) == 5);
-  VERIFY (char_traits<char>::length (exp) == 10);
-
-  test_offsets_error<CharT> offsets[] = {
-    {5, 10, 0, 0, 0xD800, 0},
-    {5, 10, 0, 0, 0xDBFF, 0},
-    {5, 10, 0, 0, 0xDC00, 0},
-    {5, 10, 0, 0, 0xDFFF, 0},
-
-    {5, 10, 1, 1, 0xD800, 1},
-    {5, 10, 1, 1, 0xDBFF, 1},
-    {5, 10, 1, 1, 0xDC00, 1},
-    {5, 10, 1, 1, 0xDFFF, 1},
-
-    {5, 10, 2, 3, 0xD800, 2},
-    {5, 10, 2, 3, 0xDBFF, 2},
-    {5, 10, 2, 3, 0xDC00, 2},
-    {5, 10, 2, 3, 0xDFFF, 2},
-
-    // dont replace anything, just show the surrogate pair
-    {5, 10, 3, 6, u'b', 0},
+  const char16_t input[] = u"b\u0448\uAAAA\U0010AAAA";
+  const unsigned char expected[] = "b\u0448\uAAAA\U0010AAAA";
+  static_assert (array_size (input) == 6, "");
+  static_assert (array_size (expected) == 11, "");
+
+  InternT in[array_size (input)];
+  ExternT exp[array_size (expected)];
+  copy (begin (input), end (input), begin (in));
+  copy (begin (expected), end (expected), begin (exp));
+  VERIFY (char_traits<InternT>::length (in) == 5);
+  VERIFY (char_traits<ExternT>::length (exp) == 10);
+
+  test_offsets_error<InternT> offsets[] = {
+    {3, 6, 0, 0, 0xD800, 0},
+    {3, 6, 0, 0, 0xDBFF, 0},
+    {3, 6, 0, 0, 0xDC00, 0},
+    {3, 6, 0, 0, 0xDFFF, 0},
+
+    {3, 6, 1, 1, 0xD800, 1},
+    {3, 6, 1, 1, 0xDBFF, 1},
+    {3, 6, 1, 1, 0xDC00, 1},
+    {3, 6, 1, 1, 0xDFFF, 1},
+
+    {3, 6, 2, 3, 0xD800, 2},
+    {3, 6, 2, 3, 0xDBFF, 2},
+    {3, 6, 2, 3, 0xDC00, 2},
+    {3, 6, 2, 3, 0xDFFF, 2},
 
     // make the leading surrogate a trailing one
     {5, 10, 3, 6, 0xDC00, 3},
@@ -1206,6 +1439,9 @@ ucs2_to_utf8_out_error (const std::codecvt<CharT, char, mbstate_t> &cvt)
     // make the trailing surrogate a BMP char
     {5, 10, 3, 6, u'z', 4},
 
+    // don't replace anything in the test cases bellow, just show the surrogate
+    // pair (fourth CP) fully or partially
+    {5, 10, 3, 6, u'b', 0},
     {5, 7, 3, 6, u'b', 0}, // no space for fourth CP
     {5, 8, 3, 6, u'b', 0}, // no space for fourth CP
     {5, 9, 3, 6, u'b', 0}, // no space for fourth CP
@@ -1214,23 +1450,21 @@ ucs2_to_utf8_out_error (const std::codecvt<CharT, char, mbstate_t> &cvt)
     {4, 7, 3, 6, u'b', 0},  // incomplete fourth CP, and no space for it
     {4, 8, 3, 6, u'b', 0},  // incomplete fourth CP, and no space for it
     {4, 9, 3, 6, u'b', 0},  // incomplete fourth CP, and no space for it
-
   };
 
   for (auto t : offsets)
     {
-      CharT in[array_size (valid_in)] = {};
-      char out[array_size (exp) - 1] = {};
+      ExternT out[array_size (exp) - 1] = {};
       VERIFY (t.in_size <= array_size (in));
       VERIFY (t.out_size <= array_size (out));
       VERIFY (t.expected_in_next <= t.in_size);
       VERIFY (t.expected_out_next <= t.out_size);
-      copy (begin (valid_in), end (valid_in), begin (in));
+      auto old_char = in[t.replace_pos];
       in[t.replace_pos] = t.replace_char;
 
       auto state = mbstate_t{};
-      auto in_next = (const CharT *) nullptr;
-      auto out_next = (char *) nullptr;
+      auto in_next = (const InternT *) nullptr;
+      auto out_next = (ExternT *) nullptr;
       auto res = codecvt_base::result ();
 
       res = cvt.out (state, in, in + t.in_size, in_next, out, out + t.out_size,
@@ -1238,25 +1472,831 @@ ucs2_to_utf8_out_error (const std::codecvt<CharT, char, mbstate_t> &cvt)
       VERIFY (res == cvt.error);
       VERIFY (in_next == in + t.expected_in_next);
       VERIFY (out_next == out + t.expected_out_next);
-      VERIFY (char_traits<char>::compare (out, exp, t.expected_out_next) == 0);
+      VERIFY (char_traits<ExternT>::compare (out, exp, t.expected_out_next)
+	      == 0);
       if (t.expected_out_next < array_size (out))
 	VERIFY (out[t.expected_out_next] == 0);
+
+      in[t.replace_pos] = old_char;
     }
 }
 
-template <class CharT>
+template <class InternT, class ExternT>
 void
-ucs2_to_utf8_out (const std::codecvt<CharT, char, mbstate_t> &cvt)
+ucs2_to_utf8_out (const std::codecvt<InternT, ExternT, mbstate_t> &cvt)
 {
   ucs2_to_utf8_out_ok (cvt);
   ucs2_to_utf8_out_partial (cvt);
   ucs2_to_utf8_out_error (cvt);
 }
 
-template <class CharT>
+template <class InternT, class ExternT>
 void
-test_utf8_ucs2_cvts (const std::codecvt<CharT, char, mbstate_t> &cvt)
+test_utf8_ucs2_cvt (const std::codecvt<InternT, ExternT, mbstate_t> &cvt)
 {
   utf8_to_ucs2_in (cvt);
   ucs2_to_utf8_out (cvt);
 }
+
+enum utf16_endianess
+{
+  utf16_big_endian,
+  utf16_little_endian
+};
+
+template <class Iter1, class Iter2>
+Iter2
+utf16_to_bytes (Iter1 f, Iter1 l, Iter2 o, utf16_endianess e)
+{
+  if (e == utf16_big_endian)
+    for (; f != l; ++f)
+      {
+	*o++ = (*f >> 8) & 0xFF;
+	*o++ = *f & 0xFF;
+      }
+  else
+    for (; f != l; ++f)
+      {
+	*o++ = *f & 0xFF;
+	*o++ = (*f >> 8) & 0xFF;
+      }
+  return o;
+}
+
+template <class InternT>
+void
+utf16_to_utf32_in_ok (const std::codecvt<InternT, char, mbstate_t> &cvt,
+		      utf16_endianess endianess)
+{
+  using namespace std;
+  const char16_t input[] = u"b\u0448\uAAAA\U0010AAAA";
+  const char32_t expected[] = U"b\u0448\uAAAA\U0010AAAA";
+  static_assert (array_size (input) == 6, "");
+  static_assert (array_size (expected) == 5, "");
+
+  char in[array_size (input) * 2];
+  InternT exp[array_size (expected)];
+  utf16_to_bytes (begin (input), end (input), begin (in), endianess);
+  copy (begin (expected), end (expected), begin (exp));
+
+  test_offsets_ok offsets[] = {{0, 0}, {2, 1}, {4, 2}, {6, 3}, {10, 4}};
+  for (auto t : offsets)
+    {
+      InternT out[array_size (exp) - 1] = {};
+      VERIFY (t.in_size <= array_size (in));
+      VERIFY (t.out_size <= array_size (out));
+      auto state = mbstate_t{};
+      auto in_next = (const char *) nullptr;
+      auto out_next = (InternT *) nullptr;
+      auto res = codecvt_base::result ();
+
+      res = cvt.in (state, in, in + t.in_size, in_next, out, out + t.out_size,
+		    out_next);
+      VERIFY (res == cvt.ok);
+      VERIFY (in_next == in + t.in_size);
+      VERIFY (out_next == out + t.out_size);
+      VERIFY (char_traits<InternT>::compare (out, exp, t.out_size) == 0);
+      if (t.out_size < array_size (out))
+	VERIFY (out[t.out_size] == 0);
+
+      state = {};
+      auto len = cvt.length (state, in, in + t.in_size, t.out_size);
+      VERIFY (len >= 0);
+      VERIFY (static_cast<size_t> (len) == t.in_size);
+    }
+
+  for (auto t : offsets)
+    {
+      InternT out[array_size (exp)] = {};
+      VERIFY (t.in_size <= array_size (in));
+      VERIFY (t.out_size <= array_size (out));
+      auto state = mbstate_t{};
+      auto in_next = (const char *) nullptr;
+      auto out_next = (InternT *) nullptr;
+      auto res = codecvt_base::result ();
+
+      res
+	= cvt.in (state, in, in + t.in_size, in_next, out, end (out), out_next);
+      VERIFY (res == cvt.ok);
+      VERIFY (in_next == in + t.in_size);
+      VERIFY (out_next == out + t.out_size);
+      VERIFY (char_traits<InternT>::compare (out, exp, t.out_size) == 0);
+      if (t.out_size < array_size (out))
+	VERIFY (out[t.out_size] == 0);
+
+      state = {};
+      auto len = cvt.length (state, in, in + t.in_size, array_size (out));
+      VERIFY (len >= 0);
+      VERIFY (static_cast<size_t> (len) == t.in_size);
+    }
+}
+
+template <class InternT>
+void
+utf16_to_utf32_in_partial (const std::codecvt<InternT, char, mbstate_t> &cvt,
+			   utf16_endianess endianess)
+{
+  using namespace std;
+  const char16_t input[] = u"b\u0448\uAAAA\U0010AAAA";
+  const char32_t expected[] = U"b\u0448\uAAAA\U0010AAAA";
+  static_assert (array_size (input) == 6, "");
+  static_assert (array_size (expected) == 5, "");
+
+  char in[array_size (input) * 2];
+  InternT exp[array_size (expected)];
+  utf16_to_bytes (begin (input), end (input), begin (in), endianess);
+  copy (begin (expected), end (expected), begin (exp));
+
+  test_offsets_partial offsets[] = {
+    {2, 0, 0, 0}, // no space for first CP
+    {1, 1, 0, 0}, // incomplete first CP
+    {1, 0, 0, 0}, // incomplete first CP, and no space for it
+
+    {4, 1, 2, 1}, // no space for second CP
+    {3, 2, 2, 1}, // incomplete second CP
+    {3, 1, 2, 1}, // incomplete second CP, and no space for it
+
+    {6, 2, 4, 2}, // no space for third CP
+    {5, 3, 4, 2}, // incomplete third CP
+    {5, 2, 4, 2}, // incomplete third CP, and no space for it
+
+    {10, 3, 6, 3}, // no space for fourth CP
+    {7, 4, 6, 3},  // incomplete fourth CP
+    {8, 4, 6, 3},  // incomplete fourth CP
+    {9, 4, 6, 3},  // incomplete fourth CP
+    {7, 3, 6, 3},  // incomplete fourth CP, and no space for it
+    {8, 3, 6, 3},  // incomplete fourth CP, and no space for it
+    {9, 3, 6, 3},  // incomplete fourth CP, and no space for it
+  };
+
+  for (auto t : offsets)
+    {
+      InternT out[array_size (exp) - 1] = {};
+      VERIFY (t.in_size <= array_size (in));
+      VERIFY (t.out_size <= array_size (out));
+      VERIFY (t.expected_in_next <= t.in_size);
+      VERIFY (t.expected_out_next <= t.out_size);
+      auto state = mbstate_t{};
+      auto in_next = (const char *) nullptr;
+      auto out_next = (InternT *) nullptr;
+      auto res = codecvt_base::result ();
+
+      res = cvt.in (state, in, in + t.in_size, in_next, out, out + t.out_size,
+		    out_next);
+      VERIFY (res == cvt.partial);
+      VERIFY (in_next == in + t.expected_in_next);
+      VERIFY (out_next == out + t.expected_out_next);
+      VERIFY (char_traits<InternT>::compare (out, exp, t.expected_out_next)
+	      == 0);
+      if (t.expected_out_next < array_size (out))
+	VERIFY (out[t.expected_out_next] == 0);
+
+      state = {};
+      auto len = cvt.length (state, in, in + t.in_size, t.out_size);
+      VERIFY (len >= 0);
+      VERIFY (static_cast<size_t> (len) == t.expected_in_next);
+    }
+}
+
+template <class InternT>
+void
+utf16_to_utf32_in_error (const std::codecvt<InternT, char, mbstate_t> &cvt,
+			 utf16_endianess endianess)
+{
+  using namespace std;
+  char16_t input[] = u"b\u0448\uAAAA\U0010AAAA";
+  const char32_t expected[] = U"b\u0448\uAAAA\U0010AAAA";
+  static_assert (array_size (input) == 6, "");
+  static_assert (array_size (expected) == 5, "");
+
+  InternT exp[array_size (expected)];
+  copy (begin (expected), end (expected), begin (exp));
+
+  // The only possible error in UTF-16 is unpaired surrogate code units.
+  // So we replace valid code points (scalar values) with lone surrogate CU.
+  test_offsets_error<char16_t> offsets[] = {
+    {10, 4, 0, 0, 0xD800, 0},
+    {10, 4, 0, 0, 0xDBFF, 0},
+    {10, 4, 0, 0, 0xDC00, 0},
+    {10, 4, 0, 0, 0xDFFF, 0},
+
+    {10, 4, 2, 1, 0xD800, 1},
+    {10, 4, 2, 1, 0xDBFF, 1},
+    {10, 4, 2, 1, 0xDC00, 1},
+    {10, 4, 2, 1, 0xDFFF, 1},
+
+    {10, 4, 4, 2, 0xD800, 2},
+    {10, 4, 4, 2, 0xDBFF, 2},
+    {10, 4, 4, 2, 0xDC00, 2},
+    {10, 4, 4, 2, 0xDFFF, 2},
+
+    // make the leading surrogate a trailing one
+    {10, 4, 6, 3, 0xDC00, 3},
+    {10, 4, 6, 3, 0xDFFF, 3},
+
+    // make the trailing surrogate a leading one
+    {10, 4, 6, 3, 0xD800, 4},
+    {10, 4, 6, 3, 0xDBFF, 4},
+
+    // make the trailing surrogate a BMP char
+    {10, 4, 6, 3, u'z', 4},
+  };
+
+  for (auto t : offsets)
+    {
+      char in[array_size (input) * 2];
+      InternT out[array_size (exp) - 1] = {};
+      VERIFY (t.in_size <= array_size (in));
+      VERIFY (t.out_size <= array_size (out));
+      VERIFY (t.expected_in_next <= t.in_size);
+      VERIFY (t.expected_out_next <= t.out_size);
+      auto old_char = input[t.replace_pos];
+      input[t.replace_pos] = t.replace_char; // replace in input, not in in
+      utf16_to_bytes (begin (input), end (input), begin (in), endianess);
+
+      auto state = mbstate_t{};
+      auto in_next = (const char *) nullptr;
+      auto out_next = (InternT *) nullptr;
+      auto res = codecvt_base::result ();
+
+      res = cvt.in (state, in, in + t.in_size, in_next, out, out + t.out_size,
+		    out_next);
+      VERIFY (res == cvt.error);
+      VERIFY (in_next == in + t.expected_in_next);
+      VERIFY (out_next == out + t.expected_out_next);
+      VERIFY (char_traits<InternT>::compare (out, exp, t.expected_out_next)
+	      == 0);
+      if (t.expected_out_next < array_size (out))
+	VERIFY (out[t.expected_out_next] == 0);
+
+      state = {};
+      auto len = cvt.length (state, in, in + t.in_size, t.out_size);
+      VERIFY (len >= 0);
+      VERIFY (static_cast<size_t> (len) == t.expected_in_next);
+
+      input[t.replace_pos] = old_char;
+    }
+}
+
+template <class InternT>
+void
+utf32_to_utf16_out_ok (const std::codecvt<InternT, char, mbstate_t> &cvt,
+		       utf16_endianess endianess)
+{
+  using namespace std;
+  const char32_t input[] = U"b\u0448\uAAAA\U0010AAAA";
+  const char16_t expected[] = u"b\u0448\uAAAA\U0010AAAA";
+  static_assert (array_size (input) == 5, "");
+  static_assert (array_size (expected) == 6, "");
+
+  InternT in[array_size (input)];
+  char exp[array_size (expected) * 2];
+  copy (begin (input), end (input), begin (in));
+  utf16_to_bytes (begin (expected), end (expected), begin (exp), endianess);
+
+  test_offsets_ok offsets[] = {{0, 0}, {1, 2}, {2, 4}, {3, 6}, {4, 10}};
+  for (auto t : offsets)
+    {
+      char out[array_size (exp) - 2] = {};
+      VERIFY (t.in_size <= array_size (in));
+      VERIFY (t.out_size <= array_size (out));
+      auto state = mbstate_t{};
+      auto in_next = (const InternT *) nullptr;
+      auto out_next = (char *) nullptr;
+      auto res = codecvt_base::result ();
+
+      res = cvt.out (state, in, in + t.in_size, in_next, out, out + t.out_size,
+		     out_next);
+      VERIFY (res == cvt.ok);
+      VERIFY (in_next == in + t.in_size);
+      VERIFY (out_next == out + t.out_size);
+      VERIFY (char_traits<char>::compare (out, exp, t.out_size) == 0);
+      if (t.out_size < array_size (out))
+	VERIFY (out[t.out_size] == 0);
+    }
+}
+
+template <class InternT>
+void
+utf32_to_utf16_out_partial (const std::codecvt<InternT, char, mbstate_t> &cvt,
+			    utf16_endianess endianess)
+{
+  using namespace std;
+  const char32_t input[] = U"b\u0448\uAAAA\U0010AAAA";
+  const char16_t expected[] = u"b\u0448\uAAAA\U0010AAAA";
+  static_assert (array_size (input) == 5, "");
+  static_assert (array_size (expected) == 6, "");
+
+  InternT in[array_size (input)];
+  char exp[array_size (expected) * 2];
+  copy (begin (input), end (input), begin (in));
+  utf16_to_bytes (begin (expected), end (expected), begin (exp), endianess);
+
+  test_offsets_partial offsets[] = {
+    {1, 0, 0, 0}, // no space for first CP
+    {1, 1, 0, 0}, // no space for first CP
+
+    {2, 2, 1, 2}, // no space for second CP
+    {2, 3, 1, 2}, // no space for second CP
+
+    {3, 4, 2, 4}, // no space for third CP
+    {3, 5, 2, 4}, // no space for third CP
+
+    {4, 6, 3, 6}, // no space for fourth CP
+    {4, 7, 3, 6}, // no space for fourth CP
+    {4, 8, 3, 6}, // no space for fourth CP
+    {4, 9, 3, 6}, // no space for fourth CP
+  };
+  for (auto t : offsets)
+    {
+      char out[array_size (exp) - 2] = {};
+      VERIFY (t.in_size <= array_size (in));
+      VERIFY (t.out_size <= array_size (out));
+      VERIFY (t.expected_in_next <= t.in_size);
+      VERIFY (t.expected_out_next <= t.out_size);
+      auto state = mbstate_t{};
+      auto in_next = (const InternT *) nullptr;
+      auto out_next = (char *) nullptr;
+      auto res = codecvt_base::result ();
+
+      res = cvt.out (state, in, in + t.in_size, in_next, out, out + t.out_size,
+		     out_next);
+      VERIFY (res == cvt.partial);
+      VERIFY (in_next == in + t.expected_in_next);
+      VERIFY (out_next == out + t.expected_out_next);
+      VERIFY (char_traits<char>::compare (out, exp, t.expected_out_next) == 0);
+      if (t.expected_out_next < array_size (out))
+	VERIFY (out[t.expected_out_next] == 0);
+    }
+}
+
+template <class InternT>
+void
+utf32_to_utf16_out_error (const std::codecvt<InternT, char, mbstate_t> &cvt,
+			  utf16_endianess endianess)
+{
+  using namespace std;
+  const char32_t input[] = U"b\u0448\uAAAA\U0010AAAA";
+  const char16_t expected[] = u"b\u0448\uAAAA\U0010AAAA";
+  static_assert (array_size (input) == 5, "");
+  static_assert (array_size (expected) == 6, "");
+
+  InternT in[array_size (input)];
+  char exp[array_size (expected) * 2];
+  copy (begin (input), end (input), begin (in));
+  utf16_to_bytes (begin (expected), end (expected), begin (exp), endianess);
+
+  test_offsets_error<InternT> offsets[] = {
+
+    // Surrogate CP
+    {4, 10, 0, 0, 0xD800, 0},
+    {4, 10, 1, 2, 0xDBFF, 1},
+    {4, 10, 2, 4, 0xDC00, 2},
+    {4, 10, 3, 6, 0xDFFF, 3},
+
+    // CP out of range
+    {4, 10, 0, 0, 0x00110000, 0},
+    {4, 10, 1, 2, 0x00110000, 1},
+    {4, 10, 2, 4, 0x00110000, 2},
+    {4, 10, 3, 6, 0x00110000, 3}};
+
+  for (auto t : offsets)
+    {
+      char out[array_size (exp) - 2] = {};
+      VERIFY (t.in_size <= array_size (in));
+      VERIFY (t.out_size <= array_size (out));
+      VERIFY (t.expected_in_next <= t.in_size);
+      VERIFY (t.expected_out_next <= t.out_size);
+      auto old_char = in[t.replace_pos];
+      in[t.replace_pos] = t.replace_char;
+
+      auto state = mbstate_t{};
+      auto in_next = (const InternT *) nullptr;
+      auto out_next = (char *) nullptr;
+      auto res = codecvt_base::result ();
+
+      res = cvt.out (state, in, in + t.in_size, in_next, out, out + t.out_size,
+		     out_next);
+      VERIFY (res == cvt.error);
+      VERIFY (in_next == in + t.expected_in_next);
+      VERIFY (out_next == out + t.expected_out_next);
+      VERIFY (char_traits<char>::compare (out, exp, t.expected_out_next) == 0);
+      if (t.expected_out_next < array_size (out))
+	VERIFY (out[t.expected_out_next] == 0);
+
+      in[t.replace_pos] = old_char;
+    }
+}
+
+template <class InternT>
+void
+test_utf16_utf32_cvt (const std::codecvt<InternT, char, mbstate_t> &cvt,
+		      utf16_endianess endianess)
+{
+  utf16_to_utf32_in_ok (cvt, endianess);
+  utf16_to_utf32_in_partial (cvt, endianess);
+  utf16_to_utf32_in_error (cvt, endianess);
+  utf32_to_utf16_out_ok (cvt, endianess);
+  utf32_to_utf16_out_partial (cvt, endianess);
+  utf32_to_utf16_out_error (cvt, endianess);
+}
+
+template <class InternT>
+void
+utf16_to_ucs2_in_ok (const std::codecvt<InternT, char, mbstate_t> &cvt,
+		     utf16_endianess endianess)
+{
+  using namespace std;
+  const char16_t input[] = u"b\u0448\uAAAA";
+  const char16_t expected[] = u"b\u0448\uAAAA";
+  static_assert (array_size (input) == 4, "");
+  static_assert (array_size (expected) == 4, "");
+
+  char in[array_size (input) * 2];
+  InternT exp[array_size (expected)];
+  utf16_to_bytes (begin (input), end (input), begin (in), endianess);
+  copy (begin (expected), end (expected), begin (exp));
+
+  test_offsets_ok offsets[] = {{0, 0}, {2, 1}, {4, 2}, {6, 3}};
+  for (auto t : offsets)
+    {
+      InternT out[array_size (exp) - 1] = {};
+      VERIFY (t.in_size <= array_size (in));
+      VERIFY (t.out_size <= array_size (out));
+      auto state = mbstate_t{};
+      auto in_next = (const char *) nullptr;
+      auto out_next = (InternT *) nullptr;
+      auto res = codecvt_base::result ();
+
+      res = cvt.in (state, in, in + t.in_size, in_next, out, out + t.out_size,
+		    out_next);
+      VERIFY (res == cvt.ok);
+      VERIFY (in_next == in + t.in_size);
+      VERIFY (out_next == out + t.out_size);
+      VERIFY (char_traits<InternT>::compare (out, exp, t.out_size) == 0);
+      if (t.out_size < array_size (out))
+	VERIFY (out[t.out_size] == 0);
+
+      state = {};
+      auto len = cvt.length (state, in, in + t.in_size, t.out_size);
+      VERIFY (len >= 0);
+      VERIFY (static_cast<size_t> (len) == t.in_size);
+    }
+
+  for (auto t : offsets)
+    {
+      InternT out[array_size (exp)] = {};
+      VERIFY (t.in_size <= array_size (in));
+      VERIFY (t.out_size <= array_size (out));
+      auto state = mbstate_t{};
+      auto in_next = (const char *) nullptr;
+      auto out_next = (InternT *) nullptr;
+      auto res = codecvt_base::result ();
+
+      res
+	= cvt.in (state, in, in + t.in_size, in_next, out, end (out), out_next);
+      VERIFY (res == cvt.ok);
+      VERIFY (in_next == in + t.in_size);
+      VERIFY (out_next == out + t.out_size);
+      VERIFY (char_traits<InternT>::compare (out, exp, t.out_size) == 0);
+      if (t.out_size < array_size (out))
+	VERIFY (out[t.out_size] == 0);
+
+      state = {};
+      auto len = cvt.length (state, in, in + t.in_size, array_size (out));
+      VERIFY (len >= 0);
+      VERIFY (static_cast<size_t> (len) == t.in_size);
+    }
+}
+
+template <class InternT>
+void
+utf16_to_ucs2_in_partial (const std::codecvt<InternT, char, mbstate_t> &cvt,
+			  utf16_endianess endianess)
+{
+  using namespace std;
+  const char16_t input[] = u"b\u0448\uAAAA";
+  const char16_t expected[] = u"b\u0448\uAAAA";
+  static_assert (array_size (input) == 4, "");
+  static_assert (array_size (expected) == 4, "");
+
+  char in[array_size (input) * 2];
+  InternT exp[array_size (expected)];
+  utf16_to_bytes (begin (input), end (input), begin (in), endianess);
+  copy (begin (expected), end (expected), begin (exp));
+
+  test_offsets_partial offsets[] = {
+    {2, 0, 0, 0}, // no space for first CP
+    {1, 1, 0, 0}, // incomplete first CP
+    {1, 0, 0, 0}, // incomplete first CP, and no space for it
+
+    {4, 1, 2, 1}, // no space for second CP
+    {3, 2, 2, 1}, // incomplete second CP
+    {3, 1, 2, 1}, // incomplete second CP, and no space for it
+
+    {6, 2, 4, 2}, // no space for third CP
+    {5, 3, 4, 2}, // incomplete third CP
+    {5, 2, 4, 2}, // incomplete third CP, and no space for it
+  };
+
+  for (auto t : offsets)
+    {
+      InternT out[array_size (exp) - 1] = {};
+      VERIFY (t.in_size <= array_size (in));
+      VERIFY (t.out_size <= array_size (out));
+      VERIFY (t.expected_in_next <= t.in_size);
+      VERIFY (t.expected_out_next <= t.out_size);
+      auto state = mbstate_t{};
+      auto in_next = (const char *) nullptr;
+      auto out_next = (InternT *) nullptr;
+      auto res = codecvt_base::result ();
+
+      res = cvt.in (state, in, in + t.in_size, in_next, out, out + t.out_size,
+		    out_next);
+      VERIFY (res == cvt.partial);
+      VERIFY (in_next == in + t.expected_in_next);
+      VERIFY (out_next == out + t.expected_out_next);
+      VERIFY (char_traits<InternT>::compare (out, exp, t.expected_out_next)
+	      == 0);
+      if (t.expected_out_next < array_size (out))
+	VERIFY (out[t.expected_out_next] == 0);
+
+      state = {};
+      auto len = cvt.length (state, in, in + t.in_size, t.out_size);
+      VERIFY (len >= 0);
+      VERIFY (static_cast<size_t> (len) == t.expected_in_next);
+    }
+}
+
+template <class InternT>
+void
+utf16_to_ucs2_in_error (const std::codecvt<InternT, char, mbstate_t> &cvt,
+			utf16_endianess endianess)
+{
+  using namespace std;
+  char16_t input[] = u"b\u0448\uAAAA\U0010AAAA";
+  const char16_t expected[] = u"b\u0448\uAAAA\U0010AAAA";
+  static_assert (array_size (input) == 6, "");
+  static_assert (array_size (expected) == 6, "");
+
+  InternT exp[array_size (expected)];
+  copy (begin (expected), end (expected), begin (exp));
+
+  // The only possible error in UTF-16 is unpaired surrogate code units.
+  // Additionally, because the target encoding is UCS-2, a proper pair of
+  // surrogates is also error. Simply, any surrogate CU is error.
+  test_offsets_error<char16_t> offsets[] = {
+    {6, 3, 0, 0, 0xD800, 0},
+    {6, 3, 0, 0, 0xDBFF, 0},
+    {6, 3, 0, 0, 0xDC00, 0},
+    {6, 3, 0, 0, 0xDFFF, 0},
+
+    {6, 3, 2, 1, 0xD800, 1},
+    {6, 3, 2, 1, 0xDBFF, 1},
+    {6, 3, 2, 1, 0xDC00, 1},
+    {6, 3, 2, 1, 0xDFFF, 1},
+
+    {6, 3, 4, 2, 0xD800, 2},
+    {6, 3, 4, 2, 0xDBFF, 2},
+    {6, 3, 4, 2, 0xDC00, 2},
+    {6, 3, 4, 2, 0xDFFF, 2},
+
+    // make the leading surrogate a trailing one
+    {10, 5, 6, 3, 0xDC00, 3},
+    {10, 5, 6, 3, 0xDFFF, 3},
+
+    // make the trailing surrogate a leading one
+    {10, 5, 6, 3, 0xD800, 4},
+    {10, 5, 6, 3, 0xDBFF, 4},
+
+    // make the trailing surrogate a BMP char
+    {10, 5, 6, 3, u'z', 4},
+
+    // don't replace anything in the test cases bellow, just show the surrogate
+    // pair (fourth CP) fully or partially (just the first surrogate)
+    {10, 5, 6, 3, u'b', 0},
+    {8, 5, 6, 3, u'b', 0},
+    {9, 5, 6, 3, u'b', 0},
+
+    {10, 4, 6, 3, u'b', 0},
+    {8, 4, 6, 3, u'b', 0},
+    {9, 4, 6, 3, u'b', 0},
+  };
+
+  for (auto t : offsets)
+    {
+      char in[array_size (input) * 2];
+      InternT out[array_size (exp) - 1] = {};
+      VERIFY (t.in_size <= array_size (in));
+      VERIFY (t.out_size <= array_size (out));
+      VERIFY (t.expected_in_next <= t.in_size);
+      VERIFY (t.expected_out_next <= t.out_size);
+      auto old_char = input[t.replace_pos];
+      input[t.replace_pos] = t.replace_char; // replace in input, not in in
+      utf16_to_bytes (begin (input), end (input), begin (in), endianess);
+
+      auto state = mbstate_t{};
+      auto in_next = (const char *) nullptr;
+      auto out_next = (InternT *) nullptr;
+      auto res = codecvt_base::result ();
+
+      res = cvt.in (state, in, in + t.in_size, in_next, out, out + t.out_size,
+		    out_next);
+      VERIFY (res == cvt.error);
+      VERIFY (in_next == in + t.expected_in_next);
+      VERIFY (out_next == out + t.expected_out_next);
+      VERIFY (char_traits<InternT>::compare (out, exp, t.expected_out_next)
+	      == 0);
+      if (t.expected_out_next < array_size (out))
+	VERIFY (out[t.expected_out_next] == 0);
+
+      state = {};
+      auto len = cvt.length (state, in, in + t.in_size, t.out_size);
+      VERIFY (len >= 0);
+      VERIFY (static_cast<size_t> (len) == t.expected_in_next);
+
+      input[t.replace_pos] = old_char;
+    }
+}
+
+template <class InternT>
+void
+ucs2_to_utf16_out_ok (const std::codecvt<InternT, char, mbstate_t> &cvt,
+		      utf16_endianess endianess)
+{
+  using namespace std;
+  const char16_t input[] = u"b\u0448\uAAAA";
+  const char16_t expected[] = u"b\u0448\uAAAA";
+  static_assert (array_size (input) == 4, "");
+  static_assert (array_size (expected) == 4, "");
+
+  InternT in[array_size (input)];
+  char exp[array_size (expected) * 2];
+  copy (begin (input), end (input), begin (in));
+  utf16_to_bytes (begin (expected), end (expected), begin (exp), endianess);
+
+  test_offsets_ok offsets[] = {{0, 0}, {1, 2}, {2, 4}, {3, 6}};
+  for (auto t : offsets)
+    {
+      char out[array_size (exp) - 2] = {};
+      VERIFY (t.in_size <= array_size (in));
+      VERIFY (t.out_size <= array_size (out));
+      auto state = mbstate_t{};
+      auto in_next = (const InternT *) nullptr;
+      auto out_next = (char *) nullptr;
+      auto res = codecvt_base::result ();
+
+      res = cvt.out (state, in, in + t.in_size, in_next, out, out + t.out_size,
+		     out_next);
+      VERIFY (res == cvt.ok);
+      VERIFY (in_next == in + t.in_size);
+      VERIFY (out_next == out + t.out_size);
+      VERIFY (char_traits<char>::compare (out, exp, t.out_size) == 0);
+      if (t.out_size < array_size (out))
+	VERIFY (out[t.out_size] == 0);
+    }
+}
+
+template <class InternT>
+void
+ucs2_to_utf16_out_partial (const std::codecvt<InternT, char, mbstate_t> &cvt,
+			   utf16_endianess endianess)
+{
+  using namespace std;
+  const char16_t input[] = u"b\u0448\uAAAA";
+  const char16_t expected[] = u"b\u0448\uAAAA";
+  static_assert (array_size (input) == 4, "");
+  static_assert (array_size (expected) == 4, "");
+
+  InternT in[array_size (input)];
+  char exp[array_size (expected) * 2];
+  copy (begin (input), end (input), begin (in));
+  utf16_to_bytes (begin (expected), end (expected), begin (exp), endianess);
+
+  test_offsets_partial offsets[] = {
+    {1, 0, 0, 0}, // no space for first CP
+    {1, 1, 0, 0}, // no space for first CP
+
+    {2, 2, 1, 2}, // no space for second CP
+    {2, 3, 1, 2}, // no space for second CP
+
+    {3, 4, 2, 4}, // no space for third CP
+    {3, 5, 2, 4}, // no space for third CP
+  };
+  for (auto t : offsets)
+    {
+      char out[array_size (exp) - 2] = {};
+      VERIFY (t.in_size <= array_size (in));
+      VERIFY (t.out_size <= array_size (out));
+      VERIFY (t.expected_in_next <= t.in_size);
+      VERIFY (t.expected_out_next <= t.out_size);
+      auto state = mbstate_t{};
+      auto in_next = (const InternT *) nullptr;
+      auto out_next = (char *) nullptr;
+      auto res = codecvt_base::result ();
+
+      res = cvt.out (state, in, in + t.in_size, in_next, out, out + t.out_size,
+		     out_next);
+      VERIFY (res == cvt.partial);
+      VERIFY (in_next == in + t.expected_in_next);
+      VERIFY (out_next == out + t.expected_out_next);
+      VERIFY (char_traits<char>::compare (out, exp, t.expected_out_next) == 0);
+      if (t.expected_out_next < array_size (out))
+	VERIFY (out[t.expected_out_next] == 0);
+    }
+}
+
+template <class InternT>
+void
+ucs2_to_utf16_out_error (const std::codecvt<InternT, char, mbstate_t> &cvt,
+			 utf16_endianess endianess)
+{
+  using namespace std;
+  const char16_t input[] = u"b\u0448\uAAAA\U0010AAAA";
+  const char16_t expected[] = u"b\u0448\uAAAA\U0010AAAA";
+  static_assert (array_size (input) == 6, "");
+  static_assert (array_size (expected) == 6, "");
+
+  InternT in[array_size (input)];
+  char exp[array_size (expected) * 2];
+  copy (begin (input), end (input), begin (in));
+  utf16_to_bytes (begin (expected), end (expected), begin (exp), endianess);
+
+  test_offsets_error<InternT> offsets[] = {
+    {3, 6, 0, 0, 0xD800, 0},
+    {3, 6, 0, 0, 0xDBFF, 0},
+    {3, 6, 0, 0, 0xDC00, 0},
+    {3, 6, 0, 0, 0xDFFF, 0},
+
+    {3, 6, 1, 2, 0xD800, 1},
+    {3, 6, 1, 2, 0xDBFF, 1},
+    {3, 6, 1, 2, 0xDC00, 1},
+    {3, 6, 1, 2, 0xDFFF, 1},
+
+    {3, 6, 2, 4, 0xD800, 2},
+    {3, 6, 2, 4, 0xDBFF, 2},
+    {3, 6, 2, 4, 0xDC00, 2},
+    {3, 6, 2, 4, 0xDFFF, 2},
+
+    // make the leading surrogate a trailing one
+    {5, 10, 3, 6, 0xDC00, 3},
+    {5, 10, 3, 6, 0xDFFF, 3},
+
+    // make the trailing surrogate a leading one
+    {5, 10, 3, 6, 0xD800, 4},
+    {5, 10, 3, 6, 0xDBFF, 4},
+
+    // make the trailing surrogate a BMP char
+    {5, 10, 3, 6, u'z', 4},
+
+    // don't replace anything in the test cases bellow, just show the surrogate
+    // pair (fourth CP) fully or partially (just the first surrogate)
+    {5, 10, 3, 6, u'b', 0},
+    {5, 8, 3, 6, u'b', 0},
+    {5, 9, 3, 6, u'b', 0},
+
+    {4, 10, 3, 6, u'b', 0},
+    {4, 8, 3, 6, u'b', 0},
+    {4, 9, 3, 6, u'b', 0},
+  };
+
+  for (auto t : offsets)
+    {
+      char out[array_size (exp) - 2] = {};
+      VERIFY (t.in_size <= array_size (in));
+      VERIFY (t.out_size <= array_size (out));
+      VERIFY (t.expected_in_next <= t.in_size);
+      VERIFY (t.expected_out_next <= t.out_size);
+      auto old_char = in[t.replace_pos];
+      in[t.replace_pos] = t.replace_char;
+
+      auto state = mbstate_t{};
+      auto in_next = (const InternT *) nullptr;
+      auto out_next = (char *) nullptr;
+      auto res = codecvt_base::result ();
+
+      res = cvt.out (state, in, in + t.in_size, in_next, out, out + t.out_size,
+		     out_next);
+      VERIFY (res == cvt.error);
+      VERIFY (in_next == in + t.expected_in_next);
+      VERIFY (out_next == out + t.expected_out_next);
+      VERIFY (char_traits<char>::compare (out, exp, t.expected_out_next) == 0);
+      if (t.expected_out_next < array_size (out))
+	VERIFY (out[t.expected_out_next] == 0);
+
+      in[t.replace_pos] = old_char;
+    }
+}
+
+template <class InternT>
+void
+test_utf16_ucs2_cvt (const std::codecvt<InternT, char, mbstate_t> &cvt,
+		     utf16_endianess endianess)
+{
+  utf16_to_ucs2_in_ok (cvt, endianess);
+  utf16_to_ucs2_in_partial (cvt, endianess);
+  utf16_to_ucs2_in_error (cvt, endianess);
+  ucs2_to_utf16_out_ok (cvt, endianess);
+  ucs2_to_utf16_out_partial (cvt, endianess);
+  ucs2_to_utf16_out_error (cvt, endianess);
+}
new file mode 100644
--- /dev/null
+++ b/src/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_unicode_char8_t.cc
@@ -0,0 +1,53 @@
+// Copyright (C) 2020-2023 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do run { target c++11 } }
+// { dg-require-cstdint "" }
+// { dg-options "-fchar8_t" }
+
+#include "codecvt_unicode.h"
+
+using namespace std;
+
+void
+test_utf8_utf32_codecvts ()
+{
+  using codecvt_c32_c8 = codecvt<char32_t, char8_t, mbstate_t>;
+  auto &loc_c = locale::classic ();
+  VERIFY (has_facet<codecvt_c32_c8> (loc_c));
+
+  auto &cvt = use_facet<codecvt_c32_c8> (loc_c);
+  test_utf8_utf32_cvt (cvt);
+}
+
+void
+test_utf8_utf16_codecvts ()
+{
+  using codecvt_c16_c8 = codecvt<char16_t, char8_t, mbstate_t>;
+  auto &loc_c = locale::classic ();
+  VERIFY (has_facet<codecvt_c16_c8> (loc_c));
+
+  auto &cvt = use_facet<codecvt_c16_c8> (loc_c);
+  test_utf8_utf16_cvt (cvt);
+}
+
+int
+main ()
+{
+  test_utf8_utf32_codecvts ();
+  test_utf8_utf16_codecvts ();
+}
--- a/src/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_unicode_wchar_t.cc
+++ b/src/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_unicode_wchar_t.cc
@@ -28,7 +28,7 @@ test_utf8_utf32_codecvts ()
 {
 #if __SIZEOF_WCHAR_T__ == 4
   codecvt_utf8<wchar_t> cvt;
-  test_utf8_utf32_codecvts (cvt);
+  test_utf8_utf32_cvt (cvt);
 #endif
 }
 
@@ -37,7 +37,7 @@ test_utf8_utf16_codecvts ()
 {
 #if __SIZEOF_WCHAR_T__ >= 2
   codecvt_utf8_utf16<wchar_t> cvt;
-  test_utf8_utf16_cvts (cvt);
+  test_utf8_utf16_cvt (cvt);
 #endif
 }
 
@@ -46,7 +46,31 @@ test_utf8_ucs2_codecvts ()
 {
 #if __SIZEOF_WCHAR_T__ == 2
   codecvt_utf8<wchar_t> cvt;
-  test_utf8_ucs2_cvts (cvt);
+  test_utf8_ucs2_cvt (cvt);
+#endif
+}
+
+void
+test_utf16_utf32_codecvts ()
+{
+#if __SIZEOF_WCHAR_T__ == 4
+  codecvt_utf16<wchar_t> cvt3;
+  test_utf16_utf32_cvt (cvt3, utf16_big_endian);
+
+  codecvt_utf16<wchar_t, 0x10FFFF, codecvt_mode::little_endian> cvt4;
+  test_utf16_utf32_cvt (cvt4, utf16_little_endian);
+#endif
+}
+
+void
+test_utf16_ucs2_codecvts ()
+{
+#if __SIZEOF_WCHAR_T__ == 2
+  codecvt_utf16<wchar_t> cvt3;
+  test_utf16_ucs2_cvt (cvt3, utf16_big_endian);
+
+  codecvt_utf16<wchar_t, 0x10FFFF, codecvt_mode::little_endian> cvt4;
+  test_utf16_ucs2_cvt (cvt4, utf16_little_endian);
 #endif
 }
 
@@ -56,4 +80,6 @@ main ()
   test_utf8_utf32_codecvts ();
   test_utf8_utf16_codecvts ();
   test_utf8_ucs2_codecvts ();
+  test_utf16_utf32_codecvts ();
+  test_utf16_ucs2_codecvts ();
 }
--- a/src/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf16/79980.cc
+++ b/src/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_utf16/79980.cc
@@ -83,7 +83,7 @@ test06()
   const char src[] = "\0\x61\xAB\xCD";
   Conv<char16_t> conv("to_bytes failed", u"from_bytes failed");
   std::u16string result = conv.from_bytes(src, src+3); // incomplete character
-  VERIFY( result == u"from_bytes failed" );
+  VERIFY( result == u"\u0061" );
   VERIFY( conv.converted() == 2 );
 }
 
new file mode 100644
--- /dev/null
+++ b/src/libstdc++-v3/testsuite/23_containers/array/creation/115522.cc
@@ -0,0 +1,33 @@
+// { dg-do compile { target c++20 } }
+
+// PR libstdc++/115522 std::to_array no longer works for struct which is
+// trivial but not default constructible
+
+#include <array>
+
+void
+test_deleted_ctor()
+{
+  struct S
+  {
+    S() = delete;
+    S(int) { }
+  };
+
+  S arr[1] = {{1}};
+  auto arr1 = std::to_array(arr);
+  auto arr2 = std::to_array(std::move(arr));
+}
+
+void
+test_deleted_assignment()
+{
+  struct S
+  {
+    void operator=(const S&) = delete;
+  };
+
+  S arr[1] = {};
+  auto a1 = std::to_array(arr);
+  auto a2 = std::to_array(std::move(arr));
+}
new file mode 100644
--- /dev/null
+++ b/src/libstdc++-v3/testsuite/29_atomics/headers/stdatomic.h/115807.cc
@@ -0,0 +1,14 @@
+// { dg-do compile { target c++23 } }
+#include <stdatomic.h>
+namespace other {
+  namespace std {
+    int atomic = 0;
+  }
+  _Atomic(long) a{};
+}
+
+#include <type_traits>
+
+namespace non::std {
+  static_assert( ::std::is_same_v<_Atomic(int), ::std::atomic<int>> );
+}
new file mode 100644
--- /dev/null
+++ b/src/libstdc++-v3/testsuite/experimental/simd/pr114958.cc
@@ -0,0 +1,20 @@
+// { dg-options "-std=c++17" }
+// { dg-do compile { target x86_64-*-* } }
+// { dg-require-effective-target c++17 }
+// { dg-additional-options "-march=x86-64-v3" { target x86_64-*-* } }
+// { dg-require-cmath "" }
+// { dg-final { scan-assembler-times "vperm(?:q|pd)\\s+\\\$144" 1 } }
+
+#include <experimental/simd>
+
+namespace stdx = std::experimental;
+
+using T = std::uint64_t;
+using V = stdx::simd<T, stdx::simd_abi::_VecBuiltin<32>>;
+using V1 = stdx::simd<T, stdx::simd_abi::scalar>;
+
+V perm(V data)
+{
+  auto [carry, _] = stdx::split<3, 1>(data);
+  return concat(V1(), carry);
+}
new file mode 100644
--- /dev/null
+++ b/src/libstdc++-v3/testsuite/experimental/simd/pr115454_find_last_set.cc
@@ -0,0 +1,50 @@
+// { dg-options "-std=gnu++17" }
+// { dg-require-effective-target c++17 }
+// { dg-additional-options "-march=x86-64-v4" { target avx512f_runtime } }
+// { dg-require-cmath "" }
+
+#include <experimental/simd>
+
+namespace stdx = std::experimental;
+
+using T = std::uint64_t;
+
+template <typename U, int N>
+using V = stdx::simd<U, stdx::simd_abi::deduce_t<U, N>>;
+
+[[gnu::noinline, gnu::noipa]]
+int reduce(V<T, 4> x)
+{
+  static_assert(stdx::find_last_set(V<T, 4>([](unsigned i) { return i; }) != V<T, 4>(0)) == 3);
+  return stdx::find_last_set(x != -1);
+}
+
+[[gnu::noinline, gnu::noipa]]
+int reduce2()
+{
+  using M8 = typename V<short, 8>::mask_type;
+  using M4 = typename V<int, 4>::mask_type;
+  if constexpr (sizeof(M8) == sizeof(M4)
+		  && !std::is_same_v<M4, stdx::fixed_size_simd_mask<int, 4>>)
+    // fixed_size invariant: padding bits of masks are zero, the memcpy would violate that
+    {
+      M4 k;
+      __builtin_memcpy(&__data(k), &__data(M8(true)), sizeof(M4));
+      return stdx::find_last_set(k);
+    }
+  return 3;
+}
+
+
+int main()
+{
+  const V<T, 4> x {};
+
+  const int r = reduce(x);
+  if (r != 3)
+      __builtin_abort();
+
+  const int r2 = reduce2();
+  if (r2 != 3)
+      __builtin_abort();
+}
