aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--MAINTAINERS3
-rw-r--r--gcc/ChangeLog104
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/ada/ChangeLog126
-rw-r--r--gcc/ada/sem_ch12.adb4
-rw-r--r--gcc/ada/sem_ch8.adb115
-rw-r--r--gcc/ada/sem_type.adb11
-rw-r--r--gcc/btfout.cc3
-rw-r--r--gcc/c-family/c-attribs.cc12
-rw-r--r--gcc/c/c-typeck.cc5
-rw-r--r--gcc/cgraph.cc11
-rw-r--r--gcc/cgraph.h98
-rw-r--r--gcc/config/i386/i386-options.cc2
-rw-r--r--gcc/config/i386/i386.md66
-rw-r--r--gcc/config/i386/sse.md11
-rw-r--r--gcc/config/loongarch/genopts/loongarch.opt.in4
-rw-r--r--gcc/config/loongarch/lasx.md63
-rw-r--r--gcc/config/loongarch/loongarch.cc104
-rw-r--r--gcc/config/loongarch/loongarch.md14
-rw-r--r--gcc/config/loongarch/loongarch.opt4
-rw-r--r--gcc/config/loongarch/loongarch.opt.urls3
-rw-r--r--gcc/config/loongarch/lsx.md63
-rw-r--r--gcc/config/loongarch/simd.md82
-rw-r--r--gcc/config/riscv/riscv-avlprop.cc41
-rw-r--r--gcc/coretypes.h10
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/decl.cc8
-rw-r--r--gcc/doc/extend.texi15
-rw-r--r--gcc/doc/invoke.texi13
-rw-r--r--gcc/dwarf2out.cc16
-rw-r--r--gcc/fold-const-call.cc22
-rw-r--r--gcc/fortran/ChangeLog34
-rw-r--r--gcc/fortran/decl.cc14
-rw-r--r--gcc/fortran/primary.cc8
-rw-r--r--gcc/fortran/resolve.cc3
-rw-r--r--gcc/fortran/trans-array.cc8
-rw-r--r--gcc/fortran/trans-expr.cc3
-rw-r--r--gcc/gimple-fold.cc21
-rw-r--r--gcc/gimple-range-op.cc4
-rw-r--r--gcc/ipa-icf.cc21
-rw-r--r--gcc/ipa-modref.cc8
-rw-r--r--gcc/ipa-prop.cc16
-rw-r--r--gcc/ipa-reference.cc14
-rw-r--r--gcc/lra-constraints.cc5
-rw-r--r--gcc/lto-cgraph.cc62
-rw-r--r--gcc/lto-section-in.cc1
-rw-r--r--gcc/lto-streamer-in.cc1
-rw-r--r--gcc/lto-streamer-out.cc77
-rw-r--r--gcc/lto-streamer.h23
-rw-r--r--gcc/lto/lto-partition.cc201
-rw-r--r--gcc/lto/lto-symtab.cc6
-rw-r--r--gcc/lto/lto.cc11
-rw-r--r--gcc/m2/gm2-compiler/M2Comp.mod11
-rw-r--r--gcc/m2/gm2-compiler/M2MetaError.mod29
-rw-r--r--gcc/m2/gm2-compiler/M2Quads.mod59
-rw-r--r--gcc/m2/gm2-compiler/M2StackSpell.def10
-rw-r--r--gcc/m2/gm2-compiler/M2StackSpell.mod93
-rw-r--r--gcc/match.pd11
-rw-r--r--gcc/range-op-mixed.h41
-rw-r--r--gcc/range-op.cc76
-rw-r--r--gcc/testsuite/ChangeLog58
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/copy-prop-aggregate-sra-1.C33
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/copy-prop-aggregate-sra-2.C31
-rw-r--r--gcc/testsuite/gcc.dg/builtin-assume-aligned-1.c10
-rw-r--r--gcc/testsuite/gcc.dg/cpp/escape-3.i2
-rw-r--r--gcc/testsuite/gcc.dg/debug/btf/btf-prune-4.c61
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-4.c28
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-5.c35
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-6.c24
-rw-r--r--gcc/testsuite/gcc.dg/pointer-counted-by-10.c8
-rw-r--r--gcc/testsuite/gcc.dg/pointer-counted-by-4-void.c6
-rw-r--r--gcc/testsuite/gcc.dg/pointer-counted-by.c3
-rw-r--r--gcc/testsuite/gcc.dg/pr116815.c57
-rw-r--r--gcc/testsuite/gcc.dg/pr41488.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr91191.c20
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ctz-ch.c23
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ctz-char.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ctz-complement-char.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ctz-complement-int.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ctz-complement-long-long.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ctz-complement-long.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ctz-int.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ctz-long-long.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ctz-long.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr122478.c17
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr92834.c6
-rw-r--r--gcc/testsuite/gcc.dg/vect/slp-reduc-13.c66
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/dup-insr-1.c26
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/dup-insr-2.c26
-rw-r--r--gcc/testsuite/gcc.target/avr/pr121198.c10
-rw-r--r--gcc/testsuite/gcc.target/i386/pr116815.c31
-rw-r--r--gcc/testsuite/gcc.target/i386/pr122457.c4
-rw-r--r--gcc/testsuite/gcc.target/loongarch/conditional-move-opt-1.c4
-rw-r--r--gcc/testsuite/gcc.target/loongarch/conditional-move-opt-2.c2
-rw-r--r--gcc/testsuite/gcc.target/loongarch/conditional-move-opt-3.c14
-rw-r--r--gcc/testsuite/gcc.target/loongarch/fnmam4-vec.c14
-rw-r--r--gcc/testsuite/gcc.target/loongarch/pr122097.c271
-rw-r--r--gcc/testsuite/gcc.target/loongarch/trap-1.c9
-rw-r--r--gcc/testsuite/gcc.target/loongarch/trap-default.c9
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/pr122445.c26
-rw-r--r--gcc/testsuite/gfortran.dg/pdt_62.f0378
-rw-r--r--gcc/testsuite/gfortran.dg/pdt_63.f0326
-rw-r--r--gcc/testsuite/gfortran.dg/pdt_64.f0317
-rw-r--r--gcc/testsuite/gfortran.dg/vect/pr70102.f21
-rw-r--r--gcc/testsuite/gm2.dg/spell/iso/fail/badimport.mod14
-rw-r--r--gcc/testsuite/gnat.dg/aggr32.adb15
-rw-r--r--gcc/testsuite/gnat.dg/aggr32_pkg-child.ads6
-rw-r--r--gcc/testsuite/gnat.dg/aggr32_pkg.ads8
-rw-r--r--gcc/testsuite/gnat.dg/specs/generic_inst6.ads6
-rw-r--r--gcc/testsuite/gnat.dg/specs/generic_inst6_pkg1-child-grand1.ads3
-rw-r--r--gcc/testsuite/gnat.dg/specs/generic_inst6_pkg1-child-grand2.ads6
-rw-r--r--gcc/testsuite/gnat.dg/specs/generic_inst6_pkg1-child.ads3
-rw-r--r--gcc/testsuite/gnat.dg/specs/generic_inst6_pkg1.ads3
-rw-r--r--gcc/testsuite/gnat.dg/specs/generic_inst6_pkg2.ads3
-rw-r--r--gcc/testsuite/gnat.dg/specs/generic_inst6_pkg3.ads4
-rw-r--r--gcc/testsuite/gnat.dg/specs/generic_inst7.ads17
-rw-r--r--gcc/testsuite/gnat.dg/specs/generic_inst8.ads18
-rw-r--r--gcc/tree-ssa-forwprop.cc53
-rw-r--r--gcc/tree-ssa-loop-niter.cc93
-rw-r--r--gcc/tree-ssa-loop.cc5
-rw-r--r--gcc/tree-vect-slp.cc127
-rw-r--r--gcc/varpool.cc6
-rw-r--r--libgcobol/ChangeLog6
-rw-r--r--libgomp/ChangeLog4
-rw-r--r--libstdc++-v3/ChangeLog51
-rw-r--r--libstdc++-v3/include/bits/regex.tcc49
-rw-r--r--libstdc++-v3/include/bits/version.def9
-rw-r--r--libstdc++-v3/include/bits/version.h10
-rw-r--r--libstdc++-v3/include/std/regex1
-rw-r--r--libstdc++-v3/include/std/tuple53
-rw-r--r--libstdc++-v3/include/std/type_traits17
-rw-r--r--libstdc++-v3/src/c++23/std.cc.in4
-rw-r--r--libstdc++-v3/testsuite/17_intro/headers/c++2011/42319.cc4
-rw-r--r--libstdc++-v3/testsuite/20_util/is_implicit_lifetime/value.cc129
-rw-r--r--libstdc++-v3/testsuite/20_util/is_implicit_lifetime/version.cc27
-rw-r--r--libstdc++-v3/testsuite/20_util/tuple/requirements/empty_trivial.cc17
-rw-r--r--libstdc++-v3/testsuite/23_containers/tuple/cons/119721.cc121
-rw-r--r--libstdc++-v3/testsuite/30_threads/shared_timed_mutex/try_lock_until/116586.cc29
-rw-r--r--libstdc++-v3/testsuite/30_threads/thread/swap/1.cc2
140 files changed, 3284 insertions, 654 deletions
diff --git a/ChangeLog b/ChangeLog
index 5c42cae..3597b46 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2025-10-28 Richard Earnshaw <rearnsha@arm.com>
+
+ * .editorconfig: Explicitly set tab_width whenever a
+ config rule has indent_style = tab and indent_size != 8.
+
+2025-10-28 Artemiy Volkov <artemiy.volkov@arm.com>
+
+ * MAINTAINERS: Add myself to write after approval.
+
2025-10-27 Jennifer Schmitz <jschmitz@nvidia.com>
* MAINTAINERS: Change email address.
diff --git a/MAINTAINERS b/MAINTAINERS
index 968abe6..db64fa5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -109,6 +109,7 @@ powerpcspe port Andrew Jenner <andrew@codesourcery.com>
pru port Dimitar Dimitrov <dimitar@dinux.eu>
riscv port Kito Cheng <kito.cheng@gmail.com>
riscv port Palmer Dabbelt <palmer@dabbelt.com>
+riscv port Robin Dapp <rdapp.gcc@gmail.com>
riscv port Andrew Waterman <andrew@sifive.com>
riscv port Jim Wilson <jim.wilson.gcc@gmail.com>
rs6000/powerpc port David Edelsohn <dje.gcc@gmail.com>
@@ -317,11 +318,11 @@ Plugin Le-Chun Wu <lcwu@google.com>
register allocation Peter Bergner <bergner@tenstorrent.com>
register allocation Kenneth Zadeck <zadeck@naturalbridge.com>
register allocation Seongbae Park <seongbae.park@gmail.com>
-riscv port Robin Dapp <rdapp.gcc@gmail.com>
riscv port Juzhe Zhong <juzhe.zhong@rivai.ai>
RTL optimizers Steven Bosscher <steven@gcc.gnu.org>
selective scheduling Andrey Belevantsev <abel@ispras.ru>
selective scheduling Alexander Monakov <amonakov@ispras.ru>
+vectorizer (+ tree-if-conv) Robin Dapp <rdapp.gcc@gmail.com>
wide-int Kenneth Zadeck <zadeck@naturalbridge.com>
wide-int Mike Stump <mikestump@comcast.net>
wide-int Richard Sandiford <rdsandiford@googlemail.com>
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1ae78b4..c85ac8b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,107 @@
+2025-10-29 Jeff Law <jlaw@ventanamicro.com>
+
+ Revert:
+ 2025-10-29 Jeff Law <jlaw@ventanamicro.com>
+
+ PR target/116662
+ * config/riscv/riscv.cc (riscv_option_override): Override
+ default value for destructive interference size.
+
+2025-10-29 Jeff Law <jlaw@ventanamicro.com>
+
+ Revert:
+ 2025-10-29 Jeff Law <jlaw@ventanamicro.com>
+
+ PR target/116662
+ * config/riscv/riscv.cc (riscv_option_override): Apply correct version
+ of the patch.
+
+2025-10-29 Jeff Law <jlaw@ventanamicro.com>
+
+ PR target/116662
+ * config/riscv/riscv.cc (riscv_option_override): Apply correct version
+ of the patch.
+
+2025-10-29 Jeff Law <jlaw@ventanamicro.com>
+
+ PR target/116662
+ * config/riscv/riscv.cc (riscv_option_override): Override
+ default value for destructive interference size.
+
+2025-10-29 Andrew MacLeod <amacleod@redhat.com>
+
+ PR tree-optimization/91191
+ * gimple-range-op.cc (gimple_range_op_handler): Descend one
+ operand lower for a VIEW_CONVERT_EXPR.
+ * range-op-mixed.h (class operator_view): New.
+ * range-op.cc (range_op_table): Add VIEW_CONVERT_EXPR case.
+ (operator_view::fold_range): New.
+ (operator_view::op1_range): New.
+ (operator_view::update_bitmask): New.
+
+2025-10-29 Richard Biener <rguenther@suse.de>
+
+ * tree-vect-slp.cc (vect_analyze_slp): Mark stmts in BB roots
+ as released after vect_build_slp_instance.
+ (vect_build_slp_instance): Release scalar_stmts when exiting
+ early.
+
+2025-10-29 Lulu Cheng <chenglulu@loongson.cn>
+
+ PR target/122097
+ * config/loongarch/loongarch.cc
+ (loongarch_const_vector_bitimm_set_p): Add support for vector float.
+ (loongarch_const_vector_bitimm_clr_p): Likewise.
+ (loongarch_print_operand): Likewise.
+ * config/loongarch/simd.md (and<mode>3): Likewise.
+
+2025-10-29 Lulu Cheng <chenglulu@loongson.cn>
+
+ * config/loongarch/lasx.md (xor<mode>3): Delete.
+ (ior<mode>3): Delete.
+ (and<mode>3): Delete.
+ * config/loongarch/lsx.md (xor<mode>3): Delete.
+ (ior<mode>3): Delete.
+ (and<mode>3): Delete.
+ * config/loongarch/simd.md (xor<mode>3): Define.
+ (ior<mode>3): Likewise.
+ (and<mode>3): Likewise.
+
+2025-10-29 Xi Ruoyao <xry111@xry111.site>
+
+ * config/loongarch/genopts/loongarch.opt.in (-mbreak-code=):
+ New.
+ * config/loongarch/loongarch.opt: Regenerate.
+ * config/loongarch/loongarch.md (trap): Separate to a
+ define_insn and a define_expand which takes la_break_code.
+ * doc/invoke.texi (-mbreak-code=): Document.
+ * config/loongarch/loongarch.opt.urls: Regenerate.
+
+2025-10-28 Richard Biener <rguenther@suse.de>
+
+ * tree-vect-loop-manip.cc (vect_update_ivs_after_vectorizer):
+ Avoid explicit LOOP_VINFO_IV_EXIT reference.
+
+2025-10-28 Artemiy Volkov <artemiy.volkov@arm.com>
+
+ * match.pd: Add pattern to simplify view_convert (BIT_FIELD_REF).
+
+2025-10-28 Kito Cheng <kito.cheng@sifive.com>
+
+ * config/riscv/riscv.cc (riscv_get_vls_cc_attr): Fix error message
+ parameter order and add check_only condition. Improve diagnostic
+ message formatting with proper quoting.
+ (riscv_handle_rvv_vls_cc_attribute): Anonymize unused node parameter.
+
+2025-10-28 Avinash Jayakar <avinashd@linux.ibm.com>
+
+ PR tree-optimization/122065
+ * tree-vect-generic.cc (add_rshift): Update name and add code parameter.
+ (add_shift): Update name.
+ (expand_vector_mult): New lowering for MULT_EXPR.
+ (expand_vector_divmod): Use updated function name.
+ (expand_vector_operation): Use updated function name.
+
2025-10-27 Andrew Pinski <andrew.pinski@oss.qualcomm.com>
* expr.cc (expr_has_boolean_range): New function.
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 0bfc1e9..e82e384 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20251028
+20251030
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index bd1e2ae..fc58e04 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,129 @@
+2025-10-28 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR ada/48039
+ * sem_ch12.adb (Analyze_Subprogram_Instantiation): Call
+ Remove_Homonym to remove the enclosing package from visibility.
+
+2025-10-28 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_util.adb (Remove_Side_Effects): Use separately the Etype of
+ the expression to build new nodes and its Underlying_Type to drive
+ part of the processing.
+
+2025-10-28 Johannes Kliemann <kliemann@adacore.com>
+
+ * adaint.c: Remove __gnat_enable_signals, __gnat_disable_signals
+ and related code for QNX.
+ * libgnarl/s-taprop__qnx.adb: Disable and enable
+ signals in Ada.
+
+2025-10-28 Alexandre Oliva <oliva@adacore.com>
+
+ * sem_ch13.adb (Analyze_Aspect_Export_Import): Skip
+ Set_Is_Imported on E_Exception.
+ * sem_prag.adb (Process_Import_Or_Interface): Explain
+ why not Set_Is_Imported.
+
+2025-10-28 Denis Mazzucato <mazzucato@adacore.com>
+
+ * sem_util.adb (Collect_Primitive_Operations): Avoid setting
+ Is_Primitive for noninherited and nonoverriding subprograms not
+ declared immediately within a package specification.
+ * sem_ch13.adb (Check_Nonoverridable_Aspect_Subprograms): Better
+ error posting to allow multiple errors on same type but different
+ aggregate subprogram.
+
+2025-10-28 Ronan Desplanques <desplanques@adacore.com>
+
+ * table.ads (Clear, Is_Empty): New subprograms.
+ * table.adb (Clear, Is_Empty): Likewise.
+ (Init): Use new subprogram.
+ * atree.adb (Traverse_Func_With_Parent): Use new subprograms.
+ * fmap.adb (Empty_Tables): Use new subprogram.
+ * par_sco.adb (Process_Pending_Decisions): Likewise.
+ * sem_elab.adb (Check_Elab_Call): Likewise.
+ * sem_ch12.adb (Build_Local_Package, Analyze_Package_Instantiation,
+ Analyze_Subprogram_Instantiation): Likewise.
+ (Save_And_Reset): Use Table.Table.First.
+
+2025-10-28 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR ada/122063
+ * exp_fixd.adb (Build_Double_Divide_Code): Convert the result of the
+ multiply.
+ (Build_Multiply): Use base types of operands to size the operation.
+ (Build_Rem): Likewise.
+ (Build_Scaled_Divide_Code): Convert the result of the multiply.
+
+2025-10-28 Tonu Naks <naks@adacore.com>
+
+ * doc/gnat_rm/obsolescent_features.rst: typo
+ * gnat_rm.texi: Regenerate.
+
+2025-10-28 Javier Miranda <miranda@adacore.com>
+
+ * aspects.adb (Get_Aspect_Id): Enable aspect Unsigned_Base_Range
+ using -gnatd.u
+ * debug.adb (Debug_Flag_Dot_U): Document this switch.
+ * einfo-utils.adb (Is_Modular_Integer_Type): Return True if
+ the entity is a modular integer type and its base type does
+ not have the attribute has_unsigned_base_range_aspect.
+ (Is_Signed_Integer_Type): Return True if the entity is a signed
+ integer type, or it is a modular integer type and its base type
+ has the attribute has_unsigned_base_range_aspect.
+ * einfo.ads (E_Modular_Integer_Type): Add documentation of
+ Has_Unsigned_Base_Range_Aspect.
+ * par-ch4.adb (Scan_Apostrophe): Enable attribute Unsigned_Base_Range
+ using -gnatd.u
+ * sem_ch13.adb (Analyze_One_Aspect): Check general language
+ restrictions on aspect Unsigned_Base_Range. For Unsigned_Base_Range
+ aspect, do not delay the generation of the pragma becase we need
+ to process it before any type or subtype derivation is analyzed.
+ * sem_ch3.adb (Build_Scalar_Bound): Disable code analyzing the
+ bound with the base type of the parent type because, for unsigned
+ base range types, their base type is a modular type but their
+ type is a signed integer type.
+ * sem_prag.adb (Analyze_Pragma): Enable pragma Unsigned_Base_Range
+ using -gnatd.u. Check more errors on Unsigned_Base_Range pragma,
+ and create the new base type only when required.
+
+2025-10-28 Ronan Desplanques <desplanques@adacore.com>
+
+ * sem_ch12.adb (Build_Local_Package)
+ (Analyze_Package_Instantiation, Analyze_Subprogram_Instantiation):
+ Fix Set_Last calls.
+ (Set_Instance_Of): Use Table.Table.Append.
+ (Save_And_Reset): Remove useless call. Remove defensive code.
+ (Restore): Remove incorrect Set_Last call and adapt to
+ Set_Instance_Of change.
+
+2025-10-28 Denis Mazzucato <mazzucato@adacore.com>
+
+ * sem_prag.adb (Analyze_Pragma): Add enclosing quotation when the
+ invalid switch ends with a space.
+
+2025-10-28 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR ada/59234
+ * sem_ch12.adb (Analyze_Formal_Package_Declaration): Mark the
+ special name built for the formal in the parent of a child unit
+ as internal.
+
+2025-10-28 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR ada/34511
+ * sem_ch12.adb (Analyze_Associations): Add Parent_Installed formal
+ parameter and pass it in call to Analyze_One_Association.
+ (Analyze_One_Association): Add Parent_Installed formal parameter
+ and pass it in call to Instantiate_Formal_Subprogram.
+ (Analyze_Formal_Package_Declaration): Pass Parent_Installed in call
+ to Analyze_Associations.
+ (Analyze_Package_Instantiation): Likewise.
+ (Analyze_Subprogram_Instantiation): Likewise.
+ (Instantiate_Formal_Subprogram): Add Parent_Installed formal
+ parameter and prune references to the parent unit(s) only if
+ it is true.
+
2025-10-27 Eric Botcazou <ebotcazou@adacore.com>
PR ada/29958
diff --git a/gcc/ada/sem_ch12.adb b/gcc/ada/sem_ch12.adb
index b5c276a..deb19ee 100644
--- a/gcc/ada/sem_ch12.adb
+++ b/gcc/ada/sem_ch12.adb
@@ -6735,7 +6735,7 @@ package body Sem_Ch12 is
-- Remove package itself from visibility, so it does not
-- conflict with subprogram.
- Set_Name_Entity_Id (Chars (Pack_Id), Homonym (Pack_Id));
+ Remove_Homonym (Pack_Id);
-- Set name and scope of internal subprogram so that the proper
-- external name will be generated. The proper scope is the scope
@@ -13223,7 +13223,7 @@ package body Sem_Ch12 is
-- to capture local names that may be hidden if the generic is
-- a child unit.
- if Nkind (Actual) = N_Aggregate then
+ if Nkind (Unqualify (Actual)) = N_Aggregate then
Preanalyze_And_Resolve (Actual, Typ);
end if;
diff --git a/gcc/ada/sem_ch8.adb b/gcc/ada/sem_ch8.adb
index 86344b5..e9d00d0 100644
--- a/gcc/ada/sem_ch8.adb
+++ b/gcc/ada/sem_ch8.adb
@@ -7225,6 +7225,8 @@ package body Sem_Ch8 is
begin
while Present (Id) loop
+ -- The immediate case is when Id is an entity of the prefix
+
if Scope (Id) = P_Name then
Candidate := Id;
Is_New_Candidate := True;
@@ -7250,6 +7252,53 @@ package body Sem_Ch8 is
end if;
end if;
+ -- If the name of a generic child unit appears within an instance
+ -- of itself, then it is resolved to the renaming of the name of
+ -- the instance built in Sem_Ch12, so we get to the generic parent
+ -- through the renaming.
+
+ elsif Ekind (Id) in E_Function | E_Package | E_Procedure
+ and then Present (Renamed_Entity (Id))
+ and then Is_Generic_Instance (Renamed_Entity (Id))
+ and then In_Open_Scopes (Renamed_Entity (Id))
+ then
+ declare
+ Gen_Inst : constant Entity_Id := Renamed_Entity (Id);
+ Gen_Par : constant Entity_Id :=
+ Generic_Parent
+ (Specification (Unit_Declaration_Node (Gen_Inst)));
+
+ begin
+ -- The easy case is when Gen_Par is an entity of the prefix
+
+ if Scope (Gen_Par) = P_Name then
+ Is_New_Candidate := True;
+
+ -- Now the prefix may also be within an instance of itself,
+ -- but we do not need to go through the renaming for it, as
+ -- this was done on entry to the procedure.
+
+ elsif Is_Generic_Instance (P_Name)
+ and then In_Open_Scopes (P_Name)
+ then
+ declare
+ Gen_Par_P : constant Entity_Id :=
+ Generic_Parent
+ (Specification (Unit_Declaration_Node (P_Name)));
+
+ begin
+ if Scope (Gen_Par) = Gen_Par_P then
+ Is_New_Candidate := True;
+ else
+ Is_New_Candidate := False;
+ end if;
+ end;
+
+ else
+ Is_New_Candidate := False;
+ end if;
+ end;
+
-- Ada 2005 (AI-217): Handle shadow entities associated with
-- types declared in limited-withed nested packages. We don't need
-- to handle E_Incomplete_Subtype entities because the entities
@@ -7284,22 +7333,6 @@ package body Sem_Ch8 is
Candidate := Get_Full_View (Id);
Is_New_Candidate := True;
- -- An unusual case arises with a fully qualified name for an
- -- entity local to a generic child unit package, within an
- -- instantiation of that package. The name of the unit now
- -- denotes the renaming created within the instance. This is
- -- only relevant in an instance body, see below.
-
- elsif Is_Generic_Instance (Scope (Id))
- and then In_Open_Scopes (Scope (Id))
- and then In_Instance_Body
- and then Ekind (Scope (Id)) = E_Package
- and then Ekind (Id) = E_Package
- and then Renamed_Entity (Id) = Scope (Id)
- and then Is_Immediately_Visible (P_Name)
- then
- Is_New_Candidate := True;
-
else
Is_New_Candidate := False;
end if;
@@ -7434,55 +7467,6 @@ package body Sem_Ch8 is
end if;
else
- -- Within the instantiation of a child unit, the prefix may
- -- denote the parent instance, but the selector has the name
- -- of the original child. That is to say, when A.B appears
- -- within an instantiation of generic child unit B, the scope
- -- stack includes an instance of A (P_Name) and an instance
- -- of B under some other name. We scan the scope to find this
- -- child instance, which is the desired entity.
- -- Note that the parent may itself be a child instance, if
- -- the reference is of the form A.B.C, in which case A.B has
- -- already been rewritten with the proper entity.
-
- if In_Open_Scopes (P_Name)
- and then Is_Generic_Instance (P_Name)
- then
- declare
- Gen_Par : constant Entity_Id :=
- Generic_Parent (Specification
- (Unit_Declaration_Node (P_Name)));
- S : Entity_Id := Current_Scope;
- P : Entity_Id;
-
- begin
- for J in reverse 0 .. Scope_Stack.Last loop
- S := Scope_Stack.Table (J).Entity;
-
- exit when S = Standard_Standard;
-
- if Ekind (S) in E_Function | E_Package | E_Procedure
- then
- P :=
- Generic_Parent (Specification
- (Unit_Declaration_Node (S)));
-
- -- Check that P is a generic child of the generic
- -- parent of the prefix.
-
- if Present (P)
- and then Chars (P) = Chars (Selector)
- and then Scope (P) = Gen_Par
- then
- Id := S;
- goto Found;
- end if;
- end if;
-
- end loop;
- end;
- end if;
-
-- If this is a selection from Ada, System or Interfaces, then
-- we assume a missing with for the corresponding package.
@@ -7589,7 +7573,6 @@ package body Sem_Ch8 is
end if;
end if;
- <<Found>>
if Comes_From_Source (N)
and then Is_Remote_Access_To_Subprogram_Type (Id)
and then Ekind (Id) = E_Access_Subprogram_Type
diff --git a/gcc/ada/sem_type.adb b/gcc/ada/sem_type.adb
index 32d0833..31a2acd 100644
--- a/gcc/ada/sem_type.adb
+++ b/gcc/ada/sem_type.adb
@@ -610,14 +610,17 @@ package body Sem_Type is
First_Interp := All_Interp.Last;
Add_One_Interp (N, Ent, Etype (N));
- -- For expanded name, pick up all additional entities from the
- -- same scope, since these are obviously also visible. Note that
- -- these are not necessarily contiguous on the homonym chain.
+ -- For an expanded name, pick up additional visible entities from
+ -- the same scope. Note that these are not necessarily contiguous
+ -- on the homonym chain.
if Nkind (N) = N_Expanded_Name then
H := Homonym (Ent);
while Present (H) loop
- if Scope (H) = Scope (Entity (N)) then
+ if Scope (H) = Scope (Entity (N))
+ and then (not Is_Hidden (H)
+ or else Is_Immediately_Visible (H))
+ then
Add_One_Interp (N, H, Etype (H));
end if;
diff --git a/gcc/btfout.cc b/gcc/btfout.cc
index 5a210cd..eb794ff 100644
--- a/gcc/btfout.cc
+++ b/gcc/btfout.cc
@@ -1138,7 +1138,8 @@ btf_add_used_type_1 (ctf_container_ref ctfc, ctf_dtdef_ref dtd,
/* Try to avoid chasing pointers to struct/union types if the
underlying type isn't used. */
- if (check_ptr && seen_ptr && create_fixups)
+ if (check_ptr && seen_ptr && create_fixups
+ && kind != BTF_KIND_TYPEDEF)
{
ctf_dtdef_ref ref = dtd->ref_type;
uint32_t ref_kind = btf_dtd_kind (ref);
diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc
index 8ca767a..28a034f 100644
--- a/gcc/c-family/c-attribs.cc
+++ b/gcc/c-family/c-attribs.cc
@@ -2963,14 +2963,16 @@ handle_counted_by_attribute (tree *node, tree name,
" array member field", name);
*no_add_attrs = true;
}
- /* This attribute cannot be applied to a pointer to void type. */
+ /* This attribute can be applied to a pointer to void type, but issue
+ warning when -Wpointer-arith is presenting. */
else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
&& TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == VOID_TYPE)
{
- error_at (DECL_SOURCE_LOCATION (decl),
- "%qE attribute is not allowed for a pointer to void",
- name);
- *no_add_attrs = true;
+ if (warn_pointer_arith)
+ warning_at (DECL_SOURCE_LOCATION (decl),
+ OPT_Wpointer_arith,
+ "%qE attribute is used for a pointer to void",
+ name);
}
/* This attribute cannot be applied to a pointer to function type. */
else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 371583b..bc0fb6b 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -3179,7 +3179,10 @@ build_access_with_size_for_counted_by (location_t loc, tree ref,
tree result_type = is_fam ? c_build_pointer_type (TREE_TYPE (ref))
: TREE_TYPE (ref);
- tree element_size = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (ref)));
+ tree element_type = TREE_TYPE (TREE_TYPE (ref));
+ tree element_size = VOID_TYPE_P (element_type)
+ ? build_one_cst (size_type_node)
+ : TYPE_SIZE_UNIT (element_type);
tree first_param = is_fam
? c_fully_fold (array_to_pointer_conversion (loc, ref),
diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index d1b2e2a..ab09376 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -2220,11 +2220,7 @@ cgraph_node::release_body (bool keep_arguments)
if (!used_as_abstract_origin && DECL_INITIAL (decl))
DECL_INITIAL (decl) = error_mark_node;
release_function_body (decl);
- if (lto_file_data)
- {
- lto_free_function_in_decl_state_for_node (this);
- lto_file_data = NULL;
- }
+ lto_free_function_in_decl_state_for_node (this);
if (flag_checking && clones)
{
/* It is invalid to release body before materializing clones except
@@ -2336,10 +2332,7 @@ cgraph_node::remove (void)
release_body ();
}
else
- {
- lto_free_function_in_decl_state_for_node (this);
- lto_file_data = NULL;
- }
+ lto_free_function_in_decl_state_for_node (this);
decl = NULL;
if (call_site_hash)
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 069e007..a937d0a 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -37,10 +37,12 @@ extern void debuginfo_early_stop (void);
class ipa_opt_pass_d;
typedef ipa_opt_pass_d *ipa_opt_pass;
-/* Symbol table consists of functions and variables.
+/* Toplevel consists of functions, variables and assembly.
TODO: add labels and CONST_DECLs. */
-enum symtab_type
+enum toplevel_type
{
+ TOPLEVEL_BASE,
+ TOPLEVEL_ASM,
SYMTAB_SYMBOL,
SYMTAB_FUNCTION,
SYMTAB_VARIABLE
@@ -100,18 +102,37 @@ enum symbol_partitioning_class
SYMBOL_DUPLICATE
};
+/* Base of all toplevel entries.
+ Inherited by symtab_node and asm_node. */
+struct GTY ((desc ("%h.type"), tag ("TOPLEVEL_BASE"))) toplevel_node {
+ /* Constructor. */
+ explicit toplevel_node (toplevel_type t)
+ : lto_file_data (NULL), order (-1), type (t)
+ {}
+
+ /* File stream where this node is being written to. */
+ struct lto_file_decl_data * lto_file_data;
+
+ /* Ordering of all cgraph nodes. */
+ int order;
+
+ /* Type of the node. */
+ ENUM_BITFIELD (toplevel_type) type : 8;
+};
+
/* Base of all entries in the symbol table.
The symtab_node is inherited by cgraph and varpol nodes. */
-struct GTY((desc ("%h.type"), tag ("SYMTAB_SYMBOL"),
+struct GTY ((tag ("SYMTAB_SYMBOL"),
chain_next ("%h.next"), chain_prev ("%h.previous")))
- symtab_node
+ symtab_node: public toplevel_node
{
public:
friend class symbol_table;
/* Constructor. */
- explicit symtab_node (symtab_type t)
- : type (t), resolution (LDPR_UNKNOWN), definition (false), alias (false),
+ explicit symtab_node (toplevel_type t)
+ : toplevel_node (t),
+ resolution (LDPR_UNKNOWN), definition (false), alias (false),
transparent_alias (false), weakref (false), cpp_implicit_alias (false),
symver (false), analyzed (false), writeonly (false),
refuse_visibility_changes (false), externally_visible (false),
@@ -121,9 +142,9 @@ public:
used_from_other_partition (false), in_other_partition (false),
address_taken (false), in_init_priority_hash (false),
need_lto_streaming (false), offloadable (false), ifunc_resolver (false),
- order (-1), next_sharing_asm_name (NULL),
+ next_sharing_asm_name (NULL),
previous_sharing_asm_name (NULL), same_comdat_group (NULL), ref_list (),
- alias_target (NULL), lto_file_data (NULL), aux (NULL),
+ alias_target (NULL), aux (NULL),
x_comdat_group (NULL_TREE), x_section (NULL), m_uid (-1)
{}
@@ -498,9 +519,6 @@ public:
return m_uid;
}
- /* Type of the symbol. */
- ENUM_BITFIELD (symtab_type) type : 8;
-
/* The symbols resolution. */
ENUM_BITFIELD (ld_plugin_symbol_resolution) resolution : 8;
@@ -609,9 +627,6 @@ public:
unsigned ifunc_resolver : 1;
- /* Ordering of all symtab entries. */
- int order;
-
/* Declaration representing the symbol. */
tree decl;
@@ -642,9 +657,6 @@ public:
Once alias is resolved, this pointer become NULL. */
tree alias_target;
- /* File stream where this node is being written to. */
- struct lto_file_decl_data * lto_file_data;
-
void *GTY ((skip)) aux;
/* Comdat group the symbol is in. Can be private if GGC allowed that. */
@@ -2224,13 +2236,14 @@ private:
/* Every top level asm statement is put into a asm_node. */
-struct GTY(()) asm_node {
+struct GTY ((tag ("TOPLEVEL_ASM"))) asm_node: public toplevel_node {
+ explicit asm_node (tree asm_str)
+ : toplevel_node (TOPLEVEL_ASM), next (NULL), asm_str (asm_str)
+ {}
/* Next asm node. */
asm_node *next;
/* String for this asm node. */
tree asm_str;
- /* Ordering of all cgraph nodes. */
- int order;
};
/* Report whether or not THIS symtab node is a function, aka cgraph_node. */
@@ -2253,6 +2266,47 @@ is_a_helper <varpool_node *>::test (symtab_node *p)
return p && p->type == SYMTAB_VARIABLE;
}
+/* Report whether or not THIS toplevel node is a function, aka cgraph_node. */
+
+template <>
+template <>
+inline bool
+is_a_helper <cgraph_node *>::test (toplevel_node *p)
+{
+ return p && p->type == SYMTAB_FUNCTION;
+}
+
+/* Report whether or not THIS toplevel node is a variable, aka varpool_node. */
+
+template <>
+template <>
+inline bool
+is_a_helper <varpool_node *>::test (toplevel_node *p)
+{
+ return p && p->type == SYMTAB_VARIABLE;
+}
+
+/* Report whether or not THIS toplevel node is a symtab_node. */
+
+template <>
+template <>
+inline bool
+is_a_helper <symtab_node *>::test (toplevel_node *p)
+{
+ return p && p->type >= SYMTAB_SYMBOL;
+}
+
+/* Report whether or not THIS toplevel node is a toplevel assembly, aka
+ asm_node. */
+
+template <>
+template <>
+inline bool
+is_a_helper <asm_node *>::test (toplevel_node *p)
+{
+ return p && p->type == TOPLEVEL_ASM;
+}
+
typedef void (*cgraph_edge_hook)(cgraph_edge *, void *);
typedef void (*cgraph_node_hook)(cgraph_node *, void *);
typedef void (*varpool_node_hook)(varpool_node *, void *);
@@ -2919,10 +2973,8 @@ symbol_table::finalize_toplevel_asm (tree asm_str)
{
asm_node *node;
- node = ggc_cleared_alloc<asm_node> ();
- node->asm_str = asm_str;
+ node = new (ggc_cleared_alloc<asm_node> ()) asm_node (asm_str);
node->order = order++;
- node->next = NULL;
if (asmnodes == NULL)
asmnodes = node;
diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc
index dadcf76..ba598a8 100644
--- a/gcc/config/i386/i386-options.cc
+++ b/gcc/config/i386/i386-options.cc
@@ -2917,7 +2917,7 @@ ix86_option_override_internal (bool main_args_p,
else
{
opts->x_ix86_move_max = opts->x_prefer_vector_width_type;
- if (opts_set->x_ix86_move_max == PVW_NONE)
+ if (opts->x_ix86_move_max == PVW_NONE)
{
if (TARGET_AVX512F_P (opts->x_ix86_isa_flags))
opts->x_ix86_move_max = PVW_AVX512;
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 218377a..b812d8b 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -27353,6 +27353,72 @@
(match_dup 0))]
"peep2_reg_dead_p (2, operands[0])"
[(set (match_dup 2) (match_dup 1))])
+
+;; umax (a, add (a, b)) => [sum, ovf] = add (a, b); ovf ? a : sum
+;; umin (a, add (a, b)) => [sum, ovf] = add (a, b); ovf ? sum : a
+
+(define_code_attr ovf_add_cmp [(umax "geu") (umin "ltu")])
+
+(define_int_iterator ovf_comm [1 2])
+
+(define_insn_and_split "*plus_within_<code><mode>3_<ovf_comm>"
+ [(set (match_operand:SWI248 0 "register_operand")
+ (umaxmin:SWI248
+ (plus:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
+ (match_operand:SWI248 2 "<general_operand>"))
+ (match_dup ovf_comm)))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_CMOVE
+ && ix86_pre_reload_split ()"
+ "#"
+ "&& 1"
+ [(parallel
+ [(set (reg:CCC FLAGS_REG)
+ (compare:CCC
+ (plus:SWI248 (match_dup 1) (match_dup 2))
+ (match_dup ovf_comm)))
+ (set (match_dup 3)
+ (plus:SWI248 (match_dup 1) (match_dup 2)))])
+ (set (match_dup 0)
+ (if_then_else:SWI248
+ (<ovf_add_cmp> (reg:CCC FLAGS_REG) (const_int 0))
+ (match_dup 3)
+ (match_dup ovf_comm)))]
+{
+ operands[<ovf_comm>] = force_reg (<MODE>mode, operands[<ovf_comm>]);
+ operands[3] = gen_reg_rtx (<MODE>mode);
+})
+
+;; umax (a, sub (a, b)) => [diff, udf] = sub (a, b); udf ? diff : a
+;; umin (a, sub (a, b)) => [diff, udf] = sub (a, b); udf ? a : diff
+
+(define_code_attr udf_sub_cmp [(umax "ltu") (umin "geu")])
+
+(define_insn_and_split "*minus_within_<code><mode>3"
+ [(set (match_operand:SWI248 0 "register_operand")
+ (umaxmin:SWI248
+ (minus:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
+ (match_operand:SWI248 2 "<general_operand>"))
+ (match_dup 1)))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_CMOVE
+ && ix86_pre_reload_split ()"
+ "#"
+ "&& 1"
+ [(parallel
+ [(set (reg:CC FLAGS_REG)
+ (compare:CC (match_dup 1) (match_dup 2)))
+ (set (match_dup 3)
+ (minus:SWI248 (match_dup 1) (match_dup 2)))])
+ (set (match_dup 0)
+ (if_then_else:SWI248
+ (<udf_sub_cmp> (reg:CC FLAGS_REG) (const_int 0))
+ (match_dup 3)
+ (match_dup 1)))]
+{
+ operands[1] = force_reg (<MODE>mode, operands[1]);
+ operands[3] = gen_reg_rtx (<MODE>mode);
+})
;; Misc patterns (?)
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 5eba992..7d91585 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -643,6 +643,9 @@
(define_mode_iterator VI2_AVX512F
[(V32HI "TARGET_AVX512F") (V16HI "TARGET_AVX2") V8HI])
+(define_mode_iterator VI2_AVX10_2
+ [(V32HI "TARGET_AVX10_2") (V16HI "TARGET_AVX2") V8HI])
+
(define_mode_iterator VI2_AVX512VNNIBW
[(V32HI "TARGET_AVX512BW || TARGET_AVX512VNNI")
(V16HI "TARGET_AVX2") V8HI])
@@ -32334,8 +32337,8 @@
(define_expand "usdot_prod<sseunpackmodelower><mode>"
[(match_operand:<sseunpackmode> 0 "register_operand")
- (match_operand:VI2_AVX512F 1 "register_operand")
- (match_operand:VI2_AVX512F 2 "register_operand")
+ (match_operand:VI2_AVX10_2 1 "register_operand")
+ (match_operand:VI2_AVX10_2 2 "register_operand")
(match_operand:<sseunpackmode> 3 "register_operand")]
"TARGET_AVXVNNIINT16 || TARGET_AVX10_2"
{
@@ -32352,8 +32355,8 @@
(define_expand "udot_prod<sseunpackmodelower><mode>"
[(match_operand:<sseunpackmode> 0 "register_operand")
- (match_operand:VI2_AVX512F 1 "register_operand")
- (match_operand:VI2_AVX512F 2 "register_operand")
+ (match_operand:VI2_AVX10_2 1 "register_operand")
+ (match_operand:VI2_AVX10_2 2 "register_operand")
(match_operand:<sseunpackmode> 3 "register_operand")]
"TARGET_AVXVNNIINT16 || TARGET_AVX10_2"
{
diff --git a/gcc/config/loongarch/genopts/loongarch.opt.in b/gcc/config/loongarch/genopts/loongarch.opt.in
index 39c1545..f0c089a 100644
--- a/gcc/config/loongarch/genopts/loongarch.opt.in
+++ b/gcc/config/loongarch/genopts/loongarch.opt.in
@@ -205,6 +205,10 @@ mmax-inline-memcpy-size=
Target Joined RejectNegative UInteger Var(la_max_inline_memcpy_size) Init(1024) Save
-mmax-inline-memcpy-size=SIZE Set the max size of memcpy to inline, default is 1024.
+mbreak-code=
+Target Joined UInteger Var(la_break_code) Init(-1) Save
+-mbreak-code=CODE Use 'break CODE' for traps supposed to be unrecoverable, or an 'amswap.w' instruction leading to INE if CODE is out of range.
+
Enum
Name(explicit_relocs) Type(int)
The code model option names for -mexplicit-relocs:
diff --git a/gcc/config/loongarch/lasx.md b/gcc/config/loongarch/lasx.md
index eed4d2b..c4186b0 100644
--- a/gcc/config/loongarch/lasx.md
+++ b/gcc/config/loongarch/lasx.md
@@ -834,59 +834,6 @@
[(set_attr "type" "simd_div")
(set_attr "mode" "<MODE>")])
-(define_insn "xor<mode>3"
- [(set (match_operand:LASX 0 "register_operand" "=f,f,f")
- (xor:LASX
- (match_operand:LASX 1 "register_operand" "f,f,f")
- (match_operand:LASX 2 "reg_or_vector_same_val_operand" "f,YC,Urv8")))]
- "ISA_HAS_LASX"
- "@
- xvxor.v\t%u0,%u1,%u2
- xvbitrevi.%v0\t%u0,%u1,%V2
- xvxori.b\t%u0,%u1,%B2"
- [(set_attr "type" "simd_logic,simd_bit,simd_logic")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "ior<mode>3"
- [(set (match_operand:LASX 0 "register_operand" "=f,f,f")
- (ior:LASX
- (match_operand:LASX 1 "register_operand" "f,f,f")
- (match_operand:LASX 2 "reg_or_vector_same_val_operand" "f,YC,Urv8")))]
- "ISA_HAS_LASX"
- "@
- xvor.v\t%u0,%u1,%u2
- xvbitseti.%v0\t%u0,%u1,%V2
- xvori.b\t%u0,%u1,%B2"
- [(set_attr "type" "simd_logic,simd_bit,simd_logic")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "and<mode>3"
- [(set (match_operand:LASX 0 "register_operand" "=f,f,f")
- (and:LASX
- (match_operand:LASX 1 "register_operand" "f,f,f")
- (match_operand:LASX 2 "reg_or_vector_same_val_operand" "f,YZ,Urv8")))]
- "ISA_HAS_LASX"
-{
- switch (which_alternative)
- {
- case 0:
- return "xvand.v\t%u0,%u1,%u2";
- case 1:
- {
- rtx elt0 = CONST_VECTOR_ELT (operands[2], 0);
- unsigned HOST_WIDE_INT val = ~UINTVAL (elt0);
- operands[2] = loongarch_gen_const_int_vector (<MODE>mode, val & (-val));
- return "xvbitclri.%v0\t%u0,%u1,%V2";
- }
- case 2:
- return "xvandi.b\t%u0,%u1,%B2";
- default:
- gcc_unreachable ();
- }
-}
- [(set_attr "type" "simd_logic,simd_bit,simd_logic")
- (set_attr "mode" "<MODE>")])
-
(define_insn "one_cmpl<mode>2"
[(set (match_operand:ILASX 0 "register_operand" "=f")
(not:ILASX (match_operand:ILASX 1 "register_operand" "f")))]
@@ -1035,16 +982,6 @@
[(set_attr "type" "simd_fmadd")
(set_attr "mode" "<MODE>")])
-(define_insn "fnma<mode>4"
- [(set (match_operand:FLASX 0 "register_operand" "=f")
- (fma:FLASX (neg:FLASX (match_operand:FLASX 1 "register_operand" "f"))
- (match_operand:FLASX 2 "register_operand" "f")
- (match_operand:FLASX 3 "register_operand" "0")))]
- "ISA_HAS_LASX"
- "xvfnmsub.<flasxfmt>\t%u0,%u1,%u2,%u0"
- [(set_attr "type" "simd_fmadd")
- (set_attr "mode" "<MODE>")])
-
(define_expand "sqrt<mode>2"
[(set (match_operand:FLASX 0 "register_operand")
(sqrt:FLASX (match_operand:FLASX 1 "register_operand")))]
diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc
index 5c2a9eb..740c861 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -1718,14 +1718,36 @@ loongarch_symbol_binds_local_p (const_rtx x)
bool
loongarch_const_vector_bitimm_set_p (rtx op, machine_mode mode)
{
- if (GET_CODE (op) == CONST_VECTOR && op != CONST0_RTX (mode))
+ if (GET_CODE (op) == CONST_VECTOR
+ && (GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT
+ || GET_MODE_CLASS (mode) == MODE_VECTOR_INT))
{
- unsigned HOST_WIDE_INT val = UINTVAL (CONST_VECTOR_ELT (op, 0));
+ unsigned HOST_WIDE_INT val;
+
+ if (GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)
+ {
+ rtx val_s = CONST_VECTOR_ELT (op, 0);
+ const REAL_VALUE_TYPE *x = CONST_DOUBLE_REAL_VALUE (val_s);
+ if (GET_MODE (val_s) == DFmode)
+ {
+ long tmp[2];
+ REAL_VALUE_TO_TARGET_DOUBLE (*x, tmp);
+ val = (unsigned HOST_WIDE_INT) tmp[1] << 32 | tmp[0];
+ }
+ else
+ {
+ long tmp;
+ REAL_VALUE_TO_TARGET_SINGLE (*x, tmp);
+ val = (unsigned HOST_WIDE_INT) tmp;
+ }
+ }
+ else
+ val = UINTVAL (CONST_VECTOR_ELT (op, 0));
+
int vlog2 = exact_log2 (val & GET_MODE_MASK (GET_MODE_INNER (mode)));
if (vlog2 != -1)
{
- gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
gcc_assert (vlog2 >= 0 && vlog2 <= GET_MODE_UNIT_BITSIZE (mode) - 1);
return loongarch_const_vector_same_val_p (op, mode);
}
@@ -1740,14 +1762,35 @@ loongarch_const_vector_bitimm_set_p (rtx op, machine_mode mode)
bool
loongarch_const_vector_bitimm_clr_p (rtx op, machine_mode mode)
{
- if (GET_CODE (op) == CONST_VECTOR && op != CONSTM1_RTX (mode))
+ if (GET_CODE (op) == CONST_VECTOR
+ && (GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT
+ || GET_MODE_CLASS (mode) == MODE_VECTOR_INT))
{
- unsigned HOST_WIDE_INT val = ~UINTVAL (CONST_VECTOR_ELT (op, 0));
+ unsigned HOST_WIDE_INT val;
+ if (GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)
+ {
+ rtx val_s = CONST_VECTOR_ELT (op, 0);
+ const REAL_VALUE_TYPE *x = CONST_DOUBLE_REAL_VALUE (val_s);
+ if (GET_MODE (val_s) == DFmode)
+ {
+ long tmp[2];
+ REAL_VALUE_TO_TARGET_DOUBLE (*x, tmp);
+ val = ~((unsigned HOST_WIDE_INT) tmp[1] << 32 | tmp[0]);
+ }
+ else
+ {
+ long tmp;
+ REAL_VALUE_TO_TARGET_SINGLE (*x, tmp);
+ val = ~((unsigned HOST_WIDE_INT) tmp);
+ }
+ }
+ else
+ val = ~UINTVAL (CONST_VECTOR_ELT (op, 0));
+
int vlog2 = exact_log2 (val & GET_MODE_MASK (GET_MODE_INNER (mode)));
if (vlog2 != -1)
{
- gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
gcc_assert (vlog2 >= 0 && vlog2 <= GET_MODE_UNIT_BITSIZE (mode) - 1);
return loongarch_const_vector_same_val_p (op, mode);
}
@@ -5490,12 +5533,32 @@ loongarch_expand_conditional_move (rtx *operands)
}
}
+ auto is_binary_op_0_keep_orig = [](enum rtx_code code)
+ {
+ switch (code)
+ {
+ case PLUS:
+ case MINUS:
+ case IOR:
+ case XOR:
+ case ROTATE:
+ case ROTATERT:
+ case ASHIFT:
+ case ASHIFTRT:
+ case LSHIFTRT:
+ return true;
+ default:
+ return false;
+ }
+ };
+
/* Check if the optimization conditions are met. */
if (value_if_true_insn
&& value_if_false_insn
- /* Make sure that value_if_false and var are the same. */
- && BINARY_P (value_if_true_insn_src
- = SET_SRC (single_set (value_if_true_insn)))
+ /* Make sure that the orig value OP 0 keep orig. */
+ && (value_if_true_insn_src
+ = SET_SRC (single_set (value_if_true_insn)))
+ && is_binary_op_0_keep_orig ( GET_CODE (value_if_true_insn_src))
/* Make sure that both value_if_true and value_if_false
has the same var. */
&& rtx_equal_p (XEXP (value_if_true_insn_src, 0),
@@ -6450,7 +6513,28 @@ loongarch_print_operand (FILE *file, rtx op, int letter)
if (CONST_VECTOR_P (op))
{
machine_mode mode = GET_MODE_INNER (GET_MODE (op));
- unsigned HOST_WIDE_INT val = UINTVAL (CONST_VECTOR_ELT (op, 0));
+ rtx val_s = CONST_VECTOR_ELT (op, 0);
+ unsigned HOST_WIDE_INT val;
+
+ if (GET_MODE_CLASS (mode) == MODE_FLOAT)
+ {
+ const REAL_VALUE_TYPE *x = CONST_DOUBLE_REAL_VALUE (val_s);
+ if (GET_MODE (val_s) == DFmode)
+ {
+ long tmp[2];
+ REAL_VALUE_TO_TARGET_DOUBLE (*x, tmp);
+ val = (unsigned HOST_WIDE_INT) (tmp[1] << 32 | tmp[0]);
+ }
+ else
+ {
+ long tmp;
+ REAL_VALUE_TO_TARGET_SINGLE (*x, tmp);
+ val = (unsigned HOST_WIDE_INT) tmp;
+ }
+ }
+ else
+ val = UINTVAL (val_s);
+
int vlog2 = exact_log2 (val & GET_MODE_MASK (mode));
if (vlog2 != -1)
fprintf (file, "%d", vlog2);
diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md
index be9a235..625f30c 100644
--- a/gcc/config/loongarch/loongarch.md
+++ b/gcc/config/loongarch/loongarch.md
@@ -679,14 +679,22 @@
;; ....................
;;
-(define_insn "trap"
- [(trap_if (const_int 1) (const_int 0))]
+(define_insn "*trap"
+ [(trap_if (const_int 1) (match_operand 0 "const_int_operand"))]
""
{
- return "break\t0";
+ return (const_uimm15_operand (operands[0], VOIDmode)
+ ? "break\t%0"
+ : "amswap.w\t$r0,$r1,$r0");
}
[(set_attr "type" "trap")])
+(define_expand "trap"
+ [(trap_if (const_int 1) (match_dup 0))]
+ ""
+{
+ operands[0] = GEN_INT (la_break_code);
+})
;;
diff --git a/gcc/config/loongarch/loongarch.opt b/gcc/config/loongarch/loongarch.opt
index fbe61c0..628eabe 100644
--- a/gcc/config/loongarch/loongarch.opt
+++ b/gcc/config/loongarch/loongarch.opt
@@ -213,6 +213,10 @@ mmax-inline-memcpy-size=
Target Joined RejectNegative UInteger Var(la_max_inline_memcpy_size) Init(1024) Save
-mmax-inline-memcpy-size=SIZE Set the max size of memcpy to inline, default is 1024.
+mbreak-code=
+Target Joined UInteger Var(la_break_code) Init(-1) Save
+-mbreak-code=CODE Use 'break CODE' for traps supposed to be unrecoverable, or an 'amswap.w' instruction leading to INE if CODE is out of range.
+
Enum
Name(explicit_relocs) Type(int)
The code model option names for -mexplicit-relocs:
diff --git a/gcc/config/loongarch/loongarch.opt.urls b/gcc/config/loongarch/loongarch.opt.urls
index 606a211..c93f046 100644
--- a/gcc/config/loongarch/loongarch.opt.urls
+++ b/gcc/config/loongarch/loongarch.opt.urls
@@ -48,6 +48,9 @@ UrlSuffix(gcc/LoongArch-Options.html#index-mstrict-align-1)
mmax-inline-memcpy-size=
UrlSuffix(gcc/LoongArch-Options.html#index-mmax-inline-memcpy-size)
+mbreak-code=
+UrlSuffix(gcc/LoongArch-Options.html#index-mbreak-code)
+
mexplicit-relocs=
UrlSuffix(gcc/LoongArch-Options.html#index-mexplicit-relocs-1)
diff --git a/gcc/config/loongarch/lsx.md b/gcc/config/loongarch/lsx.md
index fb0236b..5424b47 100644
--- a/gcc/config/loongarch/lsx.md
+++ b/gcc/config/loongarch/lsx.md
@@ -654,59 +654,6 @@
[(set_attr "type" "simd_div")
(set_attr "mode" "<MODE>")])
-(define_insn "xor<mode>3"
- [(set (match_operand:LSX 0 "register_operand" "=f,f,f")
- (xor:LSX
- (match_operand:LSX 1 "register_operand" "f,f,f")
- (match_operand:LSX 2 "reg_or_vector_same_val_operand" "f,YC,Urv8")))]
- "ISA_HAS_LSX"
- "@
- vxor.v\t%w0,%w1,%w2
- vbitrevi.%v0\t%w0,%w1,%V2
- vxori.b\t%w0,%w1,%B2"
- [(set_attr "type" "simd_logic,simd_bit,simd_logic")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "ior<mode>3"
- [(set (match_operand:LSX 0 "register_operand" "=f,f,f")
- (ior:LSX
- (match_operand:LSX 1 "register_operand" "f,f,f")
- (match_operand:LSX 2 "reg_or_vector_same_val_operand" "f,YC,Urv8")))]
- "ISA_HAS_LSX"
- "@
- vor.v\t%w0,%w1,%w2
- vbitseti.%v0\t%w0,%w1,%V2
- vori.b\t%w0,%w1,%B2"
- [(set_attr "type" "simd_logic,simd_bit,simd_logic")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "and<mode>3"
- [(set (match_operand:LSX 0 "register_operand" "=f,f,f")
- (and:LSX
- (match_operand:LSX 1 "register_operand" "f,f,f")
- (match_operand:LSX 2 "reg_or_vector_same_val_operand" "f,YZ,Urv8")))]
- "ISA_HAS_LSX"
-{
- switch (which_alternative)
- {
- case 0:
- return "vand.v\t%w0,%w1,%w2";
- case 1:
- {
- rtx elt0 = CONST_VECTOR_ELT (operands[2], 0);
- unsigned HOST_WIDE_INT val = ~UINTVAL (elt0);
- operands[2] = loongarch_gen_const_int_vector (<MODE>mode, val & (-val));
- return "vbitclri.%v0\t%w0,%w1,%V2";
- }
- case 2:
- return "vandi.b\t%w0,%w1,%B2";
- default:
- gcc_unreachable ();
- }
-}
- [(set_attr "type" "simd_logic,simd_bit,simd_logic")
- (set_attr "mode" "<MODE>")])
-
(define_insn "one_cmpl<mode>2"
[(set (match_operand:ILSX 0 "register_operand" "=f")
(not:ILSX (match_operand:ILSX 1 "register_operand" "f")))]
@@ -852,16 +799,6 @@
[(set_attr "type" "simd_fmadd")
(set_attr "mode" "<MODE>")])
-(define_insn "fnma<mode>4"
- [(set (match_operand:FLSX 0 "register_operand" "=f")
- (fma:FLSX (neg:FLSX (match_operand:FLSX 1 "register_operand" "f"))
- (match_operand:FLSX 2 "register_operand" "f")
- (match_operand:FLSX 3 "register_operand" "0")))]
- "ISA_HAS_LSX"
- "vfnmsub.<flsxfmt>\t%w0,%w1,%w2,%w0"
- [(set_attr "type" "simd_fmadd")
- (set_attr "mode" "<MODE>")])
-
(define_expand "sqrt<mode>2"
[(set (match_operand:FLSX 0 "register_operand")
(sqrt:FLSX (match_operand:FLSX 1 "register_operand")))]
diff --git a/gcc/config/loongarch/simd.md b/gcc/config/loongarch/simd.md
index 4156b26..fb20935 100644
--- a/gcc/config/loongarch/simd.md
+++ b/gcc/config/loongarch/simd.md
@@ -431,6 +431,17 @@
[(set_attr "type" "simd_int_arith")
(set_attr "mode" "<MODE>")])
+;; <x>vfnmsub.{s/d}
+(define_insn "fnma<mode>4"
+ [(set (match_operand:FVEC 0 "register_operand" "=f")
+ (fma:FVEC (neg:FVEC (match_operand:FVEC 1 "register_operand" "f"))
+ (match_operand:FVEC 2 "register_operand" "f")
+ (match_operand:FVEC 3 "register_operand" "f")))]
+ "!HONOR_SIGNED_ZEROS (<MODE>mode)"
+ "<x>vfnmsub.<simdfmt>\t%<wu>0,%<wu>1,%<wu>2,%<wu>3"
+ [(set_attr "type" "simd_fmadd")
+ (set_attr "mode" "<MODE>")])
+
;; <x>vfcmp.*.{s/d} with defined RTX code
;; There are no fcmp.{sugt/suge/cgt/cge}.{s/d} menmonics in GAS, so we have
;; to reverse the operands ourselves :(.
@@ -972,6 +983,77 @@
DONE;
})
+(define_insn "xor<mode>3"
+ [(set (match_operand:ALLVEC 0 "register_operand" "=f,f,f")
+ (xor:ALLVEC
+ (match_operand:ALLVEC 1 "register_operand" "f,f,f")
+ (match_operand:ALLVEC 2 "reg_or_vector_same_val_operand" "f,YC,Urv8")))]
+ ""
+ "@
+ <x>vxor.v\t%<wu>0,%<wu>1,%<wu>2
+ <x>vbitrevi.%v0\t%<wu>0,%<wu>1,%V2
+ <x>vxori.b\t%<wu>0,%<wu>1,%B2"
+ [(set_attr "type" "simd_logic,simd_bit,simd_logic")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "ior<mode>3"
+ [(set (match_operand:ALLVEC 0 "register_operand" "=f,f,f")
+ (ior:ALLVEC
+ (match_operand:ALLVEC 1 "register_operand" "f,f,f")
+ (match_operand:ALLVEC 2 "reg_or_vector_same_val_operand" "f,YC,Urv8")))]
+ ""
+ "@
+ <x>vor.v\t%<wu>0,%<wu>1,%<wu>2
+ <x>vbitseti.%v0\t%<wu>0,%<wu>1,%V2
+ <x>vori.b\t%<wu>0,%<wu>1,%B2"
+ [(set_attr "type" "simd_logic,simd_bit,simd_logic")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "and<mode>3"
+ [(set (match_operand:ALLVEC 0 "register_operand" "=f,f,f")
+ (and:ALLVEC
+ (match_operand:ALLVEC 1 "register_operand" "f,f,f")
+ (match_operand:ALLVEC 2 "reg_or_vector_same_val_operand" "f,YZ,Urv8")))]
+ ""
+{
+ switch (which_alternative)
+ {
+ case 0:
+ return "<x>vand.v\t%<wu>0,%<wu>1,%<wu>2";
+ case 1:
+ {
+ rtx elt0 = CONST_VECTOR_ELT (operands[2], 0);
+ unsigned HOST_WIDE_INT val;
+ if (GET_MODE_CLASS (<MODE>mode) == MODE_VECTOR_FLOAT)
+ {
+ const REAL_VALUE_TYPE *x = CONST_DOUBLE_REAL_VALUE (elt0);
+ if (GET_MODE (elt0) == DFmode)
+ {
+ long tmp[2];
+ REAL_VALUE_TO_TARGET_DOUBLE (*x, tmp);
+ val = ~((unsigned HOST_WIDE_INT) tmp[1] << 32 | tmp[0]);
+ }
+ else
+ {
+ long tmp;
+ REAL_VALUE_TO_TARGET_SINGLE (*x, tmp);
+ val = ~((unsigned HOST_WIDE_INT) tmp);
+ }
+ }
+ else
+ val = ~UINTVAL (elt0);
+ operands[2] = loongarch_gen_const_int_vector (<VIMODE>mode, val & (-val));
+ return "<x>vbitclri.%v0\t%<wu>0,%<wu>1,%V2";
+ }
+ case 2:
+ return "<x>vandi.b\t%<wu>0,%<wu>1,%B2";
+ default:
+ gcc_unreachable ();
+ }
+}
+ [(set_attr "type" "simd_logic,simd_bit,simd_logic")
+ (set_attr "mode" "<MODE>")])
+
; The LoongArch SX Instructions.
(include "lsx.md")
diff --git a/gcc/config/riscv/riscv-avlprop.cc b/gcc/config/riscv/riscv-avlprop.cc
index b8547a7..a42764e 100644
--- a/gcc/config/riscv/riscv-avlprop.cc
+++ b/gcc/config/riscv/riscv-avlprop.cc
@@ -77,6 +77,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-pass.h"
#include "df.h"
#include "rtl-ssa.h"
+#include "rtl-iter.h"
#include "cfgcleanup.h"
#include "insn-attr.h"
#include "tm-constrs.h"
@@ -412,6 +413,46 @@ pass_avlprop::get_vlmax_ta_preferred_avl (insn_info *insn) const
&& def1->insn ()->compare_with (insn) >= 0)
return NULL_RTX;
}
+ else
+ {
+ /* If the use is in a subreg e.g. in a store it is possible that
+ we punned the vector mode with a larger mode like
+ (subreg:V1SI (reg:V4QI 123)).
+ For an AVL of 1 that means we actually store one SImode
+ element and not 1 QImode elements. But the latter is what we
+ would propagate if we took the AVL operand literally.
+ Instead we scale it by the ratio of inner and outer mode
+ (4 in the example above). */
+ int factor = 1;
+ if (use->includes_subregs ())
+ {
+ subrtx_iterator::array_type array;
+ FOR_EACH_SUBRTX (iter, array, use_insn->rtl (), NONCONST)
+ {
+ const_rtx x = *iter;
+ if (x
+ && SUBREG_P (x)
+ && REG_P (SUBREG_REG (x))
+ && REGNO (SUBREG_REG (x)) == use->regno ()
+ && known_eq (GET_MODE_SIZE (use->mode ()),
+ GET_MODE_SIZE (GET_MODE (x))))
+ {
+ if (can_div_trunc_p (GET_MODE_NUNITS (use->mode ()),
+ GET_MODE_NUNITS (GET_MODE (x)),
+ &factor))
+ {
+ gcc_assert (factor > 0);
+ break;
+ }
+ else
+ return NULL_RTX;
+ }
+ }
+ }
+
+ if (factor > 1)
+ new_use_avl = GEN_INT (INTVAL (new_use_avl) * factor);
+ }
if (!use_avl)
use_avl = new_use_avl;
diff --git a/gcc/coretypes.h b/gcc/coretypes.h
index 8c3633b..779abb9 100644
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -147,12 +147,14 @@ using dw_cfi_ref = struct dw_cfi_node *;
enum dw_cfi_oprnd_type: int;
enum dwarf_call_frame_info: int;
-/* Subclasses of symtab_node, using indentation to show the class
+/* Subclasses of toplevel_node, using indentation to show the class
hierarchy. */
-struct symtab_node;
- struct cgraph_node;
- struct varpool_node;
+struct toplevel_node;
+ struct asm_node;
+ struct symtab_node;
+ struct cgraph_node;
+ struct varpool_node;
struct cgraph_edge;
union section;
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index e03b69c..ae4581a 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2025-10-28 Marek Polacek <polacek@redhat.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ * decl.cc (finish_enum_value_list): Use fold_convert instead of
+ copy_node.
+
2025-10-27 Nathaniel Shead <nathanieloshead@gmail.com>
PR c++/122422
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index e2c20a3..751ba40 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -18958,13 +18958,9 @@ finish_enum_value_list (tree enumtype)
value = perform_implicit_conversion (underlying_type,
DECL_INITIAL (decl),
tf_warning_or_error);
- /* Do not clobber shared ints. */
- if (value != error_mark_node)
- {
- value = copy_node (value);
+ /* Do not clobber shared ints. But do share identical enumerators. */
+ value = fold_convert (enumtype, value);
- TREE_TYPE (value) = enumtype;
- }
DECL_INITIAL (decl) = value;
if (export_p)
DECL_MODULE_EXPORT_P (decl) = true;
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 882c082..8aaedae 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -7311,11 +7311,16 @@ the attribute.
When the field that represents the number of the elements is assigned a
negative integer value, the compiler treats the value as zero.
-The @code{counted_by} attribute is not allowed for a pointer to @code{void},
-a pointer to function, or a pointer to a structure or union that includes
-a flexible array member. However, it is allowed for a pointer to
-non-void incomplete structure or union types, as long as the type could
-be completed before the first reference to the pointer.
+The @code{counted_by} attribute is not allowed for a pointer to function,
+or a pointer to a structure or union that includes a flexible array member.
+However, it is allowed for a pointer to non-void incomplete structure
+or union types, as long as the type could be completed before the first
+reference to the pointer.
+
+The attribute is allowed for a pointer to @code{void}. However,
+warnings will be issued for such cases when @option{-Wpointer-arith} is
+specified. When this attribute is applied on a pointer to @code{void},
+the size of each element of this pointer array is treated as 1.
An explicit @code{counted_by} annotation defines a relationship between
two objects, @code{p->array} and @code{p->count}, and there are the
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index b40fc89..32b9c48 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -1097,7 +1097,7 @@ Objective-C and Objective-C++ Dialects}.
-mfpu=@var{fpu-type} -msimd=@var{simd-type}
-msoft-float -msingle-float -mdouble-float -mlsx -mno-lsx -mlasx -mno-lasx
-mbranch-cost=@var{n} -maddr-reg-reg-cost=@var{n} -mcheck-zero-division
--mno-check-zero-division
+-mno-check-zero-division -mbreak-code=@var{code}
-mcond-move-int -mno-cond-move-int
-mcond-move-float -mno-cond-move-float
-memcpy -mno-memcpy -mstrict-align -mno-strict-align -G @var{num}
@@ -28457,6 +28457,17 @@ Trap (do not trap) on integer division by zero. The default is
@option{-mcheck-zero-division} for @option{-O0} or @option{-Og}, and
@option{-mno-check-zero-division} for other optimization levels.
+@opindex mbreak-code
+@item -mbreak-code=@var{code}
+Emit a @code{break} @var{code} instruction for irrecoverable traps
+from @code{__builtin_trap} or inserted by the compiler (for example
+an erroneous path isolated with
+@option{-fisolate-erroneous-paths-dereference}), or an
+@code{amswap.w $r0, $r1, $r0} instruction which will cause the hardware
+to trigger an Instruction Not-defined Exception if @var{code} is negative
+or greater than 32767. The default is -1, meaning to use the
+@code{amswap.w} instruction.
+
@opindex mcond-move-int
@item -mcond-move-int
@itemx -mno-cond-move-int
diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc
index a817c69..ac39cf5 100644
--- a/gcc/dwarf2out.cc
+++ b/gcc/dwarf2out.cc
@@ -13842,14 +13842,14 @@ gen_btf_tag_dies (tree attr, dw_die_ref die)
if (die)
{
- /* Add AT_GNU_annotation referring to the annotation DIE.
- It may have already been added, some global declarations are processed
- twice, but if so it must be the same or we have a bug. */
- dw_die_ref existing = get_AT_ref (die, DW_AT_GNU_annotation);
- if (existing)
- gcc_checking_assert (existing == tag_die);
- else
- add_AT_die_ref (die, DW_AT_GNU_annotation, tag_die);
+ /* Add (or replace) AT_GNU_annotation referring to the annotation DIE.
+ Replacement may happen for example when 'die' is a global variable
+ which has been re-declared multiple times. In any case, the set of
+ input attributes is the one that ought to be reflected. For global
+ variable re-declarations which add additional decl tags, they will
+ have been accumulated in the variable's DECL_ATTRIBUTES for us. */
+ remove_AT (die, DW_AT_GNU_annotation);
+ add_AT_die_ref (die, DW_AT_GNU_annotation, tag_die);
}
return tag_die;
diff --git a/gcc/fold-const-call.cc b/gcc/fold-const-call.cc
index 439bf80..89c1c28 100644
--- a/gcc/fold-const-call.cc
+++ b/gcc/fold-const-call.cc
@@ -1440,6 +1440,25 @@ fold_const_fold_left (tree type, tree arg0, tree arg1, tree_code code)
return arg0;
}
+/* Fold a call to IFN_VEC_SHL_INSERT (ARG0, ARG1), returning a value
+ of type TYPE. */
+
+static tree
+fold_const_vec_shl_insert (tree, tree arg0, tree arg1)
+{
+ if (TREE_CODE (arg0) != VECTOR_CST)
+ return NULL_TREE;
+
+ /* vec_shl_insert ( dup(CST), CST) -> dup (CST). */
+ if (tree elem = uniform_vector_p (arg0))
+ {
+ if (operand_equal_p (elem, arg1))
+ return arg0;
+ }
+
+ return NULL_TREE;
+}
+
/* Try to evaluate:
*RESULT = FN (*ARG0, *ARG1)
@@ -1843,6 +1862,9 @@ fold_const_call (combined_fn fn, tree type, tree arg0, tree arg1)
case CFN_FOLD_LEFT_PLUS:
return fold_const_fold_left (type, arg0, arg1, PLUS_EXPR);
+ case CFN_VEC_SHL_INSERT:
+ return fold_const_vec_shl_insert (type, arg0, arg1);
+
case CFN_UBSAN_CHECK_ADD:
case CFN_ADD_OVERFLOW:
subcode = PLUS_EXPR;
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index c0a5710..bf828fe 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,37 @@
+2025-10-29 Yuao Ma <c8ef@outlook.com>
+
+ * trans-expr.cc (gfc_conv_gfc_desc_to_cfi_desc): Remove unreachable
+ code.
+
+2025-10-29 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/122165
+ * primary.cc (gfc_match_varspec): If the previous component ref
+ was a type specification parameter, a type inquiry ref cannot
+ follow.
+
+2025-10-29 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/122433
+ PR fortran/122434
+ * decl.cc (gfc_get_pdt_instance): Prevent a PDT component of
+ the same type as the template from being converted into an
+ instance.
+ * resolve.cc (gfc_impure_variable): The result of a pure
+ function is a valid allocate object since it is pure.
+
+2025-10-28 Yuao Ma <c8ef@outlook.com>
+
+ PR fortran/122342
+ * trans-const.cc (gfc_conv_constant): Create a variable for the
+ non-char pointer.
+
+2025-10-28 Paul-Antoine Arras <parras@baylibre.com>
+
+ PR fortran/122439
+ * openmp.cc (gfc_resolve_omp_context_selector): Skip selectors that have
+ OMP_TRAIT_INVALID.
+
2025-10-27 Paul Thomas <pault@gcc.gnu.org>
PR fortran/922290
diff --git a/gcc/fortran/decl.cc b/gcc/fortran/decl.cc
index 569786a..5b222cd 100644
--- a/gcc/fortran/decl.cc
+++ b/gcc/fortran/decl.cc
@@ -3938,6 +3938,20 @@ gfc_get_pdt_instance (gfc_actual_arglist *param_list, gfc_symbol **sym,
actual_param = param_list;
sprintf (name, "Pdt%s", pdt->name);
+ /* Prevent a PDT component of the same type as the template from being
+ converted into an instance. Doing this results in the component being
+ lost. */
+ if (gfc_current_state () == COMP_DERIVED
+ && !(gfc_state_stack->previous
+ && gfc_state_stack->previous->state == COMP_DERIVED)
+ && gfc_current_block ()->attr.pdt_template
+ && !strcmp (gfc_current_block ()->name, (*sym)->name))
+ {
+ if (ext_param_list)
+ *ext_param_list = gfc_copy_actual_arglist (param_list);
+ return MATCH_YES;
+ }
+
/* Run through the parameter name list and pick up the actual
parameter values or use the default values in the PDT declaration. */
for (; type_param_name_list;
diff --git a/gcc/fortran/primary.cc b/gcc/fortran/primary.cc
index 2d2c664..0722c76d 100644
--- a/gcc/fortran/primary.cc
+++ b/gcc/fortran/primary.cc
@@ -2690,6 +2690,14 @@ gfc_match_varspec (gfc_expr *primary, int equiv_flag, bool sub_flag,
else
component = NULL;
+ if (previous && inquiry
+ && (previous->attr.pdt_kind || previous->attr.pdt_len))
+ {
+ gfc_error_now ("R901: A type parameter ref is not a designtor and "
+ "cannot be followed by the type inquiry ref at %C");
+ return MATCH_ERROR;
+ }
+
if (intrinsic && !inquiry)
{
if (previous)
diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
index 117a51c..ecd2ada 100644
--- a/gcc/fortran/resolve.cc
+++ b/gcc/fortran/resolve.cc
@@ -18956,7 +18956,8 @@ gfc_impure_variable (gfc_symbol *sym)
{
if (ns == sym->ns)
break;
- if (ns->proc_name->attr.flavor == FL_PROCEDURE && !sym->attr.function)
+ if (ns->proc_name->attr.flavor == FL_PROCEDURE
+ && !(sym->attr.function || sym->attr.result))
return 1;
}
diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index e2b17a7..cb40816 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -268,13 +268,7 @@ gfc_conv_descriptor_data_get (tree desc)
return fold_convert (GFC_TYPE_ARRAY_DATAPTR_TYPE (type), field);
}
-/* This provides WRITE access to the data field.
-
- TUPLES_P is true if we are generating tuples.
-
- This function gets called through the following macros:
- gfc_conv_descriptor_data_set
- gfc_conv_descriptor_data_set. */
+/* This provides WRITE access to the data field. */
void
gfc_conv_descriptor_data_set (stmtblock_t *block, tree desc, tree value)
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index 67b60c7..2e88e65 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -6090,9 +6090,6 @@ gfc_conv_gfc_desc_to_cfi_desc (gfc_se *parmse, gfc_expr *e, gfc_symbol *fsym)
se.want_pointer = 1;
gfc_conv_expr (&se, e);
gfc = se.expr;
- /* gfc_conv_constant ignores se.want_poiner, e.g. for string_cst. */
- if (!POINTER_TYPE_P (TREE_TYPE (gfc)))
- gfc = gfc_build_addr_expr (NULL, gfc);
}
else
{
diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc
index edcc04a..8f72dbb 100644
--- a/gcc/gimple-fold.cc
+++ b/gcc/gimple-fold.cc
@@ -5233,24 +5233,6 @@ gimple_fold_builtin_constant_p (gimple_stmt_iterator *gsi)
return true;
}
-/* Fold __builtin_assume_aligned builtin. */
-
-static bool
-gimple_fold_builtin_assume_aligned (gimple_stmt_iterator *gsi)
-{
- if (!fold_before_rtl_expansion_p ())
- return false;
-
- gcall *call = as_a<gcall*>(gsi_stmt (*gsi));
-
- if (gimple_call_num_args (call) < 2)
- return false;
-
- gimplify_and_update_call_from_tree (gsi, gimple_call_arg (call, 0));
-
- return true;
-}
-
/* If va_list type is a simple pointer and nothing special is needed,
optimize __builtin_va_start (&ap, 0) into ap = __builtin_next_arg (0),
__builtin_va_end (&ap) out as NOP and __builtin_va_copy into a simple
@@ -5548,9 +5530,6 @@ gimple_fold_builtin (gimple_stmt_iterator *gsi)
case BUILT_IN_CONSTANT_P:
return gimple_fold_builtin_constant_p (gsi);
- case BUILT_IN_ASSUME_ALIGNED:
- return gimple_fold_builtin_assume_aligned (gsi);
-
default:;
}
diff --git a/gcc/gimple-range-op.cc b/gcc/gimple-range-op.cc
index c9bc5c0..3a22606 100644
--- a/gcc/gimple-range-op.cc
+++ b/gcc/gimple-range-op.cc
@@ -150,6 +150,10 @@ gimple_range_op_handler::gimple_range_op_handler (gimple *s)
if (TREE_CODE (ssa) == SSA_NAME)
m_op1 = ssa;
}
+ // VIEW_CONVERT_EXPR needs to descend one level deeper to pick
+ // up the symbolic operand.
+ if (TREE_CODE (m_op1) == VIEW_CONVERT_EXPR)
+ m_op1 = TREE_OPERAND (m_op1, 0);
if (gimple_num_ops (m_stmt) >= 3)
m_op2 = gimple_assign_rhs2 (m_stmt);
// Check that operands are supported types. One check is enough.
diff --git a/gcc/ipa-icf.cc b/gcc/ipa-icf.cc
index b354fb1..c7596f9 100644
--- a/gcc/ipa-icf.cc
+++ b/gcc/ipa-icf.cc
@@ -2166,7 +2166,9 @@ sem_item_optimizer::write_summary (void)
!lsei_end_p (lsei);
lsei_next_in_partition (&lsei))
{
- symtab_node *node = lsei_node (lsei);
+ symtab_node *node = dyn_cast <symtab_node *> (lsei_node (lsei));
+ if (!node)
+ continue;
if (m_symtab_node_map.get (node))
count++;
@@ -2179,7 +2181,9 @@ sem_item_optimizer::write_summary (void)
!lsei_end_p (lsei);
lsei_next_in_partition (&lsei))
{
- symtab_node *node = lsei_node (lsei);
+ symtab_node *node = dyn_cast <symtab_node *> (lsei_node (lsei));
+ if (!node)
+ continue;
sem_item **item = m_symtab_node_map.get (node);
@@ -2233,7 +2237,7 @@ sem_item_optimizer::read_section (lto_file_decl_data *file_data,
for (i = 0; i < count; i++)
{
unsigned int index;
- symtab_node *node;
+ toplevel_node *node;
lto_symtab_encoder_t encoder;
index = streamer_read_uhwi (&ib_main);
@@ -2241,12 +2245,11 @@ sem_item_optimizer::read_section (lto_file_decl_data *file_data,
node = lto_symtab_encoder_deref (encoder, index);
hashval_t hash = streamer_read_uhwi (&ib_main);
- gcc_assert (node->definition);
+ if (symtab_node *snode = dyn_cast <symtab_node *> (node))
+ gcc_assert (snode->definition);
- if (is_a<cgraph_node *> (node))
+ if (cgraph_node *cnode = dyn_cast <cgraph_node *> (node))
{
- cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
-
sem_function *fn = new sem_function (cnode, &m_bmstack);
unsigned count = streamer_read_uhwi (&ib_main);
inchash::hash hstate (0);
@@ -2263,10 +2266,8 @@ sem_item_optimizer::read_section (lto_file_decl_data *file_data,
fn->set_hash (hash);
m_items.safe_push (fn);
}
- else
+ else if (varpool_node *vnode = dyn_cast <varpool_node *> (node))
{
- varpool_node *vnode = dyn_cast <varpool_node *> (node);
-
sem_variable *var = new sem_variable (vnode, &m_bmstack);
var->set_hash (hash);
m_items.safe_push (var);
diff --git a/gcc/ipa-modref.cc b/gcc/ipa-modref.cc
index d3e5101..a319ee3 100644
--- a/gcc/ipa-modref.cc
+++ b/gcc/ipa-modref.cc
@@ -3752,8 +3752,8 @@ modref_write ()
for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
{
- symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
- cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
+ toplevel_node *tnode = lto_symtab_encoder_deref (encoder, i);
+ cgraph_node *cnode = dyn_cast <cgraph_node *> (tnode);
modref_summary_lto *r;
if (cnode && cnode->definition && !cnode->alias
@@ -3765,8 +3765,8 @@ modref_write ()
for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
{
- symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
- cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
+ toplevel_node *tnode = lto_symtab_encoder_deref (encoder, i);
+ cgraph_node *cnode = dyn_cast <cgraph_node *> (tnode);
if (cnode && cnode->definition && !cnode->alias)
{
diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc
index c8438d6..1e4b6d4 100644
--- a/gcc/ipa-prop.cc
+++ b/gcc/ipa-prop.cc
@@ -5576,8 +5576,8 @@ ipa_write_return_summaries (output_block *ob)
unsigned int count = 0;
for (int i = 0; i < lto_symtab_encoder_size (encoder); i++)
{
- symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
- cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
+ toplevel_node *tnode = lto_symtab_encoder_deref (encoder, i);
+ cgraph_node *cnode = dyn_cast <cgraph_node *> (tnode);
ipa_return_value_summary *v;
if (cnode && cnode->definition && !cnode->alias
@@ -5589,8 +5589,8 @@ ipa_write_return_summaries (output_block *ob)
for (int i = 0; i < lto_symtab_encoder_size (encoder); i++)
{
- symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
- cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
+ toplevel_node *tnode = lto_symtab_encoder_deref (encoder, i);
+ cgraph_node *cnode = dyn_cast <cgraph_node *> (tnode);
ipa_return_value_summary *v;
if (cnode && cnode->definition && !cnode->alias
@@ -5865,8 +5865,8 @@ ipcp_write_transformation_summaries (void)
for (int i = 0; i < lto_symtab_encoder_size (encoder); i++)
{
- symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
- cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
+ toplevel_node *tnode = lto_symtab_encoder_deref (encoder, i);
+ cgraph_node *cnode = dyn_cast <cgraph_node *> (tnode);
if (!cnode)
continue;
ipcp_transformation *ts = ipcp_get_transformation_summary (cnode);
@@ -5879,8 +5879,8 @@ ipcp_write_transformation_summaries (void)
for (int i = 0; i < lto_symtab_encoder_size (encoder); i++)
{
- symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
- cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
+ toplevel_node *tnode = lto_symtab_encoder_deref (encoder, i);
+ cgraph_node *cnode = dyn_cast <cgraph_node *> (tnode);
if (!cnode)
continue;
ipcp_transformation *ts = ipcp_get_transformation_summary (cnode);
diff --git a/gcc/ipa-reference.cc b/gcc/ipa-reference.cc
index 975341c..173c7a5 100644
--- a/gcc/ipa-reference.cc
+++ b/gcc/ipa-reference.cc
@@ -1070,8 +1070,8 @@ ipa_reference_write_optimization_summary (void)
/* See what variables we are interested in. */
for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
{
- symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
- varpool_node *vnode = dyn_cast <varpool_node *> (snode);
+ toplevel_node *tnode = lto_symtab_encoder_deref (encoder, i);
+ varpool_node *vnode = dyn_cast <varpool_node *> (tnode);
int id;
if (vnode
@@ -1089,8 +1089,8 @@ ipa_reference_write_optimization_summary (void)
if (ltrans_statics_bitcount)
for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
{
- symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
- cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
+ toplevel_node *tnode = lto_symtab_encoder_deref (encoder, i);
+ cgraph_node *cnode = dyn_cast <cgraph_node *> (tnode);
if (cnode && write_node_summary_p (cnode, encoder, ltrans_statics))
count++;
}
@@ -1104,15 +1104,15 @@ ipa_reference_write_optimization_summary (void)
if (ltrans_statics_bitcount)
for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
{
- symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
- cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
+ toplevel_node *tnode = lto_symtab_encoder_deref (encoder, i);
+ cgraph_node *cnode = dyn_cast <cgraph_node *> (tnode);
if (cnode && write_node_summary_p (cnode, encoder, ltrans_statics))
{
ipa_reference_optimization_summary_t info;
int node_ref;
info = get_reference_optimization_summary (cnode);
- node_ref = lto_symtab_encoder_encode (encoder, snode);
+ node_ref = lto_symtab_encoder_encode (encoder, tnode);
streamer_write_uhwi_stream (ob->main_stream, node_ref);
stream_out_bitmap (ob, info->statics_read, ltrans_statics,
diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc
index b152997..48ce7578 100644
--- a/gcc/lra-constraints.cc
+++ b/gcc/lra-constraints.cc
@@ -2552,7 +2552,10 @@ process_alt_operands (int only_alternative)
{
int regno = decode_hard_reg_constraint (p);
gcc_assert (regno >= 0);
- cl = REGNO_REG_CLASS (regno);
+ cl = NO_REGS;
+ int nregs = hard_regno_nregs (regno, mode);
+ for (int i = 0; i < nregs; ++i)
+ cl = reg_class_superunion[cl][REGNO_REG_CLASS (regno + i)];
CLEAR_HARD_REG_SET (hard_reg_constraint);
SET_HARD_REG_BIT (hard_reg_constraint, regno);
cl_filter = &hard_reg_constraint;
diff --git a/gcc/lto-cgraph.cc b/gcc/lto-cgraph.cc
index 5708ba0..4c60bf0 100644
--- a/gcc/lto-cgraph.cc
+++ b/gcc/lto-cgraph.cc
@@ -45,9 +45,6 @@ along with GCC; see the file COPYING3. If not see
#include "symtab-thunks.h"
#include "symtab-clones.h"
-/* True when asm nodes has been output. */
-bool asm_nodes_output = false;
-
static void output_cgraph_opt_summary (void);
static void input_cgraph_opt_summary (vec<symtab_node *> nodes);
@@ -82,7 +79,7 @@ lto_symtab_encoder_new (bool for_input)
lto_symtab_encoder_t encoder = XCNEW (struct lto_symtab_encoder_d);
if (!for_input)
- encoder->map = new hash_map<symtab_node *, size_t>;
+ encoder->map = new hash_map<toplevel_node *, size_t>;
encoder->nodes.create (0);
return encoder;
}
@@ -108,7 +105,7 @@ lto_symtab_encoder_delete (lto_symtab_encoder_t encoder)
int
lto_symtab_encoder_encode (lto_symtab_encoder_t encoder,
- symtab_node *node)
+ toplevel_node *node)
{
int ref;
@@ -140,7 +137,7 @@ lto_symtab_encoder_encode (lto_symtab_encoder_t encoder,
bool
lto_symtab_encoder_delete_node (lto_symtab_encoder_t encoder,
- symtab_node *node)
+ toplevel_node *node)
{
int index;
@@ -214,7 +211,7 @@ lto_set_symtab_encoder_encode_initializer (lto_symtab_encoder_t encoder,
bool
lto_symtab_encoder_in_partition_p (lto_symtab_encoder_t encoder,
- symtab_node *node)
+ toplevel_node *node)
{
int index = lto_symtab_encoder_lookup (encoder, node);
if (index == LCC_NOT_FOUND)
@@ -226,11 +223,16 @@ lto_symtab_encoder_in_partition_p (lto_symtab_encoder_t encoder,
void
lto_set_symtab_encoder_in_partition (lto_symtab_encoder_t encoder,
- symtab_node *node)
+ toplevel_node *node)
{
int index = lto_symtab_encoder_encode (encoder, node);
if (dump_file)
- fprintf(dump_file, "Node %s, index %d\n", node->asm_name(), index);
+ {
+ if (symtab_node* snode = dyn_cast<symtab_node*> (node))
+ fprintf (dump_file, "Node %s, index %d\n", snode->asm_name (), index);
+ else
+ fprintf (dump_file, "Asm node, index %d\n", index);
+ }
encoder->nodes[index].in_partition = true;
}
@@ -770,7 +772,10 @@ output_refs (lto_symtab_encoder_t encoder)
for (int i = 0; i < lto_symtab_encoder_size (encoder); i++)
{
- symtab_node *node = lto_symtab_encoder_deref (encoder, i);
+ toplevel_node *tnode = lto_symtab_encoder_deref (encoder, i);
+ symtab_node *node = dyn_cast <symtab_node *> (tnode);
+ if (!node)
+ continue;
/* IPA_REF_ALIAS references are always preserved
in the boundary. Alias node can't have other references and
@@ -895,7 +900,7 @@ compute_ltrans_boundary (lto_symtab_encoder_t in_encoder)
pickle those too. */
for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
{
- symtab_node *node = lto_symtab_encoder_deref (encoder, i);
+ toplevel_node *node = lto_symtab_encoder_deref (encoder, i);
if (varpool_node *vnode = dyn_cast <varpool_node *> (node))
{
if (!lto_symtab_encoder_encode_initializer_p (encoder,
@@ -962,7 +967,11 @@ compute_ltrans_boundary (lto_symtab_encoder_t in_encoder)
to stay to aid local calling conventions. */
for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
{
- symtab_node *node = lto_symtab_encoder_deref (encoder, i);
+ toplevel_node *tnode = lto_symtab_encoder_deref (encoder, i);
+ symtab_node *node = dyn_cast <symtab_node *> (tnode);
+ if (!node)
+ continue;
+
cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
if (node->alias && node->analyzed)
@@ -980,6 +989,13 @@ compute_ltrans_boundary (lto_symtab_encoder_t in_encoder)
lto_symtab_encoder_encode (encoder, node);
}
}
+
+ for (lsei = lsei_start (in_encoder); !lsei_end_p (lsei); lsei_next (&lsei))
+ {
+ toplevel_node *tnode = lsei_node (lsei);
+ if (asm_node* node = dyn_cast <asm_node*> (tnode))
+ lto_set_symtab_encoder_in_partition (encoder, node);
+ }
lto_symtab_encoder_delete (in_encoder);
return encoder;
}
@@ -1012,11 +1028,11 @@ output_symtab (void)
n_nodes = lto_symtab_encoder_size (encoder);
for (i = 0; i < n_nodes; i++)
{
- symtab_node *node = lto_symtab_encoder_deref (encoder, i);
+ toplevel_node *node = lto_symtab_encoder_deref (encoder, i);
if (cgraph_node *cnode = dyn_cast <cgraph_node *> (node))
lto_output_node (ob, cnode, encoder);
- else
- lto_output_varpool_node (ob, dyn_cast<varpool_node *> (node), encoder);
+ else if (varpool_node *vnode = dyn_cast <varpool_node *> (node))
+ lto_output_varpool_node (ob, vnode, encoder);
}
/* Go over the nodes in SET again to write edges. */
@@ -1036,15 +1052,9 @@ output_symtab (void)
lto_destroy_simple_output_block (ob);
- /* Emit toplevel asms.
- When doing WPA we must output every asm just once. Since we do not partition asm
- nodes at all, output them to first output. This is kind of hack, but should work
- well. */
- if (!asm_nodes_output && !lto_stream_offload_p)
- {
- asm_nodes_output = true;
- lto_output_toplevel_asms ();
- }
+ /* Emit toplevel asms. */
+ if (!lto_stream_offload_p)
+ lto_output_toplevel_asms (encoder);
output_refs (encoder);
}
@@ -2111,7 +2121,7 @@ output_cgraph_opt_summary (void)
n_nodes = lto_symtab_encoder_size (encoder);
for (i = 0; i < n_nodes; i++)
{
- symtab_node *node = lto_symtab_encoder_deref (encoder, i);
+ toplevel_node *node = lto_symtab_encoder_deref (encoder, i);
cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
if (cnode && output_cgraph_opt_summary_p (cnode))
count++;
@@ -2119,7 +2129,7 @@ output_cgraph_opt_summary (void)
streamer_write_uhwi (ob, count);
for (i = 0; i < n_nodes; i++)
{
- symtab_node *node = lto_symtab_encoder_deref (encoder, i);
+ toplevel_node *node = lto_symtab_encoder_deref (encoder, i);
cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
if (cnode && output_cgraph_opt_summary_p (cnode))
{
diff --git a/gcc/lto-section-in.cc b/gcc/lto-section-in.cc
index 1dd9520..bf86219 100644
--- a/gcc/lto-section-in.cc
+++ b/gcc/lto-section-in.cc
@@ -448,7 +448,6 @@ lto_free_function_in_decl_state_for_node (symtab_node *node)
lto_free_function_in_decl_state (*slot);
node->lto_file_data->function_decl_states->clear_slot (slot);
}
- node->lto_file_data = NULL;
}
diff --git a/gcc/lto-streamer-in.cc b/gcc/lto-streamer-in.cc
index be81826..2efa1f3 100644
--- a/gcc/lto-streamer-in.cc
+++ b/gcc/lto-streamer-in.cc
@@ -2004,6 +2004,7 @@ lto_input_toplevel_asms (struct lto_file_decl_data *file_data, int order_base)
{
asm_node *node = symtab->finalize_toplevel_asm (str);
node->order = streamer_read_hwi (&ib) + order_base;
+ node->lto_file_data = file_data;
if (node->order >= symtab->order)
symtab->order = node->order + 1;
}
diff --git a/gcc/lto-streamer-out.cc b/gcc/lto-streamer-out.cc
index 308ab34..d03c41f 100644
--- a/gcc/lto-streamer-out.cc
+++ b/gcc/lto-streamer-out.cc
@@ -2554,14 +2554,18 @@ output_constructor (struct varpool_node *node, int output_order)
/* Emit toplevel asms. */
void
-lto_output_toplevel_asms (void)
+lto_output_toplevel_asms (lto_symtab_encoder_t encoder)
{
struct output_block *ob;
- struct asm_node *can;
char *section_name;
struct lto_simple_header_with_strings header;
- if (!symtab->first_asm_symbol ())
+ bool any_asm = false;
+ for (int i = 0; i < lto_symtab_encoder_size (encoder); i++)
+ if (is_a <asm_node*> (lto_symtab_encoder_deref (encoder, i)))
+ any_asm = true;
+
+ if (!any_asm)
return;
ob = create_output_block (LTO_section_asm);
@@ -2569,17 +2573,22 @@ lto_output_toplevel_asms (void)
/* Make string 0 be a NULL string. */
streamer_write_char_stream (ob->string_stream, 0);
- for (can = symtab->first_asm_symbol (); can; can = can->next)
+ for (int i = 0; i < lto_symtab_encoder_size (encoder); i++)
{
- if (TREE_CODE (can->asm_str) != STRING_CST)
+ toplevel_node *tnode = lto_symtab_encoder_deref (encoder, i);
+ asm_node *anode = dyn_cast <asm_node*> (tnode);
+ if (!anode)
+ continue;
+
+ if (TREE_CODE (anode->asm_str) != STRING_CST)
{
- sorry_at (EXPR_LOCATION (can->asm_str),
+ sorry_at (EXPR_LOCATION (anode->asm_str),
"LTO streaming of toplevel extended %<asm%> "
"unimplemented");
continue;
}
- streamer_write_string_cst (ob, ob->main_stream, can->asm_str);
- streamer_write_hwi (ob, can->order);
+ streamer_write_string_cst (ob, ob->main_stream, anode->asm_str);
+ streamer_write_hwi (ob, anode->order);
}
streamer_write_string_cst (ob, ob->main_stream, NULL_TREE);
@@ -2783,19 +2792,12 @@ create_order_remap (lto_symtab_encoder_t encoder)
{
auto_vec<int> orders;
unsigned i;
- struct asm_node* anode;
encoder->order_remap = new hash_map<int_hash<int, -1, -2>, int>;
unsigned n_nodes = lto_symtab_encoder_size (encoder);
for (i = 0; i < n_nodes; i++)
orders.safe_push (lto_symtab_encoder_deref (encoder, i)->order);
- if (!asm_nodes_output)
- {
- for (anode = symtab->first_asm_symbol (); anode; anode = anode->next)
- orders.safe_push (anode->order);
- }
-
orders.qsort (cmp_int);
int ord = 0;
int last_order = -1;
@@ -2809,14 +2811,6 @@ create_order_remap (lto_symtab_encoder_t encoder)
ord++;
}
}
-
- /* Asm nodes are currently always output only into first partition.
- We can remap already here. */
- if (!asm_nodes_output)
- {
- for (anode = symtab->first_asm_symbol (); anode; anode = anode->next)
- anode->order = *encoder->order_remap->get (anode->order);
- }
}
/* Main entry point from the pass manager. */
@@ -2831,6 +2825,13 @@ lto_output (void)
lto_symtab_encoder_t encoder = lto_get_out_decl_state ()->symtab_node_encoder;
auto_vec<symtab_node *> symbols_to_copy;
+ if (!flag_wpa)
+ {
+ asm_node *anode;
+ for (anode = symtab->first_asm_symbol (); anode; anode = anode->next)
+ lto_set_symtab_encoder_in_partition (encoder, anode);
+ }
+
create_order_remap (encoder);
prune_offload_funcs ();
@@ -2851,16 +2852,18 @@ lto_output (void)
section copying. */
for (i = 0; i < n_nodes; i++)
{
- symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
- if (snode->alias)
+ toplevel_node *tnode = lto_symtab_encoder_deref (encoder, i);
+ symtab_node *node = dyn_cast <symtab_node *> (tnode);
+ if (!node || node->alias)
continue;
- if (cgraph_node *node = dyn_cast <cgraph_node *> (snode))
+
+ if (cgraph_node *node = dyn_cast <cgraph_node *> (tnode))
{
if (lto_symtab_encoder_encode_body_p (encoder, node)
&& !node->clone_of)
symbols_to_copy.safe_push (node);
}
- else if (varpool_node *node = dyn_cast <varpool_node *> (snode))
+ else if (varpool_node *node = dyn_cast <varpool_node *> (tnode))
{
/* Wrap symbol references inside the ctor in a type
preserving MEM_REF. */
@@ -3202,7 +3205,10 @@ produce_symtab (struct output_block *ob)
for (lsei = lsei_start (encoder);
!lsei_end_p (lsei); lsei_next (&lsei))
{
- symtab_node *node = lsei_node (lsei);
+ toplevel_node *tnode = lsei_node (lsei);
+ symtab_node *node = dyn_cast<symtab_node*> (tnode);
+ if (!node)
+ continue;
if (DECL_EXTERNAL (node->decl) || !node->output_to_lto_symbol_table_p ())
continue;
@@ -3212,7 +3218,10 @@ produce_symtab (struct output_block *ob)
for (lsei = lsei_start (encoder);
!lsei_end_p (lsei); lsei_next (&lsei))
{
- symtab_node *node = lsei_node (lsei);
+ toplevel_node *tnode = lsei_node (lsei);
+ symtab_node *node = dyn_cast<symtab_node*> (tnode);
+ if (!node)
+ continue;
if (!DECL_EXTERNAL (node->decl) || !node->output_to_lto_symbol_table_p ())
continue;
@@ -3253,7 +3262,10 @@ produce_symtab_extension (struct output_block *ob,
for (lsei = lsei_start (encoder);
!lsei_end_p (lsei); lsei_next (&lsei))
{
- symtab_node *node = lsei_node (lsei);
+ toplevel_node *tnode = lsei_node (lsei);
+ symtab_node *node = dyn_cast<symtab_node*> (tnode);
+ if (!node)
+ continue;
if (DECL_EXTERNAL (node->decl) || !node->output_to_lto_symbol_table_p ())
continue;
@@ -3263,7 +3275,10 @@ produce_symtab_extension (struct output_block *ob,
for (lsei = lsei_start (encoder);
!lsei_end_p (lsei); lsei_next (&lsei))
{
- symtab_node *node = lsei_node (lsei);
+ toplevel_node *tnode = lsei_node (lsei);
+ symtab_node *node = dyn_cast<symtab_node*> (tnode);
+ if (!node)
+ continue;
if (!DECL_EXTERNAL (node->decl) || !node->output_to_lto_symbol_table_p ())
continue;
diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h
index 4b7209e3..a398f43 100644
--- a/gcc/lto-streamer.h
+++ b/gcc/lto-streamer.h
@@ -444,12 +444,12 @@ struct lto_stats_d
struct lto_encoder_entry
{
/* Constructor. */
- lto_encoder_entry (symtab_node* n)
+ lto_encoder_entry (toplevel_node* n)
: node (n), in_partition (false), body (false), only_for_inlining (true),
initializer (false)
{}
- symtab_node *node;
+ toplevel_node *node;
/* Is the node in this partition (i.e. ltrans of this partition will
be responsible for outputting it)? */
unsigned int in_partition:1;
@@ -468,7 +468,7 @@ struct lto_encoder_entry
struct lto_symtab_encoder_d
{
vec<lto_encoder_entry> nodes;
- hash_map<symtab_node *, size_t> *map;
+ hash_map<toplevel_node *, size_t> *map;
/* Mapping of input order of nodes onto output order. */
hash_map<int_hash<int, -1, -2>, int> *order_remap;
@@ -897,7 +897,7 @@ extern void lto_output_fn_decl_ref (struct lto_out_decl_state *,
struct lto_output_stream *, tree);
extern tree lto_input_var_decl_ref (lto_input_block *, lto_file_decl_data *);
extern tree lto_input_fn_decl_ref (lto_input_block *, lto_file_decl_data *);
-extern void lto_output_toplevel_asms (void);
+extern void lto_output_toplevel_asms (lto_symtab_encoder_t);
extern void produce_asm (struct output_block *ob);
extern void lto_output ();
extern void produce_asm_for_decls ();
@@ -916,19 +916,18 @@ void lto_prepare_function_for_streaming (cgraph_node *);
/* In lto-cgraph.cc */
-extern bool asm_nodes_output;
lto_symtab_encoder_t lto_symtab_encoder_new (bool);
-int lto_symtab_encoder_encode (lto_symtab_encoder_t, symtab_node *);
+int lto_symtab_encoder_encode (lto_symtab_encoder_t, toplevel_node *);
void lto_symtab_encoder_delete (lto_symtab_encoder_t);
-bool lto_symtab_encoder_delete_node (lto_symtab_encoder_t, symtab_node *);
+bool lto_symtab_encoder_delete_node (lto_symtab_encoder_t, toplevel_node *);
bool lto_symtab_encoder_encode_body_p (lto_symtab_encoder_t,
struct cgraph_node *);
bool lto_symtab_encoder_only_for_inlining_p (lto_symtab_encoder_t,
struct cgraph_node *);
bool lto_symtab_encoder_in_partition_p (lto_symtab_encoder_t,
- symtab_node *);
+ toplevel_node *);
void lto_set_symtab_encoder_in_partition (lto_symtab_encoder_t,
- symtab_node *);
+ toplevel_node *);
bool lto_symtab_encoder_encode_initializer_p (lto_symtab_encoder_t,
varpool_node *);
@@ -1104,7 +1103,7 @@ lto_symtab_encoder_size (lto_symtab_encoder_t encoder)
inline int
lto_symtab_encoder_lookup (lto_symtab_encoder_t encoder,
- symtab_node *node)
+ toplevel_node *node)
{
size_t *slot = encoder->map->get (node);
return (slot && *slot ? *(slot) - 1 : LCC_NOT_FOUND);
@@ -1125,7 +1124,7 @@ lsei_next (lto_symtab_encoder_iterator *lsei)
}
/* Return the node pointed to by LSI. */
-inline symtab_node *
+inline toplevel_node *
lsei_node (lto_symtab_encoder_iterator lsei)
{
return lsei.encoder->nodes[lsei.index].node;
@@ -1147,7 +1146,7 @@ lsei_varpool_node (lto_symtab_encoder_iterator lsei)
/* Return the cgraph node corresponding to REF using ENCODER. */
-inline symtab_node *
+inline toplevel_node *
lto_symtab_encoder_deref (lto_symtab_encoder_t encoder, int ref)
{
if (ref == LCC_NOT_FOUND)
diff --git a/gcc/lto/lto-partition.cc b/gcc/lto/lto-partition.cc
index c7e69ee..baeafc7 100644
--- a/gcc/lto/lto-partition.cc
+++ b/gcc/lto/lto-partition.cc
@@ -43,7 +43,8 @@ along with GCC; see the file COPYING3. If not see
vec<ltrans_partition> ltrans_partitions;
-static void add_symbol_to_partition (ltrans_partition part, symtab_node *node);
+static void add_symbol_to_partition (ltrans_partition part,
+ toplevel_node *node);
/* Helper for qsort; compare partitions and return one with smaller order. */
@@ -61,7 +62,7 @@ cmp_partitions_order (const void *a, const void *b)
ordera = lto_symtab_encoder_deref (pa->encoder, 0)->order;
if (lto_symtab_encoder_size (pb->encoder))
orderb = lto_symtab_encoder_deref (pb->encoder, 0)->order;
- return orderb - ordera;
+ return ordera - orderb;
}
/* Create new partition with name NAME.
@@ -87,6 +88,15 @@ new_partition (const char *name)
return part;
}
+/* If the cgraph is empty, create one cgraph node set so that there is still
+ an output file for any variables that need to be exported in a DSO. */
+static void
+create_partition_if_empty ()
+{
+ if (!ltrans_partitions.length ())
+ new_partition ("empty");
+}
+
/* Free memory used by ltrans partition.
Encoder can be kept to be freed after streaming. */
static void
@@ -266,9 +276,15 @@ contained_in_symbol (symtab_node *node)
of other symbol definition, add the other symbol, too. */
static void
-add_symbol_to_partition (ltrans_partition part, symtab_node *node)
+add_symbol_to_partition (ltrans_partition part, toplevel_node *tnode)
{
symtab_node *node1;
+ symtab_node* node = dyn_cast <symtab_node*> (tnode);
+ if (!node)
+ {
+ lto_set_symtab_encoder_in_partition (part->encoder, tnode);
+ return;
+ }
/* Verify that we do not try to duplicate something that cannot be. */
gcc_checking_assert (node->get_partitioning_class () == SYMBOL_DUPLICATE
@@ -299,22 +315,53 @@ undo_partition (ltrans_partition partition, unsigned int n_nodes)
{
while (lto_symtab_encoder_size (partition->encoder) > (int)n_nodes)
{
- symtab_node *node = lto_symtab_encoder_deref (partition->encoder,
- n_nodes);
- partition->symbols--;
- cgraph_node *cnode;
+ toplevel_node *tnode = lto_symtab_encoder_deref (partition->encoder,
+ n_nodes);
/* After UNDO we no longer know what was visited. */
if (partition->initializers_visited)
delete partition->initializers_visited;
partition->initializers_visited = NULL;
- if (!node->alias && (cnode = dyn_cast <cgraph_node *> (node))
- && node->get_partitioning_class () == SYMBOL_PARTITION)
- partition->insns -= ipa_size_summaries->get (cnode)->size;
- lto_symtab_encoder_delete_node (partition->encoder, node);
- node->aux = (void *)((size_t)node->aux - 1);
+ lto_symtab_encoder_delete_node (partition->encoder, tnode);
+
+ if (symtab_node* node = dyn_cast <symtab_node *> (tnode))
+ {
+ partition->symbols--;
+ cgraph_node *cnode;
+ if (!node->alias && (cnode = dyn_cast <cgraph_node *> (node))
+ && node->get_partitioning_class () == SYMBOL_PARTITION)
+ partition->insns -= ipa_size_summaries->get (cnode)->size;
+ node->aux = (void *)((size_t)node->aux - 1);
+ }
+ }
+}
+
+/* Insert node into its file partition. */
+static void
+node_into_file_partition (toplevel_node* node,
+ hash_map<lto_file_decl_data *,
+ ltrans_partition>& pmap)
+{
+ ltrans_partition partition;
+
+ struct lto_file_decl_data *file_data = node->lto_file_data;
+
+ if (file_data)
+ {
+ ltrans_partition *slot = &pmap.get_or_insert (file_data);
+ if (*slot)
+ partition = *slot;
+ else
+ {
+ partition = new_partition (file_data->file_name);
+ *slot = partition;
+ }
}
+ else
+ partition = new_partition ("");
+
+ add_symbol_to_partition (partition, node);
}
/* Group cgrah nodes by input files. This is used mainly for testing
@@ -324,10 +371,7 @@ void
lto_1_to_1_map (void)
{
symtab_node *node;
- struct lto_file_decl_data *file_data;
hash_map<lto_file_decl_data *, ltrans_partition> pmap;
- ltrans_partition partition;
- int npartitions = 0;
FOR_EACH_SYMBOL (node)
{
@@ -335,41 +379,38 @@ lto_1_to_1_map (void)
|| symbol_partitioned_p (node))
continue;
- file_data = node->lto_file_data;
-
- if (file_data)
- {
- ltrans_partition *slot = &pmap.get_or_insert (file_data);
- if (*slot)
- partition = *slot;
- else
- {
- partition = new_partition (file_data->file_name);
- *slot = partition;
- npartitions++;
- }
- }
- else if (!file_data && ltrans_partitions.length ())
- partition = ltrans_partitions[0];
- else
- {
- partition = new_partition ("");
- npartitions++;
- }
-
- add_symbol_to_partition (partition, node);
+ node_into_file_partition (node, pmap);
}
- /* If the cgraph is empty, create one cgraph node set so that there is still
- an output file for any variables that need to be exported in a DSO. */
- if (!npartitions)
- new_partition ("empty");
+ struct asm_node *anode;
+ for (anode = symtab->first_asm_symbol (); anode; anode = anode->next)
+ node_into_file_partition (anode, pmap);
+
+ create_partition_if_empty ();
/* Order partitions by order of symbols because they are linked into binary
that way. */
ltrans_partitions.qsort (cmp_partitions_order);
}
+/* Creates partition with all toplevel assembly.
+
+ Before toplevel asm could be partitioned, all toplevel asm was inserted
+ into first partition.
+ This function achieves similar behavior for partitionings that cannot
+ easily satisfy requirements of toplevel asm. */
+static void
+create_asm_partition (void)
+{
+ struct asm_node *anode = symtab->first_asm_symbol ();
+ if (anode)
+ {
+ ltrans_partition partition = new_partition ("asm_nodes");
+ for (; anode; anode = anode->next)
+ add_symbol_to_partition (partition, anode);
+ }
+}
+
/* Maximal partitioning. Put every new symbol into new partition if possible. */
void
@@ -377,7 +418,6 @@ lto_max_map (void)
{
symtab_node *node;
ltrans_partition partition;
- int npartitions = 0;
FOR_EACH_SYMBOL (node)
{
@@ -386,10 +426,10 @@ lto_max_map (void)
continue;
partition = new_partition (node->asm_name ());
add_symbol_to_partition (partition, node);
- npartitions++;
}
- if (!npartitions)
- new_partition ("empty");
+
+ create_asm_partition ();
+ create_partition_if_empty ();
}
/* Helper function for qsort; sort nodes by order. */
@@ -398,7 +438,7 @@ node_cmp (const void *pa, const void *pb)
{
const symtab_node *a = *static_cast<const symtab_node * const *> (pa);
const symtab_node *b = *static_cast<const symtab_node * const *> (pb);
- return b->order - a->order;
+ return a->order - b->order;
}
/* Add all symtab nodes from NEXT_NODE to PARTITION in order. */
@@ -467,16 +507,17 @@ join_partitions (ltrans_partition into, ltrans_partition from)
before adding any symbols to other partition. */
for (lsei = lsei_start (encoder); !lsei_end_p (lsei); lsei_next (&lsei))
{
- symtab_node *node = lsei_node (lsei);
- node->aux = (void *)((size_t)node->aux - 1);
+ if (symtab_node *node = dyn_cast <symtab_node*> (lsei_node (lsei)))
+ node->aux = (void *)((size_t)node->aux - 1);
}
for (lsei = lsei_start (encoder); !lsei_end_p (lsei); lsei_next (&lsei))
{
- symtab_node *node = lsei_node (lsei);
+ toplevel_node *node = lsei_node (lsei);
- if (symbol_partitioned_p (node))
- continue;
+ if (symtab_node *snode = dyn_cast <symtab_node*> (node))
+ if (symbol_partitioned_p (snode))
+ continue;
add_symbol_to_partition (into, node);
}
@@ -498,16 +539,17 @@ split_partition_into_nodes (ltrans_partition part)
for (lsei = lsei_start (encoder); !lsei_end_p (lsei); lsei_next (&lsei))
{
- symtab_node *node = lsei_node (lsei);
- node->aux = (void *)((size_t)node->aux - 1);
+ if (symtab_node *node = dyn_cast <symtab_node*> (lsei_node (lsei)))
+ node->aux = (void *)((size_t)node->aux - 1);
}
for (lsei = lsei_start (encoder); !lsei_end_p (lsei); lsei_next (&lsei))
{
- symtab_node *node = lsei_node (lsei);
+ toplevel_node *node = lsei_node (lsei);
- if (node->get_partitioning_class () != SYMBOL_PARTITION
- || symbol_partitioned_p (node))
+ symtab_node *snode = dyn_cast <symtab_node*> (node);
+ if (snode->get_partitioning_class () != SYMBOL_PARTITION
+ || symbol_partitioned_p (snode))
continue;
ltrans_partition new_part = new_partition_no_push (part->name);
@@ -527,8 +569,8 @@ is_partition_reorder (ltrans_partition part)
for (lsei = lsei_start (encoder); !lsei_end_p (lsei); lsei_next (&lsei))
{
- symtab_node *node = lsei_node (lsei);
- if (node->no_reorder)
+ symtab_node *node = dyn_cast <symtab_node*> (lsei_node (lsei));
+ if (!node || node->no_reorder)
return false;
}
return true;
@@ -1167,20 +1209,22 @@ lto_balanced_map (int n_lto_partitions, int max_partition_size)
callgraph or IPA reference edge leaving the partition contributes into
COST. Every edge inside partition was earlier computed as one leaving
it and thus we need to subtract it from COST. */
- while (last_visited_node < lto_symtab_encoder_size (partition->encoder))
+ for (; last_visited_node < lto_symtab_encoder_size (partition->encoder);
+ last_visited_node++)
{
int j;
struct ipa_ref *ref = NULL;
- symtab_node *snode = lto_symtab_encoder_deref (partition->encoder,
- last_visited_node);
+ toplevel_node *tnode = lto_symtab_encoder_deref (partition->encoder,
+ last_visited_node);
+
+ symtab_node* snode = dyn_cast <symtab_node*> (tnode);
+ if (!snode)
+ continue;
if (cgraph_node *node = dyn_cast <cgraph_node *> (snode))
{
struct cgraph_edge *edge;
-
- last_visited_node++;
-
gcc_assert (node->definition || node->weakref);
/* Compute boundary cost of callgraph edges. */
@@ -1197,8 +1241,7 @@ lto_balanced_map (int n_lto_partitions, int max_partition_size)
gcc_assert (edge_cost > 0);
index = lto_symtab_encoder_lookup (partition->encoder,
edge->callee);
- if (index != LCC_NOT_FOUND
- && index < last_visited_node - 1)
+ if (index != LCC_NOT_FOUND && index < last_visited_node)
cost -= edge_cost, internal += edge_cost;
else
cost += edge_cost;
@@ -1216,15 +1259,12 @@ lto_balanced_map (int n_lto_partitions, int max_partition_size)
gcc_assert (edge_cost > 0);
index = lto_symtab_encoder_lookup (partition->encoder,
edge->caller);
- if (index != LCC_NOT_FOUND
- && index < last_visited_node - 1)
+ if (index != LCC_NOT_FOUND && index < last_visited_node)
cost -= edge_cost, internal += edge_cost;
else
cost += edge_cost;
}
}
- else
- last_visited_node++;
/* Compute boundary cost of IPA REF edges and at the same time look into
variables referenced from current partition and try to add them. */
@@ -1242,8 +1282,7 @@ lto_balanced_map (int n_lto_partitions, int max_partition_size)
add_symbol_to_partition (partition, vnode);
index = lto_symtab_encoder_lookup (partition->encoder,
vnode);
- if (index != LCC_NOT_FOUND
- && index < last_visited_node - 1)
+ if (index != LCC_NOT_FOUND && index < last_visited_node)
cost--, internal++;
else
cost++;
@@ -1255,8 +1294,7 @@ lto_balanced_map (int n_lto_partitions, int max_partition_size)
node = dyn_cast <cgraph_node *> (ref->referred);
index = lto_symtab_encoder_lookup (partition->encoder,
node);
- if (index != LCC_NOT_FOUND
- && index < last_visited_node - 1)
+ if (index != LCC_NOT_FOUND && index < last_visited_node)
cost--, internal++;
else
cost++;
@@ -1281,8 +1319,7 @@ lto_balanced_map (int n_lto_partitions, int max_partition_size)
add_symbol_to_partition (partition, vnode);
index = lto_symtab_encoder_lookup (partition->encoder,
vnode);
- if (index != LCC_NOT_FOUND
- && index < last_visited_node - 1)
+ if (index != LCC_NOT_FOUND && index < last_visited_node)
cost--, internal++;
else
cost++;
@@ -1295,8 +1332,7 @@ lto_balanced_map (int n_lto_partitions, int max_partition_size)
gcc_assert (node->definition);
index = lto_symtab_encoder_lookup (partition->encoder,
node);
- if (index != LCC_NOT_FOUND
- && index < last_visited_node - 1)
+ if (index != LCC_NOT_FOUND && index < last_visited_node)
cost--, internal++;
else
cost++;
@@ -1401,6 +1437,8 @@ lto_balanced_map (int n_lto_partitions, int max_partition_size)
gcc_assert (next_nodes.length () || npartitions != 1 || !best_cost || best_cost == -1);
add_sorted_nodes (next_nodes, partition);
+ create_asm_partition ();
+
if (dump_file)
{
fprintf (dump_file, "\nPartition sizes:\n");
@@ -1872,7 +1910,10 @@ lto_promote_cross_file_statics (void)
for (lsei = lsei_start (encoder); !lsei_end_p (lsei);
lsei_next (&lsei))
{
- symtab_node *node = lsei_node (lsei);
+ toplevel_node *tnode = lsei_node (lsei);
+ symtab_node *node = dyn_cast <symtab_node*> (tnode);
+ if (!node)
+ continue;
/* If symbol is static, rename it if its assembler name
clashes with anything else in this unit. */
diff --git a/gcc/lto/lto-symtab.cc b/gcc/lto/lto-symtab.cc
index 66674a4..8d7fc68 100644
--- a/gcc/lto/lto-symtab.cc
+++ b/gcc/lto/lto-symtab.cc
@@ -953,11 +953,7 @@ lto_symtab_merge_symbols_1 (symtab_node *prevailing)
else
{
DECL_INITIAL (e->decl) = error_mark_node;
- if (e->lto_file_data)
- {
- lto_free_function_in_decl_state_for_node (e);
- e->lto_file_data = NULL;
- }
+ lto_free_function_in_decl_state_for_node (e);
symtab->call_varpool_removal_hooks (dyn_cast<varpool_node *> (e));
}
e->remove_all_references ();
diff --git a/gcc/lto/lto.cc b/gcc/lto/lto.cc
index 183634f..a4b1bc2 100644
--- a/gcc/lto/lto.cc
+++ b/gcc/lto/lto.cc
@@ -267,7 +267,6 @@ stream_out_partitions (char *temp_filename, int blen, int min, int max,
{
/* There are no free tokens, lets do the job outselves. */
stream_out_partitions_1 (temp_filename, blen, min, max);
- asm_nodes_output = true;
return;
}
}
@@ -296,7 +295,6 @@ stream_out_partitions (char *temp_filename, int blen, int min, int max,
if (jinfo != NULL && jinfo->is_connected)
jinfo->disconnect ();
}
- asm_nodes_output = true;
#else
stream_out_partitions_1 (temp_filename, blen, min, max);
#endif
@@ -381,14 +379,17 @@ lto_wpa_write_files (void)
!lsei_end_p (lsei);
lsei_next_in_partition (&lsei))
{
- symtab_node *node = lsei_node (lsei);
- fprintf (symtab->dump_file, "%s ", node->dump_asm_name ());
+ symtab_node *node = dyn_cast<symtab_node*> (lsei_node (lsei));
+ if (node)
+ fprintf (symtab->dump_file, "%s ", node->dump_asm_name ());
}
fprintf (symtab->dump_file, "\n Symbols in boundary: ");
for (lsei = lsei_start (part->encoder); !lsei_end_p (lsei);
lsei_next (&lsei))
{
- symtab_node *node = lsei_node (lsei);
+ symtab_node *node = dyn_cast<symtab_node*> (lsei_node (lsei));
+ if (!node)
+ continue;
if (!lto_symtab_encoder_in_partition_p (part->encoder, node))
{
fprintf (symtab->dump_file, "%s ", node->dump_asm_name ());
diff --git a/gcc/m2/gm2-compiler/M2Comp.mod b/gcc/m2/gm2-compiler/M2Comp.mod
index 741daeb..0190e01 100644
--- a/gcc/m2/gm2-compiler/M2Comp.mod
+++ b/gcc/m2/gm2-compiler/M2Comp.mod
@@ -851,12 +851,11 @@ BEGIN
MergeDeps (DepContent, ChildDep, LibName)
ELSE
(* Unrecoverable error. *)
- MetaErrorString1 (Sprintf1 (InitString ('file {%%1EUAF%s} containing module {%%1a} cannot be found'),
+ MetaErrorString1 (Sprintf1 (InitString ('file {%%1EUAF%s} containing module {%%1a} cannot be found {%%1&Ds}'),
FileName), sym)
END
ELSE
- (* Unrecoverable error. *)
- MetaError1 ('the file containing the definition module {%1EMAa} cannot be found', sym)
+ MetaError1 ('the file containing the definition module {%1EMAa} cannot be found {%1&Ds}', sym)
END ;
ModuleType := Implementation
ELSE
@@ -928,15 +927,15 @@ BEGIN
qprintf0 ('\n') ;
CloseSource
ELSE
- (* It is quite legitimate to implement a module in C (and pretend it was a M2
+ (* It is legitimate to implement a module in C (and pretend it was a M2
implementation) providing that it is not the main program module and the
definition module does not declare a hidden type when -fextended-opaque
is used. *)
IF (NOT WholeProgram) OR (sym = Main) OR IsHiddenTypeDeclared (sym)
THEN
(* Unrecoverable error. *)
- MetaErrorString1 (Sprintf1 (InitString ('file {%%1EUAF%s} containing module {%%1a} cannot be found'),
- FileName), sym) ;
+ MetaErrorString1 (Sprintf1 (InitString ('file {%%1EUAF%s} containing module {%%1a} cannot be found {%%1&Ds}'),
+ FileName), sym)
END
END
END
diff --git a/gcc/m2/gm2-compiler/M2MetaError.mod b/gcc/m2/gm2-compiler/M2MetaError.mod
index aae0f02..22a1557 100644
--- a/gcc/m2/gm2-compiler/M2MetaError.mod
+++ b/gcc/m2/gm2-compiler/M2MetaError.mod
@@ -42,7 +42,6 @@ FROM SYSTEM IMPORT ADDRESS ;
FROM M2Error IMPORT MoveError ;
FROM M2Debug IMPORT Assert ;
FROM Storage IMPORT ALLOCATE ;
-FROM M2StackSpell IMPORT GetSpellHint ;
FROM Indexing IMPORT Index, InitIndex, KillIndex, GetIndice, PutIndice,
DeleteIndice, HighIndice ;
@@ -74,6 +73,7 @@ IMPORT M2Error ;
IMPORT FilterError ;
FROM FilterError IMPORT Filter, AddSymError, IsSymError ;
+FROM M2StackSpell IMPORT GetDefModuleSpellHint, GetSpellHint ;
CONST
@@ -100,6 +100,7 @@ TYPE
len,
ini : INTEGER ;
vowel,
+ filterDef,
importHint,
exportHint,
withStackHint,
@@ -533,6 +534,7 @@ BEGIN
ini := 0 ;
glyph := FALSE ; (* Nothing to output yet. *)
vowel := FALSE ; (* Check for a vowel when outputing string? *)
+ filterDef := FALSE ; (* Filter on definition module list? *)
importHint := FALSE;
exportHint := FALSE ;
withStackHint := FALSE ;
@@ -1840,7 +1842,7 @@ END op ;
(*
- continuation := {':'|'1'|'2'|'3'|'4'|'i'|'s'|'x'|'w'} =:
+ continuation := {':'|'1'|'2'|'3'|'4'|'i'|'s'|'x'|'w'|'D'} =:
*)
PROCEDURE continuation (VAR eb: errorBlock;
@@ -1860,7 +1862,8 @@ BEGIN
'i': AddImportsHint (eb) |
's': SpellHint (eb, sym, bol) |
'x': AddExportsHint (eb) |
- 'w': AddWithStackHint (eb)
+ 'w': AddWithStackHint (eb) |
+ 'D': FilterOnDefinitionModule (eb)
ELSE
InternalFormat (eb, 'expecting one of [:1234isxw]',
@@ -1956,9 +1959,15 @@ END JoinSentances ;
PROCEDURE SpellHint (VAR eb: errorBlock; sym: ARRAY OF CARDINAL; bol: CARDINAL) ;
BEGIN
- IF (bol <= HIGH (sym)) AND IsUnknown (sym[bol])
+ IF bol <= HIGH (sym)
THEN
- JoinSentances (eb, GetSpellHint (sym[bol]))
+ IF eb.filterDef AND IsDefImp (sym[bol])
+ THEN
+ JoinSentances (eb, GetDefModuleSpellHint (sym[bol]))
+ ELSIF IsUnknown (sym[bol])
+ THEN
+ JoinSentances (eb, GetSpellHint (sym[bol]))
+ END
END
END SpellHint ;
@@ -1994,6 +2003,16 @@ END AddWithStackHint ;
(*
+ FilterOnDefinitionModule - turn on filtering and include all the definition modules.
+*)
+
+PROCEDURE FilterOnDefinitionModule (VAR eb: errorBlock) ;
+BEGIN
+ eb.filterDef := TRUE
+END FilterOnDefinitionModule ;
+
+
+(*
changeColor - changes to color, c.
*)
diff --git a/gcc/m2/gm2-compiler/M2Quads.mod b/gcc/m2/gm2-compiler/M2Quads.mod
index 5ceeb4f..a263ce3 100644
--- a/gcc/m2/gm2-compiler/M2Quads.mod
+++ b/gcc/m2/gm2-compiler/M2Quads.mod
@@ -10697,44 +10697,43 @@ BEGIN
NoOfParam) ;
resulttok := functok ;
ReturnVar := MakeConstLit (resulttok, MakeKey('0'), Cardinal)
- ELSIF IsAModula2Type (OperandT (1))
- THEN
- paramtok := OperandTok (1) ;
- resulttok := MakeVirtualTok (functok, functok, paramtok) ;
- BuildSizeCheckEnd (ProcSym) ; (* Quadruple generation now on. *)
- ReturnVar := MakeTemporary (resulttok, ImmediateValue) ;
- GenQuadO (resulttok, SizeOp, ReturnVar, NulSym, OperandT(1), TRUE)
- ELSIF IsVar (OperandT (1))
- THEN
- BuildSizeCheckEnd (ProcSym) ; (* Quadruple generation now on. *)
- Type := GetSType (OperandT (1)) ;
+ ELSE
paramtok := OperandTok (1) ;
resulttok := MakeVirtualTok (functok, functok, paramtok) ;
- IF IsUnbounded (Type)
+ IF IsAModula2Type (OperandT (1))
THEN
- (* Eg. SIZE(a) ; where a is unbounded dereference HIGH and multiply by the TYPE. *)
- dim := OperandD (1) ;
- IF dim = 0
+ BuildSizeCheckEnd (ProcSym) ; (* Quadruple generation now on. *)
+ ReturnVar := MakeTemporary (resulttok, ImmediateValue) ;
+ GenQuadO (resulttok, SizeOp, ReturnVar, NulSym, OperandT(1), TRUE)
+ ELSIF IsVar (OperandT (1))
+ THEN
+ BuildSizeCheckEnd (ProcSym) ; (* Quadruple generation now on. *)
+ Type := GetSType (OperandT (1)) ;
+ IF IsUnbounded (Type)
THEN
- ReturnVar := calculateMultipicand (resulttok, OperandT (1), Type, dim)
+ (* Eg. SIZE(a) ; where a is unbounded dereference HIGH and multiply by the TYPE. *)
+ dim := OperandD (1) ;
+ IF dim = 0
+ THEN
+ ReturnVar := calculateMultipicand (resulttok, OperandT (1), Type, dim)
+ ELSE
+ ReturnVar := calculateMultipicand (resulttok, OperandA (1), Type, dim)
+ END
ELSE
- ReturnVar := calculateMultipicand (resulttok, OperandA (1), Type, dim)
+ ReturnVar := MakeTemporary (resulttok, ImmediateValue) ;
+ IF Type = NulSym
+ THEN
+ MetaErrorT1 (resulttok,
+ 'cannot get the type and size of {%1Ead}', OperandT (1))
+ END ;
+ GenQuadO (resulttok, SizeOp, ReturnVar, NulSym, Type, TRUE)
END
ELSE
- ReturnVar := MakeTemporary (resulttok, ImmediateValue) ;
- IF Type = NulSym
- THEN
- MetaErrorT1 (resulttok,
- 'cannot get the type and size of {%1Ead}', OperandT (1))
- END ;
- GenQuadO (resulttok, SizeOp, ReturnVar, NulSym, Type, TRUE)
+ MetaErrorT1 (paramtok,
+ '{%E}SYSTEM procedure {%kSIZE} expects a variable or type as its parameter, seen {%1Ed} {%1&s}',
+ OperandT (1)) ;
+ ReturnVar := MakeConstLit (paramtok, MakeKey('0'), Cardinal)
END
- ELSE
- paramtok := OperandTok (1) ;
- MetaErrorT1 (paramtok,
- '{%E}SYSTEM procedure {%kSIZE} expects a variable or type as its parameter, seen {%1Ed} {%1&s}',
- OperandT (1)) ;
- ReturnVar := MakeConstLit (resulttok, MakeKey('0'), Cardinal)
END ;
PopN (NoOfParam+1) ; (* Destroy the arguments and function. *)
PushTFtok (ReturnVar, GetSType(ProcSym), resulttok)
diff --git a/gcc/m2/gm2-compiler/M2StackSpell.def b/gcc/m2/gm2-compiler/M2StackSpell.def
index 7c1d00b..c45074a 100644
--- a/gcc/m2/gm2-compiler/M2StackSpell.def
+++ b/gcc/m2/gm2-compiler/M2StackSpell.def
@@ -59,4 +59,14 @@ PROCEDURE GetRecordField (tokno: CARDINAL;
fieldName: Name) : CARDINAL ;
+(*
+ GetDefModuleSpellHint - return a string describing a spelling
+ hint for the definition module name
+ similiar to unknown. NIL is returned
+ if no hint can be given.
+*)
+
+PROCEDURE GetDefModuleSpellHint (defimp: CARDINAL) : String ;
+
+
END M2StackSpell.
diff --git a/gcc/m2/gm2-compiler/M2StackSpell.mod b/gcc/m2/gm2-compiler/M2StackSpell.mod
index 7a072ae..ac58c1c 100644
--- a/gcc/m2/gm2-compiler/M2StackSpell.mod
+++ b/gcc/m2/gm2-compiler/M2StackSpell.mod
@@ -31,7 +31,7 @@ FROM SymbolTable IMPORT NulSym, IsModule, IsDefImp, IsRecord,
FROM SymbolKey IMPORT PerformOperation ;
FROM DynamicStrings IMPORT InitStringCharStar, InitString, Mark, string, ConCat ;
FROM FormatStrings IMPORT Sprintf1, Sprintf2, Sprintf3 ;
-FROM NameKey IMPORT KeyToCharStar ;
+FROM NameKey IMPORT KeyToCharStar, NulName ;
FROM M2MetaError IMPORT MetaErrorStringT0 ;
FROM M2StackWord IMPORT StackOfWord, PushWord, PopWord,
@@ -39,6 +39,7 @@ FROM M2StackWord IMPORT StackOfWord, PushWord, PopWord,
NoOfItemsInStackWord, PeepWord ;
FROM CDataTypes IMPORT ConstCharStar ;
+FROM M2Batch IMPORT GetModuleNo ;
IMPORT m2spellcheck ;
FROM m2spellcheck IMPORT Candidates ;
@@ -97,6 +98,60 @@ END GetRecordField ;
(*
+ CandidatePushName - push a symbol name to the candidate list.
+*)
+
+PROCEDURE CandidatePushName (cand: Candidates; sym: CARDINAL) ;
+VAR
+ str: String ;
+BEGIN
+ str := InitStringCharStar (KeyToCharStar (GetSymName (sym))) ;
+ m2spellcheck.Push (cand, string (str)) ;
+ INC (PushCount)
+END CandidatePushName ;
+
+
+(*
+ GetDefModuleSpellHint - return a string describing a spelling
+ hint for the definition module name
+ similiar to defimp. The premise is that
+ defimp has been misspelt. NIL is returned
+ if no hint can be given.
+*)
+
+PROCEDURE GetDefModuleSpellHint (defimp: CARDINAL) : String ;
+VAR
+ i : CARDINAL ;
+ sym : CARDINAL ;
+ cand : Candidates ;
+ misspell,
+ content : ConstCharStar ;
+ HintStr : String ;
+BEGIN
+ HintStr := NIL ;
+ IF GetSymName (defimp) # NulName
+ THEN
+ misspell := KeyToCharStar (GetSymName (defimp)) ;
+ i := 1 ;
+ sym := GetModuleNo (i) ;
+ cand := m2spellcheck.InitCandidates () ;
+ WHILE sym # NulSym DO
+ IF sym # defimp
+ THEN
+ CandidatePushName (cand, sym)
+ END ;
+ INC (i) ;
+ sym := GetModuleNo (i)
+ END ;
+ content := m2spellcheck.FindClosestCharStar (cand, misspell) ;
+ HintStr := BuildHintStr (HintStr, content) ;
+ m2spellcheck.KillCandidates (cand)
+ END ;
+ RETURN AddPunctuation (HintStr, '?')
+END GetDefModuleSpellHint ;
+
+
+(*
Push - push a scope onto the spelling stack.
sym might be a ModSym, DefImpSym or a varsym
of a record type denoting a with statement.
@@ -184,6 +239,30 @@ END PushCandidates ;
(*
+ BuildHintStr - create the did you mean hint and return it
+ if HintStr is NIL. Otherwise append a hint
+ to HintStr. If content is NIL then return NIL.
+*)
+
+PROCEDURE BuildHintStr (HintStr: String; content: ConstCharStar) : String ;
+VAR
+ str: String ;
+BEGIN
+ IF content # NIL
+ THEN
+ str := InitStringCharStar (content) ;
+ IF HintStr = NIL
+ THEN
+ RETURN Sprintf1 (Mark (InitString (", did you mean %s")), str)
+ ELSE
+ RETURN Sprintf2 (Mark (InitString ("%s or %s")), HintStr, str)
+ END
+ END ;
+ RETURN NIL
+END BuildHintStr ;
+
+
+(*
CheckForHintStr - lookup a spell hint matching misspelt. If one exists
then append it to HintStr. Return HintStr.
*)
@@ -193,7 +272,6 @@ PROCEDURE CheckForHintStr (sym: CARDINAL;
VAR
cand : Candidates ;
content: ConstCharStar ;
- str : String ;
BEGIN
IF IsModule (sym) OR IsDefImp (sym) OR IsProcedure (sym) OR
IsRecord (sym) OR IsEnumeration (sym)
@@ -206,16 +284,7 @@ BEGIN
content := NIL
END ;
m2spellcheck.KillCandidates (cand) ;
- IF content # NIL
- THEN
- str := InitStringCharStar (content) ;
- IF HintStr = NIL
- THEN
- RETURN Sprintf1 (Mark (InitString (", did you mean %s")), str)
- ELSE
- RETURN Sprintf2 (Mark (InitString ("%s or %s")), HintStr, str)
- END
- END
+ HintStr := BuildHintStr (HintStr, content)
END ;
RETURN HintStr
END CheckForHintStr ;
diff --git a/gcc/match.pd b/gcc/match.pd
index 00493d6..6aaf80e 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -5658,10 +5658,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
/* Squash view_converts of BFRs if no precision is lost. */
(simplify
- (view_convert (BIT_FIELD_REF @1 @2 @3))
+ (view_convert (BIT_FIELD_REF@0 @1 @2 @3))
(if (is_gimple_reg_type (type)
&& (!INTEGRAL_TYPE_P (type)
- || type_has_mode_precision_p (type)))
+ || !INTEGRAL_TYPE_P (TREE_TYPE (@0))
+ || (type_has_mode_precision_p (type)
+ && type_has_mode_precision_p (TREE_TYPE (@0)))))
(BIT_FIELD_REF:type @1 @2 @3)))
/* For integral conversions with the same precision or pointer
@@ -12021,3 +12023,8 @@ and,
&& direct_internal_fn_supported_p (IFN_AVG_CEIL, type, OPTIMIZE_FOR_BOTH))
(IFN_AVG_CEIL @0 @2)))
#endif
+
+/* vec shift left insert (dup (A), A) -> dup(A) */
+(simplify
+ (IFN_VEC_SHL_INSERT (vec_duplicate@1 @0) @0)
+ @1)
diff --git a/gcc/range-op-mixed.h b/gcc/range-op-mixed.h
index 567b0cd..db31c2b 100644
--- a/gcc/range-op-mixed.h
+++ b/gcc/range-op-mixed.h
@@ -527,6 +527,47 @@ private:
const irange &outer) const;
};
+
+class operator_view : public range_operator
+{
+public:
+ using range_operator::fold_range;
+ using range_operator::op1_range;
+ using range_operator::update_bitmask;
+ bool fold_range (irange &r, tree type,
+ const irange &op1, const irange &op2,
+ relation_trio rel = TRIO_VARYING) const override;
+ bool fold_range (prange &r, tree type,
+ const prange &op1, const prange &op2,
+ relation_trio rel = TRIO_VARYING) const final override;
+ bool fold_range (irange &r, tree type,
+ const prange &op1, const irange &op2,
+ relation_trio rel = TRIO_VARYING) const final override;
+ bool fold_range (prange &r, tree type,
+ const irange &op1, const prange &op2,
+ relation_trio rel = TRIO_VARYING) const final override;
+
+ bool op1_range (irange &r, tree type,
+ const irange &lhs, const irange &op2,
+ relation_trio rel = TRIO_VARYING) const override;
+ bool op1_range (prange &r, tree type,
+ const prange &lhs, const prange &op2,
+ relation_trio rel = TRIO_VARYING) const final override;
+ bool op1_range (irange &r, tree type,
+ const prange &lhs, const irange &op2,
+ relation_trio rel = TRIO_VARYING) const final override;
+ bool op1_range (prange &r, tree type,
+ const irange &lhs, const prange &op2,
+ relation_trio rel = TRIO_VARYING) const final override;
+
+ void update_bitmask (irange &r, const irange &lh,
+ const irange &) const final override;
+private:
+// VIEW_CONVERT_EXPR works much like a cast between integral values, so use
+// the cast operator. Non-integrals are not handled as yet.
+ operator_cast m_cast;
+};
+
class operator_plus : public range_operator
{
public:
diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index 6b6bf78..cf5b8fe 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -60,6 +60,7 @@ operator_ge op_ge;
operator_identity op_ident;
operator_cst op_cst;
operator_cast op_cast;
+operator_view op_view;
operator_plus op_plus;
operator_abs op_abs;
operator_minus op_minus;
@@ -97,6 +98,7 @@ range_op_table::range_op_table ()
set (INTEGER_CST, op_cst);
set (NOP_EXPR, op_cast);
set (CONVERT_EXPR, op_cast);
+ set (VIEW_CONVERT_EXPR, op_view);
set (FLOAT_EXPR, op_cast);
set (FIX_TRUNC_EXPR, op_cast);
set (PLUS_EXPR, op_plus);
@@ -3247,6 +3249,80 @@ operator_cast::op1_range (irange &r, tree type,
return true;
}
+// VIEW_CONVERT_EXPR works like a cast between integral values.
+// If the number of bits are not the same, behaviour is undefined,
+// so cast behaviour still works.
+
+bool
+operator_view::fold_range (irange &r, tree type,
+ const irange &op1, const irange &op2,
+ relation_trio rel) const
+{
+ return m_cast.fold_range (r, type, op1, op2, rel);
+}
+
+bool
+operator_view::fold_range (prange &r, tree type,
+ const prange &op1, const prange &op2,
+ relation_trio rel) const
+{
+ return m_cast.fold_range (r, type, op1, op2, rel);
+}
+bool
+operator_view::fold_range (irange &r, tree type,
+ const prange &op1, const irange &op2,
+ relation_trio rel) const
+{
+ return m_cast.fold_range (r, type, op1, op2, rel);
+}
+
+bool
+operator_view::fold_range (prange &r, tree type,
+ const irange &op1, const prange &op2,
+ relation_trio rel) const
+{
+ return m_cast.fold_range (r, type, op1, op2, rel);
+}
+
+bool
+operator_view::op1_range (irange &r, tree type,
+ const irange &lhs, const irange &op2,
+ relation_trio rel) const
+{
+ return m_cast.op1_range (r, type, lhs, op2, rel);
+}
+
+bool
+operator_view::op1_range (prange &r, tree type,
+ const prange &lhs, const prange &op2,
+ relation_trio rel) const
+{
+ return m_cast.op1_range (r, type, lhs, op2, rel);
+}
+
+bool
+operator_view::op1_range (irange &r, tree type,
+ const prange &lhs, const irange &op2,
+ relation_trio rel) const
+{
+ return m_cast.op1_range (r, type, lhs, op2, rel);
+}
+
+bool
+operator_view::op1_range (prange &r, tree type,
+ const irange &lhs, const prange &op2,
+ relation_trio rel) const
+{
+ return m_cast.op1_range (r, type, lhs, op2, rel);
+}
+
+void
+operator_view::update_bitmask (irange &r, const irange &lh,
+ const irange &rh) const
+{
+ m_cast.update_bitmask (r, lh, rh);
+}
+
class operator_logical_and : public range_operator
{
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 40f1582..175b1df 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,61 @@
+2025-10-29 Andrew MacLeod <amacleod@redhat.com>
+
+ PR tree-optimization/91191
+ * gcc.dg/pr91191.c: New.
+
+2025-10-29 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/122165
+ * gfortran.dg/pdt_64.f03: New test.
+
+2025-10-29 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/70102
+ * gfortran.dg/vect/pr70102.f: New testcase.
+
+2025-10-29 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/122433
+ PR fortran/122434
+ * gfortran.dg/pdt_62.f03: New test.
+ * gfortran.dg/pdt_63.f03: New test.
+
+2025-10-29 Lulu Cheng <chenglulu@loongson.cn>
+
+ PR target/122097
+ * gcc.target/loongarch/pr122097.c: New test.
+
+2025-10-29 Xi Ruoyao <xry111@xry111.site>
+
+ * gcc.target/loongarch/trap-default.c: New test.
+ * gcc.target/loongarch/trap-1.c: New test.
+
+2025-10-28 Yuao Ma <c8ef@outlook.com>
+
+ PR fortran/122342
+ * gfortran.dg/coarray_atomic_5.f90: Update testcase.
+ * gfortran.dg/team_form_3.f90: Likewise.
+
+2025-10-28 Artemiy Volkov <artemiy.volkov@arm.com>
+
+ * gcc.dg/tree-ssa/forwprop-42.c: New test.
+
+2025-10-28 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/specs/generic_inst5.ads: New test.
+ * gnat.dg/specs/generic_inst5_pkg1.ads: New helper.
+ * gnat.dg/specs/generic_inst5_pkg2.ads: Likewise.
+
+2025-10-28 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/specs/generic_inst4-child2.ads: New test.
+ * gnat.dg/specs/generic_inst4.ads: New helper.
+ * gnat.dg/specs/generic_inst4-child1.ads: Likewise.
+
+2025-10-28 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/specs/generic_inst3.ads: Add dg-do directive.
+
2025-10-27 Nathaniel Shead <nathanieloshead@gmail.com>
PR c++/122422
diff --git a/gcc/testsuite/g++.dg/tree-ssa/copy-prop-aggregate-sra-1.C b/gcc/testsuite/g++.dg/tree-ssa/copy-prop-aggregate-sra-1.C
new file mode 100644
index 0000000..52f1779
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/copy-prop-aggregate-sra-1.C
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-forwprop1-details -fdump-tree-esra-details -fexceptions" } */
+
+/* PR tree-optimization/122247 */
+
+struct s1
+{
+ int t[1024];
+};
+
+struct s1 f(void);
+
+void g(int a, int b, int );
+void p(struct s1);
+void h(struct s1 outer)
+{
+ {
+ struct s1 inner = outer;
+ p(inner);
+ }
+ g(outer.t[0], outer.t[1], outer.t[2]);
+}
+/* Forwprop should be able to copy prop the copy of `inner = outer` to the call of p.
+ Also remove this copy. */
+
+/* { dg-final { scan-tree-dump-times "after previous" 1 "forwprop1" } } */
+/* { dg-final { scan-tree-dump-times "Removing dead store stmt inner = outer" 1 "forwprop1" } } */
+
+/* The extra copy that was done by inlining is removed so SRA should not decide to cause
+ inner nor outer to be scalarized even for the 3 elements accessed afterwards. */
+/* { dg-final { scan-tree-dump-times "Disqualifying inner" 1 "esra" } } */
+/* { dg-final { scan-tree-dump-times "Disqualifying outer" 1 "esra" } } */
+
diff --git a/gcc/testsuite/g++.dg/tree-ssa/copy-prop-aggregate-sra-2.C b/gcc/testsuite/g++.dg/tree-ssa/copy-prop-aggregate-sra-2.C
new file mode 100644
index 0000000..0b05d5d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/copy-prop-aggregate-sra-2.C
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-forwprop1-details -fdump-tree-esra-details -fexceptions" } */
+
+/* PR tree-optimization/122247 */
+
+struct s1
+{
+ int t[1024];
+};
+
+struct s1 f(void);
+
+void g(int a, int b, int );
+void p(struct s1);
+void h(struct s1 outer)
+{
+ struct s1 inner = outer;
+ p(inner);
+ g(outer.t[0], outer.t[1], outer.t[2]);
+}
+/* Forwprop should be able to copy prop the copy of `inner = outer` to the call of p.
+ Also remove this copy. */
+
+/* { dg-final { scan-tree-dump-times "after previous" 1 "forwprop1" } } */
+/* { dg-final { scan-tree-dump-times "Removing dead store stmt inner = outer" 1 "forwprop1" } } */
+
+/* The extra copy that was done by inlining is removed so SRA should not decide to cause
+ inner nor outer to be scalarized even for the 3 elements accessed afterwards. */
+/* { dg-final { scan-tree-dump-times "Disqualifying inner" 1 "esra" } } */
+/* { dg-final { scan-tree-dump-times "Disqualifying outer" 1 "esra" } } */
+
diff --git a/gcc/testsuite/gcc.dg/builtin-assume-aligned-1.c b/gcc/testsuite/gcc.dg/builtin-assume-aligned-1.c
index a74ecce..01aa884 100644
--- a/gcc/testsuite/gcc.dg/builtin-assume-aligned-1.c
+++ b/gcc/testsuite/gcc.dg/builtin-assume-aligned-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O3 -fdump-tree-optimized" } */
+/* { dg-options "-O3 -fno-tree-vectorize -fdump-tree-optimized-alias" } */
void
test1 (double *out1, double *out2, double *out3, double *in1,
@@ -19,6 +19,8 @@ test1 (double *out1, double *out2, double *out3, double *in1,
}
}
+/* { dg-final { scan-tree-dump-times " ALIGN = 16, MISALIGN = 0" 5 "optimized" } } */
+
void
test2 (double *out1, double *out2, double *out3, double *in1,
double *in2, int len)
@@ -37,4 +39,8 @@ test2 (double *out1, double *out2, double *out3, double *in1,
}
}
-/* { dg-final { scan-tree-dump-not "__builtin_assume_aligned" "optimized" } } */
+
+/* { dg-final { scan-tree-dump-times " ALIGN = 32" 5 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " ALIGN = 32, MISALIGN = 16" 4 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " ALIGN = 32, MISALIGN = 0" 1 "optimized" } } */
+
diff --git a/gcc/testsuite/gcc.dg/cpp/escape-3.i b/gcc/testsuite/gcc.dg/cpp/escape-3.i
index 6eb7dc4..cb47581 100644
--- a/gcc/testsuite/gcc.dg/cpp/escape-3.i
+++ b/gcc/testsuite/gcc.dg/cpp/escape-3.i
@@ -13,4 +13,4 @@ int foo (int a, int b)
}
/* Test for "/some\\directory" instead of "/some\\\\directory" */
-/* { dg-final { scan-assembler { "/some\\\\directory" } } } */
+/* { dg-final { scan-assembler "/some\\\\\\\\directory" } } */
diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-prune-4.c b/gcc/testsuite/gcc.dg/debug/btf/btf-prune-4.c
new file mode 100644
index 0000000..3f19559
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/btf/btf-prune-4.c
@@ -0,0 +1,61 @@
+/* Test that -gprune-btf does not prune at typedefs. */
+
+/* { dg-do compile } */
+/* { dg-options "-gbtf -gprune-btf -dA" } */
+
+/* We must have the full definitions of td1 and td3. Neither are pruned.
+ td2 will be skipped entirely, only because the only reference to
+ it is through struct inner, which is pruned because inner itself
+ is only used as a pointer member.
+
+ In general, we must never get an anonymous FWD; the only FWD in this
+ case will be for 'inner' */
+
+/* Exactly 1 FWD for inner and no anonymous FWD. */
+/* { dg-final { scan-assembler-times "TYPE \[0-9\]+ BTF_KIND_FWD" 1 } } */
+/* { dg-final { scan-assembler-not "TYPE \[0-9\]+ BTF_KIND_FWD ''" } } */
+/* { dg-final { scan-assembler " BTF_KIND_FWD 'inner'" } } */
+
+/* One anonymous struct for td1 and one anonymous union for td3. */
+/* { dg-final { scan-assembler-times "TYPE \[0-9\]+ BTF_KIND_STRUCT ''" 1 } } */
+/* { dg-final { scan-assembler-times "TYPE \[0-9\]+ BTF_KIND_UNION ''" 1 } } */
+
+/* The two remaining typedefs. */
+/* { dg-final { scan-assembler " BTF_KIND_TYPEDEF 'td1'" } } */
+/* { dg-final { scan-assembler " BTF_KIND_TYPEDEF 'td3'" } } */
+
+typedef struct {
+ int x;
+ char c;
+} td1;
+
+typedef struct {
+ long l;
+ char b[4];
+} td2;
+
+typedef union {
+ long l;
+ unsigned short s[2];
+} td3;
+
+struct inner {
+ char a;
+ td2 *ptd;
+ long z;
+};
+
+struct A {
+ td1 *pt;
+ struct inner *in;
+ unsigned long l[4];
+};
+
+struct A foo;
+
+struct B {
+ int x;
+ td3 **ppptd3;
+};
+
+struct B bar;
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-4.c b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-4.c
new file mode 100644
index 0000000..6fdcdc6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-4.c
@@ -0,0 +1,28 @@
+/* Test DWARF generation for decl_tags on global decls appearing multiple
+ times with different decl_tags. PR122248. */
+/* { dg-do compile } */
+/* { dg-options "-gdwarf -dA" } */
+
+#define __tag1 __attribute__((btf_decl_tag ("tag1")))
+#define __tag2 __attribute__((btf_decl_tag ("tag2")))
+#define __tag3 __attribute__((btf_decl_tag ("tag3")))
+#define __tag4 __attribute__((btf_decl_tag ("tag4")))
+
+int foo __tag1;
+int foo __tag2;
+
+/* Result: foo has __tag1 and __tag2. */
+
+int bar __tag3;
+int bar;
+
+/* Result: bar has __tag3. */
+
+int baz;
+int baz __tag4;
+
+/* Result: baz has __tag4. */
+
+/* { dg-final { scan-assembler-times "DIE \\(\[^\n\]*\\) DW_TAG_GNU_annotation" 4 } } */
+/* { dg-final { scan-assembler-times " DW_AT_GNU_annotation" 4 } } */
+
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-5.c b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-5.c
new file mode 100644
index 0000000..c7cb60c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-5.c
@@ -0,0 +1,35 @@
+/* Test DWARF generation for decl_tags on global decls appearing multiple
+ times with different decl_tags. PR122248. */
+/* { dg-do compile } */
+/* { dg-options "-gdwarf -dA" } */
+
+#define __tag1 __attribute__((btf_decl_tag ("tag1")))
+#define __tag2 __attribute__((btf_decl_tag ("tag2")))
+#define __tag3 __attribute__((btf_decl_tag ("tag3")))
+
+struct S
+{
+ int x;
+ char c;
+};
+
+extern struct S foo __tag1;
+struct S foo __tag2;
+
+/* Result: non-completing variable DIE for 'foo' has tag1, and the
+ completing DIE (with AT_specification) for 'foo' has tag2 -> tag1. */
+
+extern int a __tag3;
+int a;
+
+/* Result: non-completing variable DIE for a has tag3, and the
+ completing DIE (with AT_specification) for 'a' also refers to tag3. */
+
+/* { dg-final { scan-assembler-times "DIE \\(\[^\n\]*\\) DW_TAG_GNU_annotation" 3 } } */
+
+/* 5 AT_GNU annotations:
+ - foo -> tag1
+ - foo -> tag2 -> tag1
+ - a -> tag3
+ - a -> tag3 */
+/* { dg-final { scan-assembler-times " DW_AT_GNU_annotation" 5 } } */
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-6.c b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-6.c
new file mode 100644
index 0000000..dd89d11
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-btf-decl-tag-6.c
@@ -0,0 +1,24 @@
+/* Test DWARF generation for decl_tags on global decls appearing multiple
+ times with different decl_tags. PR122248. */
+/* { dg-do compile } */
+/* { dg-options "-gdwarf -dA" } */
+
+#define __tag1 __attribute__((btf_decl_tag ("tag1")))
+#define __tag2 __attribute__((btf_decl_tag ("tag2")))
+#define __tag3 __attribute__((btf_decl_tag ("tag3")))
+
+__tag1
+extern int
+do_thing (int);
+
+__tag2
+__tag3
+int
+do_thing (int x)
+{
+ return x * x;
+}
+
+/* Result: do_thing has all 3 tags. */
+/* { dg-final { scan-assembler-times "DIE \\(\[^\n\]*\\) DW_TAG_GNU_annotation" 3 } } */
+/* { dg-final { scan-assembler-times " DW_AT_GNU_annotation" 3 } } */
diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-10.c b/gcc/testsuite/gcc.dg/pointer-counted-by-10.c
new file mode 100644
index 0000000..e2bd018
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pointer-counted-by-10.c
@@ -0,0 +1,8 @@
+/* Testing the correct usage of attribute counted_by for pointer to void. */
+/* { dg-do compile } */
+/* { dg-options "-O0 -Wpointer-arith" } */
+
+struct pointer_array {
+ int count;
+ void *array __attribute__ ((counted_by (count))); /* { dg-warning "attribute is used for a pointer to void" } */
+};
diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-4-void.c b/gcc/testsuite/gcc.dg/pointer-counted-by-4-void.c
new file mode 100644
index 0000000..71bac95
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pointer-counted-by-4-void.c
@@ -0,0 +1,6 @@
+/* Test the attribute counted_by for pointer field and its usage in
+ * __builtin_dynamic_object_size. */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+#define PTR_TYPE void
+#include "pointer-counted-by-4.c"
diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by.c b/gcc/testsuite/gcc.dg/pointer-counted-by.c
index 0f18828..5e9ebef 100644
--- a/gcc/testsuite/gcc.dg/pointer-counted-by.c
+++ b/gcc/testsuite/gcc.dg/pointer-counted-by.c
@@ -49,9 +49,10 @@ struct pointer_array_6 {
int *array_6 __attribute__ ((counted_by (days)));
};
+/* counted_by is allowed for pointer to void when GNU extension is enabled. */
struct pointer_array_7 {
int count;
- void *array_7 __attribute__ ((counted_by (count))); /* { dg-error "attribute is not allowed for a pointer to void" } */
+ void *array_7 __attribute__ ((counted_by (count)));
};
struct pointer_array_8 {
diff --git a/gcc/testsuite/gcc.dg/pr116815.c b/gcc/testsuite/gcc.dg/pr116815.c
new file mode 100644
index 0000000..b5f1330
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr116815.c
@@ -0,0 +1,57 @@
+/* PR target/116815 */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+[[gnu::always_inline]]
+inline unsigned min (unsigned a, unsigned b)
+{
+ return (a < b) ? a : b;
+}
+
+[[gnu::always_inline]]
+inline unsigned max (unsigned a, unsigned b)
+{
+ return (a > b) ? a : b;
+}
+
+[[gnu::noipa]] unsigned
+umaxadd (unsigned a, unsigned b)
+{
+ return max (a + b, a);
+}
+
+[[gnu::noipa]] unsigned
+umaxsub (unsigned a, unsigned b)
+{
+ return max (a - b, a);
+}
+
+[[gnu::noipa]] unsigned
+uminadd (unsigned a, unsigned b)
+{
+ return min (a + b, a);
+}
+
+[[gnu::noipa]] unsigned
+uminsub (unsigned a, unsigned b)
+{
+ return min (a - b, a);
+}
+
+int
+main ()
+{
+ /* Overflows to 0x30000000. */
+ if (umaxadd (0x90000000, 0xa0000000) != 0x90000000)
+ __builtin_abort ();
+
+ if (uminadd (0x90000000, 0xa0000000) != 0x30000000)
+ __builtin_abort ();
+
+ /* Underflows to 0x60000000. */
+ if (umaxsub (0x00000000, 0xa0000000) != 0x60000000)
+ __builtin_abort ();
+
+ if (uminsub (0x00000000, 0xa0000000) != 0x00000000)
+ __builtin_abort ();
+}
diff --git a/gcc/testsuite/gcc.dg/pr41488.c b/gcc/testsuite/gcc.dg/pr41488.c
index 1e4bf19..a7ba367 100644
--- a/gcc/testsuite/gcc.dg/pr41488.c
+++ b/gcc/testsuite/gcc.dg/pr41488.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-ivcanon-scev" } */
+/* { dg-options "-O2 -fno-tree-scev-cprop -fdump-tree-ivcanon-scev" } */
struct struct_t
{
diff --git a/gcc/testsuite/gcc.dg/pr91191.c b/gcc/testsuite/gcc.dg/pr91191.c
new file mode 100644
index 0000000..7bf727e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr91191.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp" } */
+
+unsigned char reg(_Bool b) {
+ union U {
+ unsigned char f0;
+ _Bool f1;
+ };
+ union U u;
+ u.f1 = b;
+ if (u.f0 > 1) {
+ // This cannot happen
+ // if b is only allowed
+ // to be 0 or 1:
+ return 42;
+ }
+ return 13;
+}
+
+/* { dg-final { scan-tree-dump "return 13" "evrp" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ctz-ch.c b/gcc/testsuite/gcc.dg/tree-ssa/ctz-ch.c
new file mode 100644
index 0000000..5d72597
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ctz-ch.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+typedef unsigned long BITMAP_WORD;
+
+bool
+bmp_iter_set (BITMAP_WORD bits, unsigned *bit_no)
+{
+ /* If our current word is nonzero, it contains the bit we want. */
+ if (bits)
+ {
+ while (!(bits & 1))
+ {
+ bits >>= 1;
+ *bit_no += 1;
+ }
+ return true;
+ }
+
+ return false;
+}
+
+/* { dg-final { scan-tree-dump-times "__builtin_ctz|\\.CTZ" 1 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ctz-char.c b/gcc/testsuite/gcc.dg/tree-ssa/ctz-char.c
index 3cd166a..fa8b7f3 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ctz-char.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ctz-char.c
@@ -1,6 +1,6 @@
/* { dg-do run } */
/* { dg-require-effective-target ctz } */
-/* { dg-options "-O2 -fno-tree-ch -fdump-tree-optimized" } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
#define PREC (__CHAR_BIT__)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ctz-complement-char.c b/gcc/testsuite/gcc.dg/tree-ssa/ctz-complement-char.c
index b9afe88..5ebc321 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ctz-complement-char.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ctz-complement-char.c
@@ -1,6 +1,6 @@
/* { dg-do run } */
/* { dg-require-effective-target ctz } */
-/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-options "-O2 -fno-tree-ch -fdump-tree-optimized" } */
#define PREC (__CHAR_BIT__)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ctz-complement-int.c b/gcc/testsuite/gcc.dg/tree-ssa/ctz-complement-int.c
index d2702a6..0ce4b6b 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ctz-complement-int.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ctz-complement-int.c
@@ -1,6 +1,6 @@
/* { dg-do run } */
/* { dg-require-effective-target ctz } */
-/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-options "-O2 -fno-tree-ch -fdump-tree-optimized" } */
#define PREC (__CHAR_BIT__ * __SIZEOF_INT__)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ctz-complement-long-long.c b/gcc/testsuite/gcc.dg/tree-ssa/ctz-complement-long-long.c
index 1ea0d5d..f98bec0 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ctz-complement-long-long.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ctz-complement-long-long.c
@@ -1,6 +1,6 @@
/* { dg-do run } */
/* { dg-require-effective-target ctzll } */
-/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-options "-O2 -fno-tree-ch -fdump-tree-optimized" } */
#define PREC (__CHAR_BIT__ * __SIZEOF_LONG_LONG__)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ctz-complement-long.c b/gcc/testsuite/gcc.dg/tree-ssa/ctz-complement-long.c
index 80fb02d..8edb372 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ctz-complement-long.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ctz-complement-long.c
@@ -1,6 +1,6 @@
/* { dg-do run } */
/* { dg-require-effective-target ctzl } */
-/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-options "-O2 -fno-tree-ch -fdump-tree-optimized" } */
#define PREC (__CHAR_BIT__ * __SIZEOF_LONG__)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ctz-int.c b/gcc/testsuite/gcc.dg/tree-ssa/ctz-int.c
index 7f63493..2bf3ae6 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ctz-int.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ctz-int.c
@@ -1,6 +1,6 @@
/* { dg-do run } */
/* { dg-require-effective-target ctz } */
-/* { dg-options "-O2 -fno-tree-ch -fdump-tree-optimized" } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
#define PREC (__CHAR_BIT__ * __SIZEOF_INT__)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ctz-long-long.c b/gcc/testsuite/gcc.dg/tree-ssa/ctz-long-long.c
index 924f61b..2e15948 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ctz-long-long.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ctz-long-long.c
@@ -1,6 +1,6 @@
/* { dg-do run } */
/* { dg-require-effective-target ctzll } */
-/* { dg-options "-O2 -fno-tree-ch -fdump-tree-optimized" } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
#define PREC (__CHAR_BIT__ * __SIZEOF_LONG_LONG__)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ctz-long.c b/gcc/testsuite/gcc.dg/tree-ssa/ctz-long.c
index 178945d..2e3be65 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ctz-long.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ctz-long.c
@@ -1,6 +1,6 @@
/* { dg-do run } */
/* { dg-require-effective-target ctzl } */
-/* { dg-options "-O2 -fno-tree-ch -fdump-tree-optimized" } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
#define PREC (__CHAR_BIT__ * __SIZEOF_LONG__)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr122478.c b/gcc/testsuite/gcc.dg/tree-ssa/pr122478.c
new file mode 100644
index 0000000..bc63f71
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr122478.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-additional-options "-fgimple" } */
+
+unsigned char __GIMPLE (ssa)
+foo (unsigned short mask__701)
+{
+ _Bool _19;
+ unsigned char _180;
+
+__BB(2):
+ _19 = __BIT_FIELD_REF <_Bool> (mask__701, 1, 12);
+ _180 = __VIEW_CONVERT<unsigned char>(_19);
+ return _180;
+}
+
+/* { dg-final { scan-tree-dump-times "VIEW_CONVERT_EXPR" "optimized" 1 } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr92834.c b/gcc/testsuite/gcc.dg/tree-ssa/pr92834.c
index 889048d..70acf74 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr92834.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr92834.c
@@ -1,8 +1,8 @@
/* PR tree-optimization/92834 */
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-optimized" } */
-/* { dg-final { scan-tree-dump-times "MIN_EXPR <" 8 "optimized" } } */
-/* { dg-final { scan-tree-dump-times "MAX_EXPR <" 8 "optimized" } } */
+/* { dg-options "-O2 -fdump-tree-phiopt1" } */
+/* { dg-final { scan-tree-dump-times "MIN_EXPR <" 16 "phiopt1" } } */
+/* { dg-final { scan-tree-dump-times "MAX_EXPR <" 16 "phiopt1" } } */
static inline unsigned
umax1 (unsigned a, unsigned b)
diff --git a/gcc/testsuite/gcc.dg/vect/slp-reduc-13.c b/gcc/testsuite/gcc.dg/vect/slp-reduc-13.c
new file mode 100644
index 0000000..00e91fc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/slp-reduc-13.c
@@ -0,0 +1,66 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_int } */
+/* { dg-additional-options "-fgimple" } */
+
+int q[2];
+
+void __GIMPLE (ssa,guessed_local(16535624),startwith("loop"))
+foo (int * r)
+{
+ int i;
+ int sum2;
+ int sum1;
+ int _1;
+ long unsigned int _2;
+ long unsigned int _3;
+ int * _4;
+ int _24;
+ __SIZETYPE__ _6;
+ __SIZETYPE__ _7;
+ int * _8;
+ int _9;
+ int _13;
+ unsigned int _30;
+ unsigned int _31;
+
+ __BB(2,guessed_local(16535624)):
+ goto __BB3(precise(134217728));
+
+ __BB(3,loop_header(1),guessed_local(1057206200)):
+ sum1_5 = __PHI (__BB5: sum1_18, __BB2: 0);
+ sum2_26 = __PHI (__BB5: sum2_19, __BB2: 0);
+ i_28 = __PHI (__BB5: i_20, __BB2: 0);
+ _31 = __PHI (__BB5: _30, __BB2: 64u);
+ _1 = i_28 * 2;
+ _2 = (long unsigned int) _1;
+ _3 = _2 * 4ul;
+ _4 = r_17(D) + _3;
+ _24 = __MEM <int> (_4);
+ /* Deliberately have swapped operands here */
+ sum1_18 = sum1_5 + _24;
+ _13 = _1 + 1;
+ _6 = (__SIZETYPE__) _13;
+ _7 = _6 * 4ul;
+ _8 = r_17(D) + _7;
+ _9 = __MEM <int> (_8);
+ /* versus here. */
+ sum2_19 = _9 + sum2_26;
+ i_20 = i_28 + 1;
+ _30 = _31 - 1u;
+ if (_30 != 0u)
+ goto __BB5(guessed(132118446));
+ else
+ goto __BB4(guessed(2099282));
+
+ __BB(5,guessed_local(1040670576)):
+ goto __BB3(precise(134217728));
+
+ __BB(4,guessed_local(16535624)):
+ sum1_33 = __PHI (__BB3: sum1_18);
+ sum2_32 = __PHI (__BB3: sum2_19);
+ q[0] = sum1_33;
+ q[1] = sum2_32;
+ return;
+}
+
+/* { dg-final { scan-tree-dump "SLP discovery of size 2 reduction group succeeded" "vect" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/dup-insr-1.c b/gcc/testsuite/gcc.target/aarch64/sve/dup-insr-1.c
new file mode 100644
index 0000000..41dcbba
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/dup-insr-1.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-optimized" } */
+/* PR target/116075 */
+
+#include <arm_sve.h>
+
+svint8_t f(void)
+{
+ svint8_t tt;
+ tt = svdup_s8 (0);
+ tt = svinsr (tt, 0);
+ return tt;
+}
+
+svint8_t f1(int8_t t)
+{
+ svint8_t tt;
+ tt = svdup_s8 (t);
+ tt = svinsr (tt, t);
+ return tt;
+}
+
+/* The above 2 functions should have removed the VEC_SHL_INSERT. */
+
+/* { dg-final { scan-tree-dump-not ".VEC_SHL_INSERT " "optimized" } } */
+
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/dup-insr-2.c b/gcc/testsuite/gcc.target/aarch64/sve/dup-insr-2.c
new file mode 100644
index 0000000..8eafe97
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/dup-insr-2.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-optimized" } */
+/* PR target/116075 */
+
+#include <arm_sve.h>
+
+svint8_t f(int8_t t)
+{
+ svint8_t tt;
+ tt = svdup_s8 (0);
+ tt = svinsr (tt, t);
+ return tt;
+}
+
+svint8_t f1(int8_t t)
+{
+ svint8_t tt;
+ tt = svdup_s8 (t);
+ tt = svinsr (tt, 0);
+ return tt;
+}
+
+/* The above 2 functions should not have removed the VEC_SHL_INSERT. */
+
+/* { dg-final { scan-tree-dump-times ".VEC_SHL_INSERT " 2 "optimized" } } */
+
diff --git a/gcc/testsuite/gcc.target/avr/pr121198.c b/gcc/testsuite/gcc.target/avr/pr121198.c
new file mode 100644
index 0000000..551247e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/avr/pr121198.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-Os -mmcu=atmega8" } */
+
+long
+test (void)
+{
+ long x;
+ __asm__ ("" : "={r22}" (x));
+ return x;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr116815.c b/gcc/testsuite/gcc.target/i386/pr116815.c
new file mode 100644
index 0000000..1cd2f72
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr116815.c
@@ -0,0 +1,31 @@
+/* PR target/116815 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-march=pentiumpro" { target ia32 } } */
+
+static inline __attribute__ ((always_inline))
+unsigned max (unsigned a, unsigned b) { return a > b ? a : b; }
+
+static inline __attribute__ ((always_inline))
+unsigned min (unsigned a, unsigned b) { return a < b ? a : b; }
+
+#define OPERATION(op, type, N, exp1, exp2) \
+ unsigned u##op##type##N (unsigned a, unsigned b) { return op (exp1, exp2); }
+
+OPERATION (max, add, 1, a, a + b)
+OPERATION (max, add, 2, a, b + a)
+OPERATION (max, add, 3, a + b, a)
+OPERATION (max, add, 4, b + a, a)
+
+OPERATION (min, add, 1, a, a + b)
+OPERATION (min, add, 2, a, b + a)
+OPERATION (min, add, 3, a + b, a)
+OPERATION (min, add, 4, b + a, a)
+
+OPERATION (max, sub, 1, a, a - b)
+OPERATION (max, sub, 2, a - b, a)
+
+OPERATION (min, sub, 1, a, a - b)
+OPERATION (min, sub, 2, a - b, a)
+
+/* { dg-final { scan-assembler-not "cmp" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr122457.c b/gcc/testsuite/gcc.target/i386/pr122457.c
new file mode 100644
index 0000000..dc57fb2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr122457.c
@@ -0,0 +1,4 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=x86-64-v4 -mavxvnniint16" } */
+
+#include "vnniint16-auto-vectorize-2.c"
diff --git a/gcc/testsuite/gcc.target/loongarch/conditional-move-opt-1.c b/gcc/testsuite/gcc.target/loongarch/conditional-move-opt-1.c
index ed13471..47802aa 100644
--- a/gcc/testsuite/gcc.target/loongarch/conditional-move-opt-1.c
+++ b/gcc/testsuite/gcc.target/loongarch/conditional-move-opt-1.c
@@ -27,7 +27,7 @@ void
test_lt ()
{
if (lm < ln)
- lr *= (1 << 16);
+ lr += (1 << 16);
lr += lm;
}
@@ -35,7 +35,7 @@ void
test_le ()
{
if (lm <= ln)
- lr = lm * ((long)1 << 32);
+ lr = lm + ((long)1 << 32);
else
lr = lm;
lr += lm;
diff --git a/gcc/testsuite/gcc.target/loongarch/conditional-move-opt-2.c b/gcc/testsuite/gcc.target/loongarch/conditional-move-opt-2.c
index ac72d4d..743fd5e 100644
--- a/gcc/testsuite/gcc.target/loongarch/conditional-move-opt-2.c
+++ b/gcc/testsuite/gcc.target/loongarch/conditional-move-opt-2.c
@@ -29,7 +29,7 @@ void
test_lez ()
{
if (lm <= 0)
- lr &= (1 << 16);
+ lr |= (1 << 16);
lr += lm;
}
diff --git a/gcc/testsuite/gcc.target/loongarch/conditional-move-opt-3.c b/gcc/testsuite/gcc.target/loongarch/conditional-move-opt-3.c
new file mode 100644
index 0000000..9588798
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/conditional-move-opt-3.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler "maskeqz" } } */
+/* { dg-final { scan-assembler "masknez" } } */
+
+extern long lm, ln, lr;
+
+void
+test_and ()
+{
+ if (lm < 0)
+ lr &= (1 << 16);
+ lr += lm;
+}
diff --git a/gcc/testsuite/gcc.target/loongarch/fnmam4-vec.c b/gcc/testsuite/gcc.target/loongarch/fnmam4-vec.c
new file mode 100644
index 0000000..0969303
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/fnmam4-vec.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-Ofast -mlasx -ftree-vectorize" } */
+/* { dg-require-effective-target loongarch_asx } */
+
+void
+foo (float *u, float x, float *y, float z)
+{
+ int i;
+ for (i = 0; i < 1024; i++)
+ *(u++) = (x - y[i] * z);
+}
+
+/* { dg-final { scan-assembler-not "\tvori.b"} } */
+/* { dg-final { scan-assembler-not "\txvori.b"} } */
diff --git a/gcc/testsuite/gcc.target/loongarch/pr122097.c b/gcc/testsuite/gcc.target/loongarch/pr122097.c
new file mode 100644
index 0000000..5d32b19
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/pr122097.c
@@ -0,0 +1,271 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -mabi=lp64d -mlsx" } */
+/* { dg-final { scan-assembler "vbitseti\.d\t\\\$vr\[0-9\]+,\\\$vr\[0-9\]+,63" } } */
+
+typedef long unsigned int size_t;
+typedef unsigned char simde__mmask8;
+typedef long simde__m128i __attribute__ ((__aligned__ ((16))))
+__attribute__ ((__vector_size__ (16))) __attribute__ ((__may_alias__));
+typedef union
+{
+
+ __attribute__ ((__aligned__ ((16)))) long i64
+ __attribute__ ((__vector_size__ (16))) __attribute__ ((__may_alias__));
+} simde__m128i_private;
+typedef double simde_float64;
+typedef simde_float64 simde__m128d __attribute__ ((__aligned__ ((16))))
+__attribute__ ((__vector_size__ (16))) __attribute__ ((__may_alias__));
+typedef long int int_fast32_t;
+typedef union
+{
+
+ __attribute__ ((__aligned__ ((16)))) int_fast32_t i32f
+ __attribute__ ((__vector_size__ (16))) __attribute__ ((__may_alias__));
+ __attribute__ ((__aligned__ ((16)))) long i64
+ __attribute__ ((__vector_size__ (16))) __attribute__ ((__may_alias__));
+ __attribute__ ((__aligned__ ((16)))) simde_float64 f64
+ __attribute__ ((__vector_size__ (16))) __attribute__ ((__may_alias__));
+} simde__m128d_private;
+__attribute__ ((__always_inline__)) inline static simde__m128d
+simde__m128d_from_private (simde__m128d_private v)
+{
+ simde__m128d r;
+ __builtin_memcpy (&r, &v, sizeof (r));
+ return r;
+}
+
+__attribute__ ((__always_inline__)) inline static simde__m128d
+simde_mm_set_pd (simde_float64 e1, simde_float64 e0)
+{
+
+ simde__m128d_private r_;
+ r_.f64[0] = e0;
+ r_.f64[1] = e1;
+
+ return simde__m128d_from_private (r_);
+}
+__attribute__ ((__always_inline__)) inline static simde__m128i
+simde_mm_castpd_si128 (simde__m128d a)
+{
+ simde__m128i r;
+ __builtin_memcpy (&r, &a, sizeof (a));
+ return r;
+}
+
+__attribute__ ((__always_inline__)) inline static simde__m128i
+simde__m128i_from_private (simde__m128i_private v)
+{
+ simde__m128i r;
+ __builtin_memcpy (&r, &v, sizeof (r));
+ return r;
+}
+
+__attribute__ ((__always_inline__)) inline static simde__m128i_private
+simde__m128i_to_private (simde__m128i v)
+{
+ simde__m128i_private r;
+ __builtin_memcpy (&r, &v, sizeof (r));
+ return r;
+}
+__attribute__ ((__always_inline__)) inline static simde__m128d
+simde_mm_castsi128_pd (simde__m128i a)
+{
+ simde__m128d r;
+ __builtin_memcpy (&r, &a, sizeof (a));
+ return r;
+}
+
+__attribute__ ((__always_inline__)) inline static simde__m128i
+simde_mm_mask_mov_epi64 (simde__m128i src, simde__mmask8 k, simde__m128i a)
+{
+
+ simde__m128i_private src_ = simde__m128i_to_private (src),
+ a_ = simde__m128i_to_private (a), r_;
+
+ for (size_t i = 0; i < (sizeof (r_.i64) / sizeof (r_.i64[0])); i++)
+ {
+ r_.i64[i] = ((k >> i) & 1) ? a_.i64[i] : src_.i64[i];
+ }
+
+ return simde__m128i_from_private (r_);
+}
+
+__attribute__ ((__always_inline__)) inline static simde__m128d
+simde_mm_mask_mov_pd (simde__m128d src, simde__mmask8 k, simde__m128d a)
+{
+ return simde_mm_castsi128_pd (simde_mm_mask_mov_epi64 (
+ simde_mm_castpd_si128 (src), k, simde_mm_castpd_si128 (a)));
+}
+
+static double
+simde_test_f64_precision_to_slop (int precision)
+{
+ return __builtin_expect (!!(precision == 0x7fffffff), 0)
+ ? 0.0
+ : __builtin_pow (10.0, -((double)(precision)));
+}
+__attribute__ ((__always_inline__)) inline static void
+simde_mm_storeu_pd (simde_float64 *mem_addr, simde__m128d a)
+{
+
+ __builtin_memcpy (mem_addr, &a, sizeof (a));
+}
+int simde_test_equal_f64 (simde_float64 a, simde_float64 b,
+ simde_float64 slop);
+void simde_test_debug_printf_ (const char *format, ...);
+static int
+simde_assert_equal_vf64_ (size_t vec_len, simde_float64 const a[(vec_len)],
+ simde_float64 const b[(vec_len)], simde_float64 slop,
+ const char *filename, int line, const char *astr,
+ const char *bstr)
+{
+ for (size_t i = 0; i < vec_len; i++)
+ {
+ if (__builtin_expect (!!(!simde_test_equal_f64 (a[i], b[i], slop)), 0))
+ {
+ simde_test_debug_printf_ (
+ "%s:%d: assertion failed: %s[%zu] ~= %s[%zu] (%f ~= %f)\n",
+ filename, line, astr, i, bstr, i, ((double)(a[i])),
+ ((double)(b[i])));
+ return 1;
+ }
+ }
+ return 0;
+}
+static int
+simde_test_x86_assert_equal_f64x2_ (simde__m128d a, simde__m128d b,
+ simde_float64 slop, const char *filename,
+ int line, const char *astr,
+ const char *bstr)
+{
+ simde_float64 a_[sizeof (a) / sizeof (simde_float64)],
+ b_[sizeof (a) / sizeof (simde_float64)];
+ simde_mm_storeu_pd (a_, a);
+ simde_mm_storeu_pd (b_, b);
+ return simde_assert_equal_vf64_ (sizeof (a_) / sizeof (a_[0]), a_, b_, slop,
+ filename, line, astr, bstr);
+}
+__attribute__ ((__always_inline__)) inline static simde__m128d_private
+simde__m128d_to_private (simde__m128d v)
+{
+ simde__m128d_private r;
+ __builtin_memcpy (&r, &v, sizeof (r));
+ return r;
+}
+__attribute__ ((__always_inline__)) inline static simde__m128d
+simde_mm_min_pd (simde__m128d a, simde__m128d b)
+{
+
+ simde__m128d_private r_, a_ = simde__m128d_to_private (a),
+ b_ = simde__m128d_to_private (b);
+
+ for (size_t i = 0; i < (sizeof (r_.f64) / sizeof (r_.f64[0])); i++)
+ {
+ r_.f64[i] = (a_.f64[i] < b_.f64[i]) ? a_.f64[i] : b_.f64[i];
+ }
+
+ return simde__m128d_from_private (r_);
+}
+
+__attribute__ ((__always_inline__)) inline static simde__m128d
+simde_mm_max_pd (simde__m128d a, simde__m128d b)
+{
+
+ simde__m128d_private r_, a_ = simde__m128d_to_private (a),
+ b_ = simde__m128d_to_private (b);
+
+ for (size_t i = 0; i < (sizeof (r_.f64) / sizeof (r_.f64[0])); i++)
+ {
+ r_.f64[i] = (a_.f64[i] > b_.f64[i]) ? a_.f64[i] : b_.f64[i];
+ }
+
+ return simde__m128d_from_private (r_);
+}
+
+__attribute__ ((__always_inline__)) inline static simde__m128d
+simde_x_mm_abs_pd (simde__m128d a)
+{
+
+ simde__m128d_private r_, a_ = simde__m128d_to_private (a);
+ for (size_t i = 0; i < (sizeof (r_.f64) / sizeof (r_.f64[0])); i++)
+ {
+ r_.f64[i] = __builtin_fabs (a_.f64[i]);
+ }
+
+ return simde__m128d_from_private (r_);
+}
+__attribute__ ((__always_inline__)) inline static simde__m128d
+simde_mm_cmple_pd (simde__m128d a, simde__m128d b)
+{
+
+ simde__m128d_private r_, a_ = simde__m128d_to_private (a),
+ b_ = simde__m128d_to_private (b);
+
+ r_.i64 = ((__typeof__ (r_.i64))((a_.f64 <= b_.f64)));
+ return simde__m128d_from_private (r_);
+}
+
+__attribute__ ((__always_inline__)) inline static simde__m128d
+simde_x_mm_select_pd (simde__m128d a, simde__m128d b, simde__m128d mask)
+{
+ simde__m128d_private r_, a_ = simde__m128d_to_private (a),
+ b_ = simde__m128d_to_private (b),
+ mask_ = simde__m128d_to_private (mask);
+
+ r_.i64 = a_.i64 ^ ((a_.i64 ^ b_.i64) & mask_.i64);
+ return simde__m128d_from_private (r_);
+}
+simde__m128d simde_mm_cmpge_pd (simde__m128d a, simde__m128d b);
+
+simde__m128d
+simde_x_mm_copysign_pd (simde__m128d dest, simde__m128d src)
+{
+ simde__m128d_private r_, dest_ = simde__m128d_to_private (dest),
+ src_ = simde__m128d_to_private (src);
+ for (size_t i = 0; i < (sizeof (r_.f64) / sizeof (r_.f64[0])); i++)
+ {
+ r_.f64[i] = __builtin_copysign (dest_.f64[i], src_.f64[i]);
+ }
+
+ return simde__m128d_from_private (r_);
+}
+simde__m128d simde_mm_or_pd (simde__m128d a, simde__m128d b);
+
+simde__m128d simde_mm_set1_pd (simde_float64 a);
+
+__attribute__ ((__always_inline__)) inline static simde__m128d
+simde_mm_range_pd (simde__m128d a, simde__m128d b, int imm8)
+{
+ simde__m128d r;
+
+ r = simde_x_mm_select_pd (
+ b, a, simde_mm_cmple_pd (simde_x_mm_abs_pd (a), simde_x_mm_abs_pd (b)));
+
+ r = simde_x_mm_copysign_pd (r, a);
+
+ return r;
+}
+int
+test_simde_mm_mask_range_pd (void)
+{
+
+ simde__m128d src, a, b, e, r;
+
+ src = simde_mm_set_pd (-2.92, -85.39);
+ a = simde_mm_set_pd (-47.59, -122.31);
+ b = simde_mm_set_pd (877.42, 69.15);
+ e = simde_mm_set_pd (-47.59, -69.15);
+ r = simde_mm_mask_mov_pd (src, 143, simde_mm_range_pd (a, b, 2));
+ do
+ {
+ if (simde_test_x86_assert_equal_f64x2_ (
+ r, e, simde_test_f64_precision_to_slop (1),
+ "../test/x86/avx512/range.c", 1454, "r", "e"))
+ {
+ return 1;
+ }
+ }
+ while (0);
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/loongarch/trap-1.c b/gcc/testsuite/gcc.target/loongarch/trap-1.c
new file mode 100644
index 0000000..8936f60
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/trap-1.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -w -fisolate-erroneous-paths-dereference -mbreak-code=1" } */
+/* { dg-final { scan-assembler "break\\t1" } } */
+
+int
+bug (void)
+{
+ return *(int *)0;
+}
diff --git a/gcc/testsuite/gcc.target/loongarch/trap-default.c b/gcc/testsuite/gcc.target/loongarch/trap-default.c
new file mode 100644
index 0000000..32948d4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/trap-default.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -w -fisolate-erroneous-paths-dereference" } */
+/* { dg-final { scan-assembler "amswap\\.w\\t\\\$r0,\\\$r1,\\\$r0" } } */
+
+int
+bug (void)
+{
+ return *(int *)0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr122445.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr122445.c
new file mode 100644
index 0000000..4736868
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr122445.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcbv_zvl256b -mabi=lp64d -O3 -mrvv-vector-bits=zvl --param=riscv-autovec-mode=V4QI -mtune=generic-ooo -fdump-rtl-avlprop-all" } */
+
+typedef unsigned char uint8_t;
+typedef short int16_t;
+
+#define FDEC_STRIDE 32
+
+static inline uint8_t x264_clip_uint8( int x )
+{
+ return x;
+}
+
+void
+x264_add4x4_idct (uint8_t *p_dst, int16_t d[16])
+{
+ for( int y = 0; y < 4; y++ )
+ {
+ for( int x = 0; x < 4; x++ )
+ p_dst[x] = x264_clip_uint8( p_dst[x] + d[y*4+x] );
+ p_dst += FDEC_STRIDE;
+ }
+}
+
+/* { dg-final { scan-rtl-dump "Propagating AVL: \\(const_int 4" "avlprop" } } */
+/* { dg-final { scan-rtl-dump-not "Propagating AVL: \\(const_int 1" "avlprop" } } */
diff --git a/gcc/testsuite/gfortran.dg/pdt_62.f03 b/gcc/testsuite/gfortran.dg/pdt_62.f03
new file mode 100644
index 0000000..efbcdad
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pdt_62.f03
@@ -0,0 +1,78 @@
+! { dg-do run }
+!
+! Test fix for PR122433
+!
+! Contributed by Damian Rouson <damian@archaeologic.codes>
+!
+module neuron_m
+ implicit none
+
+ type string_t
+ character(len=:), allocatable :: string_
+ end type
+
+ type neuron_t(k)
+ integer, kind :: k = kind(1.)
+ real(k) bias_
+ type(neuron_t(k)), allocatable :: next
+ end type
+
+contains
+ recursive function from_json(neuron_lines, start) result(neuron)
+ type(string_t) neuron_lines(:)
+ integer start
+ type(neuron_t) neuron
+ character(len=:), allocatable :: line
+ line = neuron_lines(start+1)%string_
+ read(line(index(line, ":")+1:), fmt=*) neuron%bias_
+ line = adjustr(neuron_lines(start+3)%string_)
+! Used to give "Error: Syntax error in IF-clause" for next line.
+ if (line(len(line):) == ",") neuron%next = from_json(neuron_lines, start+4)
+ end function
+ recursive function from_json_8(neuron_lines, start) result(neuron)
+ type(string_t) neuron_lines(:)
+ integer start
+ type(neuron_t(kind(1d0))) neuron
+ character(len=:), allocatable :: line
+ line = neuron_lines(start+1)%string_
+ read(line(index(line, ":")+1:), fmt=*) neuron%bias_
+ line = adjustr(neuron_lines(start+3)%string_)
+ if (line(len(line):) == ",") neuron%next = from_json_8(neuron_lines, start+4)
+ end function
+end module
+
+ use neuron_m
+ call foo
+ call bar
+contains
+ subroutine foo
+ type(neuron_t) neuron
+ type(string_t) :: neuron_lines(8)
+ neuron_lines(2)%string_ = "real : 4.0 "
+ neuron_lines(4)%string_ = " ,"
+ neuron_lines(6)%string_ = "real : 8.0 "
+ neuron_lines(8)%string_ = " "
+ neuron = from_json(neuron_lines, 1)
+ if (int (neuron%bias_) /= 4) stop 1
+ if (allocated (neuron%next)) then
+ if (int (neuron%next%bias_) /= 8) stop 2
+ else
+ stop 3
+ endif
+ end subroutine
+ subroutine bar
+ type(neuron_t(kind(1d0))) neuron
+ type(string_t) :: neuron_lines(8)
+ neuron_lines(2)%string_ = "real : 4.0d0 "
+ neuron_lines(4)%string_ = " ,"
+ neuron_lines(6)%string_ = "real : 8.0d0 "
+ neuron_lines(8)%string_ = " "
+ neuron = from_json_8(neuron_lines, 1)
+ if (int (neuron%bias_) /= 4) stop 1
+ if (allocated (neuron%next)) then
+ if (int (neuron%next%bias_) /= 8) stop 2
+ else
+ stop 3
+ endif
+ end subroutine
+end
diff --git a/gcc/testsuite/gfortran.dg/pdt_63.f03 b/gcc/testsuite/gfortran.dg/pdt_63.f03
new file mode 100644
index 0000000..127e5fe
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pdt_63.f03
@@ -0,0 +1,26 @@
+! { dg-do compile }
+!
+! Test fix for PR122434
+!
+! Contributed by Damian Rouson <damian@archaeologic.codes>
+!
+module neuron_m
+ implicit none
+
+ type neuron_t
+ real, allocatable :: weight_
+ end type
+
+ interface
+ type(neuron_t) pure module function from_json() result(neuron)
+ end function
+ end interface
+
+contains
+ module procedure from_json
+ associate(num_inputs => 1)
+! Gave "Error: Bad allocate-object at (1) for a PURE procedure" in next line.
+ allocate(neuron%weight_, source=0.)
+ end associate
+ end procedure
+end module
diff --git a/gcc/testsuite/gfortran.dg/pdt_64.f03 b/gcc/testsuite/gfortran.dg/pdt_64.f03
new file mode 100644
index 0000000..dfa4e3a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pdt_64.f03
@@ -0,0 +1,17 @@
+! { dg-do compile }
+!
+! Test the fix for PR122165.
+!
+! Contributed by Steve Kargl <kargls@comcast.net>
+!
+program foo
+ implicit none
+ type dt(k,l)
+ integer(8), len :: k = 1
+ integer(8), KIND :: l = 1
+ character(k) :: arr
+ end type
+ type(dt(:)), allocatable :: d1
+ if (d1%k%kind /= 8) stop 1 ! { dg-error "cannot be followed by the type inquiry ref" }
+ if (d1%l%kind /= 8) stop 2 ! { dg-error "cannot be followed by the type inquiry ref" }
+end
diff --git a/gcc/testsuite/gfortran.dg/vect/pr70102.f b/gcc/testsuite/gfortran.dg/vect/pr70102.f
new file mode 100644
index 0000000..b6a2878
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/vect/pr70102.f
@@ -0,0 +1,21 @@
+! { dg-do compile }
+! { dg-additional-options "-Ofast" }
+ subroutine test (x,y,z)
+ integer x,y,z
+ real*8 a(5,x,y,z),b(5,x,y,z)
+ real*8 c
+
+ c = 0.0d0
+ do k=1,z
+ do j=1,y
+ do i=1,x
+ do l=1,5
+ c = c + a(l,i,j,k)*b(l,i,j,k)
+ enddo
+ enddo
+ enddo
+ enddo
+ write(30,*)'c ==',c
+ return
+ end
+! { dg-final { scan-tree-dump "vectorizing a reduction chain" "vect" { target vect_double } } }
diff --git a/gcc/testsuite/gm2.dg/spell/iso/fail/badimport.mod b/gcc/testsuite/gm2.dg/spell/iso/fail/badimport.mod
new file mode 100644
index 0000000..337cf34
--- /dev/null
+++ b/gcc/testsuite/gm2.dg/spell/iso/fail/badimport.mod
@@ -0,0 +1,14 @@
+
+(* { dg-do compile } *)
+(* { dg-options "-g -c" } *)
+
+MODULE badimport ;
+
+IMPORT ASCII ;
+FROM StrIO IMPORT WriteString ;
+FROM ASCIi IMPORT nul ;
+ (* { dg-error "error: the file containing the definition module 'ASCIi' cannot be found, did you mean ASCII" "ASCIi" { target *-*-* } 9 } *)
+
+BEGIN
+
+END badimport.
diff --git a/gcc/testsuite/gnat.dg/aggr32.adb b/gcc/testsuite/gnat.dg/aggr32.adb
new file mode 100644
index 0000000..e5b0887
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/aggr32.adb
@@ -0,0 +1,15 @@
+-- { dg-do compile }
+
+with Aggr32_Pkg.Child;
+
+procedure Aggr32 (W, H : Positive) is
+
+ use Aggr32_Pkg;
+
+ package Test_1 is new Child (Frame => (Width => W, Height => H));
+
+ package Test_2 is new Child (Frame => Rec'(Width => W, Height => H));
+
+begin
+ null;
+end;
diff --git a/gcc/testsuite/gnat.dg/aggr32_pkg-child.ads b/gcc/testsuite/gnat.dg/aggr32_pkg-child.ads
new file mode 100644
index 0000000..352e2b5
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/aggr32_pkg-child.ads
@@ -0,0 +1,6 @@
+generic
+
+ Frame : Rec;
+
+package Aggr32_Pkg.Child is
+end Aggr32_Pkg.Child;
diff --git a/gcc/testsuite/gnat.dg/aggr32_pkg.ads b/gcc/testsuite/gnat.dg/aggr32_pkg.ads
new file mode 100644
index 0000000..e0e8bef
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/aggr32_pkg.ads
@@ -0,0 +1,8 @@
+package Aggr32_Pkg is
+
+ type Rec is record
+ Width : Positive;
+ Height : Positive;
+ end record;
+
+end Aggr32_Pkg;
diff --git a/gcc/testsuite/gnat.dg/specs/generic_inst6.ads b/gcc/testsuite/gnat.dg/specs/generic_inst6.ads
new file mode 100644
index 0000000..0f15207
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/generic_inst6.ads
@@ -0,0 +1,6 @@
+-- { dg-do compile }
+
+with Generic_Inst6_Pkg1.Child.Grand2;
+with Generic_Inst6_Pkg3;
+
+package Generic_Inst6 is new Generic_Inst6_Pkg3.Grand2;
diff --git a/gcc/testsuite/gnat.dg/specs/generic_inst6_pkg1-child-grand1.ads b/gcc/testsuite/gnat.dg/specs/generic_inst6_pkg1-child-grand1.ads
new file mode 100644
index 0000000..4d8e7ce
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/generic_inst6_pkg1-child-grand1.ads
@@ -0,0 +1,3 @@
+generic
+package Generic_Inst6_Pkg1.Child.Grand1 is
+end Generic_Inst6_Pkg1.Child.Grand1;
diff --git a/gcc/testsuite/gnat.dg/specs/generic_inst6_pkg1-child-grand2.ads b/gcc/testsuite/gnat.dg/specs/generic_inst6_pkg1-child-grand2.ads
new file mode 100644
index 0000000..326a3e0
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/generic_inst6_pkg1-child-grand2.ads
@@ -0,0 +1,6 @@
+with Generic_Inst6_Pkg1.Child.Grand1;
+
+generic
+package Generic_Inst6_Pkg1.Child.Grand2 is
+ package My_Grand1 is new Generic_Inst6_Pkg1.Child.Grand1;
+end Generic_Inst6_Pkg1.Child.Grand2;
diff --git a/gcc/testsuite/gnat.dg/specs/generic_inst6_pkg1-child.ads b/gcc/testsuite/gnat.dg/specs/generic_inst6_pkg1-child.ads
new file mode 100644
index 0000000..3676052
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/generic_inst6_pkg1-child.ads
@@ -0,0 +1,3 @@
+generic
+package Generic_Inst6_Pkg1.Child is
+end Generic_Inst6_Pkg1.Child;
diff --git a/gcc/testsuite/gnat.dg/specs/generic_inst6_pkg1.ads b/gcc/testsuite/gnat.dg/specs/generic_inst6_pkg1.ads
new file mode 100644
index 0000000..a480bbd
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/generic_inst6_pkg1.ads
@@ -0,0 +1,3 @@
+generic
+package Generic_Inst6_Pkg1 is
+end Generic_Inst6_Pkg1;
diff --git a/gcc/testsuite/gnat.dg/specs/generic_inst6_pkg2.ads b/gcc/testsuite/gnat.dg/specs/generic_inst6_pkg2.ads
new file mode 100644
index 0000000..98b2011
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/generic_inst6_pkg2.ads
@@ -0,0 +1,3 @@
+with Generic_Inst6_Pkg1;
+
+package Generic_Inst6_Pkg2 is new Generic_Inst6_Pkg1;
diff --git a/gcc/testsuite/gnat.dg/specs/generic_inst6_pkg3.ads b/gcc/testsuite/gnat.dg/specs/generic_inst6_pkg3.ads
new file mode 100644
index 0000000..395b9f0
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/generic_inst6_pkg3.ads
@@ -0,0 +1,4 @@
+with Generic_Inst6_Pkg1.Child;
+with Generic_Inst6_Pkg2;
+
+package Generic_Inst6_Pkg3 is new Generic_Inst6_Pkg2.Child;
diff --git a/gcc/testsuite/gnat.dg/specs/generic_inst7.ads b/gcc/testsuite/gnat.dg/specs/generic_inst7.ads
new file mode 100644
index 0000000..3132525
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/generic_inst7.ads
@@ -0,0 +1,17 @@
+-- { dg-do compile }
+
+package Generic_Inst7 is
+
+ function F return Integer is (0);
+
+ generic
+ with function Foo return Integer;
+ package P is
+ type Color is (Foo);
+ end P;
+
+ package My_P is new P (F);
+
+ I : Integer := My_P.Foo; -- { dg-error "expected type|found type" }
+
+end Generic_Inst7;
diff --git a/gcc/testsuite/gnat.dg/specs/generic_inst8.ads b/gcc/testsuite/gnat.dg/specs/generic_inst8.ads
new file mode 100644
index 0000000..0eac709
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/generic_inst8.ads
@@ -0,0 +1,18 @@
+-- { dg-do compile }
+
+package Generic_Inst8 is
+
+ function F return Integer is (0);
+
+ generic
+ with function Foo return Integer;
+ package P is
+ type Color1 is (Foo);
+ type Color2 is (Foo);
+ end P;
+
+ package My_P is new P (F);
+
+ I : Integer := My_P.Foo; -- { dg-error "no visible interpretation|use" }
+
+end Generic_Inst8;
diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc
index 79ac25f..9a993ab 100644
--- a/gcc/tree-ssa-forwprop.cc
+++ b/gcc/tree-ssa-forwprop.cc
@@ -216,31 +216,6 @@ static bitmap to_purge;
/* Const-and-copy lattice. */
static vec<tree> lattice;
-/* forwprop_may_propagate_copy is like may_propagate_copy except
- after the final folding, don't allow propagating of pointer ORIG
- that have a lower alignment than the DEST name.
- This is to prevent losing alignment information from
- __builtin_assume_aligned for expand (See also PR 122086). */
-static bool
-forwprop_may_propagate_copy (tree dest, tree orig,
- bool dest_not_abnormal_phi_edge_p = false)
-{
- if (!may_propagate_copy (dest, orig, dest_not_abnormal_phi_edge_p))
- return false;
-
- /* Only check alignment for the final folding. */
- if (!(cfun->curr_properties & PROP_last_full_fold))
- return true;
-
- /* Alignment only matters for pointer types. */
- if (!POINTER_TYPE_P (TREE_TYPE (dest)) || !POINTER_TYPE_P (TREE_TYPE (orig)))
- return true;
-
- unsigned aligndest = get_pointer_alignment (dest);
- unsigned alignorig = get_pointer_alignment (orig);
- return aligndest <= alignorig;
-}
-
/* Set the lattice entry for NAME to VAL. */
static void
fwprop_set_lattice_val (tree name, tree val)
@@ -1818,6 +1793,7 @@ do_simple_agr_dse (gassign *stmt, bool full_walk)
/* Only handle clobbers of a full decl. */
if (!DECL_P (lhs))
return;
+ clobber_kind kind = (clobber_kind)CLOBBER_KIND (gimple_assign_rhs1 (stmt));
ao_ref_init (&read, lhs);
tree vuse = gimple_vuse (stmt);
unsigned limit = full_walk ? param_sccvn_max_alias_queries_per_access : 4;
@@ -1839,6 +1815,25 @@ do_simple_agr_dse (gassign *stmt, bool full_walk)
basic_block ubb = gimple_bb (use_stmt);
if (stmt == use_stmt)
continue;
+ /* If the use is the same kind of clobber for lhs,
+ then it can be safely skipped; this happens with eh
+ and sometimes jump threading. */
+ if (gimple_clobber_p (use_stmt, kind)
+ && lhs == gimple_assign_lhs (use_stmt))
+ continue;
+ /* If the use is a phi and it is single use then check if that single use
+ is a clobber of the same kind and lhs is the same. */
+ if (gphi *use_phi = dyn_cast<gphi*>(use_stmt))
+ {
+ use_operand_p ou;
+ gimple *ostmt;
+ if (single_imm_use (gimple_phi_result (use_phi), &ou, &ostmt)
+ && gimple_clobber_p (ostmt, kind)
+ && lhs == gimple_assign_lhs (ostmt))
+ continue;
+ /* A phi node will never be dominating the clobber. */
+ return;
+ }
/* The use needs to be dominating the clobber. */
if ((ubb != bb && !dominated_by_p (CDI_DOMINATORS, bb, ubb))
|| ref_maybe_used_by_stmt_p (use_stmt, &read, false))
@@ -5202,7 +5197,7 @@ pass_forwprop::execute (function *fun)
}
if (all_same)
{
- if (forwprop_may_propagate_copy (res, first))
+ if (may_propagate_copy (res, first))
to_remove_defs.safe_push (SSA_NAME_VERSION (res));
fwprop_set_lattice_val (res, first);
}
@@ -5557,7 +5552,7 @@ pass_forwprop::execute (function *fun)
{
if (!is_gimple_debug (stmt))
bitmap_set_bit (simple_dce_worklist, SSA_NAME_VERSION (use));
- if (forwprop_may_propagate_copy (use, val))
+ if (may_propagate_copy (use, val))
{
propagate_value (usep, val);
substituted_p = true;
@@ -5720,7 +5715,7 @@ pass_forwprop::execute (function *fun)
/* If we can propagate the lattice-value mark the
stmt for removal. */
if (val != lhs
- && forwprop_may_propagate_copy (lhs, val))
+ && may_propagate_copy (lhs, val))
to_remove_defs.safe_push (SSA_NAME_VERSION (lhs));
fwprop_set_lattice_val (lhs, val);
}
@@ -5742,7 +5737,7 @@ pass_forwprop::execute (function *fun)
continue;
tree val = fwprop_ssa_val (arg);
if (val != arg
- && forwprop_may_propagate_copy (arg, val, !(e->flags & EDGE_ABNORMAL)))
+ && may_propagate_copy (arg, val, !(e->flags & EDGE_ABNORMAL)))
propagate_value (use_p, val);
}
diff --git a/gcc/tree-ssa-loop-niter.cc b/gcc/tree-ssa-loop-niter.cc
index 6e13086..cc76383 100644
--- a/gcc/tree-ssa-loop-niter.cc
+++ b/gcc/tree-ssa-loop-niter.cc
@@ -2321,6 +2321,48 @@ is_rshift_by_1 (gassign *stmt)
return false;
}
+/* Helper for number_of_iterations_cltz that uses ranger to determine
+ if SRC's range, shifted left (when LEFT_SHIFT is true) or right
+ by NUM_IGNORED_BITS, is guaranteed to be != 0 on LOOP's preheader
+ edge.
+ Return true if so or false otherwise. */
+
+static bool
+shifted_range_nonzero_p (loop_p loop, tree src,
+ bool left_shift, int num_ignored_bits)
+{
+ int_range_max r (TREE_TYPE (src));
+ gcc_assert (num_ignored_bits >= 0);
+
+ if (get_range_query (cfun)->range_on_edge
+ (r, loop_preheader_edge (loop), src)
+ && !r.varying_p ()
+ && !r.undefined_p ())
+ {
+ if (num_ignored_bits)
+ {
+ range_op_handler op (left_shift ? LSHIFT_EXPR : RSHIFT_EXPR);
+ int_range_max shifted_range (TREE_TYPE (src));
+ wide_int shift_count = wi::shwi (num_ignored_bits,
+ TYPE_PRECISION (TREE_TYPE
+ (src)));
+ int_range_max shift_amount
+ (TREE_TYPE (src), shift_count, shift_count);
+
+ if (op.fold_range (shifted_range, TREE_TYPE (src), r,
+ shift_amount))
+ r = shifted_range;
+ }
+
+ /* If the range does not contain zero we are good. */
+ if (!range_includes_zero_p (r))
+ return true;
+ }
+
+ return false;
+}
+
+
/* See comment below for number_of_iterations_bitcount.
For c[lt]z, we have:
@@ -2438,6 +2480,9 @@ number_of_iterations_cltz (loop_p loop, edge exit,
tree src = gimple_phi_arg_def (phi, loop_preheader_edge (loop)->dest_idx);
int src_precision = TYPE_PRECISION (TREE_TYPE (src));
+ /* Save the original SSA name before preprocessing for ranger queries. */
+ tree unshifted_src = src;
+
/* Apply any needed preprocessing to src. */
int num_ignored_bits;
if (left_shift)
@@ -2463,10 +2508,52 @@ number_of_iterations_cltz (loop_p loop, edge exit,
expr = fold_convert (unsigned_type_node, expr);
- tree assumptions = fold_build2 (NE_EXPR, boolean_type_node, src,
- build_zero_cst (TREE_TYPE (src)));
+ /* If the copy-header (ch) pass peeled one iteration we're shifting
+ SRC by preprocessing it above.
+
+ A loop like
+ if (bits)
+ {
+ while (!(bits & 1))
+ {
+ bits >>= 1;
+ cnt += 1;
+ }
+ return cnt;
+ }
+ ch (roughly) transforms into:
+ if (bits)
+ {
+ if (!(bits & 1)
+ {
+ do
+ {
+ bits >>= 1;
+ cnt += 1;
+ } while (!(bits & 1));
+ }
+ else
+ cnt = 1;
+ return cnt;
+ }
+
+ Then, our preprocessed SRC (that is used for c[tl]z computation)
+ will be bits >> 1, and the assumption is bits >> 1 != 0. */
+
+ tree assumptions;
+ if (shifted_range_nonzero_p (loop, unshifted_src,
+ left_shift, num_ignored_bits))
+ assumptions = boolean_true_node;
+ else
+ {
+ /* If ranger couldn't prove the assumption, try
+ simplify_using_initial_conditions. */
+ assumptions = fold_build2 (NE_EXPR, boolean_type_node, src,
+ build_zero_cst (TREE_TYPE (src)));
+ assumptions = simplify_using_initial_conditions (loop, assumptions);
+ }
- niter->assumptions = simplify_using_initial_conditions (loop, assumptions);
+ niter->assumptions = assumptions;
niter->may_be_zero = boolean_false_node;
niter->niter = simplify_using_initial_conditions (loop, expr);
diff --git a/gcc/tree-ssa-loop.cc b/gcc/tree-ssa-loop.cc
index 5629524..dc4b560 100644
--- a/gcc/tree-ssa-loop.cc
+++ b/gcc/tree-ssa-loop.cc
@@ -28,6 +28,7 @@ along with GCC; see the file COPYING3. If not see
#include "tm_p.h"
#include "fold-const.h"
#include "gimple-iterator.h"
+#include "gimple-range.h"
#include "tree-ssa-loop-ivopts.h"
#include "tree-ssa-loop-manip.h"
#include "tree-ssa-loop-niter.h"
@@ -404,11 +405,15 @@ pass_scev_cprop::execute (function *)
{
bool any = false;
+ enable_ranger (cfun);
+
/* Perform final value replacement in loops, in case the replacement
expressions are cheap. */
for (auto loop : loops_list (cfun, LI_FROM_INNERMOST))
any |= final_value_replacement_loop (loop);
+ disable_ranger (cfun);
+
return any ? TODO_cleanup_cfg | TODO_update_ssa_only_virtuals : 0;
}
diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc
index e02b337..aa6c3e2 100644
--- a/gcc/tree-vect-slp.cc
+++ b/gcc/tree-vect-slp.cc
@@ -558,7 +558,8 @@ vect_get_operand_map (const gimple *stmt, bool gather_scatter_p = false,
if (gimple_assign_rhs_code (assign) == COND_EXPR
&& COMPARISON_CLASS_P (gimple_assign_rhs1 (assign)))
gcc_unreachable ();
- if (TREE_CODE_CLASS (gimple_assign_rhs_code (assign)) == tcc_comparison
+ if ((TREE_CODE_CLASS (gimple_assign_rhs_code (assign)) == tcc_comparison
+ || commutative_tree_code (gimple_assign_rhs_code (assign)))
&& swap)
return op1_op0_map;
if (gather_scatter_p)
@@ -1352,7 +1353,12 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char *swap,
uniform but only that of the first stmt matters. */
&& !(first_reduc_idx != -1
&& STMT_VINFO_REDUC_IDX (stmt_info) != -1
- && REDUC_GROUP_FIRST_ELEMENT (stmt_info)))
+ && REDUC_GROUP_FIRST_ELEMENT (stmt_info))
+ && !(first_reduc_idx != -1
+ && STMT_VINFO_REDUC_IDX (stmt_info) != -1
+ && rhs_code.is_tree_code ()
+ && commutative_tree_code (tree_code (rhs_code))
+ && first_reduc_idx == 1 - STMT_VINFO_REDUC_IDX (stmt_info)))
{
if (dump_enabled_p ())
{
@@ -1617,6 +1623,15 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char *swap,
&& (swap_tree_comparison ((tree_code)first_stmt_code)
== (tree_code)rhs_code))
swap[i] = 1;
+
+ if (i != 0
+ && first_reduc_idx != STMT_VINFO_REDUC_IDX (stmt_info)
+ && first_reduc_idx != -1
+ && STMT_VINFO_REDUC_IDX (stmt_info) != -1
+ && rhs_code.is_tree_code ()
+ && commutative_tree_code (tree_code (rhs_code))
+ && first_reduc_idx == 1 - STMT_VINFO_REDUC_IDX (stmt_info))
+ swap[i] = 1;
}
matches[i] = true;
@@ -4045,7 +4060,9 @@ vect_build_slp_store_interleaving (vec<slp_tree> &rhs_nodes,
}
/* Analyze an SLP instance starting from SCALAR_STMTS which are a group
- of KIND. Return true if successful. */
+ of KIND. Return true if successful. SCALAR_STMTS is owned by this
+ function, REMAIN and ROOT_STMT_INFOS ownership is transfered back to
+ the caller upon failure. */
static bool
vect_build_slp_instance (vec_info *vinfo,
@@ -4059,7 +4076,10 @@ vect_build_slp_instance (vec_info *vinfo,
{
/* If there's no budget left bail out early. */
if (*limit == 0)
- return false;
+ {
+ scalar_stmts.release ();
+ return false;
+ }
if (kind == slp_inst_kind_ctor)
{
@@ -4159,6 +4179,10 @@ vect_build_slp_instance (vec_info *vinfo,
if (dump_enabled_p ())
{
+ if (kind == slp_inst_kind_reduc_group)
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "SLP discovery of size %d reduction group "
+ "succeeded\n", group_size);
dump_printf_loc (MSG_NOTE, vect_location,
"Final SLP tree for instance %p:\n",
(void *) new_instance);
@@ -5564,10 +5588,10 @@ vect_analyze_slp (vec_info *vinfo, unsigned max_tree_size,
bb_vinfo->roots[i].remain,
max_tree_size, &limit, bst_map, false))
{
- bb_vinfo->roots[i].stmts = vNULL;
bb_vinfo->roots[i].roots = vNULL;
bb_vinfo->roots[i].remain = vNULL;
}
+ bb_vinfo->roots[i].stmts = vNULL;
}
}
@@ -6297,6 +6321,7 @@ private:
/* Layout selection. */
bool is_compatible_layout (slp_tree, unsigned int);
+ bool is_compatible_layout (const slpg_partition_info &, unsigned int);
int change_layout_cost (slp_tree, unsigned int, unsigned int);
slpg_partition_layout_costs &partition_layout_costs (unsigned int,
unsigned int);
@@ -6304,6 +6329,7 @@ private:
int, unsigned int);
int internal_node_cost (slp_tree, int, unsigned int);
void start_choosing_layouts ();
+ bool legitimize ();
/* Cost propagation. */
slpg_layout_cost edge_layout_cost (graph_edge *, unsigned int,
@@ -6710,6 +6736,29 @@ vect_optimize_slp_pass::is_compatible_layout (slp_tree node,
return true;
}
+/* Return true if layout LAYOUT_I is compatible with the number of SLP lanes
+ that NODE would operate on for each NODE in PARTITION.
+ This test is independent of NODE's actual operations. */
+
+bool
+vect_optimize_slp_pass::is_compatible_layout (const slpg_partition_info
+ &partition,
+ unsigned int layout_i)
+{
+ for (unsigned int order_i = partition.node_begin;
+ order_i < partition.node_end; ++order_i)
+ {
+ unsigned int node_i = m_partitioned_nodes[order_i];
+ auto &vertex = m_vertices[node_i];
+
+ /* The layout is incompatible if it is individually incompatible
+ with any node in the partition. */
+ if (!is_compatible_layout (vertex.node, layout_i))
+ return false;
+ }
+ return true;
+}
+
/* Return the cost (in arbtirary units) of going from layout FROM_LAYOUT_I
to layout TO_LAYOUT_I for a node like NODE. Return -1 if either of the
layouts is incompatible with NODE or if the change is not possible for
@@ -8029,6 +8078,62 @@ vect_optimize_slp_pass::decide_masked_load_lanes ()
}
}
+/* Perform legitimizing attempts. This is intended to improve the
+ situation when layout 0 is not valid which is a situation the cost
+ based propagation does not handle well.
+ Return true if further layout optimization is possible, false if
+ the layout configuration should be considered final. */
+
+bool
+vect_optimize_slp_pass::legitimize ()
+{
+ /* Perform a very simple legitimizing attempt by attempting to choose
+ a single layout for all partitions that will make all permutations
+ a noop. That should also be the optimal layout choice in case
+ layout zero is legitimate.
+ ??? Disconnected components of the SLP graph could have distinct
+ single layouts. */
+ int single_layout_i = -1;
+ unsigned deferred_up_to = -1U;
+ for (unsigned partition_i = 0; partition_i < m_partitions.length ();
+ ++partition_i)
+ {
+ auto &partition = m_partitions[partition_i];
+ if (single_layout_i == -1)
+ {
+ single_layout_i = partition.layout;
+ deferred_up_to = partition_i;
+ }
+ else if (partition.layout == single_layout_i || partition.layout == -1)
+ ;
+ else
+ single_layout_i = 0;
+ if (single_layout_i == 0)
+ return true;
+
+ if (single_layout_i != -1
+ && !is_compatible_layout (partition, single_layout_i))
+ return true;
+ }
+
+ if (single_layout_i <= 0)
+ return true;
+
+ for (unsigned partition_i = 0; partition_i < deferred_up_to; ++partition_i)
+ if (!is_compatible_layout (m_partitions[partition_i],
+ single_layout_i))
+ return true;
+
+ for (unsigned partition_i = 0; partition_i < m_partitions.length ();
+ ++partition_i)
+ {
+ auto &partition = m_partitions[partition_i];
+ partition.layout = single_layout_i;
+ }
+
+ return false;
+}
+
/* Main entry point for the SLP graph optimization pass. */
void
@@ -8039,8 +8144,11 @@ vect_optimize_slp_pass::run ()
start_choosing_layouts ();
if (m_perms.length () > 1)
{
- forward_pass ();
- backward_pass ();
+ if (legitimize ())
+ {
+ forward_pass ();
+ backward_pass ();
+ }
if (dump_enabled_p ())
dump ();
materialize ();
@@ -9031,8 +9139,11 @@ vect_slp_analyze_operations (vec_info *vinfo)
stmt_vec_info stmt_info;
if (!SLP_INSTANCE_ROOT_STMTS (instance).is_empty ())
stmt_info = SLP_INSTANCE_ROOT_STMTS (instance)[0];
- else
+ else if (!SLP_TREE_SCALAR_STMTS (node).is_empty ()
+ && SLP_TREE_SCALAR_STMTS (node)[0])
stmt_info = SLP_TREE_SCALAR_STMTS (node)[0];
+ else
+ stmt_info = SLP_TREE_REPRESENTATIVE (node);
if (is_a <loop_vec_info> (vinfo))
{
if (dump_enabled_p ())
diff --git a/gcc/varpool.cc b/gcc/varpool.cc
index 976e0fa..8dc5f98 100644
--- a/gcc/varpool.cc
+++ b/gcc/varpool.cc
@@ -172,11 +172,7 @@ void
varpool_node::remove (void)
{
symtab->call_varpool_removal_hooks (this);
- if (lto_file_data)
- {
- lto_free_function_in_decl_state_for_node (this);
- lto_file_data = NULL;
- }
+ lto_free_function_in_decl_state_for_node (this);
/* When streaming we can have multiple nodes associated with decl. */
if (symtab->state == LTO_STREAMING)
diff --git a/libgcobol/ChangeLog b/libgcobol/ChangeLog
index fdf22f8..315e1cc 100644
--- a/libgcobol/ChangeLog
+++ b/libgcobol/ChangeLog
@@ -1,3 +1,9 @@
+2025-10-28 Sam James <sam@gentoo.org>
+
+ PR cobol/122451
+ * xmlparse.cc (context_t): Make 'ctxt' public.
+ (xml_push_parse): Fix xmlCtxtGetVersion argument.
+
2025-10-27 Sam James <sam@gentoo.org>
PR cobol/122451
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index ab7f752..5066792 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,3 +1,7 @@
+2025-10-28 Thomas Schwinge <tschwinge@baylibre.com>
+
+ * env.c (initialize_env): Simplify 'parse_stacksize' call.
+
2025-10-23 Andrew Stubbs <ams@baylibre.com>
* Makefile.am (libgomp_la_SOURCES): Add simple-allocator.c.
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 77ab059..dee1e50 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,54 @@
+2025-10-29 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/bits/regex.tcc (regex_traits::value): Use __c instead
+ of __ch.
+
+2025-10-29 Jonathan Wakely <jwakely@redhat.com>
+
+ * testsuite/17_intro/headers/c++2011/42319.cc: Include <ios>
+ instead of <bits/char_traits.h>. Add no_pch option. Remove
+ explicit -std=gnu++11 option.
+ * testsuite/30_threads/thread/swap/1.cc: Include <utility>
+ instead of <bits/move.h>.
+
+2025-10-29 Tomasz Kamiński <tkaminsk@redhat.com>
+
+ PR libstdc++/119721
+ * include/std/tuple (tuple<>::operator=(const _Tuple&) const)
+ [__cpp_lib_ranges_zip]: Define.
+ * testsuite/23_containers/tuple/cons/119721.cc: Test const
+ assignment.
+
+2025-10-29 Osama Abdelkader <osama.abdelkader@gmail.com>
+ Tomasz Kamiński <tkaminsk@redhat.com>
+
+ PR libstdc++/119721
+ * include/std/tuple (tuple<>::tuple(const tuple&))
+ (tuple<>::operator=(const tuple&)): Define as defaulted.
+ (tuple<>::swap): Moved the defintion after assignments.
+ (tuple<>::tuple(_UTuple&&))
+ (tuple<>::tuple(allocator_arg_t, const _Alloc&, _UTuple&&))
+ (tuple<>::operator=(_UTuple&&)) [__cpp_lib_tuple_like]: Define.
+ (tuple<>::operator==, tuple<>::opeator<=>): Parenthesize
+ constrains individually.
+ * testsuite/23_containers/tuple/cons/119721.cc: New test for
+ constructors and assignments with empty tuple-like types.
+ * testsuite/20_util/tuple/requirements/empty_trivial.cc:
+ New test verifying tuple<> remains trivially copyable.
+
+2025-10-29 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/bits/regex.tcc (regex_traits::value): Implement
+ without using istringstream.
+ * include/std/regex: Do not include <sstream>.
+
+2025-10-28 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/122401
+ * testsuite/30_threads/shared_timed_mutex/try_lock_until/116586.cc:
+ Do not try to acquire locks on the thread that already holds a
+ lock. Add -pthread for et pthread.
+
2025-10-27 Jonathan Wakely <jwakely@redhat.com>
PR libstdc++/122401
diff --git a/libstdc++-v3/include/bits/regex.tcc b/libstdc++-v3/include/bits/regex.tcc
index b94fe44..48917cd 100644
--- a/libstdc++-v3/include/bits/regex.tcc
+++ b/libstdc++-v3/include/bits/regex.tcc
@@ -331,20 +331,53 @@ namespace __detail
&& __c == __fctyp.widen('_'));
}
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr
template<typename _Ch_type>
int
regex_traits<_Ch_type>::
value(_Ch_type __ch, int __radix) const
{
- std::basic_istringstream<char_type> __is(string_type(1, __ch));
- long __v;
- if (__radix == 8)
- __is >> std::oct;
- else if (__radix == 16)
- __is >> std::hex;
- __is >> __v;
- return __is.fail() ? -1 : __v;
+ if constexpr (sizeof(_Ch_type) > 1)
+ {
+ const auto& __ctyp = std::use_facet<ctype<_Ch_type>>(_M_locale);
+ const char __c = __ctyp.narrow(__ch, '\0');
+ return regex_traits<char>{}.value(__c, __radix);
+ }
+ else
+ {
+ const char __c = static_cast<char>(__ch);
+ const char __max_digit = __radix == 8 ? '7' : '9';
+ if ('0' <= __c && __c <= __max_digit)
+ return __c - '0';
+ if (__radix < 16)
+ return -1;
+ switch (__c)
+ {
+ case 'a':
+ case 'A':
+ return 10;
+ case 'b':
+ case 'B':
+ return 11;
+ case 'c':
+ case 'C':
+ return 12;
+ case 'd':
+ case 'D':
+ return 13;
+ case 'e':
+ case 'E':
+ return 14;
+ case 'f':
+ case 'F':
+ return 15;
+ default:
+ return -1;
+ }
+ }
}
+#pragma GCC diagnostic pop
template<typename _Bi_iter, typename _Alloc>
template<typename _Out_iter>
diff --git a/libstdc++-v3/include/bits/version.def b/libstdc++-v3/include/bits/version.def
index 1bf98f7..29ecf15 100644
--- a/libstdc++-v3/include/bits/version.def
+++ b/libstdc++-v3/include/bits/version.def
@@ -2191,6 +2191,15 @@ ftms = {
};
};
+ftms = {
+ name = is_implicit_lifetime;
+ values = {
+ v = 202302;
+ cxxmin = 23;
+ extra_cond = "__has_builtin(__builtin_is_implicit_lifetime)";
+ };
+};
+
// Standard test specifications.
stds[97] = ">= 199711L";
stds[03] = ">= 199711L";
diff --git a/libstdc++-v3/include/bits/version.h b/libstdc++-v3/include/bits/version.h
index 66de8b4..5901d27 100644
--- a/libstdc++-v3/include/bits/version.h
+++ b/libstdc++-v3/include/bits/version.h
@@ -2455,4 +2455,14 @@
#endif /* !defined(__cpp_lib_philox_engine) */
#undef __glibcxx_want_philox_engine
+#if !defined(__cpp_lib_is_implicit_lifetime)
+# if (__cplusplus >= 202100L) && (__has_builtin(__builtin_is_implicit_lifetime))
+# define __glibcxx_is_implicit_lifetime 202302L
+# if defined(__glibcxx_want_all) || defined(__glibcxx_want_is_implicit_lifetime)
+# define __cpp_lib_is_implicit_lifetime 202302L
+# endif
+# endif
+#endif /* !defined(__cpp_lib_is_implicit_lifetime) */
+#undef __glibcxx_want_is_implicit_lifetime
+
#undef __glibcxx_want_all
diff --git a/libstdc++-v3/include/std/regex b/libstdc++-v3/include/std/regex
index 0223066..9121d26 100644
--- a/libstdc++-v3/include/std/regex
+++ b/libstdc++-v3/include/std/regex
@@ -41,7 +41,6 @@
#include <bitset>
#include <locale>
-#include <sstream>
#include <stack>
#include <stdexcept>
#include <string>
diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index c064a92..d4db125 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -1984,14 +1984,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
class tuple<>
{
public:
+ // We need the default since we're going to define no-op
+ // allocator constructors.
+ tuple() = default;
+ // Defaulted copy operations to maintain trivial copyability.
+ // and support non-const assignment expressions.
+ tuple(const tuple&) = default;
+ tuple& operator=(const tuple&) = default;
+
_GLIBCXX20_CONSTEXPR
void swap(tuple&) noexcept { /* no-op */ }
+
#if __cpp_lib_ranges_zip // >= C++23
- constexpr void swap(const tuple&) const noexcept { /* no-op */ }
+ template<same_as<tuple> _Tuple = tuple>
+ constexpr const tuple&
+ operator=(const _Tuple&) const noexcept
+ { return *this; }
+
+ constexpr void swap(const tuple&) const noexcept
+ { /* no-op */ }
#endif
- // We need the default since we're going to define no-op
- // allocator constructors.
- tuple() = default;
+
// No-op allocator constructors.
template<typename _Alloc>
_GLIBCXX20_CONSTEXPR
@@ -2001,16 +2014,42 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
tuple(allocator_arg_t, const _Alloc&, const tuple&) noexcept { }
#if __cpp_lib_tuple_like // >= C++23
- // Comparison operators for tuple<> with other empty tuple-like types
template<__tuple_like _UTuple>
- requires (!__is_tuple_v<_UTuple> && tuple_size_v<_UTuple> == 0)
+ requires (!is_same_v<remove_cvref_t<_UTuple>, tuple>)
+ && (!is_same_v<remove_cvref_t<_UTuple>, allocator_arg_t>)
+ && (tuple_size_v<remove_cvref_t<_UTuple>> == 0)
+ constexpr
+ tuple(_UTuple&&) noexcept { }
+
+ template<typename _Alloc, __tuple_like _UTuple>
+ requires (!is_same_v<remove_cvref_t<_UTuple>, tuple>)
+ && (tuple_size_v<remove_cvref_t<_UTuple>> == 0)
+ constexpr
+ tuple(allocator_arg_t, const _Alloc&, _UTuple&&) noexcept { }
+
+ template<__tuple_like _UTuple>
+ requires (!is_same_v<remove_cvref_t<_UTuple>, tuple>)
+ && (tuple_size_v<remove_cvref_t<_UTuple>> == 0)
+ constexpr tuple&
+ operator=(_UTuple&&) noexcept
+ { return *this; }
+
+ template<__tuple_like _UTuple>
+ requires (!is_same_v<remove_cvref_t<_UTuple>, tuple>)
+ && (tuple_size_v<remove_cvref_t<_UTuple>> == 0)
+ constexpr const tuple&
+ operator=(_UTuple&&) const noexcept
+ { return *this; }
+
+ template<__tuple_like _UTuple>
+ requires (!__is_tuple_v<_UTuple>) && (tuple_size_v<_UTuple> == 0)
[[nodiscard]]
friend constexpr bool
operator==(const tuple&, const _UTuple&) noexcept
{ return true; }
template<__tuple_like _UTuple>
- requires (!__is_tuple_v<_UTuple> && tuple_size_v<_UTuple> == 0)
+ requires (!__is_tuple_v<_UTuple>) && (tuple_size_v<_UTuple> == 0)
friend constexpr strong_ordering
operator<=>(const tuple&, const _UTuple&) noexcept
{ return strong_ordering::equal; }
diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index 77ebb7e..d28b0773 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -47,6 +47,7 @@
#define __glibcxx_want_is_aggregate
#define __glibcxx_want_is_constant_evaluated
#define __glibcxx_want_is_final
+#define __glibcxx_want_is_implicit_lifetime
#define __glibcxx_want_is_invocable
#define __glibcxx_want_is_layout_compatible
#define __glibcxx_want_is_nothrow_convertible
@@ -4053,6 +4054,22 @@ template<typename _Ret, typename _Fn, typename... _Args>
# endif
#endif
+#ifdef __cpp_lib_is_implicit_lifetime // C++ >= 23
+ /// True if the type is an implicit-lifetime type.
+ /// @since C++23
+
+ template<typename _Tp>
+ struct is_implicit_lifetime
+ : bool_constant<__builtin_is_implicit_lifetime(_Tp)>
+ { };
+
+ /// @ingroup variable_templates
+ /// @since C++23
+ template<typename _Tp>
+ inline constexpr bool is_implicit_lifetime_v
+ = __builtin_is_implicit_lifetime(_Tp);
+#endif
+
#ifdef __cpp_lib_reference_from_temporary // C++ >= 23 && ref_{converts,constructs}_from_temp
/// True if _Tp is a reference type, a _Up value can be bound to _Tp in
/// direct-initialization, and a temporary object would be bound to
diff --git a/libstdc++-v3/src/c++23/std.cc.in b/libstdc++-v3/src/c++23/std.cc.in
index 4c11b1b..28f0e8c 100644
--- a/libstdc++-v3/src/c++23/std.cc.in
+++ b/libstdc++-v3/src/c++23/std.cc.in
@@ -3230,6 +3230,10 @@ export namespace std
using std::is_scoped_enum;
using std::is_scoped_enum_v;
#endif
+#if __cpp_lib_is_implicit_lifetime
+ using std::is_implicit_lifetime;
+ using std::is_implicit_lifetime_v;
+#endif
}
// <typeindex>
diff --git a/libstdc++-v3/testsuite/17_intro/headers/c++2011/42319.cc b/libstdc++-v3/testsuite/17_intro/headers/c++2011/42319.cc
index cd576ca..350a548 100644
--- a/libstdc++-v3/testsuite/17_intro/headers/c++2011/42319.cc
+++ b/libstdc++-v3/testsuite/17_intro/headers/c++2011/42319.cc
@@ -1,5 +1,5 @@
// { dg-do compile }
-// { dg-options "-std=gnu++11" }
+// { dg-add-options no_pch }
// Copyright (C) 2009-2025 Free Software Foundation, Inc.
//
@@ -19,4 +19,4 @@
// <http://www.gnu.org/licenses/>.
// libstdc++/42319
-#include <bits/char_traits.h>
+#include <ios>
diff --git a/libstdc++-v3/testsuite/20_util/is_implicit_lifetime/value.cc b/libstdc++-v3/testsuite/20_util/is_implicit_lifetime/value.cc
new file mode 100644
index 0000000..d8cb181
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/is_implicit_lifetime/value.cc
@@ -0,0 +1,129 @@
+// Copyright (C) 2025 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do compile { target c++23 } }
+// { dg-add-options no_pch }
+
+#include <type_traits>
+
+#ifndef __cpp_lib_is_implicit_lifetime
+# error "Feature test macro for is_implicit_lifetime is missing in <type_traits>"
+#elif __cpp_lib_is_implicit_lifetime < 202302L
+# error "Feature test macro for is_implicit_lifetime has wrong value in <type_traits>"
+#endif
+
+#include <testsuite_tr1.h>
+
+template<typename T>
+ concept Is_implicit_lifetime
+ = __gnu_test::test_category<std::is_implicit_lifetime, T>(true);
+
+static_assert( ! Is_implicit_lifetime<void> );
+static_assert( ! Is_implicit_lifetime<const void> );
+static_assert( ! Is_implicit_lifetime<volatile void> );
+static_assert( Is_implicit_lifetime<char> );
+static_assert( Is_implicit_lifetime<signed char> );
+static_assert( Is_implicit_lifetime<const unsigned char> );
+static_assert( Is_implicit_lifetime<short> );
+static_assert( Is_implicit_lifetime<volatile unsigned short> );
+static_assert( Is_implicit_lifetime<int> );
+static_assert( Is_implicit_lifetime<unsigned int> );
+static_assert( Is_implicit_lifetime<const volatile long> );
+static_assert( Is_implicit_lifetime<unsigned long> );
+static_assert( Is_implicit_lifetime<long long> );
+static_assert( Is_implicit_lifetime<unsigned long long> );
+static_assert( Is_implicit_lifetime<float> );
+static_assert( Is_implicit_lifetime<double> );
+static_assert( Is_implicit_lifetime<long double volatile> );
+enum W { W1 };
+static_assert( Is_implicit_lifetime<W> );
+enum class X : int { X1 };
+static_assert( Is_implicit_lifetime<const volatile X> );
+static_assert( Is_implicit_lifetime<int *> );
+static_assert( Is_implicit_lifetime<int (*) (int)> );
+struct Y { int g; int foo (int); };
+static_assert( Is_implicit_lifetime<int (Y::*)> );
+static_assert( Is_implicit_lifetime<int (Y::*) (int)> );
+static_assert( ! Is_implicit_lifetime<int &> );
+static_assert( ! Is_implicit_lifetime<char &&> );
+static_assert( Is_implicit_lifetime<int []> );
+static_assert( Is_implicit_lifetime<int [1]> );
+static_assert( Is_implicit_lifetime<const Y [42]> );
+static_assert( ! Is_implicit_lifetime<int ()> );
+static_assert( ! Is_implicit_lifetime<int () &> );
+static_assert( ! Is_implicit_lifetime<int () const> );
+static_assert( ! Is_implicit_lifetime<int (&) ()> );
+struct Z;
+static_assert( Is_implicit_lifetime<Z []> );
+static_assert( Is_implicit_lifetime<Z [5]> );
+struct A { int a, b, c; };
+static_assert( Is_implicit_lifetime<A> );
+class B { static int a; private: static int b; public: int c; };
+static_assert( Is_implicit_lifetime<B> );
+struct C { C () {} int a, b, c; };
+static_assert( Is_implicit_lifetime<C> );
+struct D { explicit D (int) {} int a, b, c; };
+static_assert( Is_implicit_lifetime<D> );
+struct E : public A { int d, e, f; };
+static_assert( Is_implicit_lifetime<E> );
+struct F : public C { using C::C; int d, e, f; };
+static_assert( Is_implicit_lifetime<F> );
+class G { int a, b; };
+static_assert( Is_implicit_lifetime<G> );
+struct H { private: int a, b; };
+static_assert( Is_implicit_lifetime<H> );
+struct I { protected: int a, b; };
+static_assert( Is_implicit_lifetime<I> );
+struct J { int a, b; void foo (); };
+static_assert( Is_implicit_lifetime<J> );
+struct K { int a, b; virtual void foo (); };
+static_assert( ! Is_implicit_lifetime<K> );
+struct L : virtual public A { int d, e; };
+static_assert( ! Is_implicit_lifetime<L> );
+struct M : protected A { int d, e; };
+static_assert( Is_implicit_lifetime<M> );
+struct N : private A { int d, e; };
+static_assert( Is_implicit_lifetime<N> );
+struct O { O () = delete; int a, b, c; };
+static_assert( Is_implicit_lifetime<O> );
+struct P { P () = default; int a, b, c; };
+static_assert( Is_implicit_lifetime<P> );
+struct Q { Q (); Q (const Q &); int a, b, c; };
+static_assert( ! Is_implicit_lifetime<Q> );
+struct R { R (); R (const R &); R (R &&) = default; int a, b, c; };
+static_assert( Is_implicit_lifetime<R> );
+struct S { S (); ~S (); int a, b, c; };
+static_assert( ! Is_implicit_lifetime<S> );
+static_assert( Is_implicit_lifetime<S [3]> );
+struct T { T (); ~T () = default; int a, b, c; };
+static_assert( Is_implicit_lifetime<T> );
+struct U { U (); U (const U &) = default; int a, b, c; };
+static_assert( Is_implicit_lifetime<U> );
+struct V { V () = default; V (const V &); int a, b, c; };
+static_assert( Is_implicit_lifetime<V> );
+struct AA { Q a; Q b; };
+static_assert( Is_implicit_lifetime<AA> );
+struct AB { Q a; Q b; ~AB () = default; };
+static_assert( Is_implicit_lifetime<AB> );
+struct AC { Q a; Q b; ~AC () {} };
+static_assert( ! Is_implicit_lifetime<AC> );
+struct AD : public Q {};
+static_assert( Is_implicit_lifetime<AD> );
+struct AE : public Q { ~AE () = default; };
+static_assert( Is_implicit_lifetime<AE> );
+struct AF : public Q { ~AF () {} };
+static_assert( ! Is_implicit_lifetime<AF> );
diff --git a/libstdc++-v3/testsuite/20_util/is_implicit_lifetime/version.cc b/libstdc++-v3/testsuite/20_util/is_implicit_lifetime/version.cc
new file mode 100644
index 0000000..ed90b47
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/is_implicit_lifetime/version.cc
@@ -0,0 +1,27 @@
+// Copyright (C) 2025 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do compile { target c++23 } }
+// { dg-add-options no_pch }
+
+#include <version>
+
+#ifndef __cpp_lib_is_implicit_lifetime
+# error "Feature test macro for is_implicit_lifetime is missing in <version>"
+#elif __cpp_lib_is_implicit_lifetime < 202302L
+# error "Feature test macro for is_implicit_lifetime has wrong value in <version>"
+#endif
diff --git a/libstdc++-v3/testsuite/20_util/tuple/requirements/empty_trivial.cc b/libstdc++-v3/testsuite/20_util/tuple/requirements/empty_trivial.cc
new file mode 100644
index 0000000..ee18bb3
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/tuple/requirements/empty_trivial.cc
@@ -0,0 +1,17 @@
+// { dg-do compile { target c++11 } }
+
+#include <tuple>
+#include <type_traits>
+
+// Check that tuple<> has the expected trivial properties
+static_assert(std::is_trivially_copyable<std::tuple<>>::value,
+ "tuple<> should be trivially copyable");
+static_assert(std::is_trivially_copy_constructible<std::tuple<>>::value,
+ "tuple<> should be trivially copy constructible");
+static_assert(std::is_trivially_move_constructible<std::tuple<>>::value,
+ "tuple<> should be trivially move constructible");
+static_assert(std::is_trivially_copy_assignable<std::tuple<>>::value,
+ "tuple<> should be trivially copy assignable");
+static_assert(std::is_trivially_move_assignable<std::tuple<>>::value,
+ "tuple<> should be trivially move assignable");
+
diff --git a/libstdc++-v3/testsuite/23_containers/tuple/cons/119721.cc b/libstdc++-v3/testsuite/23_containers/tuple/cons/119721.cc
new file mode 100644
index 0000000..1d15238
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/tuple/cons/119721.cc
@@ -0,0 +1,121 @@
+// { dg-do run { target c++23 } }
+
+// Test for PR libstdc++/119721: tuple<> construction/assignment with array<T, 0>
+
+#include <tuple>
+#include <array>
+#include <memory>
+#include <testsuite_hooks.h>
+
+constexpr void
+test01()
+{
+ std::array<int, 0> a{};
+
+ // Constructor from array<int, 0>
+ std::tuple<> t1(a);
+ std::tuple<> t2(std::move(a));
+
+ // Assignment from array<int, 0>
+ std::tuple<> t3;
+ t3 = a;
+ t3 = std::move(a);
+
+ VERIFY( t1 == a );
+ VERIFY( t2 == a );
+ VERIFY( t3 == a );
+}
+
+constexpr void
+test02()
+{
+ // Test with non-comparable element type
+ struct NonComparable
+ {
+ void operator==(const NonComparable&) const = delete;
+ void operator<=>(const NonComparable&) const = delete;
+ };
+
+ std::array<NonComparable, 0> a{};
+
+ std::tuple<> t1(a);
+ std::tuple<> t2(std::move(a));
+
+ std::tuple<> t3;
+ t3 = a;
+ t3 = std::move(a);
+
+ VERIFY( t1 == a );
+}
+
+constexpr void
+test03()
+{
+ // Test assignment return type (non-const assignment)
+ std::tuple<> t, u;
+ std::tuple<>& r1 = (t = u);
+ VERIFY( &r1 == &t );
+
+ std::tuple<>& r2 = (t = {});
+ VERIFY( &r2 == &t );
+
+ std::array<int, 0> a{};
+ std::tuple<>& r3 = (t = a);
+ VERIFY( &r3 == &t );
+}
+
+constexpr void
+test04()
+{
+ std::array<int, 0> a{};
+ const std::tuple<> t1;
+
+ // Const assignment from array
+ std::tuple<> t2;
+ const std::tuple<>& r1 = (t1 = t2);
+ VERIFY( &r1 == &t1 );
+ const std::tuple<>& r2 = (t1 = std::move(t2));
+ VERIFY( &r2 == &t1 );
+
+ const std::tuple<>& r3 = (t1 = {});
+ VERIFY( &r3 == &t1 );
+
+ // Const assignment from array
+ const std::tuple<>& r4 = (t1 = a);
+ VERIFY( &r4 == &t1 );
+ const std::tuple<>& r5 = (t1 = std::move(a));
+ VERIFY( &r5 == &t1 );
+}
+
+void
+test05()
+{
+ std::array<int, 0> a{};
+ std::allocator<int> alloc;
+
+ // Allocator constructor from array
+ std::tuple<> t1(std::allocator_arg, alloc, a);
+ std::tuple<> t2(std::allocator_arg, alloc, std::move(a));
+
+ VERIFY( t1 == a );
+ VERIFY( t2 == a );
+}
+
+int main()
+{
+ auto test_all = [] {
+ test01();
+ test02();
+ test03();
+ test04();
+ return true;
+ };
+
+ test_all();
+ static_assert( test_all() );
+
+ // allocator test is not constexpr
+ test05();
+ return 0;
+}
+
diff --git a/libstdc++-v3/testsuite/30_threads/shared_timed_mutex/try_lock_until/116586.cc b/libstdc++-v3/testsuite/30_threads/shared_timed_mutex/try_lock_until/116586.cc
index cebbb3a..5736b7d 100644
--- a/libstdc++-v3/testsuite/30_threads/shared_timed_mutex/try_lock_until/116586.cc
+++ b/libstdc++-v3/testsuite/30_threads/shared_timed_mutex/try_lock_until/116586.cc
@@ -1,4 +1,7 @@
// { dg-do run { target c++14 } }
+// { dg-additional-options "-pthread" { target pthread } }
+// { dg-require-gthreads "" }
+// { dg-require-effective-target hosted }
#include <shared_mutex>
#include <chrono>
@@ -8,10 +11,18 @@
namespace chrono = std::chrono;
-// thread.timedmutex.requirements.general:
+// [thread.timedmutex.requirements.general]:
// If abs_time has already passed, the function attempts to obtain
// ownership without blocking (as if by calling try_lock()).
+// C++14 [thread.sharedtimedmutex.class] 3.2 says it's undefined for a thread
+// to attempt to recursively gain any ownership of a shared_timed_mutex.
+// This isn't just theoretical, as Glibc's pthread_rwlock_timedrdlock will
+// return EDEADLK if called on the same thread that already holds the
+// exclusive (write) lock.
+#define VERIFY_IN_NEW_THREAD(X) \
+ (void) std::async(std::launch::async, [&] { VERIFY(X); })
+
template <typename Clock>
void
test_exclusive_absolute(chrono::nanoseconds offset)
@@ -19,7 +30,7 @@ test_exclusive_absolute(chrono::nanoseconds offset)
std::shared_timed_mutex stm;
chrono::time_point<Clock> tp(offset);
VERIFY(stm.try_lock_until(tp));
- VERIFY(!stm.try_lock_until(tp));
+ VERIFY_IN_NEW_THREAD(!stm.try_lock_until(tp));
}
template <typename Clock>
@@ -32,15 +43,7 @@ test_shared_absolute(chrono::nanoseconds offset)
stm.unlock_shared();
VERIFY(stm.try_lock_for(chrono::seconds{10}));
-
- {
- // NPTL will give us EDEADLK if pthread_rwlock_timedrdlock() is called on
- // the same thread that already holds the exclusive (write) lock, so let's
- // arrange for a different thread to try to acquire the shared lock.
- auto t = std::async(std::launch::async, [&stm, tp]() {
- VERIFY(!stm.try_lock_shared_until(tp));
- });
- }
+ VERIFY_IN_NEW_THREAD(!stm.try_lock_shared_until(tp));
}
// The type of clock used for the actual wait depends on whether
@@ -53,7 +56,7 @@ test_exclusive_relative(chrono::nanoseconds offset)
std::shared_timed_mutex stm;
const auto d = -Clock::now().time_since_epoch() + offset;
VERIFY(stm.try_lock_for(d));
- VERIFY(!stm.try_lock_for(d));
+ VERIFY_IN_NEW_THREAD(!stm.try_lock_for(d));
}
template <typename Clock>
@@ -66,7 +69,7 @@ test_shared_relative(chrono::nanoseconds offset)
stm.unlock_shared();
// Should complete immediately
VERIFY(stm.try_lock_for(chrono::seconds{10}));
- VERIFY(!stm.try_lock_shared_for(d));
+ VERIFY_IN_NEW_THREAD(!stm.try_lock_shared_for(d));
}
int main()
diff --git a/libstdc++-v3/testsuite/30_threads/thread/swap/1.cc b/libstdc++-v3/testsuite/30_threads/thread/swap/1.cc
index 9616b15..b1fde09 100644
--- a/libstdc++-v3/testsuite/30_threads/thread/swap/1.cc
+++ b/libstdc++-v3/testsuite/30_threads/thread/swap/1.cc
@@ -23,7 +23,7 @@
#include <thread>
#include <system_error>
-#include <bits/move.h> // std::move
+#include <utility> // std::move
#include <testsuite_hooks.h>
void f() { }