diff options
Diffstat (limited to 'gcc')
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; |
