diff options
112 files changed, 2154 insertions, 298 deletions
@@ -1,3 +1,16 @@ +2025-10-20 Tamar Christina <tamar.christina@arm.com> + + * MAINTAINERS (Various Maintainers): Add myself for the vectorizer. + +2025-10-20 Christophe Lyon <christophe.lyon@linaro.org> + + * .forgejo/workflows/sanity-checks.yaml: New file. + +2025-10-20 Richard Biener <rguenther@suse.de> + + * MAINTAINERS (auto-vectorizer): Change attribution to + vectorizer (+ tree-if-conv). + 2025-10-15 Basil Milanich <bmilanich@gmail.com> * Makefile.tpl (distclean): Remove extraenous semicolon. diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fe5a6f5..ddb02e7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,115 @@ +2025-10-20 Josef Melcr <jmelcr02@gmail.com> + + * ipa-fnsummary.cc (redirect_to_unreachable): Purge callback + edges when redirecting the carrying edge. + (analyze_function_body): Fix typo. + +2025-10-20 Svante Signell <svante.signell@gmail.com> + + PR go/104290 + * config/gnu.h (OPTION_GLIBC_P, OPTION_GLIBC): Define. + +2025-10-20 Takayuki 'January June' Suwa <jjsuwa_sys3175@yahoo.co.jp> + + * config/xtensa/constraints.md (R, U): + Change define_memory_constraint to define_special_memory_constraint. + * config/xtensa/xtensa.md + (movsi_internal, movhi_internal, movqi_internal): + Rearrange their alternatives in the order of constant assignment, register- + register move, load, store and special. And also consolidate overlapping + alternatives. + (movsf_internal): Rearrange the alternatives as above, and remove the '^' + alternative character which is no longer needed. + +2025-10-20 Takayuki 'January June' Suwa <jjsuwa_sys3175@yahoo.co.jp> + + * config/xtensa/xtensa.cc + (constantsynth_method_const16): New. + (constantsynth_methods): Append constantsynth_method_const16(). + (constantsynth_info): Add cost calculation for full-word constant + assignment when TARGET_CONST16 is enabled. + (constantsynth_pass1): Change it so that it works regardless of + TARGET_CONST16. + * config/xtensa/xtensa.md (*xtensa_const16): New. + +2025-10-20 Takayuki 'January June' Suwa <jjsuwa_sys3175@yahoo.co.jp> + + * config/xtensa/xtensa.cc (do_largeconst): + Change split_DI_SF_DF_const() to be called unconditionally. + +2025-10-20 Olivier Hainque <hainque@adacore.com> + + * config.gcc (powerpc*-wrs-vxworks7r*): Add linux-protos.h + to tm_p_file. + +2025-10-20 Olivier Hainque <hainque@adacore.com> + + * config/vxworks.h (VXWORKS_OS_CPP_BUILTINS): Only + builtin_define TOOL and TOOL_FAMILY for !TARGET_VXWORKS7. + Augment comment on VXWORKS_PERSONALITY. + * config/vxworks/vxworks-predef.h: Infer TOOL and TOOL_FAMILY + from the VSB autoconf.h when we have one, determined by the presence + of a _VSB_CONFIG_FILE definition. + +2025-10-20 Srinath Parvathaneni <srinath.parvathaneni@arm.com> + + * config/aarch64/aarch64-elf.h (ASM_SPEC): Update the macro. + * config/aarch64/aarch64.cc (aarch64_valid_sysreg_name_p): + Add feature check condition. + (aarch64_retrieve_sysreg): Likewise. + * config/aarch64/aarch64.opt (menable-sysreg-checking): + Define new flag. + * doc/invoke.texi (menable-sysreg-checking): Document new flag. + +2025-10-20 Richard Biener <rguenther@suse.de> + + PR tree-optimization/121631 + * tree-vect-loop.cc (vect_create_epilog_for_reduction): + When the reduction operation invokes UB on signed overflow + make sure to perform operations with it on an unsigned type. + +2025-10-20 Richard Biener <rguenther@suse.de> + + PR tree-optimization/101639 + PR tree-optimization/103495 + * tree-vectorizer.h (vect_reduc_info_s): Add reduc_type_for_mask. + (VECT_REDUC_INFO_VECTYPE_FOR_MASK): New. + * tree-vect-patterns.cc (vect_determine_mask_precision): + Return whether the mask precision changed. + (vect_determine_precisions): Iterate mask precision computation + for loop vectorization. + * tree-vect-loop.cc (get_initial_defs_for_reduction): Properly + convert non-mask initial values to a mask initial def for + the reduction. + (sbool_reduction_fn_for_fn): New function. + (vect_create_epilog_for_reduction): For a mask input convert + it to the vector type analysis decided to use. Use a regular + conversion for the final convert to the scalar code type. + (vectorizable_reduction): Support mask reductions. Verify + we can compute a data vector from the mask result or a direct + maks reduction is provided by the target. + +2025-10-20 Richard Biener <rguenther@suse.de> + + * doc/md.texi (reduc_sbool_{and,ior,xor}_scal_<mode>): Document. + * optabs.def (reduc_sbool_and_scal_optab, + reduc_sbool_ior_scal_optab, reduc_sbool_xor_scal_optab): New. + * internal-fn.def (REDUC_SBOOL_AND, REDUC_SBOOL_IOR, + REDUC_SBOO_XOR): Likewise. + * internal-fn.cc (reduc_sbool_direct): New initializer. + (expand_reduc_sbool_optab_fn): New expander. + (direct_reduc_sbool_optab_supported_p): New. + +2025-10-20 H.J. Lu <hjl.tools@gmail.com> + + PR target/99930 + PR target/122323 + * config/i386/i386-expand.cc (ix86_expand_copysign): Swap + operands[1] with operands[2]. Optimize copysign (x, const_double) + instead of copysign (const_double, x). + * config/i386/i386.md (copysign<mode>3): Swap constraints for + operands[1] and operands[2]. + 2025-10-19 Georg-Johann Lay <avr@gjlay.de> * config/avr/avr.cc (avr_nonzero_bits_lsr_operands_p): Also diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index bc3f416..85077f4 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20251020 +20251021 diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 24d03d4..806a2ca 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,41 @@ +2025-10-20 Eric Botcazou <ebotcazou@adacore.com> + + PR ada/102078 + * affinity.c (__gnat_set_affinity_mask): Add U qualifier. + +2025-10-20 Eric Botcazou <ebotcazou@adacore.com> + + PR ada/32318 + * libgnat/g-catiio.adb (Image_Helper) <'c'>: Fix comment. + +2025-10-20 Eric Botcazou <ebotcazou@adacore.com> + + PR ada/68179 + * exp_ch3.adb (Expand_Freeze_Array_Type): Build an initialization + procedure for a type derived from String declared with the aspect + Default_Aspect_Component_Value. + +2025-10-20 Eric Botcazou <ebotcazou@adacore.com> + + PR ada/52319 + * sem_ch7.adb (Uninstall_Declarations): Use direct test on Nkind + to spot operators. + * sem_ch8.adb (End_Use_Package): Also test the Etype of operators + to spot those which are primitive operators of use-visible types. + +2025-10-20 Nicolas Boulenguez <nicolas@debian.org> + + PR ada/87777 + * gnatchop.adb: Add with clause for Osint. + (Locate_Executable): Delete. + (Gnatchop): Use Osint.Program_Name and Locate_Exec_On_Path instead + of Locate_Executable to locate GCC's driver executable. + +2025-10-20 Eric Botcazou <ebotcazou@adacore.com> + + PR ada/107536 + * exp_ch2.adb (Expand_Renaming): Mark the entity as referenced. + 2025-10-17 Eric Botcazou <ebotcazou@adacore.com> PR ada/122295 diff --git a/gcc/ada/affinity.c b/gcc/ada/affinity.c index 58f491f..5b95d70 100644 --- a/gcc/ada/affinity.c +++ b/gcc/ada/affinity.c @@ -56,7 +56,7 @@ __gnat_set_affinity_mask (TASK_ID tid, unsigned mask) CPUSET_ZERO(cpuset); for (index = 0; index < sizeof (unsigned) * 8; index++) - if (mask & (1 << index)) + if (mask & (1U << index)) CPUSET_SET(cpuset, index); return taskCpuAffinitySet (tid, cpuset); diff --git a/gcc/ada/libgnat/g-catiio.adb b/gcc/ada/libgnat/g-catiio.adb index 5310706..d229b3b 100644 --- a/gcc/ada/libgnat/g-catiio.adb +++ b/gcc/ada/libgnat/g-catiio.adb @@ -515,7 +515,7 @@ package body GNAT.Calendar.Time_IO is Result := Result & Image (Month_Name'Image (Month_Name'Val (Month - 1))); - -- Locale's date and time (Sat Nov 04 12:02:33 EST 1989) + -- Locale's date and time (Sat Nov 04 12:02:33 1989) when 'c' => case Padding is diff --git a/gcc/c-family/c-omp.cc b/gcc/c-family/c-omp.cc index fe272888..3c2ee9f 100644 --- a/gcc/c-family/c-omp.cc +++ b/gcc/c-family/c-omp.cc @@ -4604,6 +4604,9 @@ const struct c_omp_directive c_omp_directives[] = { C_OMP_DIR_DECLARATIVE, false }, /* { "begin", "declare", "variant", PRAGMA_OMP_BEGIN, C_OMP_DIR_DECLARATIVE, false }, */ + /* 'begin metadirective' is not yet implemented; however, + it is only applicable if an end-directive exists, but + metadirectives are of limited use for declarative directives. */ /* { "begin", "metadirective", nullptr, PRAGMA_OMP_BEGIN, C_OMP_DIR_META, false }, */ { "cancel", nullptr, nullptr, PRAGMA_OMP_CANCEL, @@ -4612,8 +4615,10 @@ const struct c_omp_directive c_omp_directives[] = { C_OMP_DIR_STANDALONE, false }, { "critical", nullptr, nullptr, PRAGMA_OMP_CRITICAL, C_OMP_DIR_CONSTRUCT, false }, - /* { "declare", "mapper", nullptr, PRAGMA_OMP_DECLARE, - C_OMP_DIR_DECLARATIVE, false }, */ + /* { "declare", "induction", nullptr, PRAGMA_OMP_DECLARE, + C_OMP_DIR_DECLARATIVE, true }, */ + { "declare", "mapper", nullptr, PRAGMA_OMP_DECLARE, + C_OMP_DIR_DECLARATIVE, false }, { "declare", "reduction", nullptr, PRAGMA_OMP_DECLARE, C_OMP_DIR_DECLARATIVE, true }, { "declare", "simd", nullptr, PRAGMA_OMP_DECLARE, @@ -4639,12 +4644,18 @@ const struct c_omp_directive c_omp_directives[] = { /* error with at(execution) is C_OMP_DIR_STANDALONE. */ { "error", nullptr, nullptr, PRAGMA_OMP_ERROR, C_OMP_DIR_UTILITY, false }, + /* { "flatten", nullptr, nullptr, PRAGMA_OMP_FLATTEN, + C_OMP_DIR_CONSTRUCT, true }, */ { "flush", nullptr, nullptr, PRAGMA_OMP_FLUSH, C_OMP_DIR_STANDALONE, false }, { "for", nullptr, nullptr, PRAGMA_OMP_FOR, C_OMP_DIR_CONSTRUCT, true }, + /* { "fuse", nullptr, nullptr, PRAGMA_OMP_FUSE, + C_OMP_DIR_CONSTRUCT, true }, */ /* { "groupprivate", nullptr, nullptr, PRAGMA_OMP_GROUPPRIVATE, C_OMP_DIR_DECLARATIVE, false }, */ + /* { "interchange", nullptr, nullptr, PRAGMA_OMP_INTERCHANGE, + C_OMP_DIR_CONSTRUCT, true }, */ { "interop", nullptr, nullptr, PRAGMA_OMP_INTEROP, C_OMP_DIR_STANDALONE, false }, { "loop", nullptr, nullptr, PRAGMA_OMP_LOOP, @@ -4676,6 +4687,10 @@ const struct c_omp_directive c_omp_directives[] = { C_OMP_DIR_CONSTRUCT, true }, { "single", nullptr, nullptr, PRAGMA_OMP_SINGLE, C_OMP_DIR_CONSTRUCT, false }, + /* { "split", nullptr, nullptr, PRAGMA_OMP_SPLIT, + C_OMP_DIR_CONSTRUCT, true }, */ + /* { "stripe", nullptr, nullptr, PRAGMA_OMP_STRIPE, + C_OMP_DIR_CONSTRUCT, true }, */ { "target", "data", nullptr, PRAGMA_OMP_TARGET, C_OMP_DIR_CONSTRUCT, false }, { "target", "enter", "data", PRAGMA_OMP_TARGET, @@ -4688,6 +4703,10 @@ const struct c_omp_directive c_omp_directives[] = { C_OMP_DIR_CONSTRUCT, true }, { "task", nullptr, nullptr, PRAGMA_OMP_TASK, C_OMP_DIR_CONSTRUCT, false }, + /* { "task", "iteration", nullptr, PRAGMA_OMP_TASK_ITERATION, + C_OMP_DIR_STANDALONE, false }, */ + /* { "taskgraph", nullptr, nullptr, PRAGMA_OMP_TASKGRAPH, + C_OMP_DIR_CONSTRUCT, false }, */ { "taskgroup", nullptr, nullptr, PRAGMA_OMP_TASKGROUP, C_OMP_DIR_CONSTRUCT, false }, { "taskloop", nullptr, nullptr, PRAGMA_OMP_TASKLOOP, diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index 4a940d5..061892a 100644 --- a/gcc/c/c-decl.cc +++ b/gcc/c/c-decl.cc @@ -71,7 +71,8 @@ enum decl_context FUNCDEF, /* Function definition */ PARM, /* Declaration of parm before function body */ FIELD, /* Declaration inside struct or union */ - TYPENAME}; /* Typename (inside cast or sizeof) */ + TYPENAME, /* Typename (inside cast or sizeof) */ + GENERIC_ASSOC }; /* Typename in generic association */ /* States indicating how grokdeclarator() should handle declspecs marked with __attribute__((deprecated)) or __attribute__((unavailable)). @@ -5456,19 +5457,11 @@ build_array_declarator (location_t loc, "ISO C90 does not support %<static%> or type " "qualifiers in parameter array declarators"); if (vla_unspec_p) - pedwarn_c90 (loc, OPT_Wpedantic, - "ISO C90 does not support %<[*]%> array declarators"); - if (vla_unspec_p) { - if (!current_scope->parm_flag) - { - /* C99 6.7.5.2p4 */ - error_at (loc, "%<[*]%> not allowed in other than " - "function prototype scope"); - declarator->u.array.vla_unspec_p = false; - return NULL; - } - current_scope->had_vla_unspec = true; + pedwarn_c90 (loc, OPT_Wpedantic, + "ISO C90 does not support %<[*]%> array declarators"); + if (current_scope->parm_flag) + current_scope->had_vla_unspec = true; } return declarator; } @@ -5574,6 +5567,29 @@ groktypename (struct c_type_name *type_name, tree *expr, return type; } + +/* Decode a "typename", such as "int **", returning a ..._TYPE node, + as for groktypename but setting the context to GENERIC_ASSOC. */ + +tree +grokgenassoc (struct c_type_name *type_name) +{ + tree type; + tree attrs = type_name->specs->attrs; + + type_name->specs->attrs = NULL_TREE; + + type = grokdeclarator (type_name->declarator, type_name->specs, GENERIC_ASSOC, + false, NULL, &attrs, NULL, NULL, DEPRECATED_NORMAL); + + /* Apply attributes. */ + attrs = c_warn_type_attributes (type, attrs); + decl_attributes (&type, attrs, 0); + + return type; +} + + /* Looks up the most recent pushed declaration corresponding to DECL. */ static tree @@ -6772,6 +6788,7 @@ build_arg_spec_attribute (tree type, bool static_p, tree attrs) or before a function body). Make a PARM_DECL, or return void_type_node. TYPENAME if for a typename (in a cast or sizeof). Don't make a DECL node; just return the ..._TYPE node. + GENERIC_ASSOC for typenames in a generic association. FIELD for a struct or union field; make a FIELD_DECL. INITIALIZED is true if the decl has an initializer. WIDTH is non-NULL for bit-fields, and is a pointer to an INTEGER_CST node @@ -6908,6 +6925,7 @@ grokdeclarator (const struct c_declarator *declarator, { gcc_assert (decl_context == PARM || decl_context == TYPENAME + || decl_context == GENERIC_ASSOC || (decl_context == FIELD && declarator->kind == cdk_id)); gcc_assert (!initialized); @@ -7481,14 +7499,6 @@ grokdeclarator (const struct c_declarator *declarator, itype = build_index_type (NULL_TREE); } - if (array_parm_vla_unspec_p) - { - /* C99 6.7.5.2p4 */ - if (decl_context == TYPENAME) - warning (0, "%<[*]%> not in a declaration"); - size_varies = true; - } - /* Complain about arrays of incomplete types. */ if (!COMPLETE_TYPE_P (type)) { @@ -7527,6 +7537,22 @@ grokdeclarator (const struct c_declarator *declarator, type = c_build_array_type (type, itype); } + if (array_parm_vla_unspec_p) + { + /* C99 6.7.5.2p4 */ + if (decl_context == TYPENAME) + warning (0, "%<[*]%> not in a declaration"); + else if (decl_context != GENERIC_ASSOC + && decl_context != PARM + && decl_context != FIELD) + { + error ("%<[*]%> not allowed in other than function prototype scope " + "or generic association"); + type = error_mark_node; + } + size_varies = true; + } + if (type != error_mark_node) { /* The GCC extension for zero-length arrays differs from @@ -7898,7 +7924,7 @@ grokdeclarator (const struct c_declarator *declarator, /* If this is a type name (such as, in a cast or sizeof), compute the type and return it now. */ - if (decl_context == TYPENAME) + if (decl_context == TYPENAME || decl_context == GENERIC_ASSOC) { /* Note that the grammar rejects storage classes in typenames and fields. */ diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc index ea0294f..56fb0be 100644 --- a/gcc/c/c-parser.cc +++ b/gcc/c/c-parser.cc @@ -11240,7 +11240,7 @@ c_parser_generic_selection (c_parser *parser) c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); return error_expr; } - assoc.type = groktypename (type_name, NULL, NULL); + assoc.type = grokgenassoc (type_name); if (assoc.type == error_mark_node) { c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); @@ -15787,11 +15787,15 @@ c_parser_pragma (c_parser *parser, enum pragma_context context, bool *if_p, gcc_assert (id != PRAGMA_NONE); if (parser->omp_for_parse_state && parser->omp_for_parse_state->in_intervening_code - && id >= PRAGMA_OMP__START_ - && id <= PRAGMA_OMP__LAST_) - { - error_at (input_location, - "intervening code must not contain OpenMP directives"); + && id >= PRAGMA_OMP__START_ && id <= PRAGMA_OMP__LAST_ + /* Allow a safe subset of non-executable directives. See classification in + array c_omp_directives. */ + && id != PRAGMA_OMP_METADIRECTIVE && id != PRAGMA_OMP_NOTHING + && id != PRAGMA_OMP_ASSUME && id != PRAGMA_OMP_ERROR) + { + error_at ( + input_location, + "intervening code must not contain executable OpenMP directives"); parser->omp_for_parse_state->fail = true; c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL); return false; @@ -29334,6 +29338,14 @@ c_parser_omp_error (c_parser *parser, enum pragma_context context) "may only be used in compound statements"); return true; } + if (parser->omp_for_parse_state + && parser->omp_for_parse_state->in_intervening_code) + { + error_at (loc, "%<#pragma omp error%> with %<at(execution)%> clause " + "may not be used in intervening code"); + parser->omp_for_parse_state->fail = true; + return true; + } tree fndecl = builtin_decl_explicit (severity_fatal ? BUILT_IN_GOMP_ERROR : BUILT_IN_GOMP_WARNING); @@ -29480,6 +29492,7 @@ c_parser_omp_assumption_clauses (c_parser *parser, bool is_assume) directive[1], directive[2]); if (dir + && dir->id != PRAGMA_OMP_END && (dir->kind == C_OMP_DIR_DECLARATIVE || dir->kind == C_OMP_DIR_INFORMATIONAL || dir->kind == C_OMP_DIR_META)) @@ -29863,6 +29876,17 @@ c_parser_omp_metadirective (c_parser *parser, bool *if_p) } c_parser_skip_to_pragma_eol (parser); + /* If only one selector matches and it evaluates to 'omp nothing', no need to + proceed. */ + if (ctxs.length () == 1) + { + tree ctx = ctxs[0]; + if (ctx == NULL_TREE + || (omp_context_selector_matches (ctx, NULL_TREE, false) == 1 + && directive_tokens[0].pragma_kind == PRAGMA_OMP_NOTHING)) + return; + } + if (!default_seen) { /* Add a default clause that evaluates to 'omp nothing'. */ @@ -29943,7 +29967,7 @@ c_parser_omp_metadirective (c_parser *parser, bool *if_p) if (standalone_body == NULL_TREE) { standalone_body = push_stmt_list (); - c_parser_statement (parser, if_p); + c_parser_statement (parser, if_p); // TODO skip this standalone_body = pop_stmt_list (standalone_body); } else diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h index 162add0..f367cda 100644 --- a/gcc/c/c-tree.h +++ b/gcc/c/c-tree.h @@ -713,6 +713,7 @@ extern struct c_arg_info *get_parm_info (bool, tree); extern tree grokfield (location_t, struct c_declarator *, struct c_declspecs *, tree, tree *, tree *); extern tree groktypename (struct c_type_name *, tree *, bool *); +extern tree grokgenassoc (struct c_type_name *); extern tree grokparm (const struct c_parm *, tree *); extern tree implicitly_declare (location_t, tree); extern void keep_next_level (void); diff --git a/gcc/config.gcc b/gcc/config.gcc index 2ecce1c..4400410 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -6108,7 +6108,6 @@ case ${target} in c_target_objs="${c_target_objs} ${cpu_type}-c.o" cxx_target_objs="${cxx_target_objs} ${cpu_type}-c.o" d_target_objs="${d_target_objs} ${cpu_type}-d.o" - jit_target_objs="${jit_target_objs} ${cpu_type}-jit.o" tmake_file="${cpu_type}/t-${cpu_type} ${tmake_file}" ;; diff --git a/gcc/config/gnu.h b/gcc/config/gnu.h index 6b8f36b..825e743 100644 --- a/gcc/config/gnu.h +++ b/gcc/config/gnu.h @@ -19,6 +19,10 @@ You should have received a copy of the GNU General Public License along with GCC. If not, see <http://www.gnu.org/licenses/>. */ +/* C libraries used on GNU/Hurd. */ +#define OPTION_GLIBC_P(opts) (DEFAULT_LIBC == LIBC_GLIBC) +#define OPTION_GLIBC OPTION_GLIBC_P (&global_options) + #undef GNU_USER_TARGET_OS_CPP_BUILTINS #define GNU_USER_TARGET_OS_CPP_BUILTINS() \ do { \ diff --git a/gcc/config/i386/i386-features.cc b/gcc/config/i386/i386-features.cc index 9348f55..8e27784 100644 --- a/gcc/config/i386/i386-features.cc +++ b/gcc/config/i386/i386-features.cc @@ -449,6 +449,30 @@ scalar_chain::analyze_register_chain (bitmap candidates, df_ref ref, return true; } +/* Check whether X is a convertible *concatditi_? variant. X is known + to be any_or_plus:TI, i.e. PLUS:TI, IOR:TI or XOR:TI. */ + +static bool +timode_concatdi_p (rtx x) +{ + rtx op0 = XEXP (x, 0); + rtx op1 = XEXP (x, 1); + + if (GET_CODE (op1) == ASHIFT) + std::swap (op0, op1); + + return GET_CODE (op0) == ASHIFT + && GET_CODE (XEXP (op0, 0)) == ZERO_EXTEND + && GET_MODE (XEXP (XEXP (op0, 0), 0)) == DImode + && REG_P (XEXP (XEXP (op0, 0), 0)) + && CONST_INT_P (XEXP (op0, 1)) + && INTVAL (XEXP (op0, 1)) == 64 + && GET_CODE (op1) == ZERO_EXTEND + && GET_MODE (XEXP (op1, 0)) == DImode + && REG_P (XEXP (op1, 0)); +} + + /* Add instruction into a chain. Return true if OK, false if the search was aborted. */ @@ -477,9 +501,26 @@ scalar_chain::add_insn (bitmap candidates, unsigned int insn_uid, if (!analyze_register_chain (candidates, ref, disallowed)) return false; - /* The operand(s) of VEC_SELECT don't need to be converted/convertible. */ - if (def_set && GET_CODE (SET_SRC (def_set)) == VEC_SELECT) - return true; + /* The operand(s) of VEC_SELECT, ZERO_EXTEND and similar ops don't need + to be converted/convertible. */ + if (def_set) + switch (GET_CODE (SET_SRC (def_set))) + { + case VEC_SELECT: + return true; + case ZERO_EXTEND: + if (GET_MODE (XEXP (SET_SRC (def_set), 0)) == DImode) + return true; + break; + case PLUS: + case IOR: + case XOR: + if (smode == TImode && timode_concatdi_p (SET_SRC (def_set))) + return true; + break; + default: + break; + } for (ref = DF_INSN_UID_USES (insn_uid); ref; ref = DF_REF_NEXT_LOC (ref)) if (!DF_REF_REG_MEM_P (ref)) @@ -1628,14 +1669,34 @@ timode_scalar_chain::compute_convert_gain () break; case AND: + if (!MEM_P (dst)) + igain = COSTS_N_INSNS (1); + if (CONST_SCALAR_INT_P (XEXP (src, 1))) + igain += timode_immed_const_gain (XEXP (src, 1), bb); + break; + case XOR: case IOR: + if (timode_concatdi_p (src)) + { + /* vmovq;vpinsrq (11 bytes). */ + igain = speed_p ? -2 * ix86_cost->sse_to_integer + : -COSTS_N_BYTES (11); + break; + } if (!MEM_P (dst)) igain = COSTS_N_INSNS (1); if (CONST_SCALAR_INT_P (XEXP (src, 1))) igain += timode_immed_const_gain (XEXP (src, 1), bb); break; + case PLUS: + if (timode_concatdi_p (src)) + /* vmovq;vpinsrq (11 bytes). */ + igain = speed_p ? -2 * ix86_cost->sse_to_integer + : -COSTS_N_BYTES (11); + break; + case ASHIFT: case LSHIFTRT: /* See ix86_expand_v1ti_shift. */ @@ -1794,6 +1855,13 @@ timode_scalar_chain::compute_convert_gain () igain = !speed_p ? -COSTS_N_BYTES (6) : -COSTS_N_INSNS (1); break; + case ZERO_EXTEND: + if (GET_MODE (XEXP (src, 0)) == DImode) + /* xor (2 bytes) vs. vmovq (5 bytes). */ + igain = speed_p ? COSTS_N_INSNS (1) - ix86_cost->sse_to_integer + : -COSTS_N_BYTES (3); + break; + default: break; } @@ -1858,6 +1926,28 @@ timode_scalar_chain::fix_debug_reg_uses (rtx reg) } } +/* Convert SRC, a *concatditi3 pattern, into a vec_concatv2di instruction. + Insert this before INSN, and return the result as a V1TImode subreg. */ + +static rtx +timode_convert_concatdi (rtx src, rtx_insn *insn) +{ + rtx hi, lo; + rtx tmp = gen_reg_rtx (V2DImode); + if (GET_CODE (XEXP (src, 0)) == ASHIFT) + { + hi = XEXP (XEXP (XEXP (src, 0), 0), 0); + lo = XEXP (XEXP (src, 1), 0); + } + else + { + hi = XEXP (XEXP (XEXP (src, 1), 0), 0); + lo = XEXP (XEXP (src, 0), 0); + } + emit_insn_before (gen_vec_concatv2di (tmp, lo, hi), insn); + return gen_rtx_SUBREG (V1TImode, tmp, 0); +} + /* Convert INSN from TImode to V1T1mode. */ void @@ -1967,10 +2057,24 @@ timode_scalar_chain::convert_insn (rtx_insn *insn) PUT_MODE (src, V1TImode); break; } - /* FALLTHRU */ + convert_op (&XEXP (src, 0), insn); + convert_op (&XEXP (src, 1), insn); + PUT_MODE (src, V1TImode); + if (MEM_P (dst)) + { + tmp = gen_reg_rtx (V1TImode); + emit_insn_before (gen_rtx_SET (tmp, src), insn); + src = tmp; + } + break; case XOR: case IOR: + if (timode_concatdi_p (src)) + { + src = timode_convert_concatdi (src, insn); + break; + } convert_op (&XEXP (src, 0), insn); convert_op (&XEXP (src, 1), insn); PUT_MODE (src, V1TImode); @@ -2010,6 +2114,26 @@ timode_scalar_chain::convert_insn (rtx_insn *insn) PUT_MODE (src, V1TImode); break; + case ZERO_EXTEND: + if (GET_MODE (XEXP (src, 0)) == DImode) + { + /* Convert to *vec_concatv2di_0. */ + rtx tmp = gen_reg_rtx (V2DImode); + rtx pat = gen_rtx_VEC_CONCAT (V2DImode, XEXP (src, 0), const0_rtx); + emit_insn_before (gen_move_insn (tmp, pat), insn); + src = gen_rtx_SUBREG (vmode, tmp, 0); + } + else + gcc_unreachable (); + break; + + case PLUS: + if (timode_concatdi_p (src)) + src = timode_convert_concatdi (src, insn); + else + gcc_unreachable (); + break; + default: gcc_unreachable (); } @@ -2389,6 +2513,8 @@ timode_scalar_to_vector_candidate_p (rtx_insn *insn) case IOR: case XOR: + if (timode_concatdi_p (src)) + return true; return (REG_P (XEXP (src, 0)) || timode_mem_p (XEXP (src, 0))) && (REG_P (XEXP (src, 1)) @@ -2408,6 +2534,13 @@ timode_scalar_to_vector_candidate_p (rtx_insn *insn) && CONST_INT_P (XEXP (src, 1)) && (INTVAL (XEXP (src, 1)) & ~0x7f) == 0; + case PLUS: + return timode_concatdi_p (src); + + case ZERO_EXTEND: + return REG_P (XEXP (src, 0)) + && GET_MODE (XEXP (src, 0)) == DImode; + default: return false; } diff --git a/gcc/config/rs6000/vxworks.h b/gcc/config/rs6000/vxworks.h index 9eb074b..13c706b 100644 --- a/gcc/config/rs6000/vxworks.h +++ b/gcc/config/rs6000/vxworks.h @@ -290,5 +290,21 @@ along with GCC; see the file COPYING3. If not see trigger visible link errors (hence remain harmless) if the support isn't really there. */ +/* Select a format to encode pointers in exception handling data. CODE + is 0 for data, 1 for code labels, 2 for function pointers. GLOBAL is + true if the symbol may be affected by dynamic relocations. + + This is essentially the linux64.h version with an extra guard on + TARGET_VXWORKS_RTP to avoid DW_EH_PE_indirect in 64bit DKMs as they + could result in references from one DKM to resolve to symbols exposed + by a previsouly loaded DKM even if the symbol is also provided by the + DKM where the reference takes place. */ +#undef ASM_PREFERRED_EH_DATA_FORMAT +#define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \ + ((TARGET_64BIT && TARGET_VXWORKS_RTP) || flag_pic \ + ? (((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel \ + | (TARGET_64BIT ? DW_EH_PE_udata8 : DW_EH_PE_sdata4)) \ + : DW_EH_PE_absptr) + #endif /* TARGET_VXWORKS7 */ diff --git a/gcc/config/vxworks.h b/gcc/config/vxworks.h index 7268ace..bfad070 100644 --- a/gcc/config/vxworks.h +++ b/gcc/config/vxworks.h @@ -75,22 +75,27 @@ extern void vxworks_driver_init (unsigned int *, struct cl_decoded_option **); #if TARGET_VXWORKS7 -/* We arrange not rely on fixed includes for vx7 and the headers spread over - common kernel/rtp directories in addition to specific ones for each mode. - Setup sysroot_headers_suffix_spec to deal with kernel/rtp distinction. */ +/* We arrange not to rely on fixed includes for vx7 and the headers spread + over common kernel/rtp directories in addition to specific ones for each + mode. Setup sysroot_headers_suffix_spec to deal with the kernel/rtp + distinction. */ #undef SYSROOT_HEADERS_SUFFIX_SPEC #define SYSROOT_HEADERS_SUFFIX_SPEC "%{mrtp:/usr/h;:/krnl/h}" +/* Now expand everything using sysroot(+suffix) relative references. The + absence of %getenv(VSB_DIR) allows all-gcc builds with possible self-tests + to succeed without having to define the variable at all. */ + #undef VXWORKS_ADDITIONAL_CPP_SPEC -#define VXWORKS_ADDITIONAL_CPP_SPEC \ - "%{!nostdinc:%{!fself-test=*: \ - %{isystem*} \ - -idirafter %:getenv(VSB_DIR /h) \ - -idirafter %:getenv(VSB_DIR /share/h) \ - -idirafter =/system \ - -idirafter =/public \ - }}" +#define VXWORKS_ADDITIONAL_CPP_SPEC \ + "%{!nostdinc: \ + %{isystem*} \ + -idirafter =/../../h \ + -idirafter =/../../share/h \ + -idirafter =/system \ + -idirafter =/public \ + }" #else /* TARGET_VXWORKS7 */ diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index 309ebc8..925dc67 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -3170,6 +3170,9 @@ diagnose_trait_expr (location_t loc, tree expr, tree args) case CPTK_IS_FUNCTION: inform (loc, "%qT is not a function", t1); break; + case CPTK_IS_IMPLICIT_LIFETIME: + inform (decl_loc, "%qT is not an implicit-lifetime type", t1); + break; case CPTK_IS_INVOCABLE: { if (!TREE_VEC_LENGTH (t2)) diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def index 5e4493a..c820184 100644 --- a/gcc/cp/cp-trait.def +++ b/gcc/cp/cp-trait.def @@ -76,6 +76,7 @@ DEFTRAIT_EXPR (IS_EMPTY, "__is_empty", 1) DEFTRAIT_EXPR (IS_ENUM, "__is_enum", 1) DEFTRAIT_EXPR (IS_FINAL, "__is_final", 1) DEFTRAIT_EXPR (IS_FUNCTION, "__is_function", 1) +DEFTRAIT_EXPR (IS_IMPLICIT_LIFETIME, "__builtin_is_implicit_lifetime", 1) DEFTRAIT_EXPR (IS_INVOCABLE, "__is_invocable", -1) DEFTRAIT_EXPR (IS_LAYOUT_COMPATIBLE, "__is_layout_compatible", 2) DEFTRAIT_EXPR (IS_LITERAL_TYPE, "__is_literal_type", 1) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index fcba9f5..8c211ab 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -8376,6 +8376,7 @@ extern bool std_layout_type_p (const_tree); extern bool trivial_type_p (const_tree); extern bool trivially_relocatable_type_p (tree); extern bool replaceable_type_p (tree); +extern bool implicit_lifetime_type_p (tree); extern bool trivially_copyable_p (const_tree); extern bool type_has_unique_obj_representations (const_tree); extern bool scalarish_type_p (const_tree); diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 9280632..0917a16 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -51233,6 +51233,7 @@ cp_parser_omp_assumption_clauses (cp_parser *parser, cp_token *pragma_tok, directive[1], directive[2]); if (dir + && dir->id != PRAGMA_OMP_END && (dir->kind == C_OMP_DIR_DECLARATIVE || dir->kind == C_OMP_DIR_INFORMATIONAL || dir->kind == C_OMP_DIR_META)) @@ -51241,9 +51242,9 @@ cp_parser_omp_assumption_clauses (cp_parser *parser, cp_token *pragma_tok, "informational, and meta directives " "not permitted", p); else if (dir == NULL - || dir->id == PRAGMA_OMP_END - || (!dir->second && directive[1]) - || (!dir->third && directive[2])) + || dir->id == PRAGMA_OMP_END + || (!dir->second && directive[1]) + || (!dir->third && directive[2])) error_at (dloc, "unknown OpenMP directive name in " "%qs clause argument", p); else @@ -52739,6 +52740,18 @@ cp_parser_omp_metadirective (cp_parser *parser, cp_token *pragma_tok, } cp_parser_skip_to_pragma_eol (parser, pragma_tok); + /* If only one selector matches and it evaluates to 'omp nothing', no need to + proceed. */ + if (ctxs.length () == 1) + { + tree ctx = ctxs[0]; + if (ctx == NULL_TREE + || (omp_context_selector_matches (ctx, NULL_TREE, false) == 1 + && cp_parser_pragma_kind (&directive_tokens[0]) + == PRAGMA_OMP_NOTHING)) + return; + } + if (!default_seen) { /* Add a default clause that evaluates to 'omp nothing'. */ @@ -53851,6 +53864,14 @@ cp_parser_omp_error (cp_parser *parser, cp_token *pragma_tok, "may only be used in compound statements"); return true; } + if (parser->omp_for_parse_state + && parser->omp_for_parse_state->in_intervening_code) + { + error_at (loc, "%<#pragma omp error%> with %<at(execution)%> clause " + "may not be used in intervening code"); + parser->omp_for_parse_state->fail = true; + return true; + } tree fndecl = builtin_decl_explicit (severity_fatal ? BUILT_IN_GOMP_ERROR : BUILT_IN_GOMP_WARNING); @@ -54768,11 +54789,15 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context, bool *if_p) id = cp_parser_pragma_kind (pragma_tok); if (parser->omp_for_parse_state && parser->omp_for_parse_state->in_intervening_code - && id >= PRAGMA_OMP__START_ - && id <= PRAGMA_OMP__LAST_) - { - error_at (pragma_tok->location, - "intervening code must not contain OpenMP directives"); + && id >= PRAGMA_OMP__START_ && id <= PRAGMA_OMP__LAST_ + /* Allow a safe subset of non-executable directives. See classification in + array c_omp_directives. */ + && id != PRAGMA_OMP_METADIRECTIVE && id != PRAGMA_OMP_NOTHING + && id != PRAGMA_OMP_ASSUME && id != PRAGMA_OMP_ERROR) + { + error_at ( + pragma_tok->location, + "intervening code must not contain executable OpenMP directives"); parser->omp_for_parse_state->fail = true; cp_parser_skip_to_pragma_eol (parser, pragma_tok); return false; diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index c818b73..ad12155 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -13595,6 +13595,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2) case CPTK_IS_FUNCTION: return type_code1 == FUNCTION_TYPE; + case CPTK_IS_IMPLICIT_LIFETIME: + return implicit_lifetime_type_p (type1); + case CPTK_IS_INVOCABLE: return !error_operand_p (build_invoke (type1, type2, tf_none)); @@ -13914,6 +13917,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2) type to know whether an array is an aggregate, so use kind=4 here. */ case CPTK_IS_AGGREGATE: case CPTK_IS_FINAL: + case CPTK_IS_IMPLICIT_LIFETIME: if (!check_trait_type (type1, /* kind = */ 4)) return error_mark_node; break; diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc index 814465c..3edb74a 100644 --- a/gcc/cp/tree.cc +++ b/gcc/cp/tree.cc @@ -5097,6 +5097,42 @@ replaceable_type_p (tree t) return true; } +/* Returns 1 iff type T is an implicit-lifetime type, as defined in + [basic.types.general] and [class.prop]. */ + +bool +implicit_lifetime_type_p (tree t) +{ + if (SCALAR_TYPE_P (t) + || (TREE_CODE (t) == ARRAY_TYPE + && !(TYPE_SIZE (t) && integer_zerop (TYPE_SIZE (t)))) + /* GNU extension. */ + || TREE_CODE (t) == VECTOR_TYPE) + return true; + if (!CLASS_TYPE_P (t)) + return false; + t = TYPE_MAIN_VARIANT (t); + if (CP_AGGREGATE_TYPE_P (t) + && (!CLASSTYPE_DESTRUCTOR (t) + || !user_provided_p (CLASSTYPE_DESTRUCTOR (t)))) + return true; + if (is_trivially_xible (BIT_NOT_EXPR, t, NULL_TREE)) + { + if (is_trivially_xible (INIT_EXPR, t, make_tree_vec (0))) + return true; + tree arg = make_tree_vec (1); + tree ct + = cp_build_qualified_type (t, (cp_type_quals (t) | TYPE_QUAL_CONST)); + TREE_VEC_ELT (arg, 0) = cp_build_reference_type (ct, /*rval=*/false); + if (is_trivially_xible (INIT_EXPR, t, arg)) + return true; + TREE_VEC_ELT (arg, 0) = t; + if (is_trivially_xible (INIT_EXPR, t, arg)) + return true; + } + return false; +} + /* Returns 1 iff type T is a POD type, as defined in [basic.types]. */ bool diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index a14202f..19473df 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -3161,7 +3161,8 @@ enum gfc_exec_op EXEC_OACC_DATA, EXEC_OACC_HOST_DATA, EXEC_OACC_LOOP, EXEC_OACC_UPDATE, EXEC_OACC_WAIT, EXEC_OACC_CACHE, EXEC_OACC_ENTER_DATA, EXEC_OACC_EXIT_DATA, EXEC_OACC_ATOMIC, EXEC_OACC_DECLARE, - EXEC_OMP_CRITICAL, EXEC_OMP_DO, EXEC_OMP_FLUSH, EXEC_OMP_MASTER, + EXEC_OMP_CRITICAL, EXEC_OMP_FIRST_OPENMP_EXEC = EXEC_OMP_CRITICAL, + EXEC_OMP_DO, EXEC_OMP_FLUSH, EXEC_OMP_MASTER, EXEC_OMP_ORDERED, EXEC_OMP_PARALLEL, EXEC_OMP_PARALLEL_DO, EXEC_OMP_PARALLEL_SECTIONS, EXEC_OMP_PARALLEL_WORKSHARE, EXEC_OMP_SECTIONS, EXEC_OMP_SINGLE, EXEC_OMP_WORKSHARE, @@ -3192,7 +3193,8 @@ enum gfc_exec_op EXEC_OMP_PARALLEL_MASKED_TASKLOOP, EXEC_OMP_PARALLEL_MASKED_TASKLOOP_SIMD, EXEC_OMP_MASKED_TASKLOOP, EXEC_OMP_MASKED_TASKLOOP_SIMD, EXEC_OMP_SCOPE, EXEC_OMP_UNROLL, EXEC_OMP_TILE, EXEC_OMP_INTEROP, EXEC_OMP_METADIRECTIVE, - EXEC_OMP_ERROR, EXEC_OMP_ALLOCATE, EXEC_OMP_ALLOCATORS, EXEC_OMP_DISPATCH + EXEC_OMP_ERROR, EXEC_OMP_ALLOCATE, EXEC_OMP_ALLOCATORS, EXEC_OMP_DISPATCH, + EXEC_OMP_LAST_OPENMP_EXEC = EXEC_OMP_DISPATCH }; /* Enum Definition for locality types. */ diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc index 9e282c7..8cea724 100644 --- a/gcc/fortran/openmp.cc +++ b/gcc/fortran/openmp.cc @@ -59,6 +59,7 @@ struct gfc_omp_directive { and "nothing". */ static const struct gfc_omp_directive gfc_omp_directives[] = { + /* allocate as alias for allocators is also executive. */ {"allocate", GFC_OMP_DIR_DECLARATIVE, ST_OMP_ALLOCATE}, {"allocators", GFC_OMP_DIR_EXECUTABLE, ST_OMP_ALLOCATORS}, {"assumes", GFC_OMP_DIR_INFORMATIONAL, ST_OMP_ASSUMES}, @@ -68,6 +69,7 @@ static const struct gfc_omp_directive gfc_omp_directives[] = { {"cancellation point", GFC_OMP_DIR_EXECUTABLE, ST_OMP_CANCELLATION_POINT}, {"cancel", GFC_OMP_DIR_EXECUTABLE, ST_OMP_CANCEL}, {"critical", GFC_OMP_DIR_EXECUTABLE, ST_OMP_CRITICAL}, + /* {"declare induction", GFC_OMP_DIR_DECLARATIVE, ST_OMP_DECLARE_INDUCTION}, */ /* {"declare mapper", GFC_OMP_DIR_DECLARATIVE, ST_OMP_DECLARE_MAPPER}, */ {"declare reduction", GFC_OMP_DIR_DECLARATIVE, ST_OMP_DECLARE_REDUCTION}, {"declare simd", GFC_OMP_DIR_DECLARATIVE, ST_OMP_DECLARE_SIMD}, @@ -79,7 +81,10 @@ static const struct gfc_omp_directive gfc_omp_directives[] = { {"do", GFC_OMP_DIR_EXECUTABLE, ST_OMP_DO}, /* "error" becomes GFC_OMP_DIR_EXECUTABLE with at(execution) */ {"error", GFC_OMP_DIR_UTILITY, ST_OMP_ERROR}, + /* {"flatten", GFC_OMP_DIR_EXECUTABLE, ST_OMP_FLATTEN}, */ {"flush", GFC_OMP_DIR_EXECUTABLE, ST_OMP_FLUSH}, + /* {"fuse", GFC_OMP_DIR_EXECUTABLE, ST_OMP_FLUSE}, */ + /* {"interchange", GFC_OMP_DIR_EXECUTABLE, ST_OMP_INTERCHANGE}, */ {"interop", GFC_OMP_DIR_EXECUTABLE, ST_OMP_INTEROP}, {"loop", GFC_OMP_DIR_EXECUTABLE, ST_OMP_LOOP}, {"masked", GFC_OMP_DIR_EXECUTABLE, ST_OMP_MASKED}, @@ -98,11 +103,15 @@ static const struct gfc_omp_directive gfc_omp_directives[] = { {"section", GFC_OMP_DIR_SUBSIDIARY, ST_OMP_SECTION}, {"simd", GFC_OMP_DIR_EXECUTABLE, ST_OMP_SIMD}, {"single", GFC_OMP_DIR_EXECUTABLE, ST_OMP_SINGLE}, + /* {"split", GFC_OMP_DIR_EXECUTABLE, ST_OMP_SPLIT}, */ + /* {"strip", GFC_OMP_DIR_EXECUTABLE, ST_OMP_STRIP}, */ {"target data", GFC_OMP_DIR_EXECUTABLE, ST_OMP_TARGET_DATA}, {"target enter data", GFC_OMP_DIR_EXECUTABLE, ST_OMP_TARGET_ENTER_DATA}, {"target exit data", GFC_OMP_DIR_EXECUTABLE, ST_OMP_TARGET_EXIT_DATA}, {"target update", GFC_OMP_DIR_EXECUTABLE, ST_OMP_TARGET_UPDATE}, {"target", GFC_OMP_DIR_EXECUTABLE, ST_OMP_TARGET}, + /* {"taskgraph", GFC_OMP_DIR_EXECUTABLE, ST_OMP_TASKGRAPH}, */ + /* {"task iteration", GFC_OMP_DIR_EXECUTABLE, ST_OMP_TASK_ITERATION}, */ {"taskloop", GFC_OMP_DIR_EXECUTABLE, ST_OMP_TASKLOOP}, {"taskwait", GFC_OMP_DIR_EXECUTABLE, ST_OMP_TASKWAIT}, {"taskyield", GFC_OMP_DIR_EXECUTABLE, ST_OMP_TASKYIELD}, @@ -111,6 +120,7 @@ static const struct gfc_omp_directive gfc_omp_directives[] = { {"threadprivate", GFC_OMP_DIR_DECLARATIVE, ST_OMP_THREADPRIVATE}, {"tile", GFC_OMP_DIR_EXECUTABLE, ST_OMP_TILE}, {"unroll", GFC_OMP_DIR_EXECUTABLE, ST_OMP_UNROLL}, + /* {"workdistribute", GFC_OMP_DIR_EXECUTABLE, ST_OMP_WORKDISTRIBUTE}, */ {"workshare", GFC_OMP_DIR_EXECUTABLE, ST_OMP_WORKSHARE}, }; @@ -6306,9 +6316,8 @@ gfc_match_omp_interop (void) trait-score: score(score-expression) */ -match -gfc_match_omp_context_selector (gfc_omp_set_selector *oss, - bool metadirective_p) +static match +gfc_match_omp_context_selector (gfc_omp_set_selector *oss) { do { @@ -6372,22 +6381,8 @@ gfc_match_omp_context_selector (gfc_omp_set_selector *oss, gfc_error ("expected %<(%> at %C"); return MATCH_ERROR; } - if (gfc_match_expr (&os->score) != MATCH_YES - || !gfc_resolve_expr (os->score) - || os->score->ts.type != BT_INTEGER - || os->score->rank != 0) - { - gfc_error ("%<score%> argument must be constant integer " - "expression at %C"); - return MATCH_ERROR; - } - - if (os->score->expr_type == EXPR_CONSTANT - && mpz_sgn (os->score->value.integer) < 0) - { - gfc_error ("%<score%> argument must be non-negative at %C"); - return MATCH_ERROR; - } + if (gfc_match_expr (&os->score) != MATCH_YES) + return MATCH_ERROR; if (gfc_match (" )") != MATCH_YES) { @@ -6420,6 +6415,8 @@ gfc_match_omp_context_selector (gfc_omp_set_selector *oss, else { gfc_error ("expected identifier at %C"); + free (otp); + os->properties = nullptr; return MATCH_ERROR; } } @@ -6440,6 +6437,8 @@ gfc_match_omp_context_selector (gfc_omp_set_selector *oss, { gfc_error ("expected identifier or string literal " "at %C"); + free (otp); + os->properties = nullptr; return MATCH_ERROR; } @@ -6460,51 +6459,8 @@ gfc_match_omp_context_selector (gfc_omp_set_selector *oss, if (gfc_match_expr (&otp->expr) != MATCH_YES) { gfc_error ("expected expression at %C"); - return MATCH_ERROR; - } - if (!gfc_resolve_expr (otp->expr) - || (property_kind == OMP_TRAIT_PROPERTY_BOOL_EXPR - && otp->expr->ts.type != BT_LOGICAL) - || (property_kind == OMP_TRAIT_PROPERTY_DEV_NUM_EXPR - && otp->expr->ts.type != BT_INTEGER) - || otp->expr->rank != 0 - || (!metadirective_p - && otp->expr->expr_type != EXPR_CONSTANT)) - { - if (metadirective_p) - { - if (property_kind == OMP_TRAIT_PROPERTY_BOOL_EXPR) - gfc_error ("property must be a " - "logical expression at %L", - &otp->expr->where); - else - gfc_error ("property must be an " - "integer expression at %L", - &otp->expr->where); - } - else - { - if (property_kind == OMP_TRAIT_PROPERTY_BOOL_EXPR) - gfc_error ("property must be a constant " - "logical expression at %L", - &otp->expr->where); - else - gfc_error ("property must be a constant " - "integer expression at %L", - &otp->expr->where); - } - return MATCH_ERROR; - } - /* Device number must be conforming, which includes - omp_initial_device (-1) and omp_invalid_device (-4). */ - if (property_kind == OMP_TRAIT_PROPERTY_DEV_NUM_EXPR - && otp->expr->expr_type == EXPR_CONSTANT - && mpz_sgn (otp->expr->value.integer) < 0 - && mpz_cmp_si (otp->expr->value.integer, -1) != 0 - && mpz_cmp_si (otp->expr->value.integer, -4) != 0) - { - gfc_error ("property must be a conforming device number " - "at %C"); + free (otp); + os->properties = nullptr; return MATCH_ERROR; } break; @@ -6580,9 +6536,8 @@ gfc_match_omp_context_selector (gfc_omp_set_selector *oss, implementation user */ -match -gfc_match_omp_context_selector_specification (gfc_omp_set_selector **oss_head, - bool metadirective_p) +static match +gfc_match_omp_context_selector_specification (gfc_omp_set_selector **oss_head) { do { @@ -6619,7 +6574,7 @@ gfc_match_omp_context_selector_specification (gfc_omp_set_selector **oss_head, oss->code = set; *oss_head = oss; - if (gfc_match_omp_context_selector (oss, metadirective_p) != MATCH_YES) + if (gfc_match_omp_context_selector (oss) != MATCH_YES) return MATCH_ERROR; m = gfc_match (" }"); @@ -6750,8 +6705,7 @@ gfc_match_omp_declare_variant (void) return MATCH_ERROR; } has_match = true; - if (gfc_match_omp_context_selector_specification (&odv->set_selectors, - false) + if (gfc_match_omp_context_selector_specification (&odv->set_selectors) != MATCH_YES) return MATCH_ERROR; if (gfc_match (" )") != MATCH_YES) @@ -7042,7 +6996,7 @@ match_omp_metadirective (bool begin_p) if (!default_p) { - if (gfc_match_omp_context_selector_specification (&selectors, true) + if (gfc_match_omp_context_selector_specification (&selectors) != MATCH_YES) return MATCH_ERROR; @@ -11418,82 +11372,10 @@ icode_code_error_callback (gfc_code **codep, /* Errors have already been diagnosed in match_exit_cycle. */ state->errorp = true; break; - case EXEC_OMP_CRITICAL: - case EXEC_OMP_DO: - case EXEC_OMP_FLUSH: - case EXEC_OMP_MASTER: - case EXEC_OMP_ORDERED: - case EXEC_OMP_PARALLEL: - case EXEC_OMP_PARALLEL_DO: - case EXEC_OMP_PARALLEL_SECTIONS: - case EXEC_OMP_PARALLEL_WORKSHARE: - case EXEC_OMP_SECTIONS: - case EXEC_OMP_SINGLE: - case EXEC_OMP_WORKSHARE: - case EXEC_OMP_ATOMIC: - case EXEC_OMP_BARRIER: - case EXEC_OMP_END_NOWAIT: - case EXEC_OMP_END_SINGLE: - case EXEC_OMP_TASK: - case EXEC_OMP_TASKWAIT: - case EXEC_OMP_TASKYIELD: - case EXEC_OMP_CANCEL: - case EXEC_OMP_CANCELLATION_POINT: - case EXEC_OMP_TASKGROUP: - case EXEC_OMP_SIMD: - case EXEC_OMP_DO_SIMD: - case EXEC_OMP_PARALLEL_DO_SIMD: - case EXEC_OMP_TARGET: - case EXEC_OMP_TARGET_DATA: - case EXEC_OMP_TEAMS: - case EXEC_OMP_DISTRIBUTE: - case EXEC_OMP_DISTRIBUTE_SIMD: - case EXEC_OMP_DISTRIBUTE_PARALLEL_DO: - case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD: - case EXEC_OMP_TARGET_TEAMS: - case EXEC_OMP_TEAMS_DISTRIBUTE: - case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD: - case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE: - case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD: - case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO: - case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO: - case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD: - case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD: - case EXEC_OMP_TARGET_UPDATE: - case EXEC_OMP_END_CRITICAL: - case EXEC_OMP_TARGET_ENTER_DATA: - case EXEC_OMP_TARGET_EXIT_DATA: - case EXEC_OMP_TARGET_PARALLEL: - case EXEC_OMP_TARGET_PARALLEL_DO: - case EXEC_OMP_TARGET_PARALLEL_DO_SIMD: - case EXEC_OMP_TARGET_SIMD: - case EXEC_OMP_TASKLOOP: - case EXEC_OMP_TASKLOOP_SIMD: - case EXEC_OMP_SCAN: - case EXEC_OMP_DEPOBJ: - case EXEC_OMP_PARALLEL_MASTER: - case EXEC_OMP_PARALLEL_MASTER_TASKLOOP: - case EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD: - case EXEC_OMP_MASTER_TASKLOOP: - case EXEC_OMP_MASTER_TASKLOOP_SIMD: - case EXEC_OMP_LOOP: - case EXEC_OMP_PARALLEL_LOOP: - case EXEC_OMP_TEAMS_LOOP: - case EXEC_OMP_TARGET_PARALLEL_LOOP: - case EXEC_OMP_TARGET_TEAMS_LOOP: - case EXEC_OMP_MASKED: - case EXEC_OMP_PARALLEL_MASKED: - case EXEC_OMP_PARALLEL_MASKED_TASKLOOP: - case EXEC_OMP_PARALLEL_MASKED_TASKLOOP_SIMD: - case EXEC_OMP_MASKED_TASKLOOP: - case EXEC_OMP_MASKED_TASKLOOP_SIMD: - case EXEC_OMP_SCOPE: - case EXEC_OMP_ERROR: - case EXEC_OMP_DISPATCH: - gfc_error ("%s cannot contain OpenMP directive in intervening code " - "at %L", - state->name, &code->loc); - state->errorp = true; + case EXEC_OMP_ASSUME: + case EXEC_OMP_METADIRECTIVE: + /* Per OpenMP 6.0, some non-executable directives are allowed in + intervening code. */ break; case EXEC_CALL: /* Per OpenMP 5.2, the "omp_" prefix is reserved, so we don't have to @@ -11509,7 +11391,14 @@ icode_code_error_callback (gfc_code **codep, } break; default: - break; + if (code->op >= EXEC_OMP_FIRST_OPENMP_EXEC + && code->op <= EXEC_OMP_LAST_OPENMP_EXEC) + { + gfc_error ("%s cannot contain OpenMP directive in intervening code " + "at %L", + state->name, &code->loc); + state->errorp = true; + } } return 0; } @@ -12312,6 +12201,118 @@ resolve_omp_do (gfc_code *code) non_generated_count); } +/* Resolve the context selector. In particular, SKIP_P is set to true, + the context can never be matched. */ + +static void +gfc_resolve_omp_context_selector (gfc_omp_set_selector *oss, + bool is_metadirective, bool *skip_p) +{ + if (skip_p) + *skip_p = false; + for (gfc_omp_set_selector *set_selector = oss; set_selector; + set_selector = set_selector->next) + for (gfc_omp_selector *os = set_selector->trait_selectors; os; os = os->next) + { + if (os->score) + { + if (!gfc_resolve_expr (os->score) + || os->score->ts.type != BT_INTEGER + || os->score->rank != 0) + { + gfc_error ("%<score%> argument must be constant integer " + "expression at %L", &os->score->where); + gfc_free_expr (os->score); + os->score = nullptr; + } + else if (os->score->expr_type == EXPR_CONSTANT + && mpz_sgn (os->score->value.integer) < 0) + { + gfc_error ("%<score%> argument must be non-negative at %L", + &os->score->where); + gfc_free_expr (os->score); + os->score = nullptr; + } + } + + enum omp_tp_type property_kind = omp_ts_map[os->code].tp_type; + gfc_omp_trait_property *otp = os->properties; + + if (!otp) + continue; + switch (property_kind) + { + case OMP_TRAIT_PROPERTY_DEV_NUM_EXPR: + case OMP_TRAIT_PROPERTY_BOOL_EXPR: + if (!gfc_resolve_expr (otp->expr) + || (property_kind == OMP_TRAIT_PROPERTY_BOOL_EXPR + && otp->expr->ts.type != BT_LOGICAL) + || (property_kind == OMP_TRAIT_PROPERTY_DEV_NUM_EXPR + && otp->expr->ts.type != BT_INTEGER) + || otp->expr->rank != 0 + || (!is_metadirective && otp->expr->expr_type != EXPR_CONSTANT)) + { + if (is_metadirective) + { + if (property_kind == OMP_TRAIT_PROPERTY_BOOL_EXPR) + gfc_error ("property must be a " + "logical expression at %L", + &otp->expr->where); + else + gfc_error ("property must be an " + "integer expression at %L", + &otp->expr->where); + } + else + { + if (property_kind == OMP_TRAIT_PROPERTY_BOOL_EXPR) + gfc_error ("property must be a constant " + "logical expression at %L", + &otp->expr->where); + else + gfc_error ("property must be a constant " + "integer expression at %L", + &otp->expr->where); + } + /* Prevent later ICEs. */ + gfc_expr *e; + if (property_kind == OMP_TRAIT_PROPERTY_BOOL_EXPR) + e = gfc_get_logical_expr (gfc_default_logical_kind, + &otp->expr->where, true); + else + e = gfc_get_int_expr (gfc_default_integer_kind, + &otp->expr->where, 0); + gfc_free_expr (otp->expr); + otp->expr = e; + continue; + } + /* Device number must be conforming, which includes + omp_initial_device (-1) and omp_invalid_device (-4). */ + if (property_kind == OMP_TRAIT_PROPERTY_DEV_NUM_EXPR + && otp->expr->expr_type == EXPR_CONSTANT + && mpz_sgn (otp->expr->value.integer) < 0 + && mpz_cmp_si (otp->expr->value.integer, -1) != 0 + && mpz_cmp_si (otp->expr->value.integer, -4) != 0) + gfc_error ("property must be a conforming device number at %L", + &otp->expr->where); + break; + default: + break; + } + /* This only handles one specific case: User condition. + FIXME: Handle more cases by calling omp_context_selector_matches; + unfortunately, we cannot generate the tree here as, e.g., PARM_DECL + backend decl are not available at this stage - but might be used in, + e.g. user conditions. See PR122361. */ + if (skip_p && otp + && os->code == OMP_TRAIT_USER_CONDITION + && otp->expr->expr_type == EXPR_CONSTANT + && otp->expr->value.logical == false) + *skip_p = true; + } +} + + static void resolve_omp_metadirective (gfc_code *code, gfc_namespace *ns) { @@ -12319,9 +12320,38 @@ resolve_omp_metadirective (gfc_code *code, gfc_namespace *ns) while (variant) { + bool skip; + gfc_resolve_omp_context_selector (variant->selectors, true, &skip); gfc_code *variant_code = variant->code; gfc_resolve_code (variant_code, ns); - variant = variant->next; + if (skip) + { + /* The following should only be true if an error occurred + as the 'otherwise' clause should always match. */ + if (variant == code->ext.omp_variants && !variant->next) + break; + if (variant == code->ext.omp_variants) + code->ext.omp_variants = variant->next; + gfc_omp_variant *tmp = variant; + variant = variant->next; + gfc_free_omp_set_selector_list (tmp->selectors); + free (tmp); + } + else + variant = variant->next; + } + /* Replace metadirective by its body if only 'nothing' remains. */ + if (!code->ext.omp_variants->next && code->ext.omp_variants->stmt == ST_NONE) + { + gfc_code *next = code->next; + gfc_code *inner = code->ext.omp_variants->code; + gfc_free_omp_set_selector_list (code->ext.omp_variants->selectors); + free (code->ext.omp_variants); + *code = *inner; + free (inner); + while (code->next) + code = code->next; + code->next = next; } } @@ -13098,6 +13128,9 @@ gfc_resolve_omp_declare (gfc_namespace *ns) gfc_omp_declare_variant *odv; gfc_omp_namelist *range_begin = NULL; + + for (odv = ns->omp_declare_variant; odv; odv = odv->next) + gfc_resolve_omp_context_selector (odv->set_selectors, false, nullptr); for (odv = ns->omp_declare_variant; odv; odv = odv->next) for (gfc_omp_namelist *n = odv->adjust_args_list; n != NULL; n = n->next) { diff --git a/gcc/ipa-fnsummary.cc b/gcc/ipa-fnsummary.cc index e7b81d8..bf98a44 100644 --- a/gcc/ipa-fnsummary.cc +++ b/gcc/ipa-fnsummary.cc @@ -271,6 +271,8 @@ redirect_to_unreachable (struct cgraph_edge *e) es->call_stmt_time = 0; if (callee) callee->remove_symbol_and_inline_clones (); + if (e->has_callback) + e->purge_callback_edges (); return e; } @@ -3119,8 +3121,7 @@ analyze_function_body (struct cgraph_node *node, bool early) for (cbe = edge->first_callback_edge (); cbe; cbe = cbe->next_callback_edge ()) { - ipa_call_summary *es2 = ipa_call_summaries->get (cbe); - es2 = ipa_call_summaries->get_create (cbe); + ipa_call_summary *es2 = ipa_call_summaries->get_create (cbe); ipa_call_summaries->duplicate (edge, cbe, es, es2); /* Unlike speculative edges, callback edges have no real size or time; the call doesn't exist. Reflect that in diff --git a/gcc/jit/ChangeLog b/gcc/jit/ChangeLog index 1577ea0..2e2230c 100644 --- a/gcc/jit/ChangeLog +++ b/gcc/jit/ChangeLog @@ -1,3 +1,71 @@ +2025-10-20 Antoni Boucher <bouanto@zoho.com> + + * docs/topics/compatibility.rst (LIBGCCJIT_ABI_37): New ABI tag. + * docs/topics/types.rst: Document + gcc_jit_context_new_array_type_u64. + * jit-playback.cc (new_array_type): Change num_elements type to + uint64_t. + * jit-playback.h (new_array_type): Change num_elements type to + uint64_t. + * jit-recording.cc (recording::context::new_array_type): Change + num_elements type to uint64_t. + (recording::array_type::make_debug_string): Use uint64_t + format. + (recording::array_type::write_reproducer): Switch to + gcc_jit_context_new_array_type_u64. + * jit-recording.h (class array_type): Change num_elements type + to uint64_t. + (new_array_type): Change num_elements type to uint64_t. + (num_elements): Change return type to uint64_t. + * libgccjit.cc (gcc_jit_context_new_array_type_u64): + New function. + * libgccjit.h (gcc_jit_context_new_array_type_u64): + New function. + * libgccjit.exports: New function. + * libgccjit.map: New function. + +2025-10-20 Antoni Boucher <bouanto@zoho.com> + + * jit-playback.cc (add_error, add_error_va): Send DK_ERROR to + add_error_va. + (add_diagnostic): Call add_diagnostic instead of add_error. + * jit-recording.cc (DEFINE_DIAGNOSTIC_KIND): New define. + (recording::context::add_diagnostic): New function. + (recording::context::add_error): Send DK_ERROR to add_error_va. + (recording::context::add_error_va): New parameter diagnostic_kind. + * jit-recording.h (add_diagnostic): New function. + (add_error_va): New parameter diagnostic_kind. + * libgccjit.cc (jit_error): Send DK_ERROR to add_error_va. + +2025-10-20 Antoni Boucher <bouanto@zoho.com> + + PR jit/105827 + * dummy-frontend.cc: Fix lang_tree_node. + * jit-common.h: New function (jit_tree_chain_next) used by + lang_tree_node. + +2025-10-20 Antoni Boucher <bouanto@zoho.com> + + PR jit/117886 + * dummy-frontend.cc: Support some missing types. + * jit-playback.h (get_abort_on_unsupported_target_builtin): New + function. + * jit-recording.cc (get_abort_on_unsupported_target_builtin, + set_abort_on_unsupported_target_builtin): New functions. + * jit-recording.h (get_abort_on_unsupported_target_builtin, + set_abort_on_unsupported_target_builtin): New functions. + (m_abort_on_unsupported_target_builtin): New field. + * libgccjit.cc + (gcc_jit_context_set_abort_on_unsupported_target_builtin): New + function. + * libgccjit.h + (gcc_jit_context_set_abort_on_unsupported_target_builtin): New + function. + * libgccjit.exports (LIBGCCJIT_ABI_36): New ABI tag. + * libgccjit.map (LIBGCCJIT_ABI_36): New ABI tag. + * docs/topics/compatibility.rst (LIBGCCJIT_ABI_36): New ABI tag. + * docs/topics/contexts.rst: Document new function. + 2025-10-08 Antoni Boucher <bouanto@zoho.com> PR jit/112466 diff --git a/gcc/jit/docs/topics/compatibility.rst b/gcc/jit/docs/topics/compatibility.rst index 19be33e..1f8c4d9 100644 --- a/gcc/jit/docs/topics/compatibility.rst +++ b/gcc/jit/docs/topics/compatibility.rst @@ -466,3 +466,18 @@ information: * :func:`gcc_jit_target_info_cpu_supports` * :func:`gcc_jit_target_info_arch` * :func:`gcc_jit_target_info_supports_target_dependent_type` + +.. _LIBGCCJIT_ABI_36: + +``LIBGCCJIT_ABI_36`` +-------------------- +``LIBGCCJIT_ABI_36`` covers the addition of + + * :func:`gcc_jit_context_set_abort_on_unsupported_target_builtin` + +.. _LIBGCCJIT_ABI_37: + +``LIBGCCJIT_ABI_37`` +-------------------- +``LIBGCCJIT_ABI_37`` covers the addition of +:func:`gcc_jit_context_new_array_type_u64` diff --git a/gcc/jit/docs/topics/contexts.rst b/gcc/jit/docs/topics/contexts.rst index f821e9c..2229dc7 100644 --- a/gcc/jit/docs/topics/contexts.rst +++ b/gcc/jit/docs/topics/contexts.rst @@ -509,6 +509,22 @@ Boolean options #ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_bool_print_errors_to_stderr +.. function:: void \ + gcc_jit_context_set_abort_on_unsupported_target_builtin (gcc_jit_context *ctxt) + + By default, libgccjit will silently ignore when a target builtin has an + unsupported type. + + This entrypoint can be used to make it abort when the specified context + encounters such a target builtin. + + This entrypoint was added in :ref:`LIBGCCJIT_ABI_36`; you can test for + its presence using + + .. code-block:: c + + #ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_abort_on_unsupported_target_builtin + Integer options *************** diff --git a/gcc/jit/docs/topics/types.rst b/gcc/jit/docs/topics/types.rst index e699ee5..9283065 100644 --- a/gcc/jit/docs/topics/types.rst +++ b/gcc/jit/docs/topics/types.rst @@ -163,6 +163,24 @@ Pointers, `const`, and `volatile` Given non-`void` type "T", get type "T[N]" (for a constant N). .. function:: gcc_jit_type *\ + gcc_jit_context_new_array_type_u64 (gcc_jit_context *ctxt, \ + gcc_jit_location *loc, \ + gcc_jit_type *element_type, \ + uint64_t num_elements) + + Given non-`void` type "T", get type "T[N]" (for a constant N). + + This is the same as gcc_jit_context_new_array_type, but the type of + ``num_elements` different and thus allows creating bigger array types. + + This API entrypoint was added in :ref:`LIBGCCJIT_ABI_37`; you can test + for its presence using + + .. code-block:: c + + #ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_array_type_u64 + +.. function:: gcc_jit_type *\ gcc_jit_type_get_aligned (gcc_jit_type *type, \ size_t alignment_in_bytes) diff --git a/gcc/jit/dummy-frontend.cc b/gcc/jit/dummy-frontend.cc index 3ffca92..faf9d03 100644 --- a/gcc/jit/dummy-frontend.cc +++ b/gcc/jit/dummy-frontend.cc @@ -956,13 +956,15 @@ struct GTY(()) lang_identifier /* The resulting tree type. */ +/* See lang_tree_node in gcc/c/c-decl.cc. */ union GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"), - chain_next ("CODE_CONTAINS_STRUCT (TREE_CODE (&%h.generic), TS_COMMON) ? ((union lang_tree_node *) TREE_CHAIN (&%h.generic)) : NULL"))) -lang_tree_node -{ - union tree_node GTY((tag ("0"), - desc ("tree_node_structure (&%h)"))) generic; - struct lang_identifier GTY((tag ("1"))) identifier; + chain_next ("(union lang_tree_node *) jit_tree_chain_next (&%h.generic)"))) + lang_tree_node + { + union tree_node GTY ((tag ("0"), + desc ("tree_node_structure (&%h)"))) + generic; + struct lang_identifier GTY ((tag ("1"))) identifier; }; /* We don't use language_function. */ @@ -1170,6 +1172,9 @@ jit_langhook_type_for_mode (machine_mode mode, int unsignedp) recording::type* tree_type_to_jit_type (tree type) { + gcc_assert (gcc::jit::active_playback_ctxt); + gcc::jit::playback::context* ctxt = gcc::jit::active_playback_ctxt; + if (TREE_CODE (type) == VECTOR_TYPE) { tree inner_type = TREE_TYPE (type); @@ -1282,6 +1287,39 @@ recording::type* tree_type_to_jit_type (tree type) return nullptr; return element_type->get_pointer (); } + else if (type == unsigned_intTI_type_node) + return new recording::memento_of_get_type (&target_builtins_ctxt, + GCC_JIT_TYPE_UINT128_T); + else if (INTEGRAL_TYPE_P (type)) + { + unsigned int size = tree_to_uhwi (TYPE_SIZE_UNIT (type)); + return target_builtins_ctxt.get_int_type (size, TYPE_UNSIGNED (type)); + } + else if (SCALAR_FLOAT_TYPE_P (type)) + { + unsigned int size = tree_to_uhwi (TYPE_SIZE_UNIT (type)); + enum gcc_jit_types type; + switch (size) + { + case 2: + type = GCC_JIT_TYPE_BFLOAT16; + break; + case 4: + type = GCC_JIT_TYPE_FLOAT; + break; + case 8: + type = GCC_JIT_TYPE_DOUBLE; + break; + default: + if (ctxt->get_abort_on_unsupported_target_builtin ()) + { + fprintf (stderr, "Unexpected float size: %d\n", size); + abort (); + } + return NULL; + } + return new recording::memento_of_get_type (&target_builtins_ctxt, type); + } else { // Attempt to find an unqualified type when the current type has qualifiers. @@ -1301,6 +1339,13 @@ recording::type* tree_type_to_jit_type (tree type) } } } + + if (ctxt->get_abort_on_unsupported_target_builtin ()) + { + fprintf (stderr, "Unknown type:\n"); + debug_tree (type); + abort (); + } } return NULL; diff --git a/gcc/jit/jit-common.h b/gcc/jit/jit-common.h index 845726b..8c07f55 100644 --- a/gcc/jit/jit-common.h +++ b/gcc/jit/jit-common.h @@ -93,6 +93,21 @@ const int NUM_GCC_JIT_TYPES = GCC_JIT_TYPE_BFLOAT16 + 1; End of comment for inclusion in the docs. */ +/* See c_tree_chain_next in gcc/c-family/c-common.h. */ +static inline tree +jit_tree_chain_next (tree t) +{ + /* TREE_CHAIN of a type is TYPE_STUB_DECL, which is different + kind of object, never a long chain of nodes. Prefer + TYPE_NEXT_VARIANT for types. */ + if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_TYPE_COMMON)) + return TYPE_NEXT_VARIANT (t); + /* Otherwise, if there is TREE_CHAIN, return it. */ + if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_COMMON)) + return TREE_CHAIN (t); + return NULL; +} + namespace gcc { namespace jit { diff --git a/gcc/jit/jit-playback.cc b/gcc/jit/jit-playback.cc index 291ddeb..d5145d0 100644 --- a/gcc/jit/jit-playback.cc +++ b/gcc/jit/jit-playback.cc @@ -344,7 +344,7 @@ playback::type * playback::context:: new_array_type (playback::location *loc, playback::type *element_type, - int num_elements) + uint64_t num_elements) { gcc_assert (element_type); @@ -3871,7 +3871,7 @@ add_error (location *loc, const char *fmt, ...) va_list ap; va_start (ap, fmt); m_recording_ctxt->add_error_va (loc ? loc->get_recording_loc () : NULL, - fmt, ap); + diagnostics::kind::error, fmt, ap); va_end (ap); } @@ -3883,13 +3883,12 @@ playback::context:: add_error_va (location *loc, const char *fmt, va_list ap) { m_recording_ctxt->add_error_va (loc ? loc->get_recording_loc () : NULL, - fmt, ap); + diagnostics::kind::error, fmt, ap); } -/* Report a diagnostic up to the jit context as an error, - so that the compilation is treated as a failure. - For now, any kind of diagnostic is treated as an error by the jit - API. */ +/* Report a diagnostic up to the jit context, so that the + compilation is treated as a failure if the diagnostic + is an error. */ void playback::context:: @@ -3914,7 +3913,7 @@ add_diagnostic (const char *text, false); } - m_recording_ctxt->add_error (rec_loc, "%s", text); + m_recording_ctxt->add_diagnostic (rec_loc, diagnostic.m_kind, "%s", text); } /* Dealing with the linemap API. */ diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h index 07dab6f..f2ff4f7 100644 --- a/gcc/jit/jit-playback.h +++ b/gcc/jit/jit-playback.h @@ -88,7 +88,7 @@ public: type * new_array_type (location *loc, type *element_type, - int num_elements); + uint64_t num_elements); field * new_field (location *loc, @@ -340,6 +340,11 @@ public: return info; } + bool get_abort_on_unsupported_target_builtin () const + { + return m_recording_ctxt->get_abort_on_unsupported_target_builtin (); + } + private: void dump_generated_code (); diff --git a/gcc/jit/jit-recording.cc b/gcc/jit/jit-recording.cc index 2f4ecc3..754ccb2 100644 --- a/gcc/jit/jit-recording.cc +++ b/gcc/jit/jit-recording.cc @@ -847,7 +847,7 @@ recording::context::get_int_type (int num_bytes, int is_signed) recording::type * recording::context::new_array_type (recording::location *loc, recording::type *element_type, - int num_elements) + uint64_t num_elements) { if (struct_ *s = element_type->dyn_cast_struct ()) if (!s->get_fields ()) @@ -1498,6 +1498,18 @@ recording::context::set_output_ident (const char *ident) record (memento); } +bool +recording::context::get_abort_on_unsupported_target_builtin () +{ + return m_abort_on_unsupported_target_builtin; +} + +void +recording::context::set_abort_on_unsupported_target_builtin () +{ + m_abort_on_unsupported_target_builtin = true; +} + /* Set the given integer option for this context, or add an error if it's not recognized. @@ -1717,11 +1729,21 @@ recording::context::populate_target_info () it to stderr, and add it to the context. */ void +recording::context::add_diagnostic (location *loc, + diagnostics::kind diagnostic_kind, const char *fmt, ...) +{ + va_list ap; + va_start (ap, fmt); + add_error_va (loc, diagnostic_kind, fmt, ap); + va_end (ap); +} + +void recording::context::add_error (location *loc, const char *fmt, ...) { va_list ap; va_start (ap, fmt); - add_error_va (loc, fmt, ap); + add_error_va (loc, diagnostics::kind::error, fmt, ap); va_end (ap); } @@ -1729,7 +1751,8 @@ recording::context::add_error (location *loc, const char *fmt, ...) it to stderr, and add it to the context. */ void -recording::context::add_error_va (location *loc, const char *fmt, va_list ap) +recording::context::add_error_va (location *loc, + diagnostics::kind diagnostic_kind, const char *fmt, va_list ap) { int len; char *malloced_msg; @@ -1750,7 +1773,9 @@ recording::context::add_error_va (location *loc, const char *fmt, va_list ap) has_ownership = true; } if (get_logger ()) - get_logger ()->log ("error %i: %s", m_error_count, errmsg); + get_logger ()->log ("%s %i: %s", + diagnostics::get_text_for_kind (diagnostic_kind), + m_error_count, errmsg); const char *ctxt_progname = get_str_option (GCC_JIT_STR_OPTION_PROGNAME); @@ -1762,13 +1787,15 @@ recording::context::add_error_va (location *loc, const char *fmt, va_list ap) if (print_errors_to_stderr) { if (loc) - fprintf (stderr, "%s: %s: error: %s\n", + fprintf (stderr, "%s: %s: %s: %s\n", ctxt_progname, loc->get_debug_string (), + diagnostics::get_text_for_kind (diagnostic_kind), errmsg); else - fprintf (stderr, "%s: error: %s\n", + fprintf (stderr, "%s: %s: %s\n", ctxt_progname, + diagnostics::get_text_for_kind (diagnostic_kind), errmsg); } @@ -1784,7 +1811,8 @@ recording::context::add_error_va (location *loc, const char *fmt, va_list ap) m_last_error_str = const_cast <char *> (errmsg); m_owns_last_error_str = has_ownership; - m_error_count++; + if (diagnostic_kind == diagnostics::kind::error) + m_error_count++; } /* Get the message for the first error that occurred on this context, or @@ -3363,7 +3391,7 @@ recording::string * recording::array_type::make_debug_string () { return string::from_printf (m_ctxt, - "%s[%d]", + "%s[%ld]", m_element_type->get_debug_string (), m_num_elements); } @@ -3376,10 +3404,10 @@ recording::array_type::write_reproducer (reproducer &r) { const char *id = r.make_identifier (this, "array_type"); r.write (" gcc_jit_type *%s =\n" - " gcc_jit_context_new_array_type (%s,\n" - " %s, /* gcc_jit_location *loc */\n" - " %s, /* gcc_jit_type *element_type */\n" - " %i); /* int num_elements */\n", + " gcc_jit_context_new_array_type_u64 (%s,\n" + " %s, /* gcc_jit_location *loc */\n" + " %s, /* gcc_jit_type *element_type */\n" + " %li); /* int num_elements */\n", id, r.get_identifier (get_context ()), r.get_identifier (m_loc), diff --git a/gcc/jit/jit-recording.h b/gcc/jit/jit-recording.h index 4d41faa..08de684 100644 --- a/gcc/jit/jit-recording.h +++ b/gcc/jit/jit-recording.h @@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. If not see #include "jit-common.h" #include "jit-logging.h" #include "jit-target.h" +#include "diagnostic-core.h" #include "libgccjit.h" #include <string> @@ -105,7 +106,7 @@ public: type * new_array_type (location *loc, type *element_type, - int num_elements); + uint64_t num_elements); field * new_field (location *loc, @@ -270,6 +271,12 @@ public: void set_output_ident (const char *output_ident); + bool + get_abort_on_unsupported_target_builtin (); + + void + set_abort_on_unsupported_target_builtin (); + void set_int_option (enum gcc_jit_int_option opt, int value); @@ -340,12 +347,19 @@ public: } void + add_diagnostic (location *loc, enum diagnostics::kind diagnostic_kind, + const char *fmt, ...) + GNU_PRINTF (4, 5); + + void add_error (location *loc, const char *fmt, ...) GNU_PRINTF(3, 4); void - add_error_va (location *loc, const char *fmt, va_list ap) - GNU_PRINTF(3, 0); + add_error_va (location *loc, enum diagnostics::kind diagnostic_kind, + const char *fmt, + va_list ap) + GNU_PRINTF (4, 0); const char * get_first_error () const; @@ -424,6 +438,7 @@ private: type *m_FILE_type; bool m_populated_target_info = false; + bool m_abort_on_unsupported_target_builtin = false; builtins_manager *m_builtins_manager; // lazily created @@ -1030,7 +1045,7 @@ class array_type : public type array_type (context *ctxt, location *loc, type *element_type, - int num_elements) + uint64_t num_elements) : type (ctxt), m_loc (loc), m_element_type (element_type), @@ -1063,7 +1078,7 @@ class array_type : public type bool is_bool () const final override { return false; } type *is_pointer () final override { return NULL; } type *is_array () final override { return m_element_type; } - int num_elements () { return m_num_elements; } + uint64_t num_elements () { return m_num_elements; } bool is_signed () const final override { return false; } void replay_into (replayer *) final override; @@ -1075,7 +1090,7 @@ class array_type : public type private: location *m_loc; type *m_element_type; - int m_num_elements; + uint64_t m_num_elements; }; class function_type : public type diff --git a/gcc/jit/libgccjit.cc b/gcc/jit/libgccjit.cc index 3336944..3fc96fb 100644 --- a/gcc/jit/libgccjit.cc +++ b/gcc/jit/libgccjit.cc @@ -342,7 +342,7 @@ jit_error (gcc::jit::recording::context *ctxt, va_start (ap, fmt); if (ctxt) - ctxt->add_error_va (loc, fmt, ap); + ctxt->add_error_va (loc, diagnostics::kind::error, fmt, ap); else { /* No context? Send to stderr. */ @@ -784,11 +784,21 @@ gcc_jit_context_new_array_type (gcc_jit_context *ctxt, gcc_jit_type *element_type, int num_elements) { + RETURN_NULL_IF_FAIL (num_elements >= 0, ctxt, NULL, "negative size"); + return gcc_jit_context_new_array_type_u64 (ctxt, loc, element_type, + (uint64_t) num_elements); +} + +gcc_jit_type * +gcc_jit_context_new_array_type_u64 (gcc_jit_context *ctxt, + gcc_jit_location *loc, + gcc_jit_type *element_type, + uint64_t num_elements) +{ RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context"); JIT_LOG_FUNC (ctxt->get_logger ()); /* LOC can be NULL. */ RETURN_NULL_IF_FAIL (element_type, ctxt, loc, "NULL type"); - RETURN_NULL_IF_FAIL (num_elements >= 0, ctxt, NULL, "negative size"); RETURN_NULL_IF_FAIL (!element_type->is_void (), ctxt, loc, "void type for elements"); @@ -3951,6 +3961,14 @@ gcc_jit_target_info_supports_target_dependent_type (gcc_jit_target_info *info, != info->m_supported_target_dependent_types.end (); } +void +gcc_jit_context_set_abort_on_unsupported_target_builtin (gcc_jit_context *ctxt) +{ + RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context"); + + ctxt->set_abort_on_unsupported_target_builtin (); +} + /* Public entrypoint. See description in libgccjit.h. After error-checking, the real work is done by the diff --git a/gcc/jit/libgccjit.exports b/gcc/jit/libgccjit.exports index 26dc634..17864c7 100644 --- a/gcc/jit/libgccjit.exports +++ b/gcc/jit/libgccjit.exports @@ -239,16 +239,28 @@ _gcc_jit_global_set_readonly # LIBGCCJIT_ABI_30 _gcc_jit_context_convert_vector -# LIBGCCJIT_ABI_31 +# LIBGCCJIT_ABI_31 _gcc_jit_context_new_vector_access _gcc_jit_context_new_rvalue_vector_perm -# LIBGCCJIT_ABI_32 +# LIBGCCJIT_ABI_32 _gcc_jit_context_get_target_builtin_function -# LIBGCCJIT_ABI_33 +# LIBGCCJIT_ABI_33 _gcc_jit_function_new_temp -# LIBGCCJIT_ABI_34 +# LIBGCCJIT_ABI_34 _gcc_jit_context_set_output_ident +# LIBGCCJIT_ABI_35 +_gcc_jit_context_get_target_info +_gcc_jit_target_info_release +_gcc_jit_target_info_cpu_supports +_gcc_jit_target_info_arch +_gcc_jit_target_info_supports_target_dependent_type + +# LIBGCCJIT_ABI_36 +_gcc_jit_context_set_abort_on_unsupported_target_builtin + +# LIBGCCJIT_ABI_37 +_gcc_jit_context_new_array_type_u64 diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h index a585510..f71ed63 100644 --- a/gcc/jit/libgccjit.h +++ b/gcc/jit/libgccjit.h @@ -20,6 +20,7 @@ along with GCC; see the file COPYING3. If not see #ifndef LIBGCCJIT_H #define LIBGCCJIT_H +#include <stdint.h> #include <stdio.h> #ifdef __has_include #if __has_include (<sys/types.h>) @@ -676,6 +677,20 @@ gcc_jit_context_new_array_type (gcc_jit_context *ctxt, gcc_jit_type *element_type, int num_elements); +/* Given type "T", get type "T[N]" (for a constant N). + + This API entrypoint was added in LIBGCCJIT_ABI_37; you can test for its + presence using + #ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_array_type_u64 +*/ +extern gcc_jit_type * +gcc_jit_context_new_array_type_u64 (gcc_jit_context *ctxt, + gcc_jit_location *loc, + gcc_jit_type *element_type, + uint64_t num_elements); + +#define LIBGCCJIT_HAVE_gcc_jit_context_new_array_type_u64 + /* Struct-handling. */ /* Create a field, for use within a struct or union. */ @@ -2216,6 +2231,11 @@ gcc_jit_context_set_output_ident (gcc_jit_context *ctxt, #define LIBGCCJIT_HAVE_gcc_jit_context_set_output_ident +extern void +gcc_jit_context_set_abort_on_unsupported_target_builtin (gcc_jit_context *ctxt); + +#define LIBGCCJIT_HAVE_gcc_jit_context_set_abort_on_unsupported_target_builtin + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/gcc/jit/libgccjit.map b/gcc/jit/libgccjit.map index 4662ca4..4d767f4 100644 --- a/gcc/jit/libgccjit.map +++ b/gcc/jit/libgccjit.map @@ -334,3 +334,13 @@ LIBGCCJIT_ABI_35 { gcc_jit_target_info_arch; gcc_jit_target_info_supports_target_dependent_type; } LIBGCCJIT_ABI_34; + +LIBGCCJIT_ABI_36 { + global: + gcc_jit_context_set_abort_on_unsupported_target_builtin; +} LIBGCCJIT_ABI_35; + +LIBGCCJIT_ABI_37 { + global: + gcc_jit_context_new_array_type_u64; +} LIBGCCJIT_ABI_36; diff --git a/gcc/match.pd b/gcc/match.pd index bfc51e6..a4248a5 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -6571,6 +6571,23 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) tree from_type = TREE_TYPE (@1); tree c1_type = TREE_TYPE (@3), c2_type = TREE_TYPE (@2); enum tree_code code = ERROR_MARK; + enum tree_code ncmp = cmp; + tree c1 = @3; + + /* `((signed)a) < 0` should be converted back into + `a >= (unsigned)SIGNED_TYPE_MIN`. + `((signed)a) >= 0` should be converted back into + `a < (unsigned)SIGNED_TYPE_MIN`. */ + if (integer_zerop (c1) + && (cmp == GE_EXPR || cmp == LT_EXPR) + && TYPE_UNSIGNED (from_type) + && !TYPE_UNSIGNED (c1_type) + && TYPE_PRECISION (from_type) == TYPE_PRECISION (c1_type)) + { + ncmp = cmp == GE_EXPR ? LT_EXPR : GE_EXPR; + c1 = fold_convert (from_type, TYPE_MIN_VALUE (c1_type)); + c1_type = from_type; + } if (INTEGRAL_TYPE_P (from_type) && int_fits_type_p (@2, from_type) @@ -6583,8 +6600,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) && (TYPE_UNSIGNED (from_type) || TYPE_SIGN (c2_type) == TYPE_SIGN (from_type))))) { - if (cmp != EQ_EXPR) - code = minmax_from_comparison (cmp, @1, @3, @1, @2); + if (ncmp != EQ_EXPR) + code = minmax_from_comparison (ncmp, @1, c1, @1, @2); /* Can do A == C1 ? A : C2 -> A == C1 ? C1 : C2? */ else if (int_fits_type_p (@3, from_type)) code = EQ_EXPR; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 58055c5..a2ec661 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,85 @@ +2025-10-20 Jeff Law <jlaw@ventanamicro.com> + + * gcc.target/riscv/rvv/autovec/reduc/reduc-8.c: Adjust expected output. + +2025-10-20 Antoni Boucher <bouanto@zoho.com> + + * jit.dg/all-non-failing-tests.h: Add test-arrays-u64.c. + * jit.dg/test-arrays-u64.c: New test. + +2025-10-20 Josef Melcr <jmelcr02@gmail.com> + + * gcc.dg/ipa/ipcp-cb-spec1.c: Moved to libgomp/testsuite/libgomp.c/. + * gcc.dg/ipa/ipcp-cb-spec2.c: Likewise. + * gcc.dg/ipa/ipcp-cb1.c: Likewise. + +2025-10-20 Antoni Boucher <bouanto@zoho.com> + + * jit.dg/test-error-array-bounds.c: Fix test. + +2025-10-20 Thomas Schwinge <tschwinge@baylibre.com> + + PR c++/114457 + * c-c++-common/goacc/kernels-decompose-pr100280-1.c: Skip for + c++26 until PR121975 is fixed. + +2025-10-20 Eric Botcazou <ebotcazou@adacore.com> + + * gnat.dg/component_value1.adb: New test. + +2025-10-20 Eric Botcazou <ebotcazou@adacore.com> + + * gnat.dg/use_type3.adb: New test. + +2025-10-20 Srinath Parvathaneni <srinath.parvathaneni@arm.com> + + * gcc.target/aarch64/acle/asm-inlined-sysreg-1.c: New test. + * gcc.target/aarch64/acle/asm-inlined-sysreg-2.c: Likewise. + * gcc.target/aarch64/acle/rwsr-gated-1.c: Likewise. + * gcc.target/aarch64/acle/rwsr-gated-2.c: Likewise. + * lib/target-supports.exp + (check_effective_target_aarch64_sysreg_guarding_ok): Check + assembler support of -menable-sysreg-checking flag. + +2025-10-20 Jeff Law <jlaw@ventanamicro.com> + + * gcc.target/riscv/rvv/vsetvl/imm_switch-6.c: Skip scan-asm test for -O1 too. + * gcc.target/riscv/rvv/vsetvl/imm_switch-7.c: Likewise. + * gcc.target/riscv/shrink-wrap-1.c: Likewise. Skip for -Og as well. + * gcc.target/riscv/xandes/xandesperf-1.c: Adjust expected output. + +2025-10-20 Eric Botcazou <ebotcazou@adacore.com> + + * gnat.dg/renaming18.adb: New test. + +2025-10-20 Richard Biener <rguenther@suse.de> + + PR tree-optimization/101639 + PR tree-optimization/103495 + * gcc.dg/vect/vect-reduc-bool-1.c: New testcase. + * gcc.dg/vect/vect-reduc-bool-2.c: Likewise. + * gcc.dg/vect/vect-reduc-bool-3.c: Likewise. + * gcc.dg/vect/vect-reduc-bool-4.c: Likewise. + * gcc.dg/vect/vect-reduc-bool-5.c: Likewise. + * gcc.dg/vect/vect-reduc-bool-6.c: Likewise. + * gcc.dg/vect/vect-reduc-bool-7.c: Likewise. + * gcc.dg/vect/vect-reduc-bool-8.c: Likewise. + +2025-10-20 H.J. Lu <hjl.tools@gmail.com> + + PR target/99930 + PR target/122323 + * gcc.target/i386/builtin-copysign-2.c: New test. + * gcc.target/i386/builtin-copysign-3.c: Likewise. + * gcc.target/i386/builtin-copysign-4.c: Likewise. + * gcc.target/i386/builtin-copysign-5.c: Likewise. + * gcc.target/i386/builtin-copysign-6.c: Likewise. + * gcc.target/i386/builtin-copysign-7.c: Likewise. + * gcc.target/i386/builtin-copysign-8a.c: Likewise. + * gcc.target/i386/builtin-copysign-8b.c: Likewise. + * gcc.target/i386/builtin-fabs-1.c: Likewise. + * gcc.target/i386/builtin-fabs-2.c: Likewise. + 2025-10-19 Georg-Johann Lay <avr@gjlay.de> PR testsuite/122212 diff --git a/gcc/testsuite/c-c++-common/gomp/assume-2.c b/gcc/testsuite/c-c++-common/gomp/assume-2.c index 95a65fd..2cc066f 100644 --- a/gcc/testsuite/c-c++-common/gomp/assume-2.c +++ b/gcc/testsuite/c-c++-common/gomp/assume-2.c @@ -31,12 +31,14 @@ foo (int i, int *a) ; #pragma omp assume contains (begin assumes) /* { dg-error "invalid OpenMP directive name in 'contains' clause argument" } */ ; - #pragma omp assume contains (end assumes) /* { dg-error "invalid OpenMP directive name in 'contains' clause argument" } */ + #pragma omp assume contains (end assumes) /* { dg-error "unknown OpenMP directive name in 'contains' clause argument" } */ ; #pragma omp assume contains (foo) /* { dg-error "unknown OpenMP directive name in 'contains' clause argument" } */ ; #pragma omp assume absent (target enter something) /* { dg-error "unknown OpenMP directive name in 'absent' clause argument" } */ ; + #pragma omp assume contains (declare mapper) /* { dg-error "invalid OpenMP directive name in 'contains' clause argument: declarative, informational, and meta directives not permitted" } */ + ; #pragma omp assume foobar /* { dg-error "expected assumption clause" } */ ; #pragma omp assume ext_GCC_foobarbaz, ext_GCC_baz (1, 12, 1 < 17), no_parallelism /* { dg-warning "unknown assumption clause 'ext_GCC_foobarbaz'" } */ diff --git a/gcc/testsuite/c-c++-common/gomp/assumes-2.c b/gcc/testsuite/c-c++-common/gomp/assumes-2.c index 68b88be..ee03b09 100644 --- a/gcc/testsuite/c-c++-common/gomp/assumes-2.c +++ b/gcc/testsuite/c-c++-common/gomp/assumes-2.c @@ -13,7 +13,7 @@ #pragma omp assumes absent (assume) /* { dg-error "invalid OpenMP directive name in 'absent' clause argument" } */ #pragma omp assumes absent (assumes) /* { dg-error "invalid OpenMP directive name in 'absent' clause argument" } */ #pragma omp assumes contains (begin assumes) /* { dg-error "invalid OpenMP directive name in 'contains' clause argument" } */ -#pragma omp assumes contains (end assumes) /* { dg-error "invalid OpenMP directive name in 'contains' clause argument" } */ +#pragma omp assumes contains (end assumes) /* { dg-error "unknown OpenMP directive name in 'contains' clause argument" } */ #pragma omp assumes contains (foo) /* { dg-error "unknown OpenMP directive name in 'contains' clause argument" } */ #pragma omp assumes absent (target enter something) /* { dg-error "unknown OpenMP directive name in 'absent' clause argument" } */ #pragma omp assumes foobar /* { dg-error "expected assumption clause" } */ diff --git a/gcc/testsuite/c-c++-common/gomp/begin-assumes-2.c b/gcc/testsuite/c-c++-common/gomp/begin-assumes-2.c index 66b9180..189026d 100644 --- a/gcc/testsuite/c-c++-common/gomp/begin-assumes-2.c +++ b/gcc/testsuite/c-c++-common/gomp/begin-assumes-2.c @@ -43,7 +43,7 @@ void f14 (void) {} #pragma omp begin assumes contains (begin assumes) /* { dg-error "invalid OpenMP directive name in 'contains' clause argument" } */ void f15 (void) {} #pragma omp end assumes -#pragma omp begin assumes contains (end assumes) /* { dg-error "invalid OpenMP directive name in 'contains' clause argument" } */ +#pragma omp begin assumes contains (end assumes) /* { dg-error "unknown OpenMP directive name in 'contains' clause argument" } */ void f16 (void) {} #pragma omp end assumes #pragma omp begin assumes contains (foo) /* { dg-error "unknown OpenMP directive name in 'contains' clause argument" } */ diff --git a/gcc/testsuite/c-c++-common/gomp/imperfect1.c b/gcc/testsuite/c-c++-common/gomp/imperfect1.c index 705626a..bef783b 100644 --- a/gcc/testsuite/c-c++-common/gomp/imperfect1.c +++ b/gcc/testsuite/c-c++-common/gomp/imperfect1.c @@ -15,7 +15,7 @@ void s1 (int a1, int a2, int a3) f1 (0, i); for (j = 0; j < a2; j++) { -#pragma omp barrier /* { dg-error "intervening code must not contain OpenMP directives" } */ +#pragma omp barrier /* { dg-error "intervening code must not contain executable OpenMP directives" } */ f1 (1, j); if (i == 2) continue; /* { dg-error "invalid exit" } */ diff --git a/gcc/testsuite/c-c++-common/gomp/imperfect4.c b/gcc/testsuite/c-c++-common/gomp/imperfect4.c index 1a0c07c..30d1cc6 100644 --- a/gcc/testsuite/c-c++-common/gomp/imperfect4.c +++ b/gcc/testsuite/c-c++-common/gomp/imperfect4.c @@ -21,7 +21,7 @@ void s1 (int a1, int a2, int a3) /* According to the grammar, this is intervening code; we don't know that we are also missing a nested for loop until we have parsed this whole compound expression. */ -#pragma omp barrier /* { dg-error "intervening code must not contain OpenMP directives" } */ +#pragma omp barrier /* { dg-error "intervening code must not contain executable OpenMP directives" } */ f1 (2, k); f2 (2, k); } diff --git a/gcc/testsuite/c-c++-common/gomp/pr120180.c b/gcc/testsuite/c-c++-common/gomp/pr120180-1.c index cb5a0d5..52b5082 100644 --- a/gcc/testsuite/c-c++-common/gomp/pr120180.c +++ b/gcc/testsuite/c-c++-common/gomp/pr120180-1.c @@ -1,7 +1,7 @@ /* { dg-do compile } */ -/* This test used to ICE after erroring on the metadirective in the - loop nest. */ +/* This test case checks that the inner metadirective is accepted as intervening + code since it resolves to 'omp nothing'. */ int main() { @@ -14,7 +14,7 @@ int main() when(user={condition(1)}: target teams loop collapse(2) map(qq[:0]) private(i)) for(k=0; k<blksize; k++) { -#pragma omp metadirective when(user={condition(0)}: simd) default() // { dg-error "intervening code must not contain OpenMP directives" } +#pragma omp metadirective when(user={condition(0)}: simd) default() for (i=0; i<nq; i++) qq[k*nq + i] = 0.0; } diff --git a/gcc/testsuite/c-c++-common/gomp/pr120180-2.c b/gcc/testsuite/c-c++-common/gomp/pr120180-2.c new file mode 100644 index 0000000..9d9ef30 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/pr120180-2.c @@ -0,0 +1,66 @@ +/* { dg-do compile } */ + +/* This test case checks that a non-executable OpenMP directive is accepted + as intervening code. */ + +int +test1 () +{ + int blksize = 15000; + double *qq; + int i, k, nq; +#pragma omp target parallel for collapse(2) map(qq[ : 0]) private(i) + for (k = 0; k < blksize; k++) + { +#pragma omp nothing + for (i = 0; i < nq; i++) + qq[k * nq + i] = 0.0; + } + return 0; +} + +int +test2 () +{ + int i, k, m, n; + double *qq, x, z; +#pragma omp for collapse(2) + for (i = 1; i < n; i++) + { +#pragma omp assume holds(x > 1) + z = __builtin_fabs (x - i); + for (k = 0; k < m; k++) + qq[k * m + i] = z; + } + return 0; +} + +int +test3 () +{ + int i, k, m, n; + double *qq, z; +#pragma omp for collapse(2) + for (i = 1; i < n; i++) + { +#pragma omp error at(compilation) /* { dg-error "'pragma omp error' encountered" } */ + for (k = 0; k < m; k++) + qq[k * m + i] = z; + } + return 0; +} + +int +test4 () +{ + int i, k, m, n; + double *qq, z; +#pragma omp for collapse(2) + for (i = 1; i < n; i++) + { +#pragma omp error at(execution) /* { dg-error "pragma omp error' with 'at\\(execution\\)' clause may not be used in intervening code" } */ + for (k = 0; k < m; k++) + qq[k * m + i] = z; + } + return 0; +} diff --git a/gcc/testsuite/g++.dg/ext/is_implicit_lifetime.C b/gcc/testsuite/g++.dg/ext/is_implicit_lifetime.C new file mode 100644 index 0000000..22c600d --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/is_implicit_lifetime.C @@ -0,0 +1,139 @@ +// { dg-do compile { target c++11 } } +// { dg-options "" } +// { dg-add-options float16 } +// { dg-add-options float32 } +// { dg-add-options float64 } +// { dg-add-options float128 } + +struct A { int a, b, c; }; +class B { static int a; private: static int b; public: int c; }; +struct C { C () {} int a, b, c; }; +struct D { explicit D (int) {} int a, b, c; }; +struct E : public A { int d, e, f; }; +struct F : public C { using C::C; int d, e, f; }; +class G { int a, b; }; +struct H { private: int a, b; }; +struct I { protected: int a, b; }; +struct J { int a, b; void foo (); }; +struct K { int a, b; virtual void foo (); }; +struct L : virtual public A { int d, e; }; +struct M : protected A { int d, e; }; +struct N : private A { int d, e; }; +struct O { O () = delete; int a, b, c; }; +struct P { P () = default; int a, b, c; }; +struct Q { Q (); Q (const Q &); int a, b, c; }; +struct R { R (); R (const R &); R (R &&) = default; int a, b, c; }; +struct S { S (); ~S (); int a, b, c; }; +struct T { T (); ~T () = default; int a, b, c; }; +struct U { U (); U (const U &) = default; int a, b, c; }; +struct V { V () = default; V (const V &); int a, b, c; }; +enum W { W1 }; +enum class X : int { X1 }; +struct Y { int g; int foo (int); }; +struct Z; +struct AA { Q a; Q b; }; +struct AB { Q a; Q b; ~AB () = default; }; +struct AC { Q a; Q b; ~AC () {} }; +struct AD : public Q {}; +struct AE : public Q { ~AE () = default; }; +struct AF : public Q { ~AF () {} }; + +#define SA(X) static_assert ((X), #X) + +SA (!__builtin_is_implicit_lifetime (void)); +SA (!__builtin_is_implicit_lifetime (const void)); +SA (!__builtin_is_implicit_lifetime (volatile void)); +SA (__builtin_is_implicit_lifetime (char)); +SA (__builtin_is_implicit_lifetime (signed char)); +SA (__builtin_is_implicit_lifetime (const unsigned char)); +SA (__builtin_is_implicit_lifetime (short)); +SA (__builtin_is_implicit_lifetime (volatile unsigned short)); +SA (__builtin_is_implicit_lifetime (int)); +SA (__builtin_is_implicit_lifetime (unsigned int)); +SA (__builtin_is_implicit_lifetime (const volatile long)); +SA (__builtin_is_implicit_lifetime (unsigned long)); +SA (__builtin_is_implicit_lifetime (long long)); +SA (__builtin_is_implicit_lifetime (unsigned long long)); +#ifdef __SIZEOF_INT128__ +SA (__builtin_is_implicit_lifetime (__int128)); +SA (__builtin_is_implicit_lifetime (unsigned __int128)); +#endif +SA (__builtin_is_implicit_lifetime (float)); +SA (__builtin_is_implicit_lifetime (double)); +SA (__builtin_is_implicit_lifetime (long double volatile)); +#ifdef __STDCPP_FLOAT16_T__ +SA (__builtin_is_implicit_lifetime (_Float16)); +#endif +#ifdef __STDCPP_FLOAT32_T__ +SA (__builtin_is_implicit_lifetime (_Float32)); +#endif +#ifdef __STDCPP_FLOAT64_T__ +SA (__builtin_is_implicit_lifetime (const _Float64)); +#endif +#ifdef __STDCPP_FLOAT128_T__ +SA (__builtin_is_implicit_lifetime (_Float128)); +#endif +#ifdef __STDCPP_BFLOAT16_T__ +SA (__builtin_is_implicit_lifetime (decltype(0.bf16))); +#endif +SA (__builtin_is_implicit_lifetime (W)); +SA (__builtin_is_implicit_lifetime (const volatile X)); +SA (__builtin_is_implicit_lifetime (int *)); +SA (__builtin_is_implicit_lifetime (int (*) (int))); +SA (__builtin_is_implicit_lifetime (int (Y::*))); +SA (__builtin_is_implicit_lifetime (int (Y::*) (int))); +SA (!__builtin_is_implicit_lifetime (int &)); +SA (!__builtin_is_implicit_lifetime (char &&)); +SA (__builtin_is_implicit_lifetime (int [])); +SA (!__builtin_is_implicit_lifetime (int [0])); +SA (__builtin_is_implicit_lifetime (int [1])); +SA (__builtin_is_implicit_lifetime (const Y [42])); +SA (!__builtin_is_implicit_lifetime (int ())); +SA (!__builtin_is_implicit_lifetime (int () &)); +SA (!__builtin_is_implicit_lifetime (int () const)); +SA (!__builtin_is_implicit_lifetime (int (&) ())); +SA (!__builtin_is_implicit_lifetime (Z)); // { dg-error "invalid use of incomplete type 'struct Z'" } +SA (__builtin_is_implicit_lifetime (Z [])); +SA (__builtin_is_implicit_lifetime (Z [5])); +SA (__builtin_is_implicit_lifetime (A)); +SA (__builtin_is_implicit_lifetime (B)); +SA (__builtin_is_implicit_lifetime (C)); +SA (__builtin_is_implicit_lifetime (D)); +SA (__builtin_is_implicit_lifetime (E)); +SA (__builtin_is_implicit_lifetime (F)); +SA (__builtin_is_implicit_lifetime (G)); +SA (__builtin_is_implicit_lifetime (H)); +SA (__builtin_is_implicit_lifetime (I)); +SA (__builtin_is_implicit_lifetime (J)); +SA (!__builtin_is_implicit_lifetime (K)); +SA (!__builtin_is_implicit_lifetime (L)); +SA (__builtin_is_implicit_lifetime (M)); +SA (__builtin_is_implicit_lifetime (N)); +SA (__builtin_is_implicit_lifetime (O)); +SA (__builtin_is_implicit_lifetime (P)); +SA (!__builtin_is_implicit_lifetime (Q)); +SA (__builtin_is_implicit_lifetime (R)); +SA (!__builtin_is_implicit_lifetime (S)); +SA (__builtin_is_implicit_lifetime (S [3])); +SA (__builtin_is_implicit_lifetime (T)); +SA (__builtin_is_implicit_lifetime (U)); +SA (__builtin_is_implicit_lifetime (V)); +SA (__builtin_is_implicit_lifetime (_Complex double)); +SA (__builtin_is_implicit_lifetime (int [[gnu::vector_size (4 * sizeof (int))]])); +SA (__builtin_is_implicit_lifetime (AA)); +SA (__builtin_is_implicit_lifetime (AB)); +SA (!__builtin_is_implicit_lifetime (AC)); +#if __cplusplus >= 201703L +SA (__builtin_is_implicit_lifetime (AD)); +SA (__builtin_is_implicit_lifetime (AE)); +#else +SA (!__builtin_is_implicit_lifetime (AD)); +SA (!__builtin_is_implicit_lifetime (AE)); +#endif +SA (!__builtin_is_implicit_lifetime (AF)); + +void +foo (int n) +{ + SA (__builtin_is_implicit_lifetime (char [n])); +} diff --git a/gcc/testsuite/g++.dg/gomp/attrs-imperfect1.C b/gcc/testsuite/g++.dg/gomp/attrs-imperfect1.C index cf293b5..b43139c 100644 --- a/gcc/testsuite/g++.dg/gomp/attrs-imperfect1.C +++ b/gcc/testsuite/g++.dg/gomp/attrs-imperfect1.C @@ -15,7 +15,7 @@ void s1 (int a1, int a2, int a3) f1 (0, i); for (j = 0; j < a2; j++) { - [[ omp :: directive (barrier) ]] ; /* { dg-error "intervening code must not contain OpenMP directives" } */ + [[ omp :: directive (barrier) ]] ; /* { dg-error "intervening code must not contain executable OpenMP directives" } */ f1 (1, j); if (i == 2) continue; /* { dg-error "invalid exit" } */ diff --git a/gcc/testsuite/g++.dg/gomp/attrs-imperfect4.C b/gcc/testsuite/g++.dg/gomp/attrs-imperfect4.C index 16636ab..94b4db8 100644 --- a/gcc/testsuite/g++.dg/gomp/attrs-imperfect4.C +++ b/gcc/testsuite/g++.dg/gomp/attrs-imperfect4.C @@ -21,7 +21,7 @@ void s1 (int a1, int a2, int a3) /* According to the grammar, this is intervening code; we don't know that we are also missing a nested for loop until we have parsed this whole compound expression. */ - [[ omp :: directive (barrier) ]] ; /* { dg-error "intervening code must not contain OpenMP directives" } */ + [[ omp :: directive (barrier) ]] ; /* { dg-error "intervening code must not contain executable OpenMP directives" } */ f1 (2, k); f2 (2, k); } diff --git a/gcc/testsuite/g++.dg/gomp/pr120180-1.C b/gcc/testsuite/g++.dg/gomp/pr120180-1.C new file mode 100644 index 0000000..819b3ee --- /dev/null +++ b/gcc/testsuite/g++.dg/gomp/pr120180-1.C @@ -0,0 +1,26 @@ +// { dg-do compile } +// { dg-additional-options "-std=c++11" } + +// This test case checks that the inner metadirective is accepted as intervening +// code since it resolves to 'omp nothing'. + +int main() +{ + constexpr int use_teams = 1; + constexpr int use_simd = 0; + + int blksize = 15000; + double *qq; + int i, k, nq; + + #pragma omp metadirective when(user={condition(use_teams)}: teams distribute parallel for collapse(2)) \ + otherwise(parallel for collapse(1)) + for(k=0; k<blksize; k++) + { + #pragma omp metadirective when(user={condition(use_simd)}: simd) \ + otherwise(nothing) + for (i=0; i<nq; i++) + qq[k*nq + i] = 0.0; + } + return 0; +} diff --git a/gcc/testsuite/gcc.dg/c2y-generic-6.c b/gcc/testsuite/gcc.dg/c2y-generic-6.c new file mode 100644 index 0000000..7220d94 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c2y-generic-6.c @@ -0,0 +1,11 @@ +/* { dg-do "compile" } */ +/* { dg-options "-std=c2y -Wpedantic" } */ + +void f() +{ + _Generic(1, int[*]: 1, default: 0); + _Generic(1, int(*)[*]: 1, default: 0); + _Generic(1, int[sizeof(int[*])]: 1, default: 0); /* { dg-warning "not in a declaration" } */ + _Generic(1, struct { int a[*]; }: 1, default: 0); /* { dg-warning "variably modified" } */ +} + diff --git a/gcc/testsuite/gcc.dg/c2y-generic-7.c b/gcc/testsuite/gcc.dg/c2y-generic-7.c new file mode 100644 index 0000000..6ca046c --- /dev/null +++ b/gcc/testsuite/gcc.dg/c2y-generic-7.c @@ -0,0 +1,15 @@ +/* { dg-do "run" } */ +/* { dg-options "-std=c2y" } */ + +int main() +{ + int n = 1; + int a[1]; + _Generic(typeof(a), int[n++]: 0); + float b[1]; + _Generic(typeof(b), int[n++]: 0, default: 1); + if (n != 1) + __builtin_abort(); + return 0; +} + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr101024-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr101024-1.c new file mode 100644 index 0000000..14379bf --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr101024-1.c @@ -0,0 +1,39 @@ +/* PR tree-optimization/95699 */ +/* PR tree-optimization/101024 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized -fdump-tree-phiopt1" } */ +unsigned long long +f2 (unsigned long long x) +{ + if (x < 0x8000000000000000ULL) + x = 0x8000000000000000ULL; + else + { + if (x >= 0x8000000000000023ULL) + x = 0x8000000000000023ULL; + } + return x; +} +unsigned long long +f1 (unsigned long long x) +{ + if (x >= 100) + { + if (x >= 0x8000000000000000ULL) + x = 0x8000000000000000ULL; + } + else + x = 100; + return x; +} +/* f2: */ +/* { dg-final { scan-tree-dump "MIN_EXPR <\[^>\n\r]*9223372036854775843>" "optimized" } } */ +/* { dg-final { scan-tree-dump "MAX_EXPR <\[^>\n\r]*9223372036854775808>" "optimized" } } */ +/* { dg-final { scan-tree-dump "MIN_EXPR <\[^>\n\r]*9223372036854775843>" "phiopt1" } } */ +/* { dg-final { scan-tree-dump "MAX_EXPR <\[^>\n\r]*9223372036854775808>" "phiopt1" } } */ + +/* f1: */ +/* { dg-final { scan-tree-dump "MIN_EXPR <\[^>\n\r]*9223372036854775808>" "optimized" } } */ +/* { dg-final { scan-tree-dump "MAX_EXPR <\[^>\n\r]*100>" "optimized" } } */ +/* { dg-final { scan-tree-dump "MIN_EXPR <\[^>\n\r]*9223372036854775808>" "phiopt1" } } */ +/* { dg-final { scan-tree-dump "MAX_EXPR <\[^>\n\r]*100>" "phiopt1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr110068-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr110068-1.c new file mode 100644 index 0000000..df88553 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr110068-1.c @@ -0,0 +1,22 @@ +/* PR tree-optimization/95699 */ +/* PR tree-optimization/110068 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized -fdump-tree-phiopt1" } */ +/* { dg-final { scan-tree-dump-times "MIN_EXPR " 2 "phiopt1" } } */ + +#define min1(x,y) ((x) < (y) ? (x) : (y)) +unsigned +f1 (unsigned x) +{ + return min1(x, 1U<<(sizeof(x)*8-1)); +} +unsigned +f5 (unsigned x) +{ + bool t = x >= 1U<<(sizeof(x)*8-1); + if (!t) + ; + else + x = 1U<<(sizeof(x)*8-1); + return x; +} diff --git a/gcc/testsuite/gcc.dg/vect/pr104116-ceil-div-2.c b/gcc/testsuite/gcc.dg/vect/pr104116-ceil-div-2.c index 7078776..cc0cb45 100644 --- a/gcc/testsuite/gcc.dg/vect/pr104116-ceil-div-2.c +++ b/gcc/testsuite/gcc.dg/vect/pr104116-ceil-div-2.c @@ -16,6 +16,7 @@ int main (void) int *a = (int*)&arr; init_arr(a, N); div(a); + #pragma GCC novector for (int i=0; i<N; i++) { int expected = cl_div (i - N/2, 2); diff --git a/gcc/testsuite/gcc.dg/vect/pr104116-ceil-div-pow2.c b/gcc/testsuite/gcc.dg/vect/pr104116-ceil-div-pow2.c index 7aa9ae8..8abd353 100644 --- a/gcc/testsuite/gcc.dg/vect/pr104116-ceil-div-pow2.c +++ b/gcc/testsuite/gcc.dg/vect/pr104116-ceil-div-pow2.c @@ -17,6 +17,7 @@ int main (void) int *a = (int*)&arr; init_arr(a, N); div(a); + #pragma GCC novector for (int i=0; i<N; i++) { int expected = cl_div (i - N/2, 8); diff --git a/gcc/testsuite/gcc.dg/vect/pr104116-ceil-div.c b/gcc/testsuite/gcc.dg/vect/pr104116-ceil-div.c index 6f903ff..e4a8d30 100644 --- a/gcc/testsuite/gcc.dg/vect/pr104116-ceil-div.c +++ b/gcc/testsuite/gcc.dg/vect/pr104116-ceil-div.c @@ -17,6 +17,7 @@ int main (void) int *a = (int*)&arr; init_arr(a, N); div(a); + #pragma GCC novector for (int i=0; i<N; i++) { int expected = cl_div (i - N/2, 19); diff --git a/gcc/testsuite/gcc.dg/vect/pr104116-ceil-mod-2.c b/gcc/testsuite/gcc.dg/vect/pr104116-ceil-mod-2.c index ee6dfb9..6e559ab 100644 --- a/gcc/testsuite/gcc.dg/vect/pr104116-ceil-mod-2.c +++ b/gcc/testsuite/gcc.dg/vect/pr104116-ceil-mod-2.c @@ -17,6 +17,7 @@ int main (void) int *a = (int*)&arr; init_arr(a, N); div(a); + #pragma GCC novector for (int i=0; i<N; i++) { int expected = cl_mod (i - N/2, 2); diff --git a/gcc/testsuite/gcc.dg/vect/pr104116-ceil-mod-pow2.c b/gcc/testsuite/gcc.dg/vect/pr104116-ceil-mod-pow2.c index de409ea..9fdbf27 100644 --- a/gcc/testsuite/gcc.dg/vect/pr104116-ceil-mod-pow2.c +++ b/gcc/testsuite/gcc.dg/vect/pr104116-ceil-mod-pow2.c @@ -17,6 +17,7 @@ int main (void) unsigned int *a = (unsigned int*)&arr; init_arr(a, N); div(a); + #pragma GCC novector for (int i=0; i<N; i++) { unsigned int expected = cl_mod (i - N/2, 8); diff --git a/gcc/testsuite/gcc.dg/vect/pr104116-ceil-mod.c b/gcc/testsuite/gcc.dg/vect/pr104116-ceil-mod.c index f2ba936..3f85218 100644 --- a/gcc/testsuite/gcc.dg/vect/pr104116-ceil-mod.c +++ b/gcc/testsuite/gcc.dg/vect/pr104116-ceil-mod.c @@ -17,6 +17,7 @@ int main (void) int *a = (int*)&arr; init_arr(a, N); div(a); + #pragma GCC novector for (int i=0; i<N; i++) { int expected = cl_mod (i - N/2, 19); diff --git a/gcc/testsuite/gcc.dg/vect/pr104116-ceil-udiv-2.c b/gcc/testsuite/gcc.dg/vect/pr104116-ceil-udiv-2.c index db1f797..d8365c0 100644 --- a/gcc/testsuite/gcc.dg/vect/pr104116-ceil-udiv-2.c +++ b/gcc/testsuite/gcc.dg/vect/pr104116-ceil-udiv-2.c @@ -16,6 +16,7 @@ int main (void) unsigned int *ua = (unsigned int*)↑ init_uarr(ua, N); udiv(ua); + #pragma GCC novector for (int i=0; i<N; i++) { unsigned int expected = cl_udiv (0xf0000000 + i, 2); diff --git a/gcc/testsuite/gcc.dg/vect/pr104116-ceil-udiv-pow2.c b/gcc/testsuite/gcc.dg/vect/pr104116-ceil-udiv-pow2.c index 06b4257..389b6c3 100644 --- a/gcc/testsuite/gcc.dg/vect/pr104116-ceil-udiv-pow2.c +++ b/gcc/testsuite/gcc.dg/vect/pr104116-ceil-udiv-pow2.c @@ -16,6 +16,7 @@ int main (void) unsigned int *ua = (unsigned int*)↑ init_uarr(ua, N); udiv(ua); + #pragma GCC novector for (int i=0; i<N; i++) { unsigned int expected = cl_udiv (0xf0000000 + i, 8); diff --git a/gcc/testsuite/gcc.dg/vect/pr104116-ceil-udiv.c b/gcc/testsuite/gcc.dg/vect/pr104116-ceil-udiv.c index ef6e856..54aa4fb 100644 --- a/gcc/testsuite/gcc.dg/vect/pr104116-ceil-udiv.c +++ b/gcc/testsuite/gcc.dg/vect/pr104116-ceil-udiv.c @@ -16,6 +16,7 @@ int main (void) unsigned int *ua = (unsigned int*)↑ init_uarr(ua, N); udiv(ua); + #pragma GCC novector for (int i=0; i<N; i++) { unsigned int expected = cl_udiv (0xf0000000 + i, 19); diff --git a/gcc/testsuite/gcc.dg/vect/pr104116-ceil-umod-2.c b/gcc/testsuite/gcc.dg/vect/pr104116-ceil-umod-2.c index 2d0a5db..190b805 100644 --- a/gcc/testsuite/gcc.dg/vect/pr104116-ceil-umod-2.c +++ b/gcc/testsuite/gcc.dg/vect/pr104116-ceil-umod-2.c @@ -17,6 +17,7 @@ int main (void) unsigned int *a = (unsigned int*)↑ init_uarr(a, N); mod(a); + #pragma GCC novector for (int i=0; i<N; i++) { unsigned int expected = cl_umod (0xf0000000 + i, 2); diff --git a/gcc/testsuite/gcc.dg/vect/pr104116-ceil-umod-pow2.c b/gcc/testsuite/gcc.dg/vect/pr104116-ceil-umod-pow2.c index 2d0a5db..190b805 100644 --- a/gcc/testsuite/gcc.dg/vect/pr104116-ceil-umod-pow2.c +++ b/gcc/testsuite/gcc.dg/vect/pr104116-ceil-umod-pow2.c @@ -17,6 +17,7 @@ int main (void) unsigned int *a = (unsigned int*)↑ init_uarr(a, N); mod(a); + #pragma GCC novector for (int i=0; i<N; i++) { unsigned int expected = cl_umod (0xf0000000 + i, 2); diff --git a/gcc/testsuite/gcc.dg/vect/pr104116-ceil-umod.c b/gcc/testsuite/gcc.dg/vect/pr104116-ceil-umod.c index 949a509..632fd46 100644 --- a/gcc/testsuite/gcc.dg/vect/pr104116-ceil-umod.c +++ b/gcc/testsuite/gcc.dg/vect/pr104116-ceil-umod.c @@ -17,6 +17,7 @@ int main (void) unsigned int *a = (unsigned int*)↑ init_uarr(a, N); mod(a); + #pragma GCC novector for (int i=0; i<N; i++) { unsigned int expected = cl_umod (0xf0000000 + i, 19); diff --git a/gcc/testsuite/gcc.dg/vect/pr104116-floor-div-2.c b/gcc/testsuite/gcc.dg/vect/pr104116-floor-div-2.c index d93e051..b9db0d2 100644 --- a/gcc/testsuite/gcc.dg/vect/pr104116-floor-div-2.c +++ b/gcc/testsuite/gcc.dg/vect/pr104116-floor-div-2.c @@ -16,6 +16,7 @@ int main (void) int * a = (int*)&arr; init_arr(a, N); div_2(a); + #pragma GCC novector for (int i=0; i<N; i++) { int expected = fl_div (i - N/2, 2); diff --git a/gcc/testsuite/gcc.dg/vect/pr104116-floor-div-pow2.c b/gcc/testsuite/gcc.dg/vect/pr104116-floor-div-pow2.c index 9e986a7..5000c29 100644 --- a/gcc/testsuite/gcc.dg/vect/pr104116-floor-div-pow2.c +++ b/gcc/testsuite/gcc.dg/vect/pr104116-floor-div-pow2.c @@ -16,6 +16,7 @@ int main (void) int * a = (int*)&arr; init_arr(a, N); div_2(a); + #pragma GCC novector for (int i=0; i<N; i++) { int expected = fl_div (i - N/2, 8); diff --git a/gcc/testsuite/gcc.dg/vect/pr104116-floor-div.c b/gcc/testsuite/gcc.dg/vect/pr104116-floor-div.c index 89dd270..ed34249 100644 --- a/gcc/testsuite/gcc.dg/vect/pr104116-floor-div.c +++ b/gcc/testsuite/gcc.dg/vect/pr104116-floor-div.c @@ -16,6 +16,7 @@ int main (void) int * a = (int*)&arr; init_arr(a, N); div_2(a); + #pragma GCC novector for (int i=0; i<N; i++) { int expected = fl_div (i - N/2, 19); diff --git a/gcc/testsuite/gcc.dg/vect/pr104116-floor-mod-2.c b/gcc/testsuite/gcc.dg/vect/pr104116-floor-mod-2.c index 0c5c162..62995bb 100644 --- a/gcc/testsuite/gcc.dg/vect/pr104116-floor-mod-2.c +++ b/gcc/testsuite/gcc.dg/vect/pr104116-floor-mod-2.c @@ -16,6 +16,7 @@ int main (void) int * a = (int*)&arr; init_arr(a, N); mod(a); + #pragma GCC novector for (int i=0; i<N; i++) { int expected = fl_mod (i - N/2, 2); diff --git a/gcc/testsuite/gcc.dg/vect/pr104116-floor-mod-pow2.c b/gcc/testsuite/gcc.dg/vect/pr104116-floor-mod-pow2.c index f3de145..b92243d 100644 --- a/gcc/testsuite/gcc.dg/vect/pr104116-floor-mod-pow2.c +++ b/gcc/testsuite/gcc.dg/vect/pr104116-floor-mod-pow2.c @@ -16,6 +16,7 @@ int main (void) int * a = (int*)&arr; init_arr(a, N); mod(a); + #pragma GCC novector for (int i=0; i<N; i++) { int expected = fl_mod (i - N/2, 8); diff --git a/gcc/testsuite/gcc.dg/vect/pr104116-floor-mod.c b/gcc/testsuite/gcc.dg/vect/pr104116-floor-mod.c index 3e6bbe9..63843b9 100644 --- a/gcc/testsuite/gcc.dg/vect/pr104116-floor-mod.c +++ b/gcc/testsuite/gcc.dg/vect/pr104116-floor-mod.c @@ -16,6 +16,7 @@ int main (void) int * a = (int*)&arr; init_arr(a, N); mod(a); + #pragma GCC novector for (int i=0; i<N; i++) { int expected = fl_mod (i - N/2, 19); diff --git a/gcc/testsuite/gcc.dg/vect/pr104116-round-div-2.c b/gcc/testsuite/gcc.dg/vect/pr104116-round-div-2.c index c242ccb..c72866a 100644 --- a/gcc/testsuite/gcc.dg/vect/pr104116-round-div-2.c +++ b/gcc/testsuite/gcc.dg/vect/pr104116-round-div-2.c @@ -16,6 +16,7 @@ int main (void) int * a = (int*)&arr; init_arr(a, N); div(a); + #pragma GCC novector for (int i=0; i<N; i++) { int expected = rd_div (i - N/2, 2); diff --git a/gcc/testsuite/gcc.dg/vect/pr104116-round-div-pow2.c b/gcc/testsuite/gcc.dg/vect/pr104116-round-div-pow2.c index 365c2c59..9e3e1ed 100644 --- a/gcc/testsuite/gcc.dg/vect/pr104116-round-div-pow2.c +++ b/gcc/testsuite/gcc.dg/vect/pr104116-round-div-pow2.c @@ -16,6 +16,7 @@ int main (void) int * a = (int*)&arr; init_arr(a, N); div(a); + #pragma GCC novector for (int i=0; i<N; i++) { int expected = rd_div (i - N/2, 8); diff --git a/gcc/testsuite/gcc.dg/vect/pr104116-round-div.c b/gcc/testsuite/gcc.dg/vect/pr104116-round-div.c index 5c377d1..5dd0f37 100644 --- a/gcc/testsuite/gcc.dg/vect/pr104116-round-div.c +++ b/gcc/testsuite/gcc.dg/vect/pr104116-round-div.c @@ -16,6 +16,7 @@ int main (void) int * a = (int*)&arr; init_arr(a, N); div(a); + #pragma GCC novector for (int i=0; i<N; i++) { int expected = rd_div (i - N/2, 19); diff --git a/gcc/testsuite/gcc.dg/vect/pr104116-round-mod-2.c b/gcc/testsuite/gcc.dg/vect/pr104116-round-mod-2.c index 6430b3e..fe8f8bb 100644 --- a/gcc/testsuite/gcc.dg/vect/pr104116-round-mod-2.c +++ b/gcc/testsuite/gcc.dg/vect/pr104116-round-mod-2.c @@ -16,6 +16,7 @@ int main (void) int * a = (int*)&arr; init_arr(a, N); mod(a); + #pragma GCC novector for (int i=0; i<N; i++) { int expected = rd_mod (i - N/2, 2); diff --git a/gcc/testsuite/gcc.dg/vect/pr104116-round-mod-pow2.c b/gcc/testsuite/gcc.dg/vect/pr104116-round-mod-pow2.c index 46c1789..cd3bbda 100644 --- a/gcc/testsuite/gcc.dg/vect/pr104116-round-mod-pow2.c +++ b/gcc/testsuite/gcc.dg/vect/pr104116-round-mod-pow2.c @@ -16,6 +16,7 @@ int main (void) int * a = (int*)&arr; init_arr(a, N); mod(a); + #pragma GCC novector for (int i=0; i<N; i++) { int expected = rd_mod (i - N/2, 8); diff --git a/gcc/testsuite/gcc.dg/vect/pr104116-round-mod.c b/gcc/testsuite/gcc.dg/vect/pr104116-round-mod.c index e7ca44e..e617623 100644 --- a/gcc/testsuite/gcc.dg/vect/pr104116-round-mod.c +++ b/gcc/testsuite/gcc.dg/vect/pr104116-round-mod.c @@ -16,6 +16,7 @@ int main (void) int * a = (int*)&arr; init_arr(a, N); mod(a); + #pragma GCC novector for (int i=0; i<N; i++) { int expected = rd_mod (i - N/2, 19); diff --git a/gcc/testsuite/gcc.dg/vect/pr104116-round-udiv-2.c b/gcc/testsuite/gcc.dg/vect/pr104116-round-udiv-2.c index 4d42f4e..de5e0a4 100644 --- a/gcc/testsuite/gcc.dg/vect/pr104116-round-udiv-2.c +++ b/gcc/testsuite/gcc.dg/vect/pr104116-round-udiv-2.c @@ -16,6 +16,7 @@ int main (void) unsigned int * a = (unsigned int*)↑ init_uarr(a, N); div(a); + #pragma GCC novector for (unsigned int i=0; i<N; i++) { unsigned int expected = rd_udiv (0xf0000000 + i, 2); diff --git a/gcc/testsuite/gcc.dg/vect/pr104116-round-udiv-pow2.c b/gcc/testsuite/gcc.dg/vect/pr104116-round-udiv-pow2.c index 137b249..a802b97 100644 --- a/gcc/testsuite/gcc.dg/vect/pr104116-round-udiv-pow2.c +++ b/gcc/testsuite/gcc.dg/vect/pr104116-round-udiv-pow2.c @@ -16,6 +16,7 @@ int main (void) unsigned int * a = (unsigned int*)↑ init_uarr(a, N); div(a); + #pragma GCC novector for (unsigned int i=0; i<N; i++) { unsigned int expected = rd_udiv (0xf0000000 + i, 8); diff --git a/gcc/testsuite/gcc.dg/vect/pr104116-round-udiv.c b/gcc/testsuite/gcc.dg/vect/pr104116-round-udiv.c index 183a930..7d5db92 100644 --- a/gcc/testsuite/gcc.dg/vect/pr104116-round-udiv.c +++ b/gcc/testsuite/gcc.dg/vect/pr104116-round-udiv.c @@ -16,6 +16,7 @@ int main (void) unsigned int * a = (unsigned int*)↑ init_uarr(a, N); div(a); + #pragma GCC novector for (unsigned int i=0; i<N; i++) { unsigned int expected = rd_udiv (0xf0000000 + i, 19); diff --git a/gcc/testsuite/gcc.dg/vect/pr104116-round-umod-2.c b/gcc/testsuite/gcc.dg/vect/pr104116-round-umod-2.c index f321e0e..155b26a 100644 --- a/gcc/testsuite/gcc.dg/vect/pr104116-round-umod-2.c +++ b/gcc/testsuite/gcc.dg/vect/pr104116-round-umod-2.c @@ -16,6 +16,7 @@ int main (void) unsigned int * a = (unsigned int*)↑ init_uarr(a, N); mod(a); + #pragma GCC novector for (unsigned int i=0; i<N; i++) { unsigned int expected = rd_umod (0xf0000000 + i, 2); diff --git a/gcc/testsuite/gcc.dg/vect/pr104116-round-umod-pow2.c b/gcc/testsuite/gcc.dg/vect/pr104116-round-umod-pow2.c index 041ecd1..1b4911a 100644 --- a/gcc/testsuite/gcc.dg/vect/pr104116-round-umod-pow2.c +++ b/gcc/testsuite/gcc.dg/vect/pr104116-round-umod-pow2.c @@ -16,6 +16,7 @@ int main (void) unsigned int * a = (unsigned int*)↑ init_uarr(a, N); mod(a); + #pragma GCC novector for (unsigned int i=0; i<N; i++) { unsigned int expected = rd_umod (0xf0000000 + i, 8); diff --git a/gcc/testsuite/gcc.dg/vect/pr104116-round-umod.c b/gcc/testsuite/gcc.dg/vect/pr104116-round-umod.c index b5ddad1..3db289e 100644 --- a/gcc/testsuite/gcc.dg/vect/pr104116-round-umod.c +++ b/gcc/testsuite/gcc.dg/vect/pr104116-round-umod.c @@ -16,6 +16,7 @@ int main (void) unsigned int * a = (unsigned int*)↑ init_uarr(a, N); mod(a); + #pragma GCC novector for (unsigned int i=0; i<N; i++) { unsigned int expected = rd_umod (0xf0000000 + i, 19); diff --git a/gcc/testsuite/gcc.dg/vect/pr104116.h b/gcc/testsuite/gcc.dg/vect/pr104116.h index 6f14e4b..c097353 100644 --- a/gcc/testsuite/gcc.dg/vect/pr104116.h +++ b/gcc/testsuite/gcc.dg/vect/pr104116.h @@ -82,17 +82,17 @@ NAME (unsigned int * a) \ #define N 1024 int arr[N]; -__attribute__((optimize("O0"))) void init_arr (int *a, int n) { - for (int i=0; i<n; i++) - a[i] = i - n/2; + #pragma GCC novector + for (int i=0; i<n; i++) + a[i] = i - n/2; } unsigned int uarr[N]; -__attribute__((optimize("O0"))) void init_uarr (unsigned int *a, int n) { + #pragma GCC novector for (unsigned int i=0; i<n; i++) a[i] = 0xf0000000 + i; } @@ -141,7 +141,6 @@ int fl_div (int x, int y) return q; } - int fl_mod (int x, int y) { int r = x % y; diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-chain-4.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-chain-4.c new file mode 100644 index 0000000..d79676d --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-chain-4.c @@ -0,0 +1,31 @@ +#include "tree-vect.h" + +int q[32]; + +int __attribute__((noipa)) +foo () +{ + int res = 0; + for (int i = 0; i < 8; ++i) + res += q[4*i] + q[4*i+1] + q[4*i+2] + q[4*i+3]; + return res; +} + +int main() +{ + check_vect (); + + int sum = 0; +#pragma GCC novector + for (int i = 0; i < 32; ++i) + { + q[i] = i; + sum += i; + } + + if (foo () != sum) + abort (); +} + +/* { dg-final { scan-tree-dump "vectorizing a reduction chain" "vect" } } */ +/* { dg-final { scan-tree-dump "optimized: loop vectorized" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vadcq_m_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vadcq_m_s32.c index c5a5878..1802c20 100644 --- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vadcq_m_s32.c +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vadcq_m_s32.c @@ -1,6 +1,6 @@ /* { dg-require-effective-target arm_v8_1m_mve_ok } */ /* { dg-add-options arm_v8_1m_mve } */ -/* { dg-additional-options "-O2" } */ +/* { dg-additional-options "-O2 -fno-schedule-insns -fno-schedule-insns2" } */ /* { dg-final { check-function-bodies "**" "" } } */ #include "arm_mve.h" @@ -14,12 +14,12 @@ extern "C" { ** ... ** vmrs (?:ip|fp|r[0-9]+), FPSCR_nzcvqc(?: @.*|) ** ... -** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|) -** ... ** bfi (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #29, #1(?: @.*|) ** ... ** vmsr FPSCR_nzcvqc, (?:ip|fp|r[0-9]+)(?: @.*|) ** ... +** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|) +** ... ** vpst(?: @.*|) ** ... ** vadct.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|) @@ -41,12 +41,12 @@ foo (int32x4_t inactive, int32x4_t a, int32x4_t b, unsigned *carry, mve_pred16_t ** ... ** vmrs (?:ip|fp|r[0-9]+), FPSCR_nzcvqc(?: @.*|) ** ... -** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|) -** ... ** bfi (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #29, #1(?: @.*|) ** ... ** vmsr FPSCR_nzcvqc, (?:ip|fp|r[0-9]+)(?: @.*|) ** ... +** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|) +** ... ** vpst(?: @.*|) ** ... ** vadct.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|) diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vadcq_m_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vadcq_m_u32.c index 23908a4..64f221d 100644 --- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vadcq_m_u32.c +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vadcq_m_u32.c @@ -1,6 +1,6 @@ /* { dg-require-effective-target arm_v8_1m_mve_ok } */ /* { dg-add-options arm_v8_1m_mve } */ -/* { dg-additional-options "-O2" } */ +/* { dg-additional-options "-O2 -fno-schedule-insns -fno-schedule-insns2" } */ /* { dg-final { check-function-bodies "**" "" } } */ #include "arm_mve.h" @@ -14,12 +14,12 @@ extern "C" { ** ... ** vmrs (?:ip|fp|r[0-9]+), FPSCR_nzcvqc(?: @.*|) ** ... -** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|) -** ... ** bfi (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #29, #1(?: @.*|) ** ... ** vmsr FPSCR_nzcvqc, (?:ip|fp|r[0-9]+)(?: @.*|) ** ... +** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|) +** ... ** vpst(?: @.*|) ** ... ** vadct.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|) @@ -41,12 +41,12 @@ foo (uint32x4_t inactive, uint32x4_t a, uint32x4_t b, unsigned *carry, mve_pred1 ** ... ** vmrs (?:ip|fp|r[0-9]+), FPSCR_nzcvqc(?: @.*|) ** ... -** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|) -** ... ** bfi (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #29, #1(?: @.*|) ** ... ** vmsr FPSCR_nzcvqc, (?:ip|fp|r[0-9]+)(?: @.*|) ** ... +** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|) +** ... ** vpst(?: @.*|) ** ... ** vadct.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|) diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsbcq_m_s32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsbcq_m_s32.c index 940e2ed..da36d69 100644 --- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsbcq_m_s32.c +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsbcq_m_s32.c @@ -1,6 +1,6 @@ /* { dg-require-effective-target arm_v8_1m_mve_ok } */ /* { dg-add-options arm_v8_1m_mve } */ -/* { dg-additional-options "-O2" } */ +/* { dg-additional-options "-O2 -fno-schedule-insns -fno-schedule-insns2" } */ /* { dg-final { check-function-bodies "**" "" } } */ #include "arm_mve.h" @@ -14,12 +14,12 @@ extern "C" { ** ... ** vmrs (?:ip|fp|r[0-9]+), FPSCR_nzcvqc(?: @.*|) ** ... -** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|) -** ... ** bfi (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #29, #1(?: @.*|) ** ... ** vmsr FPSCR_nzcvqc, (?:ip|fp|r[0-9]+)(?: @.*|) ** ... +** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|) +** ... ** vpst(?: @.*|) ** ... ** vsbct.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|) @@ -41,12 +41,12 @@ foo (int32x4_t inactive, int32x4_t a, int32x4_t b, unsigned *carry, mve_pred16_t ** ... ** vmrs (?:ip|fp|r[0-9]+), FPSCR_nzcvqc(?: @.*|) ** ... -** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|) -** ... ** bfi (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #29, #1(?: @.*|) ** ... ** vmsr FPSCR_nzcvqc, (?:ip|fp|r[0-9]+)(?: @.*|) ** ... +** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|) +** ... ** vpst(?: @.*|) ** ... ** vsbct.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|) diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsbcq_m_u32.c b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsbcq_m_u32.c index 478b938..555690f 100644 --- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsbcq_m_u32.c +++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsbcq_m_u32.c @@ -1,6 +1,6 @@ /* { dg-require-effective-target arm_v8_1m_mve_ok } */ /* { dg-add-options arm_v8_1m_mve } */ -/* { dg-additional-options "-O2" } */ +/* { dg-additional-options "-O2 -fno-schedule-insns -fno-schedule-insns2" } */ /* { dg-final { check-function-bodies "**" "" } } */ #include "arm_mve.h" @@ -14,12 +14,12 @@ extern "C" { ** ... ** vmrs (?:ip|fp|r[0-9]+), FPSCR_nzcvqc(?: @.*|) ** ... -** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|) -** ... ** bfi (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #29, #1(?: @.*|) ** ... ** vmsr FPSCR_nzcvqc, (?:ip|fp|r[0-9]+)(?: @.*|) ** ... +** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|) +** ... ** vpst(?: @.*|) ** ... ** vsbct.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|) @@ -41,12 +41,12 @@ foo (uint32x4_t inactive, uint32x4_t a, uint32x4_t b, unsigned *carry, mve_pred1 ** ... ** vmrs (?:ip|fp|r[0-9]+), FPSCR_nzcvqc(?: @.*|) ** ... -** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|) -** ... ** bfi (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), #29, #1(?: @.*|) ** ... ** vmsr FPSCR_nzcvqc, (?:ip|fp|r[0-9]+)(?: @.*|) ** ... +** vmsr p0, (?:ip|fp|r[0-9]+)(?: @.*|) +** ... ** vpst(?: @.*|) ** ... ** vsbct.i32 q[0-9]+, q[0-9]+, q[0-9]+(?: @.*|) diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-stv-10.c b/gcc/testsuite/gcc.target/i386/sse4_1-stv-10.c new file mode 100644 index 0000000..229bc45 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse4_1-stv-10.c @@ -0,0 +1,13 @@ +/* { dg-do compile { target int128 } } */ +/* { dg-options "-O2 -msse4.1 -mstv -mno-stackrealign" } */ + +__int128 m0,m1,m2,m3; +void foo(__int128 m) +{ + m0 = m; + m1 = m; + m2 = m; + m3 = m; +} + +/* { dg-final { scan-assembler-times "movaps" 4 } } */ diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-stv-11.c b/gcc/testsuite/gcc.target/i386/sse4_1-stv-11.c new file mode 100644 index 0000000..3508bfb --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse4_1-stv-11.c @@ -0,0 +1,14 @@ +/* { dg-do compile { target int128 } } */ +/* { dg-options "-O2 -msse4.1 -mstv -mno-stackrealign" } */ + +__int128 m0,m1,m2,m3; +void foo(unsigned long x) +{ + __int128 m = x; + m0 = m; + m1 = m; + m2 = m; + m3 = m; +} + +/* { dg-final { scan-assembler-times "movaps" 4 } } */ diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-stv-12.c b/gcc/testsuite/gcc.target/i386/sse4_1-stv-12.c new file mode 100644 index 0000000..9587b64 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse4_1-stv-12.c @@ -0,0 +1,14 @@ +/* { dg-do compile { target int128 } } */ +/* { dg-options "-O2 -msse4.1 -mstv -mno-stackrealign" } */ + +__int128 m0,m1,m2,m3; +void foo(unsigned int x) +{ + __int128 m = x; + m0 = m; + m1 = m; + m2 = m; + m3 = m; +} + +/* { dg-final { scan-assembler-times "movaps" 4 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-8.c index 1e5dc23..15a1d63 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-8.c @@ -12,4 +12,4 @@ add_loop (int *x, int n, int res) return res; } -/* { dg-final { scan-assembler-times {add\s+[a-x0-9]+,\s*[a-x0-9]+,a2} 1 } } */ +/* { dg-final { scan-assembler-times {add\s+[a-x0-9]+,\s*(?:a2,\s*[a-x0-9]+|[a-x0-9]+,\s*a2)} 1 } } */ diff --git a/gcc/testsuite/gfortran.dg/gomp/declare-variant-2.f90 b/gcc/testsuite/gfortran.dg/gomp/declare-variant-2.f90 index 11be76e..02bd8623 100644 --- a/gcc/testsuite/gfortran.dg/gomp/declare-variant-2.f90 +++ b/gcc/testsuite/gfortran.dg/gomp/declare-variant-2.f90 @@ -195,7 +195,7 @@ contains !$omp declare variant (f1) match(implementation={atomic_default_mem_order("relaxed")}) ! { dg-error "expected identifier at .1." } end subroutine subroutine f77 () - !$omp declare variant (f1) match(user={condition(score(f76):.true.)}) ! { dg-error ".score. argument must be constant integer expression at .1." } + !$omp declare variant (f1) match(user={condition(score(f76):.true.)}) ! { dg-error "Unexpected use of subroutine name 'f76'" } end subroutine subroutine f78 () !$omp declare variant (f1) match(user={condition(score(-130):.true.)}) ! { dg-error ".score. argument must be non-negative" } diff --git a/gcc/testsuite/gfortran.dg/gomp/declare-variant-20.f90 b/gcc/testsuite/gfortran.dg/gomp/declare-variant-20.f90 index 17fdcb7..82b8a52 100644 --- a/gcc/testsuite/gfortran.dg/gomp/declare-variant-20.f90 +++ b/gcc/testsuite/gfortran.dg/gomp/declare-variant-20.f90 @@ -44,6 +44,7 @@ contains !$omp declare variant(variant5) match(target_device={device_num(-4)}) ! OK - omp_invalid_device (will never match) ! OK - but not handled -> PR middle-end/113904 !$omp declare variant(variant5) match(target_device={device_num(my_device)}) ! { dg-error "property must be a constant integer expression" } + ! { dg-error "Symbol 'my_device' at .1. has no IMPLICIT type" "" { target *-*-* } .-1 } !$omp declare variant(variant5) match(target_device={device_num(-2)}) ! { dg-error "property must be a conforming device number" } res = 99 diff --git a/gcc/testsuite/gfortran.dg/gomp/pr120180-1.f90 b/gcc/testsuite/gfortran.dg/gomp/pr120180-1.f90 new file mode 100644 index 0000000..f16a256 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/pr120180-1.f90 @@ -0,0 +1,31 @@ +! { dg-do compile } + +! This test case checks that the inner metadirective is accepted as intervening +! code since it resolves to 'omp nothing'. + +SUBROUTINE test1(x_min, x_max, y_min, y_max, xarea, vol_flux_x) + + IMPLICIT NONE + + INTEGER, INTENT(IN) :: x_min, x_max, y_min, y_max + + REAL(KIND=8), DIMENSION(x_min:x_max,y_min:y_max) :: xarea + REAL(KIND=8), DIMENSION(x_min:x_max,y_min:y_max) :: vol_flux_x + + INTEGER :: j,k + + !$omp metadirective & + !$omp when(user={condition(.false.)}: & + !$omp target teams distribute parallel do simd collapse(2)) & + !$omp when(user={condition(.false.)}: & + !$omp target teams distribute parallel do) & + !$omp default( & + !$omp target teams loop collapse(2)) + DO k=y_min,y_max + !$omp metadirective when(user={condition(.false.)}: simd) + DO j=x_min,x_max + vol_flux_x(j,k)=0.25_8*xarea(j,k) + ENDDO + ENDDO + +END SUBROUTINE test1 diff --git a/gcc/testsuite/gfortran.dg/gomp/pr120180-2.f90 b/gcc/testsuite/gfortran.dg/gomp/pr120180-2.f90 new file mode 100644 index 0000000..ea90ad6 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/pr120180-2.f90 @@ -0,0 +1,90 @@ +! { dg-do compile } + +! This test case checks that a non-executable OpenMP directive is accepted +! as intervening code. + +SUBROUTINE test1(x_min, x_max, y_min, y_max, xarea, vol_flux_x) + + IMPLICIT NONE + + INTEGER, INTENT(IN) :: x_min, x_max, y_min, y_max + + REAL(KIND=8), DIMENSION(x_min:x_max,y_min:y_max) :: xarea + REAL(KIND=8), DIMENSION(x_min:x_max,y_min:y_max) :: vol_flux_x + + INTEGER :: j,k + + !$omp do collapse(2) + DO k=y_min,y_max + !$omp nothing + DO j=x_min,x_max + vol_flux_x(j,k)=0.25_8*xarea(j,k) + ENDDO + ENDDO + +END SUBROUTINE test1 + +SUBROUTINE test2(x_min, x_max, y_min, y_max, x, z, vol_flux_x) + + IMPLICIT NONE + + INTEGER, INTENT(IN) :: x_min, x_max, y_min, y_max + + REAL(KIND=8) :: x, z + REAL(KIND=8), DIMENSION(x_min:x_max,y_min:y_max) :: vol_flux_x + + INTEGER :: j,k + + !$omp do collapse(2) + DO k=y_min,y_max + !$omp assume holds(x>1) + z = abs(x-1) + !$omp end assume + DO j=x_min,x_max + vol_flux_x(j,k)=0.25_8*z + ENDDO + ENDDO + +END SUBROUTINE test2 + +SUBROUTINE test3(x_min, x_max, y_min, y_max, z, vol_flux_x) + + IMPLICIT NONE + + INTEGER, INTENT(IN) :: x_min, x_max, y_min, y_max + + REAL(KIND=8) :: z + REAL(KIND=8), DIMENSION(x_min:x_max,y_min:y_max) :: vol_flux_x + + INTEGER :: j,k + + !$omp do collapse(2) + DO k=y_min,y_max + !$omp error at(compilation) ! { dg-error "OMP ERROR encountered at" } + DO j=x_min,x_max + vol_flux_x(j,k)=0.25_8*z + ENDDO + ENDDO + +END SUBROUTINE test3 + +SUBROUTINE test4(x_min, x_max, y_min, y_max, z, vol_flux_x) + + IMPLICIT NONE + + INTEGER, INTENT(IN) :: x_min, x_max, y_min, y_max + + REAL(KIND=8) :: z + REAL(KIND=8), DIMENSION(x_min:x_max,y_min:y_max) :: vol_flux_x + + INTEGER :: j,k + + !$omp do collapse(2) + DO k=y_min,y_max + !$omp error at(execution) ! { dg-error "OMP DO cannot contain OpenMP directive in intervening code" } + DO j=x_min,x_max + vol_flux_x(j,k)=0.25_8*z + ENDDO + ENDDO + +END SUBROUTINE test4 diff --git a/gcc/testsuite/gfortran.dg/gomp/pr122306-1.f90 b/gcc/testsuite/gfortran.dg/gomp/pr122306-1.f90 new file mode 100644 index 0000000..b7eb44f --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/pr122306-1.f90 @@ -0,0 +1,21 @@ +! { dg-do compile } + +! This test case checks that a function call in a context selector is accepted. + +module m + implicit none (type, external) +contains + integer function f(n) + integer :: i, n + f = 0 + !$omp metadirective & + !$omp& when(user={condition(use_target())}: target parallel do map(f) reduction(+:f)) & + !$omp& otherwise(parallel do reduction(+:f)) + do i = 1, n + f = f + 1 + end do + end + logical function use_target() + use_target = .false. + end +end diff --git a/gcc/testsuite/gfortran.dg/gomp/pr122306-2.f90 b/gcc/testsuite/gfortran.dg/gomp/pr122306-2.f90 new file mode 100644 index 0000000..799c92b --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/pr122306-2.f90 @@ -0,0 +1,33 @@ +! { dg-do compile } + +! This test case checks that various user-condition context selectors correctly +! parsed and resolved. + +SUBROUTINE test1(x_min, x_max, vol_flux_x) + IMPLICIT NONE + INTEGER, INTENT(IN) :: x_min, x_max + REAL(KIND=8), DIMENSION(x_min:x_max) :: vol_flux_x + integer, parameter :: one = 1 + INTEGER :: j + + !$omp begin metadirective when(user={condition(one < 0)}: parallel) + DO j=x_min,x_max + vol_flux_x(j)=0.25_8 + ENDDO + !$omp end metadirective +END SUBROUTINE test1 + +SUBROUTINE test2(x_min, x_max, vol_flux_x, flag) + IMPLICIT NONE + INTEGER, INTENT(IN) :: x_min, x_max + REAL(KIND=8), DIMENSION(x_min:x_max) :: vol_flux_x + LOGICAL :: flag + INTEGER :: j + + !$omp begin metadirective when(user={condition(flag)}: parallel) + DO j=x_min,x_max + vol_flux_x(j)=0.25_8 + ENDDO + !$omp end metadirective +END SUBROUTINE test2 + diff --git a/gcc/testsuite/jit.dg/all-non-failing-tests.h b/gcc/testsuite/jit.dg/all-non-failing-tests.h index 4aa18e3..dc98ad2 100644 --- a/gcc/testsuite/jit.dg/all-non-failing-tests.h +++ b/gcc/testsuite/jit.dg/all-non-failing-tests.h @@ -73,6 +73,13 @@ #undef create_code #undef verify_code +/* test-arrays-u64.c */ +#define create_code create_code_arrays_u64 +#define verify_code verify_code_arrays_u64 +#include "test-arrays-u64.c" +#undef create_code +#undef verify_code + /* test-autovectorize.c */ #define create_code create_code_autovectorize #define verify_code verify_code_autovectorize @@ -517,6 +524,9 @@ const struct testcase testcases[] = { {"arrays", create_code_arrays, verify_code_arrays}, + {"arrays-u64", + create_code_arrays_u64, + verify_code_arrays_u64}, {"autovectorize", create_code_autovectorize, verify_code_autovectorize}, diff --git a/gcc/testsuite/jit.dg/test-arrays-u64.c b/gcc/testsuite/jit.dg/test-arrays-u64.c new file mode 100644 index 0000000..ec8525c --- /dev/null +++ b/gcc/testsuite/jit.dg/test-arrays-u64.c @@ -0,0 +1,165 @@ +#include <stdlib.h> +#include <stdio.h> +#include <stddef.h> + +#include "libgccjit.h" + +#include "harness.h" + +#define ARRAY_SIZE (4) + +/* Verify that struct layout works properly when adding an array field. */ +struct array_holder2 +{ + float m_before; + int m_ints[ARRAY_SIZE]; + float m_after; +}; + +void +create_code (gcc_jit_context *ctxt, void *user_data) +{ + /* Let's try to inject the equivalent of: + + void + test_array_u64 (struct array_holder2 *ah) + { + ah->m_before = 4.0f; + for i in 0 to (ARRAY_SIZE - 1): + ah->m_ints[i] = (i * i); + ah->m_after = 2.0f; + } + */ + gcc_jit_type *void_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID); + gcc_jit_type *float_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT); + gcc_jit_type *int_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); + + gcc_jit_field *field_m_before = + gcc_jit_context_new_field (ctxt, NULL, float_type, "m_before"); + gcc_jit_field *field_m_ints = + gcc_jit_context_new_field ( + ctxt, NULL, + gcc_jit_context_new_array_type_u64 (ctxt, NULL, int_type, ARRAY_SIZE), + "m_ints"); + gcc_jit_field *field_m_after = + gcc_jit_context_new_field (ctxt, NULL, float_type, "m_after"); + + gcc_jit_field *fields[] = { + field_m_before, + field_m_ints, + field_m_after, + }; + + gcc_jit_struct *struct_type = + gcc_jit_context_new_struct_type ( + ctxt, + NULL, + "array_holder2", + 3, fields); + + gcc_jit_type *struct_ptr_type = + gcc_jit_type_get_pointer (gcc_jit_struct_as_type (struct_type)); + + /* Build the test_fn. */ + gcc_jit_param *param_ah = + gcc_jit_context_new_param (ctxt, NULL, struct_ptr_type, "ah"); + gcc_jit_function *func = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + void_type, + "test_array_u64", + 1, ¶m_ah, + 0); + + gcc_jit_block *initial = gcc_jit_function_new_block (func, "initial"); + gcc_jit_block *loop_test = gcc_jit_function_new_block (func, "loop_test"); + gcc_jit_block *loop_body = gcc_jit_function_new_block (func, "loop_body"); + gcc_jit_block *final = gcc_jit_function_new_block (func, "final"); + + /* "ah->m_before = 4.0f;" */ + gcc_jit_block_add_assignment ( + initial, NULL, + gcc_jit_rvalue_dereference_field ( + gcc_jit_param_as_rvalue (param_ah), NULL, field_m_before), + gcc_jit_context_new_rvalue_from_int (ctxt, float_type, 4)); + + gcc_jit_block_add_comment (initial, NULL, + "for i in 0 to (ARRAY_SIZE - 1):"); + gcc_jit_lvalue *i = + gcc_jit_function_new_local (func, NULL, int_type, "i"); + gcc_jit_block_add_assignment (initial, NULL, + i, + gcc_jit_context_zero (ctxt, int_type)); + + gcc_jit_block_end_with_jump (initial, NULL, loop_test); + + gcc_jit_block_end_with_conditional (loop_test, NULL, + gcc_jit_context_new_comparison ( + ctxt, NULL, + GCC_JIT_COMPARISON_LT, + gcc_jit_lvalue_as_rvalue (i), + gcc_jit_context_new_rvalue_from_int (ctxt, int_type, ARRAY_SIZE)), + loop_body, + final); + + gcc_jit_block_add_comment (loop_body, NULL, "ah->m_ints[i] = (i * i);"); + gcc_jit_block_add_assignment ( + loop_body, NULL, + gcc_jit_context_new_array_access ( + ctxt, NULL, + gcc_jit_lvalue_as_rvalue (gcc_jit_rvalue_dereference_field ( + gcc_jit_param_as_rvalue (param_ah), + NULL, + field_m_ints)), + gcc_jit_lvalue_as_rvalue (i)), + gcc_jit_context_new_binary_op ( + ctxt, NULL, + GCC_JIT_BINARY_OP_MULT, + int_type, + gcc_jit_lvalue_as_rvalue (i), + gcc_jit_lvalue_as_rvalue (i))); + + /* "i++" */ + gcc_jit_block_add_assignment_op ( + loop_body, NULL, + i, + GCC_JIT_BINARY_OP_PLUS, + gcc_jit_context_one (ctxt, int_type)); + + gcc_jit_block_end_with_jump (loop_body, NULL, loop_test); + + /* ah->m_after = 2.0f; */ + gcc_jit_block_add_assignment ( + final, NULL, + gcc_jit_rvalue_dereference_field ( + gcc_jit_param_as_rvalue (param_ah), NULL, field_m_after), + gcc_jit_context_new_rvalue_from_int (ctxt, float_type, 2)); + gcc_jit_block_end_with_void_return (final, NULL); + +} + +void +verify_code (gcc_jit_context *ctxt, gcc_jit_result *result) +{ + typedef void (*fn_type) (struct array_holder2 *ah); + + CHECK_NON_NULL (result); + fn_type test_array_u64 = + (fn_type)gcc_jit_result_get_code (result, "test_array_u64"); + CHECK_NON_NULL (test_array_u64); + + struct array_holder2 ah; + memset (&ah, 0xf0, sizeof (ah)); + + test_array_u64 (&ah); + CHECK_VALUE (ah.m_before, 4.0f); + CHECK_VALUE (ah.m_ints[0], 0); + CHECK_VALUE (ah.m_ints[1], 1); + CHECK_VALUE (ah.m_ints[2], 4); + CHECK_VALUE (ah.m_ints[3], 9); + CHECK_VALUE (ah.m_after, 2.0f); + +} diff --git a/gcc/testsuite/jit.dg/test-error-array-bounds.c b/gcc/testsuite/jit.dg/test-error-array-bounds.c index a0dead1..fb5c206 100644 --- a/gcc/testsuite/jit.dg/test-error-array-bounds.c +++ b/gcc/testsuite/jit.dg/test-error-array-bounds.c @@ -64,11 +64,7 @@ create_code (gcc_jit_context *ctxt, void *user_data) void verify_code (gcc_jit_context *ctxt, gcc_jit_result *result) { - /* Verify that the diagnostic led to the context failing... */ - CHECK_VALUE (result, NULL); - - /* ...and that the message was captured by the API. */ - CHECK_STRING_VALUE (gcc_jit_context_get_first_error (ctxt), - "array subscript 10 is above array bounds of" - " 'char[10]' [-Warray-bounds=]"); + /* Verify that the message was captured by the API. */ + CHECK_STRING_VALUE (gcc_jit_context_get_last_error (ctxt), + "while referencing 'buffer'"); } diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc index 6c24202..be684a52 100644 --- a/gcc/tree-vect-loop.cc +++ b/gcc/tree-vect-loop.cc @@ -5219,6 +5219,15 @@ vect_create_partial_epilog (tree vec_def, tree vectype, code_helper code, new_temp = gimple_build (seq, code, vectype1, dst1, dst2); } + if (!useless_type_conversion_p (vectype, TREE_TYPE (new_temp))) + { + tree dst3 = make_ssa_name (vectype); + gimple *epilog_stmt = gimple_build_assign (dst3, VIEW_CONVERT_EXPR, + build1 (VIEW_CONVERT_EXPR, + vectype, new_temp)); + gimple_seq_add_stmt_without_update (seq, epilog_stmt); + new_temp = dst3; + } return new_temp; } @@ -8211,6 +8220,10 @@ vect_transform_cycle_phi (loop_vec_info loop_vinfo, /* Leave the scalar phi in place. */ return true; + if (reduc_info && reduc_info->is_reduc_chain && dump_enabled_p ()) + dump_printf_loc (MSG_NOTE, vect_location, + "vectorizing a reduction chain\n"); + vec_num = vect_get_num_copies (loop_vinfo, slp_node); /* Check whether we should use a single PHI node and accumulate diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc index 13a2995..53fe643 100644 --- a/gcc/tree-vect-slp.cc +++ b/gcc/tree-vect-slp.cc @@ -4230,9 +4230,142 @@ vect_analyze_slp_reduc_chain (loop_vec_info vinfo, first = false; } while (!is_a <gphi *> (STMT_VINFO_STMT (next_stmt))); - if (fail || scalar_stmts.length () <= 1) + if (fail) return false; + if (scalar_stmts.length () == 1 + && code.is_tree_code () + && associative_tree_code ((tree_code)code)) + { + auto_vec<chain_op_t> chain; + auto_vec<std::pair<tree_code, gimple *> > worklist; + gimple *op_stmt = NULL, *other_op_stmt = NULL; + vect_slp_linearize_chain (vinfo, worklist, chain, (tree_code)code, + scalar_stmts[0]->stmt, op_stmt, other_op_stmt, + NULL); + if (chain.length () < 3) + { + scalar_stmts.release (); + return false; + } + + scalar_stmts.truncate (0); + stmt_vec_info tail = NULL; + for (auto el : chain) + { + if (el.dt == vect_external_def + || el.dt == vect_constant_def + || el.code != (tree_code) code) + { + scalar_stmts.release (); + return false; + } + stmt_vec_info stmt = vinfo->lookup_def (el.op); + if (STMT_VINFO_REDUC_IDX (stmt) != -1 + || STMT_VINFO_REDUC_DEF (stmt)) + { + gcc_assert (tail == NULL); + tail = stmt; + continue; + } + scalar_stmts.safe_push (stmt); + } + gcc_assert (tail); + + if (dump_enabled_p ()) + { + dump_printf_loc (MSG_NOTE, vect_location, + "Starting SLP discovery of reduction chain for\n"); + for (unsigned i = 0; i < scalar_stmts.length (); ++i) + dump_printf_loc (MSG_NOTE, vect_location, + " %G", scalar_stmts[i]->stmt); + } + + unsigned int group_size = scalar_stmts.length (); + bool *matches = XALLOCAVEC (bool, group_size); + poly_uint64 max_nunits = 1; + unsigned tree_size = 0; + slp_tree node = vect_build_slp_tree (vinfo, scalar_stmts, group_size, + &max_nunits, matches, limit, + &tree_size, bst_map); + if (!node) + { + scalar_stmts.release (); + return false; + } + + unsigned cycle_id = vinfo->reduc_infos.length (); + vect_reduc_info reduc_info = new vect_reduc_info_s (); + vinfo->reduc_infos.safe_push (reduc_info); + VECT_REDUC_INFO_DEF_TYPE (reduc_info) = STMT_VINFO_DEF_TYPE (next_stmt); + VECT_REDUC_INFO_TYPE (reduc_info) = STMT_VINFO_REDUC_TYPE (next_stmt); + VECT_REDUC_INFO_CODE (reduc_info) = STMT_VINFO_REDUC_CODE (next_stmt); + VECT_REDUC_INFO_FN (reduc_info) = IFN_LAST; + reduc_info->is_reduc_chain = true; + + /* Build the node for the PHI and possibly the conversion(s?). */ + slp_tree phis = vect_create_new_slp_node (2, ERROR_MARK); + SLP_TREE_REPRESENTATIVE (phis) = next_stmt; + phis->cycle_info.id = cycle_id; + SLP_TREE_LANES (phis) = group_size; + SLP_TREE_VECTYPE (phis) = SLP_TREE_VECTYPE (node); + /* ??? vect_cse_slp_nodes cannot cope with cycles without any + SLP_TREE_SCALAR_STMTS. */ + SLP_TREE_SCALAR_STMTS (phis).create (group_size); + for (unsigned i = 0; i < group_size; ++i) + SLP_TREE_SCALAR_STMTS (phis).quick_push (next_stmt); + + slp_tree reduc = vect_create_new_slp_node (2, ERROR_MARK); + SLP_TREE_REPRESENTATIVE (reduc) = scalar_stmt; + SLP_TREE_CHILDREN (reduc).quick_push (phis); + SLP_TREE_CHILDREN (reduc).quick_push (node); + reduc->cycle_info.id = cycle_id; + SLP_TREE_REDUC_IDX (reduc) = 0; + SLP_TREE_LANES (reduc) = group_size; + SLP_TREE_VECTYPE (reduc) = SLP_TREE_VECTYPE (node); + /* ??? For the reduction epilogue we need a live lane. */ + SLP_TREE_SCALAR_STMTS (reduc).create (group_size); + SLP_TREE_SCALAR_STMTS (reduc).quick_push (scalar_stmt); + for (unsigned i = 1; i < group_size; ++i) + SLP_TREE_SCALAR_STMTS (reduc).quick_push (NULL); + + edge le = loop_latch_edge (LOOP_VINFO_LOOP (vinfo)); + SLP_TREE_CHILDREN (phis).quick_push (NULL); + SLP_TREE_CHILDREN (phis).quick_push (NULL); + SLP_TREE_CHILDREN (phis)[le->dest_idx] = reduc; + SLP_TREE_REF_COUNT (reduc)++; + + /* Create a new SLP instance. */ + slp_instance new_instance = XNEW (class _slp_instance); + SLP_INSTANCE_TREE (new_instance) = reduc; + SLP_INSTANCE_LOADS (new_instance) = vNULL; + SLP_INSTANCE_ROOT_STMTS (new_instance) = vNULL; + SLP_INSTANCE_REMAIN_DEFS (new_instance) = vNULL; + SLP_INSTANCE_KIND (new_instance) = slp_inst_kind_reduc_chain; + new_instance->reduc_phis = NULL; + new_instance->cost_vec = vNULL; + new_instance->subgraph_entries = vNULL; + + vinfo->slp_instances.safe_push (new_instance); + + if (dump_enabled_p ()) + { + dump_printf_loc (MSG_NOTE, vect_location, + "Final SLP tree for instance %p:\n", + (void *) new_instance); + vect_print_slp_graph (MSG_NOTE, vect_location, + SLP_INSTANCE_TREE (new_instance)); + } + + return true; + } + + if (scalar_stmts.length () <= 1) + { + scalar_stmts.release (); + return false; + } + scalar_stmts.reverse (); stmt_vec_info reduc_phi_info = next_stmt; @@ -12046,7 +12179,8 @@ vect_schedule_slp (vec_info *vinfo, const vec<slp_instance> &slp_instances) /* Remove vectorized stores original scalar stmts. */ for (j = 0; SLP_TREE_SCALAR_STMTS (root).iterate (j, &store_info); j++) { - if (!STMT_VINFO_DATA_REF (store_info) + if (!store_info + || !STMT_VINFO_DATA_REF (store_info) || !DR_IS_WRITE (STMT_VINFO_DATA_REF (store_info))) break; diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index e539f31..4c4e14b 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,24 @@ +2025-10-20 Olivier Hainque <hainque@adacore.com> + Ashley Gay <gay@adacore.com> + + * config/gthr-vxworks.h: Include stdatomic.h and prevent indirect + inclusion of contents from the system version of that header. + +2025-10-20 Olivier Hainque <hainque@adacore.com> + + * config/gthr-vxworks-thread.c (__init_gthread_tcb): Make static. + (__delete_gthread_tcb): Likewise. + (__task_wrapper): Likewise. + (__gthread_create): Convert __task_wrapper to (void *) before going + to (FUNCPTR). + * config/gthr-vxworks-tls.c (tls_delete_hook): Accommodate prototype + variations between kernel and rtp. Return STATUS. + +2025-10-20 Olivier Hainque <hainque@adacore.com> + + * config/t-vxworks: -include vxworks-predef.h explicitly, as the + automatic inclusion is disabled by -nostdinc. + 2025-10-07 H.J. Lu <hjl.tools@gmail.com> PR target/120691 diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog index 3414923..c102808 100644 --- a/libgomp/ChangeLog +++ b/libgomp/ChangeLog @@ -1,3 +1,22 @@ +2025-10-20 Josef Melcr <jmelcr02@gmail.com> + + * testsuite/libgomp.c/ipcp-cb-spec1.c: Moved from + gcc/testsuite/gcc.dg/ipa/. + * testsuite/libgomp.c/ipcp-cb-spec2.c: Likewise. + * testsuite/libgomp.c/ipcp-cb1.c: Likewise. + +2025-10-20 Thomas Schwinge <tschwinge@baylibre.com> + + PR c++/114457 + PR c++/122268 + PR c++/120450 + * testsuite/libgomp.c++/target-flex-101.C: XFAIL GCN, nvptx + offloading compilation. + * testsuite/libgomp.c++/target-std__flat_map-concurrent.C: + Un-XFAIL GCN offloading compilation. + * testsuite/libgomp.c++/target-std__flat_multimap-concurrent.C: + Likewise. + 2025-10-16 Tobias Burnus <tburnus@baylibre.com> * testsuite/libgomp.c/declare-variant-4-gfx10-3-generic.c: Add diff --git a/gcc/testsuite/gcc.dg/ipa/ipcp-cb-spec1.c b/libgomp/testsuite/libgomp.c/ipcp-cb-spec1.c index a85e623..a85e623 100644 --- a/gcc/testsuite/gcc.dg/ipa/ipcp-cb-spec1.c +++ b/libgomp/testsuite/libgomp.c/ipcp-cb-spec1.c diff --git a/gcc/testsuite/gcc.dg/ipa/ipcp-cb-spec2.c b/libgomp/testsuite/libgomp.c/ipcp-cb-spec2.c index 01d7425..01d7425 100644 --- a/gcc/testsuite/gcc.dg/ipa/ipcp-cb-spec2.c +++ b/libgomp/testsuite/libgomp.c/ipcp-cb-spec2.c diff --git a/gcc/testsuite/gcc.dg/ipa/ipcp-cb1.c b/libgomp/testsuite/libgomp.c/ipcp-cb1.c index 3418b5d..3418b5d 100644 --- a/gcc/testsuite/gcc.dg/ipa/ipcp-cb1.c +++ b/libgomp/testsuite/libgomp.c/ipcp-cb1.c diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index d88e4c7..cad7409 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,25 @@ +2025-10-20 Yuao Ma <c8ef@outlook.com> + + * include/bits/version.def: Add ranges_indices FTM. + * include/bits/version.h: Regenerate. + * include/std/ranges: Implement views::indices. + * testsuite/std/ranges/indices/1.cc: New test. + +2025-10-20 Tomasz KamiĆski <tkaminsk@redhat.com> + + * include/bits/funcwrap.h (__polyfunc::__deduce_funcref): + Adjust signature produced for member object pointers. + * testsuite/20_util/function_ref/deduction.cc: Update tests. + +2025-10-20 Jonathan Wakely <jwakely@redhat.com> + + PR libstdc++/122322 + * configure.ac (with_newlib) <*-rtems*>: Remove + HAVE_SYS_IOCT4YL_H, _GLIBCXX_USE_LINK, _GLIBCXX_USE_READLINK, + _GLIBCXX_USE_SYMLINK, _GLIBCXX_USE_TRUNCATE, and + _GLIBCXX_USE_FDOPENDIR. Remove duplicates. + * configure: Regenerate. + 2025-10-18 Iain Sandoe <iain@sandoe.co.uk> PR c++/119060 |