aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog99
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/ada/ChangeLog14
-rw-r--r--gcc/ada/rtfinal.c2
-rw-r--r--gcc/ada/rtinit.c3
-rw-r--r--gcc/ada/sem_attr.adb47
-rw-r--r--gcc/analyzer/ChangeLog5
-rw-r--r--gcc/analyzer/kf.cc3
-rw-r--r--gcc/cgraph.cc6
-rw-r--r--gcc/cgraphclones.cc4
-rw-r--r--gcc/config/aarch64/aarch64-cores.def5
-rw-r--r--gcc/config/aarch64/aarch64-simd.md12
-rw-r--r--gcc/config/aarch64/aarch64-tune.md2
-rw-r--r--gcc/config/i386/sse.md3
-rw-r--r--gcc/config/mingw/winnt.cc10
-rw-r--r--gcc/cp/ChangeLog10
-rw-r--r--gcc/cp/decl.cc6
-rw-r--r--gcc/cp/decl2.cc5
-rw-r--r--gcc/cp/pt.cc7
-rw-r--r--gcc/cp/semantics.cc4
-rw-r--r--gcc/doc/invoke.texi3
-rw-r--r--gcc/fortran/ChangeLog9
-rw-r--r--gcc/fortran/decl.cc4
-rw-r--r--gcc/testsuite/ChangeLog233
-rw-r--r--gcc/testsuite/g++.dg/modules/tpl-friend-22.C24
-rw-r--r--gcc/testsuite/g++.dg/template/sfinae-deleted-pr119343.C31
-rw-r--r--gcc/testsuite/g++.dg/torture/pr123040.C61
-rw-r--r--gcc/testsuite/gcc.dg/tls/data-sections-1.c14
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr46555.c28
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr123038.c8
-rw-r--r--gcc/testsuite/gcc.target/aarch64/pr123026.c21
-rw-r--r--gcc/testsuite/gcc.target/i386/avx2-vpcmpgtq-1.c2
-rw-r--r--gcc/testsuite/gfortran.dg/assumed_charlen_dummy.f901
-rw-r--r--gcc/testsuite/gfortran.dg/automatic_char_len_1.f901
-rw-r--r--gcc/testsuite/gfortran.dg/entry_23.f1
-rw-r--r--gcc/testsuite/gfortran.dg/finalize_59.f904
-rw-r--r--gcc/testsuite/gfortran.dg/g77/f90-intrinsic-bit.f1
-rw-r--r--gcc/testsuite/gfortran.dg/g77/f90-intrinsic-mathematical.f1
-rw-r--r--gcc/testsuite/gfortran.dg/g77/f90-intrinsic-numeric.f1
-rw-r--r--gcc/testsuite/gfortran.dg/g77/intrinsic-unix-bessel.f1
-rw-r--r--gcc/testsuite/gfortran.dg/g77/intrinsic-unix-erf.f1
-rw-r--r--gcc/testsuite/gfortran.dg/initialization_9.f901
-rw-r--r--gcc/testsuite/gfortran.dg/intrinsic_actual_4.f901
-rw-r--r--gcc/testsuite/gfortran.dg/namelist_assumed_char.f902
-rw-r--r--gcc/testsuite/gfortran.dg/pr15140.f901
-rw-r--r--gcc/testsuite/gnat.dg/reduce3.adb17
-rw-r--r--gcc/tree-cfg.cc218
-rw-r--r--gcc/tree-cfg.h1
-rw-r--r--gcc/tree-cfgcleanup.cc9
-rw-r--r--gcc/tree-ssa-dce.cc212
-rw-r--r--gcc/tree-ssa-sccvn.cc5
-rw-r--r--gcc/tree-vect-patterns.cc14
-rw-r--r--gcc/tree-vect-stmts.cc49
53 files changed, 935 insertions, 294 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ed720db..e6da5b8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,102 @@
+2025-12-08 Andrew Pinski <andrew.pinski@oss.qualcomm.com>
+
+ PR tree-optimization/46555
+ * tree-cfgcleanup.cc (execute_cleanup_cfg_post_optimizing):
+ Don't set todo to include cleanupcfg; do it manually.
+ Call make_forwarders_with_degenerate_phis if optimizing.
+
+2025-12-08 Andrew Pinski <andrew.pinski@oss.qualcomm.com>
+
+ * tree-cfg.cc (make_forwarders_with_degenerate_phis): Add debug
+ dump.
+
+2025-12-08 Andrew Pinski <andrew.pinski@oss.qualcomm.com>
+
+ * tree-ssa-dce.cc (sort_phi_args): Move to tree-cfg.cc.
+ (make_forwarders_with_degenerate_phis): Move to tree-cfg.cc.
+ (perform_tree_ssa_dce): Update for the updated return type
+ of make_forwarders_with_degenerate_phis.
+ * tree-cfg.cc (sort_phi_args): Moved from tree-ssa-dce.cc.
+ (make_forwarders_with_degenerate_phis): Moved from tree-ssa-dce.cc.
+ Update return type to bool and return true if an edge was split.
+ * tree-cfg.h (make_forwarders_with_degenerate_phis): New decl.
+
+2025-12-08 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR target/80881
+ * config/mingw/winnt.cc (mingw_pe_unique_section): Put two dollar
+ signs for TLS sections after the prefix.
+ (mingw_pe_asm_named_section): Deal with all TLS sections uniformly.
+
+2025-12-08 Ezra Sitorus <Ezra.Sitorus@arm.com>
+
+ * config/aarch64/aarch64-cores.def (AARCH64_CORE): Add C1-Nano,
+ C1-Pro, C1-Premium and C1-Ultra.
+ * config/aarch64/aarch64-tune.md: Regenerate.
+ * doc/invoke.texi: Document C1 cores.
+
+2025-12-08 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/123040
+ * tree-ssa-sccvn.cc (vn_nary_build_or_lookup_1): Only insert
+ nary results.
+
+2025-12-08 Josef Melcr <josef.melcr@suse.com>
+
+ PR ipa/122798
+ * cgraph.cc (cgraph_edge::redirect_callee): Use
+ iterate_referring instead of referred_to_p.
+ * cgraphclones.cc (set_new_clone_decl_and_node_flags): Set local
+ to true iff the node does not have its address taken.
+
+2025-12-08 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/123038
+ * tree-vect-patterns.cc (vect_recog_ctz_ffs_pattern): Reject
+ pattern for reductions when the call argument is used multiple
+ times.
+
+2025-12-08 Tamar Christina <tamar.christina@arm.com>
+
+ PR target/123026
+ * config/aarch64/aarch64-simd.md (reduc_sbool_ior_scal_<mode>,
+ reduc_sbool_and_scal_<mode>): Fix tmp operands[1] override.
+
+2025-12-08 Tamar Christina <tamar.christina@arm.com>
+
+ PR tree-optimization/122868
+ * tree-vect-stmts.cc (vectorizable_load): Move check for invariant loads
+ down into the loop.
+
+2025-12-08 H.J. Lu <hjl.tools@gmail.com>
+
+ PR target/122343
+ * config/i386/sse.md (*<avx512>_cmp<mode>3_dup_op): Don't allow
+ 2 volatile memory references.
+
+2025-12-07 Jason Merrill <jason@redhat.com>
+
+ * config/darwin-c.cc (find_subframework_header): Use
+ _cpp_get_file_*.
+
+2025-12-07 H.J. Lu <hjl.tools@gmail.com>
+
+ PR target/122343
+ * common.opt: Add -ffuse-ops-with-volatile-access.
+ * common.opt.urls: Regenerated.
+ * recog.cc (general_operand): Allow volatile memory reference if
+ -ffuse-ops-with-volatile-access is enabled.
+ * simplify-rtx.cc (simplify_binary_operation_1): Keep PLUS for 2
+ volatile memory references.
+ * doc/invoke.texi: Document -ffuse-ops-with-volatile-access.
+
+2025-12-07 Alexandre Oliva <oliva@adacore.com>
+
+ * cselib.cc (dump_cselib_val): Split out of and rename to...
+ (dump_cselib_val_ptr): ... this.
+ (dump_cselib_table): Adjust. Skip cselib_preserved_hash_table
+ when not allocated.
+
2025-12-06 Alexandre Oliva <oliva@adacore.com>
PR rtl-optimization/122947
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 47f4b89..4568345 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20251207
+20251209
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index fca1a9e..8b19deb 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,17 @@
+2025-12-08 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR ada/123037
+ * rtinit.c [__MINGW32__]: Include <stdlib.h> and not <windows.h>.
+ * rtfinal.c [__MINGW32__]: Do not include <windows.h>.
+
+2025-12-07 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR ada/115349
+ * sem_attr.adb (Resolve_Attribute) <Attribute_Reduce>: Use the base
+ type as Accum_Type if the reducer is an operator from Standard and
+ the type is numeric. Use the type of the first operand for other
+ operators. Streamline the error message given for limited types.
+
2025-12-06 Denis Mazzucato <mazzucato@adacore.com>
* sem_attr.adb (Resolve_Attribute): Check if the reducer is a
diff --git a/gcc/ada/rtfinal.c b/gcc/ada/rtfinal.c
index 88bbb0e..0bd3ce4 100644
--- a/gcc/ada/rtfinal.c
+++ b/gcc/ada/rtfinal.c
@@ -46,9 +46,7 @@ extern int __gnat_rt_init_count;
/* see initialize.c */
#if defined (__MINGW32__)
-#define WIN32_LEAN_AND_MEAN
#include "mingw32.h"
-#include <windows.h>
extern CRITICAL_SECTION ProcListCS;
extern HANDLE ProcListEvt;
diff --git a/gcc/ada/rtinit.c b/gcc/ada/rtinit.c
index 598550c..3b5af0d 100644
--- a/gcc/ada/rtinit.c
+++ b/gcc/ada/rtinit.c
@@ -70,9 +70,8 @@ int __gnat_rt_init_count = 0;
and finalize properly the run-time. */
#if defined (__MINGW32__)
-#define WIN32_LEAN_AND_MEAN
+#include <stdlib.h>
#include "mingw32.h"
-#include <windows.h>
extern void __gnat_init_float (void);
diff --git a/gcc/ada/sem_attr.adb b/gcc/ada/sem_attr.adb
index ca19cad..74e9d6f 100644
--- a/gcc/ada/sem_attr.adb
+++ b/gcc/ada/sem_attr.adb
@@ -12919,7 +12919,7 @@ package body Sem_Attr is
-- Where the context is augmented with the iteration
-- variable I of the right type, and Init_Var of type
- -- Accum_Subtype. If the Reducer has both procedure and
+ -- Accum_Typ. If the Reducer has both procedure and
-- function interpretations with the proper reducer profile
-- an ambiguity error is emitted. Note that, this could be a
-- false positive as the two may coexist without ambiguity
@@ -13204,7 +13204,7 @@ package body Sem_Attr is
return;
end if;
- -- If no error has been posted and the accumulation type is
+ -- If no error has been posted and the accumulator type is
-- constrained, then the resolution of the reducer can start.
if Nkind (Reducer_N) = N_Attribute_Reference then
@@ -13252,44 +13252,50 @@ package body Sem_Attr is
end if;
end if;
- -- After resolving the reducer, determine the correct
- -- Accum_Subtype: if the reducer is an attribute (Min or Max),
- -- then the prefix type is the accumulation type.
+ -- After resolving the reducer, determine Accum_Typ: if the
+ -- reducer is an attribute (Min or Max), then its prefix is
+ -- the accumulator type.
if Nkind (Reducer_E) = N_Attribute_Reference then
- Accum_Typ := Etype (Prefix (Reducer_E));
+ Accum_Typ := Entity (Prefix (Reducer_E));
- -- If an operator from standard, then the type of its first
- -- formal woudl be Any_Type, in this case we make sure we don't
- -- use an universal type to avoid resolution problems later on.
+ -- If the reducer is an operator from Standard, then the type
+ -- of its first operand would be Any_Type. In this case, make
+ -- sure we do not have an universal type to avoid resolution
+ -- problems later on, and use the base type of numeric types
+ -- to avoid spurious subtype mismatches for the initial value.
- elsif Ekind (Reducer_E) = E_Operator
- or else Scope (Reducer_E) = Standard_Standard
- then
+ elsif Scope (Reducer_E) = Standard_Standard then
if Accum_Typ = Universal_Integer then
Accum_Typ := Standard_Integer;
elsif Accum_Typ = Universal_Real then
Accum_Typ := Standard_Float;
+ elsif Is_Numeric_Type (Accum_Typ) then
+ Accum_Typ := Base_Type (Accum_Typ);
end if;
- -- Otherwise, the Accum_Subtype is the subtype of the first
- -- formal of the reducer subprogram RM 4.5.10(19/5).
+ -- Otherwise, Accum_Typ is the subtype of the first formal
+ -- of the reducer subprogram (RM 4.5.10(19/5)).
+
+ elsif Ekind (Reducer_E) = E_Operator then
+ Accum_Typ := Etype (Left_Opnd (Reducer_E));
else
Accum_Typ := Etype (First_Formal (Reducer_E));
end if;
+
Set_Etype (N, Accum_Typ);
- -- Accumulation type must be nonlimited, RM 4.5.10(8/5)
+ -- The accumulator type must be nonlimited (RM 4.5.10(8/5))
if Is_Limited_Type (Accum_Typ) then
Error_Msg_N
- ("accumulated subtype of Reduce must be nonlimited", N);
+ ("type of reduction expression must be nonlimited", N);
- -- If the Accum_Typ is an unconstrained array and the reducer
+ -- If Accum_Typ is an unconstrained array and the reducer
-- subprogram is a function then a Constraint_Error will be
- -- raised at runtime as most computations will change its
- -- length type during the reduction execution, RM 4.5.10(25/5).
+ -- raised at run time, as most computations will change its
+ -- length during the reduction execution (RM 4.5.10(25/5)).
-- For instance, this is the case with:
-- [...]'Reduce ("&", ...)
-- When the expression yields non-empty strings, the reduction
@@ -13300,7 +13306,7 @@ package body Sem_Attr is
elsif Nkind (Reducer_E) /= N_Attribute_Reference
and then Ekind (Reducer_E) = E_Function
- and then not Is_Numeric_Type (Base_Type (Accum_Typ))
+ and then not Is_Numeric_Type (Accum_Typ)
and then not Is_Constrained (Accum_Typ)
then
declare
@@ -13318,6 +13324,7 @@ package body Sem_Attr is
-- resolving the initial expression and array aggregate.
Resolve (Init_Value_Expr, Accum_Typ);
+
if Nkind (P) = N_Aggregate then
Resolve_Aggregate (P,
Make_Array_Type (Index => Standard_Positive,
diff --git a/gcc/analyzer/ChangeLog b/gcc/analyzer/ChangeLog
index 58fc1f4..9ede664 100644
--- a/gcc/analyzer/ChangeLog
+++ b/gcc/analyzer/ChangeLog
@@ -1,3 +1,8 @@
+2025-12-07 David Malcolm <dmalcolm@redhat.com>
+
+ * kf.cc (register_known_functions): Remove duplicate calls to
+ register_atomic_builtins and register_varargs_builtins.
+
2025-11-28 Jakub Jelinek <jakub@redhat.com>
* known-function-manager.cc (known_function_manager::add): Avoid
diff --git a/gcc/analyzer/kf.cc b/gcc/analyzer/kf.cc
index b3c02e8..c9818de 100644
--- a/gcc/analyzer/kf.cc
+++ b/gcc/analyzer/kf.cc
@@ -2334,9 +2334,6 @@ register_known_functions (known_function_manager &kfm,
kfm.add ("__builtin_strlen", std::make_unique<kf_strlen> ());
kfm.add ("strstr", std::make_unique<kf_strstr> ());
kfm.add ("__builtin_strstr", std::make_unique<kf_strstr> ());
-
- register_atomic_builtins (kfm);
- register_varargs_builtins (kfm);
}
/* Known POSIX functions, and some non-standard extensions. */
diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index 3c21e17..1a7d499 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -1696,8 +1696,12 @@ cgraph_edge::redirect_callee (cgraph_node *n)
old_ref->remove_reference ();
ipa_ref *new_ref = caller->create_reference (n, IPA_REF_ADDR, call_stmt);
new_ref->lto_stmt_uid = lto_stmt_uid;
- if (!old_callee->referred_to_p ())
+ /* If the last reference to OLD_CALLEE has been redirected, unset
+ address_taken. old_ref is only used as a placeholder when looking for
+ a different reference. */
+ if (!old_callee->iterate_referring (0, old_ref))
old_callee->address_taken = 0;
+ n->mark_address_taken ();
}
if (!inline_failed)
diff --git a/gcc/cgraphclones.cc b/gcc/cgraphclones.cc
index 49f0e58..816fc53 100644
--- a/gcc/cgraphclones.cc
+++ b/gcc/cgraphclones.cc
@@ -176,7 +176,9 @@ set_new_clone_decl_and_node_flags (cgraph_node *new_node)
DECL_IS_REPLACEABLE_OPERATOR (new_node->decl) = 0;
new_node->externally_visible = 0;
- new_node->local = 1;
+ /* Clones of callbacks might have their address taken, and thus cannot be
+ local. */
+ new_node->local = !new_node->address_taken;
new_node->lowered = true;
new_node->semantic_interposition = 0;
}
diff --git a/gcc/config/aarch64/aarch64-cores.def b/gcc/config/aarch64/aarch64-cores.def
index b86d80c..851594a 100644
--- a/gcc/config/aarch64/aarch64-cores.def
+++ b/gcc/config/aarch64/aarch64-cores.def
@@ -229,6 +229,11 @@ AARCH64_CORE("grace", grace, cortexa57, V9A, (I8MM, BF16, SVE2_BITPERM, SVE2_AES
AARCH64_CORE("neoverse-v3", neoversev3, cortexa57, V9_2A, (SVE2_BITPERM, RNG, LS64, MEMTAG, PROFILE), neoversev3, 0x41, 0xd84, -1)
AARCH64_CORE("neoverse-v3ae", neoversev3ae, cortexa57, V9_2A, (SVE2_BITPERM, RNG, LS64, MEMTAG, PROFILE), neoversev3ae, 0x41, 0xd83, -1)
+AARCH64_CORE("c1-nano", c1nano, cortexa53, V9_3A, (MEMTAG, SVE2_BITPERM, F16FML, SME2, RCPC3), cortexa53, 0x41, 0xd8a, -1)
+AARCH64_CORE("c1-pro", c1pro, cortexa57, V9_3A, (MEMTAG, SVE2_BITPERM, F16FML, PROFILE, SME2, RCPC3), neoversen3, 0x41, 0xd8b, -1)
+AARCH64_CORE("c1-premium", c1premium, cortexa57, V9_3A, (MEMTAG, SVE2_BITPERM, F16FML, PROFILE, SME2, RCPC3), neoversev3, 0x41, 0xd90, -1)
+AARCH64_CORE("c1-ultra", c1ultra, cortexa57, V9_3A, (MEMTAG, SVE2_BITPERM, F16FML, PROFILE, SME2, RCPC3), cortexx925, 0x41, 0xd8c, -1)
+
AARCH64_CORE("demeter", demeter, cortexa57, V9A, (I8MM, BF16, SVE2_BITPERM, RNG, MEMTAG, PROFILE), neoversev2, 0x41, 0xd4f, -1)
/* NVIDIA ('N') cores. */
diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index 3f9d5f6..c02ffd6 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -3544,10 +3544,10 @@
rtx reduc = gen_lowpart (V4SImode, tmp);
rtx res = gen_reg_rtx (V4SImode);
emit_insn (gen_aarch64_uminpv4si (res, reduc, reduc));
- emit_move_insn (tmp, gen_lowpart (<MODE>mode, res));
+ tmp = gen_lowpart (<MODE>mode, res);
}
- rtx val = gen_reg_rtx (DImode);
- emit_move_insn (val, gen_lowpart (DImode, tmp));
+
+ rtx val = force_lowpart_subreg (DImode, tmp, <MODE>mode);
rtx cc_reg = aarch64_gen_compare_reg (EQ, val, constm1_rtx);
rtx cmp = gen_rtx_fmt_ee (EQ, SImode, cc_reg, constm1_rtx);
rtx tmp2 = gen_reg_rtx (SImode);
@@ -3607,10 +3607,10 @@
rtx reduc = gen_lowpart (V4SImode, tmp);
rtx res = gen_reg_rtx (V4SImode);
emit_insn (gen_aarch64_umaxpv4si (res, reduc, reduc));
- emit_move_insn (tmp, gen_lowpart (<MODE>mode, res));
+ tmp = gen_lowpart (<MODE>mode, res);
}
- rtx val = gen_reg_rtx (DImode);
- emit_move_insn (val, gen_lowpart (DImode, tmp));
+
+ rtx val = force_lowpart_subreg (DImode, tmp, <MODE>mode);
rtx cc_reg = aarch64_gen_compare_reg (NE, val, const0_rtx);
rtx cmp = gen_rtx_fmt_ee (NE, SImode, cc_reg, const0_rtx);
rtx tmp2 = gen_reg_rtx (SImode);
diff --git a/gcc/config/aarch64/aarch64-tune.md b/gcc/config/aarch64/aarch64-tune.md
index 292796c..d6f1bbc 100644
--- a/gcc/config/aarch64/aarch64-tune.md
+++ b/gcc/config/aarch64/aarch64-tune.md
@@ -1,5 +1,5 @@
;; -*- buffer-read-only: t -*-
;; Generated automatically by gentune.sh from aarch64-cores.def
(define_attr "tune"
- "cortexa34,cortexa35,cortexa53,cortexa57,cortexa72,cortexa73,thunderx,thunderxt88,thunderxt88p1,octeontx,octeontxt81,octeontxt83,thunderxt81,thunderxt83,ampere1,ampere1a,ampere1b,ampere1c,emag,xgene1,falkor,qdf24xx,exynosm1,phecda,thunderx2t99p1,vulcan,thunderx2t99,cortexa55,cortexa75,cortexa76,cortexa76ae,cortexa77,cortexa78,cortexa78ae,cortexa78c,cortexa65,cortexa65ae,cortexx1,cortexx1c,neoversen1,ares,neoversee1,octeontx2,octeontx2t98,octeontx2t96,octeontx2t93,octeontx2f95,octeontx2f95n,octeontx2f95mm,a64fx,fujitsu_monaka,tsv110,thunderx3t110,neoversev1,zeus,neoverse512tvb,saphira,oryon1,cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35,cortexa73cortexa53,cortexa75cortexa55,cortexa76cortexa55,cortexr82,cortexr82ae,applea12,applem1_0,applem1_1,applem1_2,applem1_3,applem2_0,applem2_1,applem2_2,applem2_3,applem3_0,applem3_1,applem3_2,applem4_0,applem4_1,applem4_2,cortexa510,cortexa520,cortexa520ae,cortexa710,cortexa715,cortexa720,cortexa720ae,cortexa725,cortexx2,cortexx3,cortexx4,cortexx925,neoversen2,cobalt100,neoversen3,neoversev2,grace,neoversev3,neoversev3ae,demeter,olympus,gb10,generic,generic_armv8_a,generic_armv9_a"
+ "cortexa34,cortexa35,cortexa53,cortexa57,cortexa72,cortexa73,thunderx,thunderxt88,thunderxt88p1,octeontx,octeontxt81,octeontxt83,thunderxt81,thunderxt83,ampere1,ampere1a,ampere1b,ampere1c,emag,xgene1,falkor,qdf24xx,exynosm1,phecda,thunderx2t99p1,vulcan,thunderx2t99,cortexa55,cortexa75,cortexa76,cortexa76ae,cortexa77,cortexa78,cortexa78ae,cortexa78c,cortexa65,cortexa65ae,cortexx1,cortexx1c,neoversen1,ares,neoversee1,octeontx2,octeontx2t98,octeontx2t96,octeontx2t93,octeontx2f95,octeontx2f95n,octeontx2f95mm,a64fx,fujitsu_monaka,tsv110,thunderx3t110,neoversev1,zeus,neoverse512tvb,saphira,oryon1,cortexa57cortexa53,cortexa72cortexa53,cortexa73cortexa35,cortexa73cortexa53,cortexa75cortexa55,cortexa76cortexa55,cortexr82,cortexr82ae,applea12,applem1_0,applem1_1,applem1_2,applem1_3,applem2_0,applem2_1,applem2_2,applem2_3,applem3_0,applem3_1,applem3_2,applem4_0,applem4_1,applem4_2,cortexa510,cortexa520,cortexa520ae,cortexa710,cortexa715,cortexa720,cortexa720ae,cortexa725,cortexx2,cortexx3,cortexx4,cortexx925,neoversen2,cobalt100,neoversen3,neoversev2,grace,neoversev3,neoversev3ae,c1nano,c1pro,c1premium,c1ultra,demeter,olympus,gb10,generic,generic_armv8_a,generic_armv9_a"
(const (symbol_ref "((enum attr_tune) aarch64_tune)")))
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 0be898c..fb79b2e 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -4900,7 +4900,8 @@
(match_operand:SI 3 "<cmp_imm_predicate>")]
UNSPEC_PCMP_ITER))]
"TARGET_AVX512F && ix86_pre_reload_split ()
- && rtx_equal_p (operands[1], operands[2])"
+ && rtx_equal_p (operands[1], operands[2])
+ && (!MEM_P (operands[1]) || !MEM_VOLATILE_P (operands[1]))"
"#"
"&& 1"
[(set (match_dup 0) (match_dup 4))]
diff --git a/gcc/config/mingw/winnt.cc b/gcc/config/mingw/winnt.cc
index b51fd8e..fe2fb4c 100644
--- a/gcc/config/mingw/winnt.cc
+++ b/gcc/config/mingw/winnt.cc
@@ -446,8 +446,11 @@ mingw_pe_unique_section (tree decl, int reloc)
prefix = ".text$";
else if (decl_readonly_section (decl, reloc))
prefix = ".rdata$";
+ /* Note that we need two dollar signs for TLS sections
+ because they need to be ASCII-sorted before .tls$ZZZ
+ to be properly laid out by the GNU linker. */
else if (DECL_THREAD_LOCAL_P (decl))
- prefix = ".tls$";
+ prefix = ".tls$$";
else
prefix = ".data$";
len = strlen (name) + strlen (prefix);
@@ -522,9 +525,6 @@ mingw_pe_asm_named_section (const char *name, unsigned int flags,
*f++ = 'e';
#endif
- if (strcmp (name, ".tls$") == 0)
- *f++ = 'd';
-
if ((flags & (SECTION_CODE | SECTION_WRITE)) == 0)
/* readonly data */
{
@@ -533,6 +533,8 @@ mingw_pe_asm_named_section (const char *name, unsigned int flags,
}
else
{
+ if (startswith (name, ".tls$"))
+ *f++ = 'd';
if (flags & SECTION_CODE)
*f++ = 'x';
if (flags & SECTION_WRITE)
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 3ad8d16..b4c2b70 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,13 @@
+2025-12-08 Egas Ribeiro <egas.g.ribeiro@tecnico.ulisboa.pt>
+
+ * pt.cc (tsubst_expr): Add TARGET_EXPR case with explanatory
+ comment and gcc_unreachable.
+
+2025-12-08 Egas Ribeiro <egas.g.ribeiro@tecnico.ulisboa.pt>
+
+ PR c++/119343
+ * pt.cc (resolve_nondeduced_context): Remove mark_used call.
+
2025-12-06 Jakub Jelinek <jakub@redhat.com>
* decl2.cc (is_late_template_attribute): Call lookup_attribute_spec
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 74c862e..31081b3 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -19750,7 +19750,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
}
}
- bool honor_interface = (!DECL_TEMPLATE_INSTANTIATION (decl1)
+ bool honor_interface = (!DECL_TEMPLOID_INSTANTIATION (decl1)
/* Implicitly-defined methods (like the
destructor for a class in which no destructor
is explicitly declared) must not be defined
@@ -19781,7 +19781,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
else if (!finfo->interface_unknown && honor_interface)
{
if (DECL_DECLARED_INLINE_P (decl1)
- || DECL_TEMPLATE_INSTANTIATION (decl1))
+ || DECL_TEMPLOID_INSTANTIATION (decl1))
{
DECL_EXTERNAL (decl1)
= (finfo->interface_only
@@ -19823,7 +19823,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
DECL_EXTERNAL (decl1) = 0;
if ((DECL_DECLARED_INLINE_P (decl1)
- || DECL_TEMPLATE_INSTANTIATION (decl1))
+ || DECL_TEMPLOID_INSTANTIATION (decl1))
&& ! DECL_INTERFACE_KNOWN (decl1))
DECL_DEFER_OUTPUT (decl1) = 1;
else
diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc
index 8ec9740..01bf26b 100644
--- a/gcc/cp/decl2.cc
+++ b/gcc/cp/decl2.cc
@@ -2510,7 +2510,7 @@ vague_linkage_p (tree decl)
|| (TREE_CODE (decl) == FUNCTION_DECL
&& DECL_DECLARED_INLINE_P (decl))
|| (DECL_LANG_SPECIFIC (decl)
- && DECL_TEMPLATE_INSTANTIATION (decl))
+ && DECL_TEMPLOID_INSTANTIATION (decl))
|| (VAR_P (decl) && DECL_INLINE_VAR_P (decl)))
return true;
else if (DECL_FUNCTION_SCOPE_P (decl))
@@ -5850,8 +5850,7 @@ c_parse_final_cleanups (void)
&& !(header_module_p ()
&& (DECL_DEFAULTED_FN (decl) || decl_tls_wrapper_p (decl)))
/* Don't complain if the template was defined. */
- && !((DECL_TEMPLATE_INSTANTIATION (decl)
- || DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (decl))
+ && !(DECL_TEMPLOID_INSTANTIATION (decl)
&& DECL_INITIAL (DECL_TEMPLATE_RESULT
(template_for_substitution (decl))))
&& warning_at (DECL_SOURCE_LOCATION (decl), 0,
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 8498730..ce30b52 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -22562,6 +22562,11 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
in response to the saved STMT_IS_FULL_EXPR_P setting. */
gcc_unreachable ();
+ case TARGET_EXPR:
+ /* TARGET_EXPR represents temporary objects and should not appear in
+ templated trees. */
+ gcc_unreachable ();
+
case OFFSET_REF:
{
/* We should only get here for an OFFSET_REF like A::m; a .* in a
@@ -24816,8 +24821,6 @@ resolve_nondeduced_context (tree orig_expr, tsubst_flags_t complain)
}
if (good == 1)
{
- if (!mark_used (goodfn, complain) && !(complain & tf_error))
- return error_mark_node;
expr = goodfn;
if (baselink)
expr = build_baselink (BASELINK_BINFO (baselink),
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 331db16..b32ab2f 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -5537,7 +5537,9 @@ expand_or_defer_fn_1 (tree fn)
of the compilation. Until that point, we do not want the back
end to output them -- but we do want it to see the bodies of
these functions so that it can inline them as appropriate. */
- if (DECL_DECLARED_INLINE_P (fn) || DECL_IMPLICIT_INSTANTIATION (fn))
+ if (DECL_DECLARED_INLINE_P (fn)
+ || DECL_IMPLICIT_INSTANTIATION (fn)
+ || DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (fn))
{
if (DECL_INTERFACE_KNOWN (fn))
/* We've already made a decision as to how this function will
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index ac36fda..b89fbf8 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -22761,7 +22761,8 @@ performance of the code. Permissible values for this option are:
@samp{cortex-a520}, @samp{cortex-a520ae}, @samp{cortex-a710}, @samp{cortex-a715},
@samp{cortex-a720}, @samp{cortex-a720ae}, @samp{ampere1}, @samp{ampere1a},
@samp{ampere1b}, @samp{ampere1c}, @samp{cobalt-100}, @samp{apple-m1},
-@samp{apple-m2}, @samp{apple-m3}, @samp{apple-m4} and @samp{native}.
+@samp{apple-m2}, @samp{apple-m3}, @samp{apple-m4}, @samp{c1-nano},
+@samp{c1-pro}, @samp{c1-premium} @samp{c1-ultra} and @samp{native}.
The values @samp{cortex-a57.cortex-a53}, @samp{cortex-a72.cortex-a53},
@samp{cortex-a73.cortex-a35}, @samp{cortex-a73.cortex-a53},
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 724da5b..4fd2183 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,12 @@
+2025-12-08 Harald Anlauf <anlauf@gmx.de>
+ Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/123025
+ * decl.cc (match_char_length): Add a check for the
+ obsolete '*' style of character declarations in the
+ alternate branch of checking so we dont miss two
+ use cases:
+
2025-12-06 Paul Thomas <pault@gcc.gnu.org>
PR fortran/122693
diff --git a/gcc/fortran/decl.cc b/gcc/fortran/decl.cc
index dfedb96..0e55171 100644
--- a/gcc/fortran/decl.cc
+++ b/gcc/fortran/decl.cc
@@ -1217,6 +1217,10 @@ match_char_length (gfc_expr **expr, bool *deferred, bool obsolescent_check)
goto syntax;
}
+ if (obsolescent_check
+ && !gfc_notify_std (GFC_STD_F95_OBS, "Old-style character length at %C"))
+ return MATCH_ERROR;
+
return MATCH_YES;
syntax:
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 8f13d2c..f8a8fba 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,236 @@
+2025-12-08 Andrew Pinski <andrew.pinski@oss.qualcomm.com>
+
+ PR tree-optimization/46555
+ * gcc.dg/tree-ssa/pr46555.c: New test.
+
+2025-12-08 Harald Anlauf <anlauf@gmx.de>
+ Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/123025
+ * gfortran.dg/assumed_charlen_dummy.f90: These tests failed
+ with the change because of the default -pedantic option
+ used by the dg.exp mechanisms. Overide this default.
+ * gfortran.dg/automatic_char_len_1.f90: Ditto.
+ * gfortran.dg/entry_23.f: Ditto.
+ * gfortran.dg/finalize_59.f90: Dito.
+ * gfortran.dg/g77/f90-intrinsic-bit.f: Ditto.
+ * gfortran.dg/g77/f90-intrinsic-mathematical.f: Ditto.
+ * gfortran.dg/g77/f90-intrinsic-numeric.f: Ditto.
+ * gfortran.dg/g77/intrinsic-unix-bessel.f: Ditto.
+ * gfortran.dg/g77/intrinsic-unix-erf.f: Ditto.
+ * gfortran.dg/initialization_9.f90: Ditto.
+ * gfortran.dg/intrinsic_actual_4.f90: Ditto.
+ * gfortran.dg/namelist_assumed_char.f90: Ditto.
+ * gfortran.dg/pr15140.f90: Ditto.
+
+2025-12-08 Egas Ribeiro <egas.g.ribeiro@tecnico.ulisboa.pt>
+
+ PR c++/119343
+ * g++.dg/template/sfinae-deleted-pr119343.C: New test.
+
+2025-12-08 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc.dg/tls/data-sections-1.c: New test.
+
+2025-12-08 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/123040
+ * g++.dg/torture/pr123040.C: New testcase.
+
+2025-12-08 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/123038
+ * gcc.dg/vect/pr123038.c: New testcase.
+
+2025-12-08 Tamar Christina <tamar.christina@arm.com>
+
+ PR target/123026
+ * gcc.target/aarch64/pr123026.c: New test.
+
+2025-12-08 H.J. Lu <hjl.tools@gmail.com>
+
+ PR target/122343
+ * gcc.target/i386/avx2-vpcmpgtq-1.c: Compile with
+ -fno-fuse-ops-with-volatile-access.
+
+2025-12-07 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/reduce3.adb: New test.
+
+2025-12-07 H.J. Lu <hjl.tools@gmail.com>
+
+ PR target/122343
+ * gcc.target/i386/20040112-1.c: Add -fomit-frame-pointer and use
+ check-function-bodies to check for loop.
+ * gcc.target/i386/avx-ne-convert-1.c: Compile with
+ -fno-fuse-ops-with-volatile-access.
+ * gcc.target/i386/avx10_2-bf16-1.c: Likewise.
+ * gcc.target/i386/avx10_2-convert-1.c: Likewise.
+ * gcc.target/i386/avx10_2-satcvt-1.c: Likewise.
+ * gcc.target/i386/avx512bf16-vcvtneps2bf16-1.c: Likewise.
+ * gcc.target/i386/avx512bf16vl-vcvtneps2bf16-1a.c: Likewise.
+ * gcc.target/i386/avx512bf16vl-vcvtneps2bf16-1b.c: Likewise.
+ * gcc.target/i386/avx512bitalg-vpshufbitqmb.c: Likewise.
+ * gcc.target/i386/avx512bw-vpcmpb-1.c: Likewise.
+ * gcc.target/i386/avx512bw-vpcmpub-1.c: Likewise.
+ * gcc.target/i386/avx512bw-vpcmpuw-1.c: Likewise.
+ * gcc.target/i386/avx512bw-vpcmpw-1.c: Likewise.
+ * gcc.target/i386/avx512dq-vcvtps2qq-1.c: Likewise.
+ * gcc.target/i386/avx512dq-vcvtps2uqq-1.c: Likewise.
+ * gcc.target/i386/avx512dq-vcvtqq2pd-1.c: Likewise.
+ * gcc.target/i386/avx512dq-vcvtqq2ps-1.c: Likewise.
+ * gcc.target/i386/avx512dq-vcvttps2qq-1.c: Likewise.
+ * gcc.target/i386/avx512dq-vcvttps2uqq-1.c: Likewise.
+ * gcc.target/i386/avx512dq-vcvtuqq2pd-1.c: Likewise.
+ * gcc.target/i386/avx512dq-vcvtuqq2ps-1.c: Likewise.
+ * gcc.target/i386/avx512dq-vextractf32x8-1.c: Likewise.
+ * gcc.target/i386/avx512dq-vextractf64x2-1.c: Likewise.
+ * gcc.target/i386/avx512dq-vextracti64x2-1.c: Likewise.
+ * gcc.target/i386/avx512dq-vfpclasspd-1.c: Likewise.
+ * gcc.target/i386/avx512dq-vfpclassps-1.c: Likewise.
+ * gcc.target/i386/avx512dq-vfpclasssd-1.c: Likewise.
+ * gcc.target/i386/avx512dq-vfpclassss-1.c: Likewise.
+ * gcc.target/i386/avx512dq-vpmullq-1.c: Likewise.
+ * gcc.target/i386/avx512dq-vpmullq-3.c: Likewise.
+ * gcc.target/i386/avx512f-pr100267-1.c: Likewise.
+ * gcc.target/i386/avx512f-vcmppd-1.c: Likewise.
+ * gcc.target/i386/avx512f-vcmpps-1.c: Likewise.
+ * gcc.target/i386/avx512f-vcvtps2pd-1.c: Likewise.
+ * gcc.target/i386/avx512f-vcvtsd2si-1.c: Likewise.
+ * gcc.target/i386/avx512f-vcvtsd2si64-1.c: Likewise.
+ * gcc.target/i386/avx512f-vcvtsd2usi-1.c: Likewise.
+ * gcc.target/i386/avx512f-vcvtsd2usi64-1.c: Likewise.
+ * gcc.target/i386/avx512f-vcvtsi2ss-1.c: Likewise.
+ * gcc.target/i386/avx512f-vcvtss2si-1.c: Likewise.
+ * gcc.target/i386/avx512f-vcvtss2si64-1.c: Likewise.
+ * gcc.target/i386/avx512f-vcvtss2usi-1.c: Likewise.
+ * gcc.target/i386/avx512f-vcvtss2usi64-1.c: Likewise.
+ * gcc.target/i386/avx512f-vcvttsd2si-1.c: Likewise.
+ * gcc.target/i386/avx512f-vcvttsd2si64-1.c: Likewise.
+ * gcc.target/i386/avx512f-vcvttsd2usi-1.c: Likewise.
+ * gcc.target/i386/avx512f-vcvttsd2usi64-1.c: Likewise.
+ * gcc.target/i386/avx512f-vcvttss2si-1.c: Likewise.
+ * gcc.target/i386/avx512f-vcvttss2si64-1.c: Likewise.
+ * gcc.target/i386/avx512f-vcvttss2usi-1.c: Likewise.
+ * gcc.target/i386/avx512f-vcvttss2usi64-1.c: Likewise.
+ * gcc.target/i386/avx512f-vextractf32x4-1.c: Likewise.
+ * gcc.target/i386/avx512f-vextractf64x4-1.c: Likewise.
+ * gcc.target/i386/avx512f-vextracti64x4-1.c: Likewise.
+ * gcc.target/i386/avx512f-vmovapd-1.c: Likewise.
+ * gcc.target/i386/avx512f-vmovaps-1.c: Likewise.
+ * gcc.target/i386/avx512f-vmovdqa64-1.c: Likewise.
+ * gcc.target/i386/avx512f-vpandnq-1.c: Likewise.
+ * gcc.target/i386/avx512f-vpbroadcastd-1.c: Likewise.
+ * gcc.target/i386/avx512f-vpbroadcastq-1.c: Likewise.
+ * gcc.target/i386/avx512f-vpcmpd-1.c: Likewise.
+ * gcc.target/i386/avx512f-vpcmpeqq-1.c: Likewise.
+ * gcc.target/i386/avx512f-vpcmpequq-1.c: Likewise.
+ * gcc.target/i386/avx512f-vpcmpged-1.c: Likewise.
+ * gcc.target/i386/avx512f-vpcmpgeq-1.c: Likewise.
+ * gcc.target/i386/avx512f-vpcmpgeud-1.c: Likewise.
+ * gcc.target/i386/avx512f-vpcmpgeuq-1.c: Likewise.
+ * gcc.target/i386/avx512f-vpcmpled-1.c: Likewise.
+ * gcc.target/i386/avx512f-vpcmpleq-1.c: Likewise.
+ * gcc.target/i386/avx512f-vpcmpleud-1.c: Likewise.
+ * gcc.target/i386/avx512f-vpcmpleuq-1.c: Likewise.
+ * gcc.target/i386/avx512f-vpcmpltd-1.c: Likewise.
+ * gcc.target/i386/avx512f-vpcmpltq-1.c: Likewise.
+ * gcc.target/i386/avx512f-vpcmpltud-1.c: Likewise.
+ * gcc.target/i386/avx512f-vpcmpltuq-1.c: Likewise.
+ * gcc.target/i386/avx512f-vpcmpneqd-1.c: Likewise.
+ * gcc.target/i386/avx512f-vpcmpneqq-1.c: Likewise.
+ * gcc.target/i386/avx512f-vpcmpnequd-1.c: Likewise.
+ * gcc.target/i386/avx512f-vpcmpnequq-1.c: Likewise.
+ * gcc.target/i386/avx512f-vpcmpq-1.c: Likewise.
+ * gcc.target/i386/avx512f-vpcmpud-1.c: Likewise.
+ * gcc.target/i386/avx512f-vpcmpuq-1.c: Likewise.
+ * gcc.target/i386/avx512f-vrndscalepd-1.c: Likewise.
+ * gcc.target/i386/avx512f-vrndscaleps-1.c: Likewise.
+ * gcc.target/i386/avx512fp16-complex-fma.c: Likewise.
+ * gcc.target/i386/avx512fp16-vaddph-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16-vcvtpd2ph-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16-vcvtph2dq-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16-vcvtph2pd-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16-vcvtph2psx-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16-vcvtph2qq-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16-vcvtph2udq-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16-vcvtph2uqq-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16-vcvtph2uw-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16-vcvtph2w-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16-vcvtps2ph-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16-vcvtqq2ph-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16-vcvttph2dq-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16-vcvttph2qq-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16-vcvttph2udq-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16-vcvttph2uqq-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16-vcvttph2uw-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16-vcvttph2w-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16-vcvtuqq2ph-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16-vfcmaddcph-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16-vfcmulcph-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16-vfmaddcph-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16-vfmulcph-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16-vfpclassph-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16-vfpclasssh-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16-vmulph-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16-vrcpph-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16-vrsqrtph-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16-vsqrtph-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16vl-vaddph-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16vl-vcvtpd2ph-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16vl-vcvtph2dq-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16vl-vcvtph2psx-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16vl-vcvtph2qq-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16vl-vcvtph2udq-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16vl-vcvtph2uqq-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16vl-vcvtph2uw-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16vl-vcvtph2w-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16vl-vcvtps2ph-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16vl-vcvtqq2ph-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16vl-vcvttph2dq-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16vl-vcvttph2udq-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16vl-vcvttph2uw-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16vl-vcvttph2w-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16vl-vcvtuqq2ph-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16vl-vfcmaddcph-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16vl-vfcmulcph-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16vl-vfmaddcph-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16vl-vfmulcph-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16vl-vfpclassph-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16vl-vmulph-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16vl-vrcpph-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16vl-vrsqrtph-1a.c: Likewise.
+ * gcc.target/i386/avx512fp16vl-vsqrtph-1a.c: Likewise.
+ * gcc.target/i386/avx512vl-pr100267-1.c: Likewise.
+ * gcc.target/i386/avx512vl-vcmppd-1.c: Likewise.
+ * gcc.target/i386/avx512vl-vcmpps-1.c: Likewise.
+ * gcc.target/i386/avx512vl-vcvtpd2ps-1.c: Likewise.
+ * gcc.target/i386/avx512vl-vcvtpd2udq-1.c: Likewise.
+ * gcc.target/i386/avx512vl-vcvttpd2udq-1.c: Likewise.
+ * gcc.target/i386/avx512vl-vcvttps2udq-1.c: Likewise.
+ * gcc.target/i386/avx512vl-vextractf32x4-1.c: Likewise.
+ * gcc.target/i386/avx512vl-vmovapd-1.c: Likewise.
+ * gcc.target/i386/avx512vl-vmovaps-1.c: Likewise.
+ * gcc.target/i386/avx512vl-vmovdqa64-1.c: Likewise.
+ * gcc.target/i386/avx512vl-vpcmpd-1.c: Likewise.
+ * gcc.target/i386/avx512vl-vpcmpeqq-1.c: Likewise.
+ * gcc.target/i386/avx512vl-vpcmpequq-1.c: Likewise.
+ * gcc.target/i386/avx512vl-vpcmpq-1.c: Likewise.
+ * gcc.target/i386/avx512vl-vpcmpud-1.c: Likewise.
+ * gcc.target/i386/avx512vl-vpcmpuq-1.c: Likewise.
+ * gcc.target/i386/pr122343-1a.c: New test.
+ * gcc.target/i386/pr122343-1b.c: Likewise.
+ * gcc.target/i386/pr122343-2a.c: Likewise.
+ * gcc.target/i386/pr122343-2b.c: Likewise.
+ * gcc.target/i386/pr122343-3.c: Likewise.
+ * gcc.target/i386/pr122343-4a.c: Likewise.
+ * gcc.target/i386/pr122343-4b.c: Likewise.
+ * gcc.target/i386/pr122343-5a.c: Likewise.
+ * gcc.target/i386/pr122343-5b.c: Likewise.
+ * gcc.target/i386/pr122343-6a.c: Likewise.
+ * gcc.target/i386/pr122343-6b.c: Likewise.
+ * gcc.target/i386/pr122343-7.c: Likewise.
+
2025-12-06 Alexandre Oliva <oliva@adacore.com>
PR rtl-optimization/122947
diff --git a/gcc/testsuite/g++.dg/modules/tpl-friend-22.C b/gcc/testsuite/g++.dg/modules/tpl-friend-22.C
new file mode 100644
index 0000000..a77d1cb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/tpl-friend-22.C
@@ -0,0 +1,24 @@
+// PR c++/122819
+// { dg-do compile { target *-*-*gnu* } }
+// { dg-additional-options "-fmodules" }
+
+export module M;
+
+template <typename T> struct S;
+void foo(S<float>);
+
+template <typename T> struct S {
+ friend void foo(S) {}
+};
+
+void foo(S<double>);
+
+void use() {
+ foo(S<int>{});
+ foo(S<float>{});
+ foo(S<double>{});
+}
+
+// { dg-final { scan-assembler "_ZW1M3fooS_1SIiE,comdat" } }
+// { dg-final { scan-assembler "_ZW1M3fooS_1SIfE,comdat" } }
+// { dg-final { scan-assembler "_ZW1M3fooS_1SIdE,comdat" } }
diff --git a/gcc/testsuite/g++.dg/template/sfinae-deleted-pr119343.C b/gcc/testsuite/g++.dg/template/sfinae-deleted-pr119343.C
new file mode 100644
index 0000000..065ad60
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/sfinae-deleted-pr119343.C
@@ -0,0 +1,31 @@
+// { dg-do compile { target c++11 } }
+// PR c++/119343 - No SFINAE for deleted explicit specializations
+
+struct true_type { static constexpr bool value = true; };
+struct false_type { static constexpr bool value = false; };
+
+struct X {
+ static void f()=delete;
+ template<int> static void g();
+};
+template<> void X::g<0>()=delete;
+struct Y {
+ static void f();
+ template<int> static void g();
+};
+
+template<class T,class=void>
+struct has_f : false_type {};
+template<class T>
+struct has_f<T,decltype(void(T::f))> : true_type {};
+
+static_assert(!has_f<X>::value, "");
+static_assert(has_f<Y>::value, "");
+
+template<class T,class=void>
+struct has_g0 : false_type {};
+template<class T>
+struct has_g0<T,decltype(void(T::template g<0>))> : true_type {};
+
+static_assert(!has_g0<X>::value, "");
+static_assert(has_g0<Y>::value, "");
diff --git a/gcc/testsuite/g++.dg/torture/pr123040.C b/gcc/testsuite/g++.dg/torture/pr123040.C
new file mode 100644
index 0000000..3ba2d90
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr123040.C
@@ -0,0 +1,61 @@
+// { dg-do compile }
+
+template <int kBytes, typename From, typename To>
+void CopyBytes(From from, To to) {
+ __builtin_memcpy(to, from, kBytes);
+}
+template <typename From, typename To> void CopySameSize(From *from, To to) {
+ CopyBytes<sizeof(From)>(from, to);
+}
+template <typename> using MakeUnsigned = char;
+template <typename Lane, int N> struct Simd {
+ using T = Lane;
+ static constexpr int kPrivateLanes = N;
+ template <typename NewT> using Rebind = Simd<NewT, 0>;
+};
+template <class D> using TFromD = D::T;
+template <class T, class D> using Rebind = D::template Rebind<T>;
+template <class D> using RebindToUnsigned = Rebind<MakeUnsigned<D>, D>;
+template <typename T, int> struct Vec128 {
+ using PrivateT = T;
+ static constexpr int kPrivateN = 6;
+ T raw[16];
+};
+template <class V> using DFromV = Simd<typename V::PrivateT, V::kPrivateN>;
+template <class D> Vec128<TFromD<D>, D::kPrivateLanes> Zero(D);
+template <class D> using VFromD = decltype(Zero(D()));
+template <class D, class VFrom> VFromD<D> BitCast(D, VFrom v) {
+ VFromD<D> to;
+ CopySameSize(&v, to.raw);
+ return to;
+}
+template <int N> Vec128<signed char, N> And(Vec128<signed char, N> b) {
+ Vec128<signed char, N> a;
+ DFromV<decltype(a)> d;
+ RebindToUnsigned<decltype(d)> du;
+ auto au(a);
+ auto bu = BitCast(du, b);
+ for (int i = 0; i < N; ++i)
+ au.raw[i] &= bu.raw[i];
+ return au;
+}
+void Or(Vec128<signed char, 16>);
+template <int N> void IfVecThenElse(Vec128<signed char, N> yes) {
+ Vec128 __trans_tmp_2 = And(yes);
+ Or(__trans_tmp_2);
+}
+template <int N> void IfThenElseZero(Vec128<signed char, N> yes) {
+ IfVecThenElse(yes);
+}
+Vec128<signed char, 16> Abs_a;
+char MaskedAbs___trans_tmp_5;
+void MaskedAbs() {
+ Vec128<signed char, 16> __trans_tmp_4;
+ for (int i = 0; i < 16; ++i) {
+ MaskedAbs___trans_tmp_5 = Abs_a.raw[i] ? -Abs_a.raw[i] : 0;
+ Abs_a.raw[i] = MaskedAbs___trans_tmp_5;
+ }
+ __trans_tmp_4 = Abs_a;
+ Vec128 __trans_tmp_3 = __trans_tmp_4;
+ IfThenElseZero(__trans_tmp_3);
+}
diff --git a/gcc/testsuite/gcc.dg/tls/data-sections-1.c b/gcc/testsuite/gcc.dg/tls/data-sections-1.c
new file mode 100644
index 0000000..c829256
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/data-sections-1.c
@@ -0,0 +1,14 @@
+/* { dg-do run } */
+/* { dg-require-effective-target tls_runtime } */
+/* { dg-options "-fdata-sections" } */
+/* { dg-add-options tls } */
+
+__thread int i = 1;
+
+int main (void)
+{
+ if (i != 1)
+ __builtin_abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr46555.c b/gcc/testsuite/gcc.dg/tree-ssa/pr46555.c
new file mode 100644
index 0000000..d4de7c2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr46555.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized-details -fdump-rtl-pro_and_epilogue" } */
+/* PR tree-optimization/46555 */
+/* Here should not remove the forwarder block (or rather recreate it and not
+ remove it again). This improves expansion to RTL as there is one less copy
+ (or constant formation) in some cases. In this case we also get the ability
+ to shrink wrap the function. */
+
+int h(void);
+int f(int a, int b, int c)
+{
+ if (a)
+ return 2;
+ h();
+ if (b)
+ return 2;
+ h();
+ if (c)
+ return 2;
+ h();
+ return 4;
+}
+
+/* { dg-final { scan-tree-dump-times "New forwarder block for edge" 1 "optimized" } } */
+/* Make sure we only have a PHI with 2 arguments here, 2 and 4. */
+/* { dg-final { scan-tree-dump "PHI <2..., 4...>|PHI <4..., 2...>" "optimized" } } */
+/* Make sure we can shrink wrap the function now too. */
+/* { dg-final { scan-rtl-dump "Performing shrink-wrapping" "pro_and_epilogue" { target { { { i?86-*-* x86_64-*-* } && { ! ia32 } } || { powerpc*-*-* aarch64*-*-* riscv*-*-* arm*-*-* } } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr123038.c b/gcc/testsuite/gcc.dg/vect/pr123038.c
new file mode 100644
index 0000000..bca831f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr123038.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+
+unsigned char f(int b)
+{
+ for (int a = 0; a < 10; a += 1)
+ b = __builtin_ffs(b);
+ return b;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/pr123026.c b/gcc/testsuite/gcc.target/aarch64/pr123026.c
new file mode 100644
index 0000000..4dcce8a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr123026.c
@@ -0,0 +1,21 @@
+/* { dg-do run } */
+/* { dg-additional-options "-O3 -march=armv8-a -std=c99" } */
+
+#include <stdbool.h>
+
+int g;
+
+__attribute__ ((noipa)) void
+foo(bool a) {
+ for (int i = 0; i < 4; i++)
+ if (!i || a)
+ g += 1;
+}
+
+int main()
+{
+ foo(0);
+ if (g != 1)
+ __builtin_abort();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx2-vpcmpgtq-1.c b/gcc/testsuite/gcc.target/i386/avx2-vpcmpgtq-1.c
index 7a98380..5e6f431 100644
--- a/gcc/testsuite/gcc.target/i386/avx2-vpcmpgtq-1.c
+++ b/gcc/testsuite/gcc.target/i386/avx2-vpcmpgtq-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-mavx2 -O2" } */
+/* { dg-options "-mavx2 -O2 -fno-fuse-ops-with-volatile-access" } */
/* { dg-final { scan-assembler "vpcmpgtq\[ \\t\]+\[^\n\]*%ymm\[0-9\]" } } */
#include <immintrin.h>
diff --git a/gcc/testsuite/gfortran.dg/assumed_charlen_dummy.f90 b/gcc/testsuite/gfortran.dg/assumed_charlen_dummy.f90
index 04f0b9f..2e0e77c 100644
--- a/gcc/testsuite/gfortran.dg/assumed_charlen_dummy.f90
+++ b/gcc/testsuite/gfortran.dg/assumed_charlen_dummy.f90
@@ -1,4 +1,5 @@
! { dg-do compile }
+! { dg-options " " }
! Test the fix for PR fortran/39893.
! Original testcase provided by Deji Akingunola.
! Reduced testcase provided by Dominique d'Humieres.
diff --git a/gcc/testsuite/gfortran.dg/automatic_char_len_1.f90 b/gcc/testsuite/gfortran.dg/automatic_char_len_1.f90
index 3ccfcb7..7f102b7 100644
--- a/gcc/testsuite/gfortran.dg/automatic_char_len_1.f90
+++ b/gcc/testsuite/gfortran.dg/automatic_char_len_1.f90
@@ -1,4 +1,5 @@
! { dg-do compile }
+! { dg-options " " }
! PR18082 - Compiler would get stuck in loop, whilst treating
! the assignments.
! Test is one of PR cases.
diff --git a/gcc/testsuite/gfortran.dg/entry_23.f b/gcc/testsuite/gfortran.dg/entry_23.f
index ebc5f66..d10ea92 100644
--- a/gcc/testsuite/gfortran.dg/entry_23.f
+++ b/gcc/testsuite/gfortran.dg/entry_23.f
@@ -1,4 +1,5 @@
! { dg-do run }
+! { dg-options " " }
! PR 97799 - this used to segfault intermittently.
! Test case by George Hockney.
PROGRAM MAIN
diff --git a/gcc/testsuite/gfortran.dg/finalize_59.f90 b/gcc/testsuite/gfortran.dg/finalize_59.f90
index 8be5f71..e9e68d4 100644
--- a/gcc/testsuite/gfortran.dg/finalize_59.f90
+++ b/gcc/testsuite/gfortran.dg/finalize_59.f90
@@ -187,7 +187,7 @@ Program Cds_Principal
Type(Uef_Vector) :: Cds_Mod_Les_materiaux
Type (Cds_Materiau_Acier_EC) :: acier_ec
Class (Cds_Materiau), pointer :: pt_materiau
- Character *(8) :: nom_materiau
+ Character(len=8) :: nom_materiau
!-------------------------------------------------------------------------------------------------
CaLL Cds_Mod_Les_materiaux%Add (acier_ec)
nom_materiau = "12345678"
@@ -199,7 +199,7 @@ Function Get_Pt_Materiau_nom (vecteur, nom_materiau)
! Fonction :
!--------------------
! Parametres en entree
- Character *(8), Intent (in) :: nom_materiau
+ Character(len=8), Intent (in) :: nom_materiau
Type (Uef_Vector) , Intent (inout) :: vecteur
! Parametres en sortie
diff --git a/gcc/testsuite/gfortran.dg/g77/f90-intrinsic-bit.f b/gcc/testsuite/gfortran.dg/g77/f90-intrinsic-bit.f
index 0ce45de..2f03db1 100644
--- a/gcc/testsuite/gfortran.dg/g77/f90-intrinsic-bit.f
+++ b/gcc/testsuite/gfortran.dg/g77/f90-intrinsic-bit.f
@@ -1,4 +1,5 @@
c { dg-do run }
+c { dg-options " " }
c f90-intrinsic-bit.f
c
c Test Fortran 90
diff --git a/gcc/testsuite/gfortran.dg/g77/f90-intrinsic-mathematical.f b/gcc/testsuite/gfortran.dg/g77/f90-intrinsic-mathematical.f
index d151fd0..f07336e 100644
--- a/gcc/testsuite/gfortran.dg/g77/f90-intrinsic-mathematical.f
+++ b/gcc/testsuite/gfortran.dg/g77/f90-intrinsic-mathematical.f
@@ -1,4 +1,5 @@
c { dg-do run }
+c { dg-options " " }
c f90-intrinsic-mathematical.f
c
c Test Fortran 90 intrinsic mathematical functions - Section 13.10.3 and
diff --git a/gcc/testsuite/gfortran.dg/g77/f90-intrinsic-numeric.f b/gcc/testsuite/gfortran.dg/g77/f90-intrinsic-numeric.f
index c8d7c56..c01efe6 100644
--- a/gcc/testsuite/gfortran.dg/g77/f90-intrinsic-numeric.f
+++ b/gcc/testsuite/gfortran.dg/g77/f90-intrinsic-numeric.f
@@ -1,4 +1,5 @@
c { dg-do run }
+c { dg-options " " }
c f90-intrinsic-numeric.f
c
c Test Fortran 90 intrinsic numeric functions - Section 13.10.2 and 13.13
diff --git a/gcc/testsuite/gfortran.dg/g77/intrinsic-unix-bessel.f b/gcc/testsuite/gfortran.dg/g77/intrinsic-unix-bessel.f
index b388806..406a8e4 100644
--- a/gcc/testsuite/gfortran.dg/g77/intrinsic-unix-bessel.f
+++ b/gcc/testsuite/gfortran.dg/g77/intrinsic-unix-bessel.f
@@ -1,4 +1,5 @@
c { dg-do run }
+c { dg-options " " }
c intrinsic-unix-bessel.f
c
c Test Bessel function intrinsics.
diff --git a/gcc/testsuite/gfortran.dg/g77/intrinsic-unix-erf.f b/gcc/testsuite/gfortran.dg/g77/intrinsic-unix-erf.f
index 250519a..6ed9590 100644
--- a/gcc/testsuite/gfortran.dg/g77/intrinsic-unix-erf.f
+++ b/gcc/testsuite/gfortran.dg/g77/intrinsic-unix-erf.f
@@ -1,4 +1,5 @@
c { dg-do run }
+c { dg-options " " }
c intrinsic-unix-erf.f
c
c Test Bessel function intrinsics.
diff --git a/gcc/testsuite/gfortran.dg/initialization_9.f90 b/gcc/testsuite/gfortran.dg/initialization_9.f90
index d904047..fe7ca63 100644
--- a/gcc/testsuite/gfortran.dg/initialization_9.f90
+++ b/gcc/testsuite/gfortran.dg/initialization_9.f90
@@ -1,4 +1,5 @@
! { dg-do compile }
+! { dg-options " " }
!
! PR fortran/31639
! Contributed by Martin Michlmayr <tbm AT cyrius DOT com>
diff --git a/gcc/testsuite/gfortran.dg/intrinsic_actual_4.f90 b/gcc/testsuite/gfortran.dg/intrinsic_actual_4.f90
index 4521c96..3358b4a 100644
--- a/gcc/testsuite/gfortran.dg/intrinsic_actual_4.f90
+++ b/gcc/testsuite/gfortran.dg/intrinsic_actual_4.f90
@@ -1,4 +1,5 @@
! { dg-do run }
+! { dg-options " " }
! Tests the fix for PR27900, in which an ICE would be caused because
! the actual argument LEN had no type.
!
diff --git a/gcc/testsuite/gfortran.dg/namelist_assumed_char.f90 b/gcc/testsuite/gfortran.dg/namelist_assumed_char.f90
index b7d063c..25edf64 100644
--- a/gcc/testsuite/gfortran.dg/namelist_assumed_char.f90
+++ b/gcc/testsuite/gfortran.dg/namelist_assumed_char.f90
@@ -8,7 +8,7 @@
! Add -std=f95, add bar()
!
subroutine foo(c)
- character*(*) c
+ character*(*) c ! { dg-warning "Old-style character length" }
namelist /abc/ c ! { dg-error "nonconstant character length in namelist" }
end subroutine
diff --git a/gcc/testsuite/gfortran.dg/pr15140.f90 b/gcc/testsuite/gfortran.dg/pr15140.f90
index 80c08dd..7f9af4f 100644
--- a/gcc/testsuite/gfortran.dg/pr15140.f90
+++ b/gcc/testsuite/gfortran.dg/pr15140.f90
@@ -1,4 +1,5 @@
! { dg-do run }
+! { dg-options "-std=legacy" }
! PR 15140: we used to fail an assertion, because we don't use the
! argument of the subroutine directly, but instead use a copy of it.
function M(NAMES)
diff --git a/gcc/testsuite/gnat.dg/reduce3.adb b/gcc/testsuite/gnat.dg/reduce3.adb
new file mode 100644
index 0000000..55934d0
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/reduce3.adb
@@ -0,0 +1,17 @@
+-- { dg-do run }
+-- { dg-options "-gnat2022" }
+
+with Ada.Containers.Vectors;
+
+procedure Reduce3 is
+
+ package Qs is new
+ Ada.Containers.Vectors (Index_Type => Positive, Element_Type => Positive);
+
+ V : Qs.Vector;
+ Sum : Positive;
+
+begin
+ V.Append (1);
+ Sum := V'Reduce ("+", 0);
+end;
diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc
index 1d20e6a..f0a5e05 100644
--- a/gcc/tree-cfg.cc
+++ b/gcc/tree-cfg.cc
@@ -10173,6 +10173,224 @@ make_pass_fixup_cfg (gcc::context *ctxt)
return new pass_fixup_cfg (ctxt);
}
+
+/* Sort PHI argument values for make_forwarders_with_degenerate_phis. */
+
+static int
+sort_phi_args (const void *a_, const void *b_)
+{
+ auto *a = (const std::pair<edge, hashval_t> *) a_;
+ auto *b = (const std::pair<edge, hashval_t> *) b_;
+ hashval_t ha = a->second;
+ hashval_t hb = b->second;
+ if (ha < hb)
+ return -1;
+ else if (ha > hb)
+ return 1;
+ else if (a->first->dest_idx < b->first->dest_idx)
+ return -1;
+ else if (a->first->dest_idx > b->first->dest_idx)
+ return 1;
+ else
+ return 0;
+}
+
+/* Look for a non-virtual PHIs and make a forwarder block when all PHIs
+ have the same argument on a set of edges. This is to not consider
+ control dependences of individual edges for same values but only for
+ the common set. Returns true if changed the CFG. */
+
+bool
+make_forwarders_with_degenerate_phis (function *fn)
+{
+ bool didsomething = false;
+
+ basic_block bb;
+ FOR_EACH_BB_FN (bb, fn)
+ {
+ /* Only PHIs with three or more arguments have opportunities. */
+ if (EDGE_COUNT (bb->preds) < 3)
+ continue;
+ /* Do not touch loop headers or blocks with abnormal predecessors.
+ ??? This is to avoid creating valid loops here, see PR103458.
+ We might want to improve things to either explicitely add those
+ loops or at least consider blocks with no backedges. */
+ if (bb->loop_father->header == bb
+ || bb_has_abnormal_pred (bb))
+ continue;
+
+ /* Take one PHI node as template to look for identical
+ arguments. Build a vector of candidates forming sets
+ of argument edges with equal values. Note optimality
+ depends on the particular choice of the template PHI
+ since equal arguments are unordered leaving other PHIs
+ with more than one set of equal arguments within this
+ argument range unsorted. We'd have to break ties by
+ looking at other PHI nodes. */
+ gphi_iterator gsi = gsi_start_nonvirtual_phis (bb);
+ if (gsi_end_p (gsi))
+ continue;
+ gphi *phi = gsi.phi ();
+ auto_vec<std::pair<edge, hashval_t>, 8> args;
+ bool need_resort = false;
+ for (unsigned i = 0; i < gimple_phi_num_args (phi); ++i)
+ {
+ edge e = gimple_phi_arg_edge (phi, i);
+ /* Skip abnormal edges since we cannot redirect them. */
+ if (e->flags & EDGE_ABNORMAL)
+ continue;
+ /* Skip loop exit edges when we are in loop-closed SSA form
+ since the forwarder we'd create does not have a PHI node. */
+ if (loops_state_satisfies_p (LOOP_CLOSED_SSA)
+ && loop_exit_edge_p (e->src->loop_father, e))
+ continue;
+
+ tree arg = gimple_phi_arg_def (phi, i);
+ if (!CONSTANT_CLASS_P (arg) && TREE_CODE (arg) != SSA_NAME)
+ need_resort = true;
+ args.safe_push (std::make_pair (e, iterative_hash_expr (arg, 0)));
+ }
+ if (args.length () < 2)
+ continue;
+ args.qsort (sort_phi_args);
+ /* The above sorting can be different between -g and -g0, as e.g. decls
+ can have different uids (-g could have bigger gaps in between them).
+ So, only use that to determine which args are equal, then change
+ second from hash value to smallest dest_idx of the edges which have
+ equal argument and sort again. If all the phi arguments are
+ constants or SSA_NAME, there is no need for the second sort, the hash
+ values are stable in that case. */
+ hashval_t hash = args[0].second;
+ args[0].second = args[0].first->dest_idx;
+ bool any_equal = false;
+ for (unsigned i = 1; i < args.length (); ++i)
+ if (hash == args[i].second
+ && operand_equal_p (PHI_ARG_DEF_FROM_EDGE (phi, args[i - 1].first),
+ PHI_ARG_DEF_FROM_EDGE (phi, args[i].first)))
+ {
+ args[i].second = args[i - 1].second;
+ any_equal = true;
+ }
+ else
+ {
+ hash = args[i].second;
+ args[i].second = args[i].first->dest_idx;
+ }
+ if (!any_equal)
+ continue;
+ if (need_resort)
+ args.qsort (sort_phi_args);
+
+ /* From the candidates vector now verify true candidates for
+ forwarders and create them. */
+ gphi *vphi = get_virtual_phi (bb);
+ unsigned start = 0;
+ while (start < args.length () - 1)
+ {
+ unsigned i;
+ for (i = start + 1; i < args.length (); ++i)
+ if (args[start].second != args[i].second)
+ break;
+ /* args[start]..args[i-1] are equal. */
+ if (start != i - 1)
+ {
+ /* Check all PHI nodes for argument equality
+ except for vops. */
+ bool equal = true;
+ gphi_iterator gsi2 = gsi;
+ gsi_next (&gsi2);
+ for (; !gsi_end_p (gsi2); gsi_next (&gsi2))
+ {
+ gphi *phi2 = gsi2.phi ();
+ if (virtual_operand_p (gimple_phi_result (phi2)))
+ continue;
+ tree start_arg
+ = PHI_ARG_DEF_FROM_EDGE (phi2, args[start].first);
+ for (unsigned j = start + 1; j < i; ++j)
+ {
+ if (!operand_equal_p (start_arg,
+ PHI_ARG_DEF_FROM_EDGE
+ (phi2, args[j].first)))
+ {
+ /* Another PHI might have a shorter set of
+ equivalent args. Go for that. */
+ i = j;
+ if (j == start + 1)
+ equal = false;
+ break;
+ }
+ }
+ if (!equal)
+ break;
+ }
+ if (equal)
+ {
+ /* If we are asked to forward all edges the block
+ has all degenerate PHIs. Do nothing in that case. */
+ if (start == 0
+ && i == args.length ()
+ && args.length () == gimple_phi_num_args (phi))
+ break;
+ /* Instead of using make_forwarder_block we are
+ rolling our own variant knowing that the forwarder
+ does not need PHI nodes apart from eventually
+ a virtual one. */
+ auto_vec<tree, 8> vphi_args;
+ if (vphi)
+ {
+ vphi_args.reserve_exact (i - start);
+ for (unsigned j = start; j < i; ++j)
+ vphi_args.quick_push
+ (PHI_ARG_DEF_FROM_EDGE (vphi, args[j].first));
+ }
+ free_dominance_info (fn, CDI_DOMINATORS);
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "New forwarder block for edge ");
+ fprintf (dump_file, "%d -> %d.\n",
+ args[start].first->src->index,
+ args[start].first->dest->index);
+ }
+ basic_block forwarder = split_edge (args[start].first);
+ profile_count count = profile_count::zero ();
+ bool irr = false;
+ for (unsigned j = start + 1; j < i; ++j)
+ {
+ edge e = args[j].first;
+ if (e->flags & EDGE_IRREDUCIBLE_LOOP)
+ irr = true;
+ redirect_edge_and_branch_force (e, forwarder);
+ redirect_edge_var_map_clear (e);
+ count += e->count ();
+ }
+ forwarder->count = count;
+ if (irr)
+ {
+ forwarder->flags |= BB_IRREDUCIBLE_LOOP;
+ single_succ_edge (forwarder)->flags
+ |= EDGE_IRREDUCIBLE_LOOP;
+ }
+
+ if (vphi)
+ {
+ tree def = copy_ssa_name (vphi_args[0]);
+ gphi *vphi_copy = create_phi_node (def, forwarder);
+ for (unsigned j = start; j < i; ++j)
+ add_phi_arg (vphi_copy, vphi_args[j - start],
+ args[j].first, UNKNOWN_LOCATION);
+ SET_PHI_ARG_DEF
+ (vphi, single_succ_edge (forwarder)->dest_idx, def);
+ }
+ didsomething = true;
+ }
+ }
+ /* Continue searching for more opportunities. */
+ start = i;
+ }
+ }
+ return didsomething;
+}
+
/* Garbage collection support for edge_def. */
extern void gt_ggc_mx (tree&);
diff --git a/gcc/tree-cfg.h b/gcc/tree-cfg.h
index 520bb3a..2e01762 100644
--- a/gcc/tree-cfg.h
+++ b/gcc/tree-cfg.h
@@ -114,6 +114,7 @@ extern edge gimple_switch_edge (function *, gswitch *, unsigned);
extern edge gimple_switch_default_edge (function *, gswitch *);
extern bool cond_only_block_p (basic_block);
extern void copy_phi_arg_into_existing_phi (edge, edge, bool = false);
+extern bool make_forwarders_with_degenerate_phis (function *);
/* Return true if the LHS of a call should be removed. */
diff --git a/gcc/tree-cfgcleanup.cc b/gcc/tree-cfgcleanup.cc
index 872ded3..093fde9 100644
--- a/gcc/tree-cfgcleanup.cc
+++ b/gcc/tree-cfgcleanup.cc
@@ -1415,8 +1415,13 @@ execute_cleanup_cfg_post_optimizing (void)
}
maybe_remove_unreachable_handlers ();
cleanup_dead_labels ();
- if (group_case_labels ())
- todo |= TODO_cleanup_cfg;
+ if (group_case_labels () && cleanup_tree_cfg ())
+ todo |= TODO_update_ssa;
+
+ /* When optimizing undo the merging of forwarder blocks
+ that phis for better out of ssa expansion. */
+ if (optimize)
+ make_forwarders_with_degenerate_phis (cfun);
basic_block bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
gimple_stmt_iterator gsi = gsi_start_nondebug_after_labels_bb (bb);
diff --git a/gcc/tree-ssa-dce.cc b/gcc/tree-ssa-dce.cc
index 317a0d6..9a9f6f9 100644
--- a/gcc/tree-ssa-dce.cc
+++ b/gcc/tree-ssa-dce.cc
@@ -1940,214 +1940,6 @@ tree_dce_done (bool aggressive)
worklist.release ();
}
-/* Sort PHI argument values for make_forwarders_with_degenerate_phis. */
-
-static int
-sort_phi_args (const void *a_, const void *b_)
-{
- auto *a = (const std::pair<edge, hashval_t> *) a_;
- auto *b = (const std::pair<edge, hashval_t> *) b_;
- hashval_t ha = a->second;
- hashval_t hb = b->second;
- if (ha < hb)
- return -1;
- else if (ha > hb)
- return 1;
- else if (a->first->dest_idx < b->first->dest_idx)
- return -1;
- else if (a->first->dest_idx > b->first->dest_idx)
- return 1;
- else
- return 0;
-}
-
-/* Look for a non-virtual PHIs and make a forwarder block when all PHIs
- have the same argument on a set of edges. This is to not consider
- control dependences of individual edges for same values but only for
- the common set. */
-
-static unsigned
-make_forwarders_with_degenerate_phis (function *fn)
-{
- unsigned todo = 0;
-
- basic_block bb;
- FOR_EACH_BB_FN (bb, fn)
- {
- /* Only PHIs with three or more arguments have opportunities. */
- if (EDGE_COUNT (bb->preds) < 3)
- continue;
- /* Do not touch loop headers or blocks with abnormal predecessors.
- ??? This is to avoid creating valid loops here, see PR103458.
- We might want to improve things to either explicitely add those
- loops or at least consider blocks with no backedges. */
- if (bb->loop_father->header == bb
- || bb_has_abnormal_pred (bb))
- continue;
-
- /* Take one PHI node as template to look for identical
- arguments. Build a vector of candidates forming sets
- of argument edges with equal values. Note optimality
- depends on the particular choice of the template PHI
- since equal arguments are unordered leaving other PHIs
- with more than one set of equal arguments within this
- argument range unsorted. We'd have to break ties by
- looking at other PHI nodes. */
- gphi_iterator gsi = gsi_start_nonvirtual_phis (bb);
- if (gsi_end_p (gsi))
- continue;
- gphi *phi = gsi.phi ();
- auto_vec<std::pair<edge, hashval_t>, 8> args;
- bool need_resort = false;
- for (unsigned i = 0; i < gimple_phi_num_args (phi); ++i)
- {
- edge e = gimple_phi_arg_edge (phi, i);
- /* Skip abnormal edges since we cannot redirect them. */
- if (e->flags & EDGE_ABNORMAL)
- continue;
- /* Skip loop exit edges when we are in loop-closed SSA form
- since the forwarder we'd create does not have a PHI node. */
- if (loops_state_satisfies_p (LOOP_CLOSED_SSA)
- && loop_exit_edge_p (e->src->loop_father, e))
- continue;
-
- tree arg = gimple_phi_arg_def (phi, i);
- if (!CONSTANT_CLASS_P (arg) && TREE_CODE (arg) != SSA_NAME)
- need_resort = true;
- args.safe_push (std::make_pair (e, iterative_hash_expr (arg, 0)));
- }
- if (args.length () < 2)
- continue;
- args.qsort (sort_phi_args);
- /* The above sorting can be different between -g and -g0, as e.g. decls
- can have different uids (-g could have bigger gaps in between them).
- So, only use that to determine which args are equal, then change
- second from hash value to smallest dest_idx of the edges which have
- equal argument and sort again. If all the phi arguments are
- constants or SSA_NAME, there is no need for the second sort, the hash
- values are stable in that case. */
- hashval_t hash = args[0].second;
- args[0].second = args[0].first->dest_idx;
- bool any_equal = false;
- for (unsigned i = 1; i < args.length (); ++i)
- if (hash == args[i].second
- && operand_equal_p (PHI_ARG_DEF_FROM_EDGE (phi, args[i - 1].first),
- PHI_ARG_DEF_FROM_EDGE (phi, args[i].first)))
- {
- args[i].second = args[i - 1].second;
- any_equal = true;
- }
- else
- {
- hash = args[i].second;
- args[i].second = args[i].first->dest_idx;
- }
- if (!any_equal)
- continue;
- if (need_resort)
- args.qsort (sort_phi_args);
-
- /* From the candidates vector now verify true candidates for
- forwarders and create them. */
- gphi *vphi = get_virtual_phi (bb);
- unsigned start = 0;
- while (start < args.length () - 1)
- {
- unsigned i;
- for (i = start + 1; i < args.length (); ++i)
- if (args[start].second != args[i].second)
- break;
- /* args[start]..args[i-1] are equal. */
- if (start != i - 1)
- {
- /* Check all PHI nodes for argument equality. */
- bool equal = true;
- gphi_iterator gsi2 = gsi;
- gsi_next (&gsi2);
- for (; !gsi_end_p (gsi2); gsi_next (&gsi2))
- {
- gphi *phi2 = gsi2.phi ();
- if (virtual_operand_p (gimple_phi_result (phi2)))
- continue;
- tree start_arg
- = PHI_ARG_DEF_FROM_EDGE (phi2, args[start].first);
- for (unsigned j = start + 1; j < i; ++j)
- {
- if (!operand_equal_p (start_arg,
- PHI_ARG_DEF_FROM_EDGE
- (phi2, args[j].first)))
- {
- /* Another PHI might have a shorter set of
- equivalent args. Go for that. */
- i = j;
- if (j == start + 1)
- equal = false;
- break;
- }
- }
- if (!equal)
- break;
- }
- if (equal)
- {
- /* If we are asked to forward all edges the block
- has all degenerate PHIs. Do nothing in that case. */
- if (start == 0
- && i == args.length ()
- && args.length () == gimple_phi_num_args (phi))
- break;
- /* Instead of using make_forwarder_block we are
- rolling our own variant knowing that the forwarder
- does not need PHI nodes apart from eventually
- a virtual one. */
- auto_vec<tree, 8> vphi_args;
- if (vphi)
- {
- vphi_args.reserve_exact (i - start);
- for (unsigned j = start; j < i; ++j)
- vphi_args.quick_push
- (PHI_ARG_DEF_FROM_EDGE (vphi, args[j].first));
- }
- free_dominance_info (fn, CDI_DOMINATORS);
- basic_block forwarder = split_edge (args[start].first);
- profile_count count = profile_count::zero ();
- bool irr = false;
- for (unsigned j = start + 1; j < i; ++j)
- {
- edge e = args[j].first;
- if (e->flags & EDGE_IRREDUCIBLE_LOOP)
- irr = true;
- redirect_edge_and_branch_force (e, forwarder);
- redirect_edge_var_map_clear (e);
- count += e->count ();
- }
- forwarder->count = count;
- if (irr)
- {
- forwarder->flags |= BB_IRREDUCIBLE_LOOP;
- single_succ_edge (forwarder)->flags
- |= EDGE_IRREDUCIBLE_LOOP;
- }
-
- if (vphi)
- {
- tree def = copy_ssa_name (vphi_args[0]);
- gphi *vphi_copy = create_phi_node (def, forwarder);
- for (unsigned j = start; j < i; ++j)
- add_phi_arg (vphi_copy, vphi_args[j - start],
- args[j].first, UNKNOWN_LOCATION);
- SET_PHI_ARG_DEF
- (vphi, single_succ_edge (forwarder)->dest_idx, def);
- }
- todo |= TODO_cleanup_cfg;
- }
- }
- /* Continue searching for more opportunities. */
- start = i;
- }
- }
- return todo;
-}
/* Main routine to eliminate dead code.
@@ -2174,8 +1966,8 @@ perform_tree_ssa_dce (bool aggressive)
scev_initialize ();
}
- if (aggressive)
- todo |= make_forwarders_with_degenerate_phis (cfun);
+ if (aggressive && make_forwarders_with_degenerate_phis (cfun))
+ todo |= TODO_cleanup_cfg;
calculate_dominance_info (CDI_DOMINATORS);
diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc
index 09f92b2..0c519cf 100644
--- a/gcc/tree-ssa-sccvn.cc
+++ b/gcc/tree-ssa-sccvn.cc
@@ -2527,7 +2527,10 @@ vn_nary_build_or_lookup_1 (gimple_match_op *res_op, bool insert,
else
{
tree val = vn_lookup_simplify_result (res_op);
- if (!val && insert)
+ /* ??? In weird cases we can end up with internal-fn calls,
+ but this isn't expected so throw the result away. See
+ PR123040 for an example. */
+ if (!val && insert && res_op->code.is_tree_code ())
{
gimple_seq stmts = NULL;
result = maybe_push_res_to_seq (res_op, &stmts);
diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc
index 555986b..af64cb8 100644
--- a/gcc/tree-vect-patterns.cc
+++ b/gcc/tree-vect-patterns.cc
@@ -1914,6 +1914,9 @@ vect_recog_ctz_ffs_pattern (vec_info *vinfo, stmt_vec_info stmt_vinfo,
&& val_new == prec)
|| (ifnnew == IFN_POPCOUNT && ifn == IFN_CTZ))
{
+ if (vect_is_reduction (stmt_vinfo))
+ return NULL;
+
/* .CTZ (X) = PREC - .CLZ ((X - 1) & ~X)
.CTZ (X) = .POPCOUNT ((X - 1) & ~X). */
if (ifnnew == IFN_CLZ)
@@ -1952,6 +1955,9 @@ vect_recog_ctz_ffs_pattern (vec_info *vinfo, stmt_vec_info stmt_vinfo,
}
else if (ifnnew == IFN_CLZ)
{
+ if (vect_is_reduction (stmt_vinfo))
+ return NULL;
+
/* .CTZ (X) = (PREC - 1) - .CLZ (X & -X)
.FFS (X) = PREC - .CLZ (X & -X). */
sub = prec - (ifn == IFN_CTZ);
@@ -1971,6 +1977,9 @@ vect_recog_ctz_ffs_pattern (vec_info *vinfo, stmt_vec_info stmt_vinfo,
}
else if (ifnnew == IFN_POPCOUNT)
{
+ if (vect_is_reduction (stmt_vinfo))
+ return NULL;
+
/* .CTZ (X) = PREC - .POPCOUNT (X | -X)
.FFS (X) = (PREC + 1) - .POPCOUNT (X | -X). */
sub = prec + (ifn == IFN_FFS);
@@ -1993,6 +2002,11 @@ vect_recog_ctz_ffs_pattern (vec_info *vinfo, stmt_vec_info stmt_vinfo,
/* .FFS (X) = .CTZ (X) + 1. */
add = 1;
val_cmp++;
+
+ if (vect_is_reduction (stmt_vinfo)
+ && defined_at_zero
+ && (!defined_at_zero_new || val != val_cmp))
+ return NULL;
}
/* Create B = .IFNNEW (A). */
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index dc155dc..95f015f 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -9920,36 +9920,35 @@ vectorizable_load (vec_info *vinfo,
bool hoist_p = (LOOP_VINFO_NO_DATA_DEPENDENCIES (loop_vinfo)
&& !nested_in_vect_loop);
- /* It is unsafe to hoist a conditional load over the conditions that make
- it valid. When early break this means that any invariant load can't be
- hoisted unless it's in the loop header or if we know something else has
- verified the load is valid to do. Alignment peeling would do this
- since getting through the prologue means the load was done at least
- once and so the vector main body is free to hoist it. However today
- GCC will hoist the load above the PFA loop. As such that makes it
- still invalid and so we can't allow it today. */
- auto stmt_bb
- = gimple_bb (STMT_VINFO_STMT (
- vect_orig_stmt (SLP_TREE_SCALAR_STMTS (slp_node)[0])));
- if (LOOP_VINFO_EARLY_BREAKS (loop_vinfo)
- && !DR_SCALAR_KNOWN_BOUNDS (dr_info)
- && stmt_bb != loop->header)
- {
- if (LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo)
- && dump_enabled_p ())
- dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ bool uniform_p = true;
+ for (stmt_vec_info sinfo : SLP_TREE_SCALAR_STMTS (slp_node))
+ {
+ /* It is unsafe to hoist a conditional load over the conditions that
+ make it valid. When early break this means that any invariant load
+ can't be hoisted unless it's in the loop header or if we know
+ something else has verified the load is valid to do. Alignment
+ peeling would do this since getting through the prologue means the
+ load was done at least once and so the vector main body is free to
+ hoist it. However today GCC will hoist the load above the PFA
+ loop. As such that makes it still invalid and so we can't allow it
+ today. */
+ if (LOOP_VINFO_EARLY_BREAKS (loop_vinfo)
+ && !DR_SCALAR_KNOWN_BOUNDS (STMT_VINFO_DR_INFO (sinfo))
+ && gimple_bb (STMT_VINFO_STMT (vect_orig_stmt (sinfo)))
+ != loop->header)
+ {
+ if (LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo)
+ && dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
"not hoisting invariant load due to early break"
"constraints\n");
- else if (dump_enabled_p ())
- dump_printf_loc (MSG_NOTE, vect_location,
+ else if (dump_enabled_p ())
+ dump_printf_loc (MSG_NOTE, vect_location,
"not hoisting invariant load due to early break"
"constraints\n");
- hoist_p = false;
- }
+ hoist_p = false;
+ }
- bool uniform_p = true;
- for (stmt_vec_info sinfo : SLP_TREE_SCALAR_STMTS (slp_node))
- {
hoist_p = hoist_p && hoist_defs_of_uses (sinfo->stmt, loop, false);
if (sinfo != SLP_TREE_SCALAR_STMTS (slp_node)[0])
uniform_p = false;