diff options
Diffstat (limited to 'gcc')
133 files changed, 2964 insertions, 403 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fe5a6f5..0695ecb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,180 @@ +2025-10-21 Antoni Boucher <bouanto@zoho.com> + + * config.gcc (jit_target_objs): Don't set this variable since + the object files don't exist. + +2025-10-21 Roger Sayle <roger@nextmovesoftware.com> + + * config/i386/i386-features.cc (timode_concatdi_p): New + function to recognize the various variants of *concatditi3_[1-7]. + (scalar_chain::add_insn): Like VEC_SELECT, ZERO_EXTEND and + timode_concatdi_p instructions don't require their input + operands to be converted (to TImode). + (timode_scalar_chain::compute_convert_gain): Split/clone XOR and + IOR cases from AND case, to handle timode_concatdi_p costs. + <case PLUS>: Handle timode_concatdi_p conversion costs. + <case ZERO_EXTEND>: Provide costs of DImode to TImode extension. + (timode_convert_concatdi): Helper function to transform + a *concatditi3 instruction into a vec_concatv2di instruction. + (timode_scalar_chain::convert_insn): Split/clone XOR and IOR + cases from ANS case, to handle timode_concatdi_p using the new + timode_convert_concatdi helper function. + <case ZERO_EXTEND>: Convert zero_extendditi2 to *vec_concatv2di_0. + <case PLUS>: Handle timode_concatdi_p using the new + timode_convert_concatdi helper function. + (timode_scalar_to_vector_candidate_p): Support timode_concatdi_p + instructions in IOR, XOR and PLUS cases. + <case ZERO_EXTEND>: Consider zero extension of a register from + DImode to TImode to be a candidate. + +2025-10-21 Richard Biener <rguenther@suse.de> + + PR tree-optimization/120687 + * tree-vect-slp.cc (vect_analyze_slp_reduc_chain): When + there's no natural reduction chain see if vect_slp_linearize_chain + can recover one and built the SLP instance manually in that + case. + (vect_schedule_slp): Deal with NULL lanes when looking for + stores to remove. + * tree-vect-loop.cc (vect_transform_cycle_phi): Dump when we + are successfully transforming a reduction chain. + +2025-10-21 Richard Biener <rguenther@suse.de> + + * tree-vect-loop.cc (vect_create_partial_epilog): Pun back + to the requested type if necessary. + +2025-10-21 Andrew Pinski <andrew.pinski@oss.qualcomm.com> + + PR tree-optimization/95699 + PR tree-optimization/101024 + PR tree-optimization/110068 + * match.pd (`(type1)x CMP CST1 ? (type2)x : CST2`): Treat + `(signed)x </>= 0` as `x >=/< SIGNED_TYPE_MIN` + +2025-10-21 Olivier Hainque <hainque@adacore.com> + + * config/rs6000/vxworks.h (ASM_PREFERRED_EH_DATA_FORMAT): + Redefine. + +2025-10-21 Olivier Hainque <hainque@adacore.com> + + * config/vxworks.h (VXWORKS_ADDITIONAL_CPP_SPEC): + Remove guard on -fself-tests and replace %:getenv(VSB_DIR) by + sysroot references. + +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..1ec5bc8 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20251020 +20251022 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/ChangeLog b/gcc/c-family/ChangeLog index 30a66de..d5d21ef 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,9 @@ +2025-10-21 Tobias Burnus <tburnus@baylibre.com> + + * c-omp.cc (c_omp_directives): Uncomment 'declare mapper', + add comment to 'begin metadirective', add 6.x unimplemented + directives as comment-out entries. + 2025-10-17 Josef Melcr <jmelcr02@gmail.com> * c-attribs.cc: Define callback attr. 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/ChangeLog b/gcc/c/ChangeLog index 241e71b..6f51dd9 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,26 @@ +2025-10-21 Martin Uecker <uecker@tugraz.at> + + * c-decl.cc (build_array_declarator): Remove error. + (grokgenassoc): New function. + (grokdeclarator): Add error. + * c-parser.cc (c_parser_generic_selection): Use grokgenassoc. + * c-tree.h (grokgenassoc): Add prototype. + +2025-10-21 Paul-Antoine Arras <parras@baylibre.com> + + PR c/120180 + PR fortran/122306 + * c-parser.cc (c_parser_pragma): Accept a subset of non-executable + OpenMP directives in intervening code. + (c_parser_omp_error): Reject 'error at(execution)' in intervening code. + (c_parser_omp_metadirective): Return early if only one selector matches + and it resolves to 'omp nothing'. + +2025-10-21 Tobias Burnus <tburnus@baylibre.com> + + * c-parser.cc (c_parser_omp_assumption_clauses): Switch to + 'unknown' not 'invalid' directive name for end directives. + 2025-10-08 Joseph Myers <josmyers@redhat.com> * c-typeck.cc (in_generic, save_maybe_used, restore_maybe_used): 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/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h index 9c18c04..dbad4a1 100644 --- a/gcc/common/config/i386/cpuinfo.h +++ b/gcc/common/config/i386/cpuinfo.h @@ -639,6 +639,22 @@ get_intel_cpu (struct __processor_model *cpu_model, default: break; } + /* Parse family and model for family 0x12. */ + else if (cpu_model2->__cpu_family == 0x12) + switch (cpu_model2->__cpu_model) + { + case 0x01: + case 0x03: + /* Nova Lake. */ + cpu = "novalake"; + CHECK___builtin_cpu_is ("corei7"); + CHECK___builtin_cpu_is ("novalake"); + cpu_model->__cpu_type = INTEL_COREI7; + cpu_model->__cpu_subtype = INTEL_COREI7_NOVALAKE; + break; + default: + break; + } /* Parse family and model for family 0x13. */ else if (cpu_model2->__cpu_family == 0x13) switch (cpu_model2->__cpu_model) diff --git a/gcc/common/config/i386/i386-common.cc b/gcc/common/config/i386/i386-common.cc index c71f2c1..a447a8d 100644 --- a/gcc/common/config/i386/i386-common.cc +++ b/gcc/common/config/i386/i386-common.cc @@ -2131,6 +2131,7 @@ const char *const processor_names[] = "arrowlake-s", "pantherlake", "diamondrapids", + "novalake", "intel", "lujiazui", "yongfeng", @@ -2272,6 +2273,8 @@ const pta processor_alias_table[] = M_CPU_SUBTYPE (INTEL_COREI7_DIAMONDRAPIDS), P_PROC_AVX10_1}, {"wildcatlake", PROCESSOR_PANTHERLAKE, CPU_HASWELL, PTA_PANTHERLAKE, M_CPU_SUBTYPE (INTEL_COREI7_PANTHERLAKE), P_PROC_AVX2}, + {"novalake", PROCESSOR_NOVALAKE, CPU_HASWELL, PTA_NOVALAKE, + M_CPU_SUBTYPE (INTEL_COREI7_NOVALAKE), P_PROC_AVX2}, {"bonnell", PROCESSOR_BONNELL, CPU_ATOM, PTA_BONNELL, M_CPU_TYPE (INTEL_BONNELL), P_PROC_SSSE3}, {"atom", PROCESSOR_BONNELL, CPU_ATOM, PTA_BONNELL, diff --git a/gcc/common/config/i386/i386-cpuinfo.h b/gcc/common/config/i386/i386-cpuinfo.h index 0e75626..e5323f1 100644 --- a/gcc/common/config/i386/i386-cpuinfo.h +++ b/gcc/common/config/i386/i386-cpuinfo.h @@ -106,6 +106,7 @@ enum processor_subtypes AMDFAM1AH_ZNVER5, ZHAOXIN_FAM7H_SHIJIDADAO, INTEL_COREI7_DIAMONDRAPIDS, + INTEL_COREI7_NOVALAKE, CPU_SUBTYPE_MAX }; diff --git a/gcc/config.gcc b/gcc/config.gcc index 2ecce1c..c678b80 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -729,7 +729,8 @@ skylake goldmont goldmont-plus tremont cascadelake tigerlake cooperlake \ sapphirerapids alderlake rocketlake eden-x2 nano nano-1000 nano-2000 nano-3000 \ nano-x2 eden-x4 nano-x4 lujiazui yongfeng shijidadao x86-64 x86-64-v2 \ x86-64-v3 x86-64-v4 sierraforest graniterapids graniterapids-d grandridge \ -arrowlake arrowlake-s clearwaterforest pantherlake diamondrapids native" +arrowlake arrowlake-s clearwaterforest pantherlake diamondrapids novalake \ +native" # Additional x86 processors supported by --with-cpu=. Each processor # MUST be separated by exactly one space. @@ -6108,7 +6109,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/driver-i386.cc b/gcc/config/i386/driver-i386.cc index fe71f55..0557df9 100644 --- a/gcc/config/i386/driver-i386.cc +++ b/gcc/config/i386/driver-i386.cc @@ -553,6 +553,7 @@ const char *host_detect_local_cpu (int argc, const char **argv) processor = PROCESSOR_PENTIUM; break; case 6: + case 18: case 19: processor = PROCESSOR_PENTIUMPRO; break; @@ -639,18 +640,27 @@ const char *host_detect_local_cpu (int argc, const char **argv) } else if (has_feature (FEATURE_AVX)) { - /* Assume Panther Lake. */ - if (has_feature (FEATURE_PREFETCHI)) - cpu = "pantherlake"; /* Assume Clearwater Forest. */ - else if (has_feature (FEATURE_USER_MSR)) + if (has_feature (FEATURE_USER_MSR)) cpu = "clearwaterforest"; - /* Assume Arrow Lake S. */ + /* Assume Nova Lake. */ + else if (has_feature (FEATURE_PREFETCHI)) + cpu = "novalake"; else if (has_feature (FEATURE_SM3)) - cpu = "arrowlake-s"; + { + if (has_feature (FEATURE_KL)) + /* Assume Arrow Lake S. */ + cpu = "arrowlake-s"; + else + /* Assume Panther Lake. */ + cpu = "pantherlake"; + } /* Assume Sierra Forest. */ - else if (has_feature (FEATURE_AVXVNNIINT8)) + else if (has_feature (FEATURE_CLDEMOTE)) cpu = "sierraforest"; + /* Assume Arrow Lake. */ + else if (has_feature (FEATURE_AVXVNNIINT8)) + cpu = "arrowlake"; /* Assume Alder Lake. */ else if (has_feature (FEATURE_SERIALIZE)) cpu = "alderlake"; diff --git a/gcc/config/i386/i386-c.cc b/gcc/config/i386/i386-c.cc index 0037465..2d92cee 100644 --- a/gcc/config/i386/i386-c.cc +++ b/gcc/config/i386/i386-c.cc @@ -295,6 +295,10 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag, def_or_undef (parse_in, "__diamondrapids"); def_or_undef (parse_in, "__diamondrapids__"); break; + case PROCESSOR_NOVALAKE: + def_or_undef (parse_in, "__novalake"); + def_or_undef (parse_in, "__novalake__"); + break; /* use PROCESSOR_max to not set/unset the arch macro. */ case PROCESSOR_max: @@ -498,6 +502,9 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag, case PROCESSOR_DIAMONDRAPIDS: def_or_undef (parse_in, "__tune_diamondrapids__"); break; + case PROCESSOR_NOVALAKE: + def_or_undef (parse_in, "__tune_novalake__"); + break; case PROCESSOR_INTEL: case PROCESSOR_GENERIC: break; 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/i386/i386-jit.cc b/gcc/config/i386/i386-jit.cc index c1e2929..73ca590 100644 --- a/gcc/config/i386/i386-jit.cc +++ b/gcc/config/i386/i386-jit.cc @@ -65,6 +65,18 @@ ix86_jit_register_target_info (void) jit_target_add_supported_target_dependent_type (GCC_JIT_TYPE_INT128_T); } + if (float16_type_node != NULL && TYPE_PRECISION (float16_type_node) == 16) + jit_target_add_supported_target_dependent_type (GCC_JIT_TYPE_FLOAT16); + + if (float32_type_node != NULL && TYPE_PRECISION (float32_type_node) == 32) + jit_target_add_supported_target_dependent_type (GCC_JIT_TYPE_FLOAT32); + + if (float64_type_node != NULL && TYPE_PRECISION (float64_type_node) == 64) + jit_target_add_supported_target_dependent_type (GCC_JIT_TYPE_FLOAT64); + + if (float128_type_node != NULL && TYPE_PRECISION (float128_type_node) == 128) + jit_target_add_supported_target_dependent_type (GCC_JIT_TYPE_FLOAT128); + #define ADD_TARGET_INFO jit_add_target_info #include "i386-rust-and-jit.inc" #undef ADD_TARGET_INFO diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc index 35cba3f..dadcf76 100644 --- a/gcc/config/i386/i386-options.cc +++ b/gcc/config/i386/i386-options.cc @@ -132,6 +132,7 @@ along with GCC; see the file COPYING3. If not see #define m_ARROWLAKE_S (HOST_WIDE_INT_1U<<PROCESSOR_ARROWLAKE_S) #define m_PANTHERLAKE (HOST_WIDE_INT_1U<<PROCESSOR_PANTHERLAKE) #define m_DIAMONDRAPIDS (HOST_WIDE_INT_1U<<PROCESSOR_DIAMONDRAPIDS) +#define m_NOVALAKE (HOST_WIDE_INT_1U<<PROCESSOR_NOVALAKE) #define m_CORE_AVX512 (m_SKYLAKE_AVX512 | m_CANNONLAKE \ | m_ICELAKE_CLIENT | m_ICELAKE_SERVER | m_CASCADELAKE \ | m_TIGERLAKE | m_COOPERLAKE | m_SAPPHIRERAPIDS \ @@ -140,7 +141,7 @@ along with GCC; see the file COPYING3. If not see #define m_CORE_AVX2 (m_HASWELL | m_SKYLAKE | m_CORE_AVX512) #define m_CORE_ALL (m_CORE2 | m_NEHALEM | m_SANDYBRIDGE | m_CORE_AVX2) #define m_CORE_HYBRID (m_ALDERLAKE | m_ARROWLAKE | m_ARROWLAKE_S \ - | m_PANTHERLAKE) + | m_PANTHERLAKE | m_NOVALAKE) #define m_GOLDMONT (HOST_WIDE_INT_1U<<PROCESSOR_GOLDMONT) #define m_GOLDMONT_PLUS (HOST_WIDE_INT_1U<<PROCESSOR_GOLDMONT_PLUS) #define m_TREMONT (HOST_WIDE_INT_1U<<PROCESSOR_TREMONT) @@ -790,6 +791,7 @@ static const struct processor_costs *processor_cost_table[] = &alderlake_cost, /* PROCESSOR_ARROWLAKE_S. */ &alderlake_cost, /* PROCESSOR_PANTHERLAKE. */ &icelake_cost, /* PROCESSOR_DIAMONDRAPIDS. */ + &alderlake_cost, /* PROCESSOR_NOVALAKE. */ &alderlake_cost, /* PROCESSOR_INTEL. */ &lujiazui_cost, /* PROCESSOR_LUJIAZUI. */ &yongfeng_cost, /* PROCESSOR_YONGFENG. */ diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 3a66d78..94f335f 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -2356,6 +2356,7 @@ enum processor_type PROCESSOR_ARROWLAKE_S, PROCESSOR_PANTHERLAKE, PROCESSOR_DIAMONDRAPIDS, + PROCESSOR_NOVALAKE, PROCESSOR_INTEL, PROCESSOR_LUJIAZUI, PROCESSOR_YONGFENG, @@ -2487,6 +2488,7 @@ constexpr wide_int_bitmask PTA_DIAMONDRAPIDS = PTA_GRANITERAPIDS_D | PTA_CMPCCXADD | PTA_SHA512 | PTA_SM3 | PTA_SM4 | PTA_AVX10_2 | PTA_APX_F | PTA_AMX_AVX512 | PTA_AMX_FP8 | PTA_AMX_TF32 | PTA_MOVRS | PTA_AMX_MOVRS; +constexpr wide_int_bitmask PTA_NOVALAKE = PTA_PANTHERLAKE | PTA_PREFETCHI; constexpr wide_int_bitmask PTA_BDVER1 = PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3 | PTA_SSE4A | PTA_CX16 | PTA_POPCNT | PTA_LZCNT diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 8b28c8e..4ad17f6 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -4632,6 +4632,33 @@ UNSPEC_PCMP_ITER))] "operands[4] = GEN_INT (INTVAL (operands[3]) ^ 4);") +(define_insn_and_split "*<avx512>_cmp<mode>3_dup_op" + [(set (match_operand:<avx512fmaskmode> 0 "register_operand") + (unspec:<avx512fmaskmode> + [(match_operand:VI1248_AVX512VLBW 1 "general_operand") + (match_operand:VI1248_AVX512VLBW 2 "general_operand") + (match_operand:SI 3 "<cmp_imm_predicate>")] + UNSPEC_PCMP_ITER))] + "TARGET_AVX512F && ix86_pre_reload_split () + && rtx_equal_p (operands[1], operands[2])" + "#" + "&& 1" + [(set (match_dup 0) (match_dup 4))] +{ + int cmp_imm = INTVAL (operands[3]); + rtx res = CONST0_RTX (<avx512fmaskmode>mode); + /* EQ/LE/NLT. */ + if (cmp_imm == 0 || cmp_imm == 2 || cmp_imm == 5) + { + int nelts = GET_MODE_NUNITS (<MODE>mode); + if (nelts >= 8) + res = CONSTM1_RTX (<avx512fmaskmode>mode); + else + res = gen_int_mode ((1u << nelts) - 1, QImode); + } + operands[4] = res; +}) + (define_insn "*<avx512>_eq<mode>3<mask_scalar_merge_name>_1" [(set (match_operand:<avx512fmaskmode> 0 "register_operand" "=k,k") (unspec:<avx512fmaskmode> 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/ChangeLog b/gcc/cp/ChangeLog index 3bf1e7d..75cd6fe 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,29 @@ +2025-10-21 Jakub Jelinek <jakub@redhat.com> + + * cp-tree.h: Implement C++23 P2674R1 - A trait for implicit lifetime + types. + (implicit_lifetime_type_p): Declare. + * tree.cc (implicit_lifetime_type_p): New function. + * cp-trait.def (IS_IMPLICIT_LIFETIME): New unary trait. + * semantics.cc (trait_expr_value): Handle CPTK_IS_IMPLICIT_LIFETIME. + (finish_trait_expr): Likewise. + * constraint.cc (diagnose_trait_expr): Likewise. + +2025-10-21 Paul-Antoine Arras <parras@baylibre.com> + + PR c/120180 + PR fortran/122306 + * parser.cc (cp_parser_omp_metadirective): Return early if only one + selector matches and it resolves to 'omp nothing'. + (cp_parser_omp_error): Reject 'error at(execution)' in intervening code. + (cp_parser_pragma): Accept a subset of non-executable OpenMP directives + as intervening code. + +2025-10-21 Tobias Burnus <tburnus@baylibre.com> + + * parser.cc (cp_parser_omp_assumption_clauses): Switch to + 'unknown' not 'invalid' directive name for end directives. + 2025-10-18 Iain Sandoe <iain@sandoe.co.uk> PR c++/119060 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/doc/extend.texi b/gcc/doc/extend.texi index 94b76b7..fb117f5 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -28408,6 +28408,9 @@ Intel Core i7 Panther Lake CPU. @item diamondrapids Intel Core i7 Diamond Rapids CPU. +@item novalake +Intel Core i7 Nova Lake CPU. + @item bonnell Intel Atom Bonnell CPU. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 189b266..b40fc89 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -35170,6 +35170,15 @@ LZCNT, PCONFIG, PKU, VAES, VPCLMULQDQ, SERIALIZE, HRESET, AVX-VNNI, UINTR, AVXIFMA, AVXVNNIINT8, AVXNECONVERT, CMPCCXADD, AVXVNNIINT16, SHA512, SM3 and SM4 instruction set support. +@item novalake +Intel Nova Lake CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3, +SSSE3, SSE4.1, SSE4.2, POPCNT, AES, PREFETCHW, PCLMUL, RDRND, XSAVE, XSAVEC, +XSAVES, XSAVEOPT, FSGSBASE, PTWRITE, RDPID, SGX, GFNI-SSE, CLWB, MOVDIRI, +MOVDIR64B, WAITPKG, ADCX, AVX, AVX2, BMI, BMI2, F16C, FMA, LZCNT, PCONFIG, PKU, +VAES, VPCLMULQDQ, SERIALIZE, HRESET, AVX-VNNI, UINTR, AVXIFMA, AVXVNNIINT8, +AVXNECONVERT, CMPCCXADD, AVXVNNIINT16, SHA512, SM3, SM4 and PREFETCHI +instruction set support. + @item sapphirerapids @itemx emeraldrapids Intel Sapphire Rapids/Emerald Rapids CPU with 64-bit extensions, MMX, SSE, diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 81d666c..792f3c7 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,30 @@ +2025-10-21 Paul-Antoine Arras <parras@baylibre.com> + + PR c/120180 + PR fortran/122306 + * gfortran.h (enum gfc_exec_op): Add EXEC_OMP_FIRST_OPENMP_EXEC and + EXEC_OMP_LAST_OPENMP_EXEC. + * openmp.cc (gfc_match_omp_context_selector): Remove static. Remove + checks on score. Add cleanup. Remove checks on trait properties. + (gfc_match_omp_context_selector_specification): Remove static. Adjust + calls to gfc_match_omp_context_selector. + (gfc_match_omp_declare_variant): Adjust call to + gfc_match_omp_context_selector_specification. + (match_omp_metadirective): Likewise. + (icode_code_error_callback): Reject all statements except + 'assume' and 'metadirective'. + (gfc_resolve_omp_context_selector): New function. + (resolve_omp_metadirective): Skip metadirectives which context selectors + can be statically resolved to false. Replace metadirective by its body + if only 'nothing' remains. + (gfc_resolve_omp_declare): Call gfc_resolve_omp_context_selector for + each variant. + +2025-10-21 Tobias Burnus <tburnus@baylibre.com> + + * openmp.cc (gfc_omp_directive): Add comment to 'allocate'; + add 6.x unimplemented directives as comment-out entries. + 2025-10-18 Yuao Ma <c8ef@outlook.com> * resolve.cc (resolve_conditional): Allow character in cond-expr. 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..ae4d7d4 100644 --- a/gcc/jit/docs/topics/types.rst +++ b/gcc/jit/docs/topics/types.rst @@ -119,6 +119,14 @@ Standard types - * - :c:data:`GCC_JIT_TYPE_LONG_DOUBLE` - + * - :c:data:`GCC_JIT_TYPE_FLOAT16` + - + * - :c:data:`GCC_JIT_TYPE_FLOAT32` + - + * - :c:data:`GCC_JIT_TYPE_FLOAT64` + - + * - :c:data:`GCC_JIT_TYPE_FLOAT128` + - * - :c:data:`GCC_JIT_TYPE_CONST_CHAR_PTR` - C type: ``(const char *)`` * - :c:data:`GCC_JIT_TYPE_SIZE_T` @@ -163,6 +171,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..0668d67 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); @@ -1190,12 +1195,6 @@ recording::type* tree_type_to_jit_type (tree type) // FIXME: wrong type. return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_VOID); - /* TODO: Remove when we add support for sized floating-point types. */ - for (int i = 0; i < NUM_FLOATN_NX_TYPES; i++) - if (type == FLOATN_NX_TYPE_NODE (i)) - // FIXME: wrong type. - return new recording::memento_of_get_type (&target_builtins_ctxt, - GCC_JIT_TYPE_VOID); if (type == void_type_node) return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_VOID); @@ -1261,6 +1260,26 @@ recording::type* tree_type_to_jit_type (tree type) else if (type == bfloat16_type_node) return new recording::memento_of_get_type (&target_builtins_ctxt, GCC_JIT_TYPE_BFLOAT16); + else if (type == float16_type_node) + { + return new recording::memento_of_get_type (&target_builtins_ctxt, + GCC_JIT_TYPE_FLOAT16); + } + else if (type == float32_type_node) + { + return new recording::memento_of_get_type (&target_builtins_ctxt, + GCC_JIT_TYPE_FLOAT32); + } + else if (type == float64_type_node) + { + return new recording::memento_of_get_type (&target_builtins_ctxt, + GCC_JIT_TYPE_FLOAT64); + } + else if (type == float128_type_node) + { + return new recording::memento_of_get_type (&target_builtins_ctxt, + GCC_JIT_TYPE_FLOAT128); + } else if (type == dfloat128_type_node) // FIXME: wrong type. return new recording::memento_of_get_type (&target_builtins_ctxt, @@ -1282,6 +1301,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 +1353,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..e32bd88 100644 --- a/gcc/jit/jit-common.h +++ b/gcc/jit/jit-common.h @@ -36,7 +36,7 @@ along with GCC; see the file COPYING3. If not see #endif #endif -const int NUM_GCC_JIT_TYPES = GCC_JIT_TYPE_BFLOAT16 + 1; +const int NUM_GCC_JIT_TYPES = GCC_JIT_TYPE_FLOAT128 + 1; /* This comment is included by the docs. @@ -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..00d5e72 100644 --- a/gcc/jit/jit-playback.cc +++ b/gcc/jit/jit-playback.cc @@ -295,6 +295,39 @@ get_tree_node_for_type (enum gcc_jit_types type_) return double_type_node; case GCC_JIT_TYPE_LONG_DOUBLE: return long_double_type_node; + case GCC_JIT_TYPE_FLOAT16: + if (float16_type_node == NULL || TYPE_PRECISION (float16_type_node) != 16) + { + add_error (NULL, "gcc_jit_types value unsupported on this target: %i", + type_); + return NULL; + } + return float16_type_node; + case GCC_JIT_TYPE_FLOAT32: + if (float32_type_node == NULL || TYPE_PRECISION (float32_type_node) != 32) + { + add_error (NULL, "gcc_jit_types value unsupported on this target: %i", + type_); + return NULL; + } + return float32_type_node; + case GCC_JIT_TYPE_FLOAT64: + if (float64_type_node == NULL || TYPE_PRECISION (float64_type_node) != 64) + { + add_error (NULL, "gcc_jit_types value unsupported on this target: %i", + type_); + return NULL; + } + return float64_type_node; + case GCC_JIT_TYPE_FLOAT128: + if (float128_type_node == NULL + || TYPE_PRECISION (float128_type_node) != 128) + { + add_error (NULL, "gcc_jit_types value unsupported on this target: %i", + type_); + return NULL; + } + return float128_type_node; case GCC_JIT_TYPE_SIZE_T: return size_type_node; @@ -344,7 +377,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 +3904,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 +3916,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 +3946,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..6816a71 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 @@ -2634,6 +2662,18 @@ recording::memento_of_get_type::get_size () m = targetm.c.mode_for_floating_type (TI_LONG_DOUBLE_TYPE); size = GET_MODE_PRECISION (m).to_constant (); break; + case GCC_JIT_TYPE_FLOAT16: + size = 16; + break; + case GCC_JIT_TYPE_FLOAT32: + size = 32; + break; + case GCC_JIT_TYPE_FLOAT64: + size = 64; + break; + case GCC_JIT_TYPE_FLOAT128: + size = 128; + break; case GCC_JIT_TYPE_SIZE_T: size = MAX_BITS_PER_WORD; break; @@ -2690,6 +2730,10 @@ recording::memento_of_get_type::dereference () case GCC_JIT_TYPE_BFLOAT16: case GCC_JIT_TYPE_DOUBLE: case GCC_JIT_TYPE_LONG_DOUBLE: + case GCC_JIT_TYPE_FLOAT16: + case GCC_JIT_TYPE_FLOAT32: + case GCC_JIT_TYPE_FLOAT64: + case GCC_JIT_TYPE_FLOAT128: case GCC_JIT_TYPE_COMPLEX_FLOAT: case GCC_JIT_TYPE_COMPLEX_DOUBLE: case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE: @@ -2755,6 +2799,10 @@ recording::memento_of_get_type::is_int () const case GCC_JIT_TYPE_BFLOAT16: case GCC_JIT_TYPE_DOUBLE: case GCC_JIT_TYPE_LONG_DOUBLE: + case GCC_JIT_TYPE_FLOAT16: + case GCC_JIT_TYPE_FLOAT32: + case GCC_JIT_TYPE_FLOAT64: + case GCC_JIT_TYPE_FLOAT128: return false; case GCC_JIT_TYPE_CONST_CHAR_PTR: @@ -2814,6 +2862,10 @@ recording::memento_of_get_type::is_signed () const case GCC_JIT_TYPE_BFLOAT16: case GCC_JIT_TYPE_DOUBLE: case GCC_JIT_TYPE_LONG_DOUBLE: + case GCC_JIT_TYPE_FLOAT16: + case GCC_JIT_TYPE_FLOAT32: + case GCC_JIT_TYPE_FLOAT64: + case GCC_JIT_TYPE_FLOAT128: case GCC_JIT_TYPE_CONST_CHAR_PTR: @@ -2874,6 +2926,10 @@ recording::memento_of_get_type::is_float () const case GCC_JIT_TYPE_BFLOAT16: case GCC_JIT_TYPE_DOUBLE: case GCC_JIT_TYPE_LONG_DOUBLE: + case GCC_JIT_TYPE_FLOAT16: + case GCC_JIT_TYPE_FLOAT32: + case GCC_JIT_TYPE_FLOAT64: + case GCC_JIT_TYPE_FLOAT128: return true; case GCC_JIT_TYPE_CONST_CHAR_PTR: @@ -2938,6 +2994,10 @@ recording::memento_of_get_type::is_bool () const case GCC_JIT_TYPE_BFLOAT16: case GCC_JIT_TYPE_DOUBLE: case GCC_JIT_TYPE_LONG_DOUBLE: + case GCC_JIT_TYPE_FLOAT16: + case GCC_JIT_TYPE_FLOAT32: + case GCC_JIT_TYPE_FLOAT64: + case GCC_JIT_TYPE_FLOAT128: return false; case GCC_JIT_TYPE_CONST_CHAR_PTR: @@ -3015,8 +3075,11 @@ static const char * const get_type_strings[] = { "__int32_t", /* GCC_JIT_TYPE_INT32_T */ "__int64_t", /* GCC_JIT_TYPE_INT64_T */ "__int128_t", /* GCC_JIT_TYPE_INT128_T */ - - "bfloat16", /* GCC_JIT_TYPE_BFLOAT16 */ + "bfloat16", /* GCC_JIT_TYPE_BFLOAT16 */ + "_Float16", /* GCC_JIT_TYPE_FLOAT16 */ + "_Float32", /* GCC_JIT_TYPE_FLOAT32 */ + "_Float64", /* GCC_JIT_TYPE_FLOAT64 */ + "__float128", /* GCC_JIT_TYPE_FLOAT128 */ }; /* Implementation of recording::memento::make_debug_string for @@ -3063,6 +3126,10 @@ static const char * const get_type_enum_strings[] = { "GCC_JIT_TYPE_INT64_T", "GCC_JIT_TYPE_INT128_T", "GCC_JIT_TYPE_BFLOAT16", + "GCC_JIT_TYPE_FLOAT16", + "GCC_JIT_TYPE_FLOAT32", + "GCC_JIT_TYPE_FLOAT64", + "GCC_JIT_TYPE_FLOAT128", }; void @@ -3363,7 +3430,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 +3443,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..1cc5e6a 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>) @@ -618,6 +619,10 @@ enum gcc_jit_types GCC_JIT_TYPE_INT128_T, GCC_JIT_TYPE_BFLOAT16, + GCC_JIT_TYPE_FLOAT16, + GCC_JIT_TYPE_FLOAT32, + GCC_JIT_TYPE_FLOAT64, + GCC_JIT_TYPE_FLOAT128, }; extern gcc_jit_type * @@ -676,6 +681,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 +2235,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..d0c104e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,185 @@ +2025-10-21 Martin Uecker <uecker@tugraz.at> + + * gcc.dg/c2y-generic-6.c: New test. + * gcc.dg/c2y-generic-7.c: New test. + +2025-10-21 Jakub Jelinek <jakub@redhat.com> + + * g++.dg/ext/is_implicit_lifetime.C: New test. + +2025-10-21 Christophe Lyon <christophe.lyon@linaro.org> + + PR target/122189 + * gcc.target/arm/mve/intrinsics/vadcq_m_s32.c + * gcc.target/arm/mve/intrinsics/vadcq_m_u32.c + * gcc.target/arm/mve/intrinsics/vsbcq_m_s32.c + * gcc.target/arm/mve/intrinsics/vsbcq_m_u32.c + +2025-10-21 Paul-Antoine Arras <parras@baylibre.com> + + PR c/120180 + PR fortran/122306 + * c-c++-common/gomp/imperfect1.c: Adjust dg-error. + * c-c++-common/gomp/imperfect4.c: Likewise. + * c-c++-common/gomp/pr120180.c: Move to... + * c-c++-common/gomp/pr120180-1.c: ...here. Remove dg-error. + * g++.dg/gomp/attrs-imperfect1.C: Adjust dg-error. + * g++.dg/gomp/attrs-imperfect4.C: Likewise. + * gfortran.dg/gomp/declare-variant-2.f90: Adjust dg-error. + * gfortran.dg/gomp/declare-variant-20.f90: Likewise. + * c-c++-common/gomp/pr120180-2.c: New test. + * g++.dg/gomp/pr120180-1.C: New test. + * gfortran.dg/gomp/pr120180-1.f90: New test. + * gfortran.dg/gomp/pr120180-2.f90: New test. + * gfortran.dg/gomp/pr122306-1.f90: New file. + * gfortran.dg/gomp/pr122306-2.f90: New file. + +2025-10-21 Roger Sayle <roger@nextmovesoftware.com> + + * gcc.target/i386/sse4_1-stv-10.c: New test case. + * gcc.target/i386/sse4_1-stv-11.c: Likewise. + * gcc.target/i386/sse4_1-stv-12.c: Likewise. + +2025-10-21 Tobias Burnus <tburnus@baylibre.com> + + * c-c++-common/gomp/assumes-2.c: Change for 'invalid' + to 'unknown' change for end directives. + * c-c++-common/gomp/begin-assumes-2.c: Likewise. + * c-c++-common/gomp/assume-2.c: Likewise. Check 'declare + mapper'. + +2025-10-21 Richard Biener <rguenther@suse.de> + + PR tree-optimization/120687 + * gcc.dg/vect/vect-reduc-chain-4.c: New testcase. + +2025-10-21 Avinash Jayakar <avinashd@linux.ibm.com> + + PR target/104116 + * gcc.dg/vect/pr104116-ceil-div-2.c: disable vectorization. + * gcc.dg/vect/pr104116-ceil-div-pow2.c: disable vectorization. + * gcc.dg/vect/pr104116-ceil-div.c: disable vectorization. + * gcc.dg/vect/pr104116-ceil-mod-2.c: disable vectorization. + * gcc.dg/vect/pr104116-ceil-mod-pow2.c: disable vectorization. + * gcc.dg/vect/pr104116-ceil-mod.c: disable vectorization. + * gcc.dg/vect/pr104116-ceil-udiv-2.c: disable vectorization. + * gcc.dg/vect/pr104116-ceil-udiv-pow2.c: disable vectorization. + * gcc.dg/vect/pr104116-ceil-udiv.c: disable vectorization. + * gcc.dg/vect/pr104116-ceil-umod-2.c: disable vectorization. + * gcc.dg/vect/pr104116-ceil-umod-pow2.c: disable vectorization. + * gcc.dg/vect/pr104116-ceil-umod.c: disable vectorization. + * gcc.dg/vect/pr104116-floor-div-2.c: disable vectorization. + * gcc.dg/vect/pr104116-floor-div-pow2.c: disable vectorization. + * gcc.dg/vect/pr104116-floor-div.c: disable vectorization. + * gcc.dg/vect/pr104116-floor-mod-2.c: disable vectorization. + * gcc.dg/vect/pr104116-floor-mod-pow2.c: disable vectorization. + * gcc.dg/vect/pr104116-floor-mod.c: disable vectorization. + * gcc.dg/vect/pr104116-round-div-2.c: disable vectorization. + * gcc.dg/vect/pr104116-round-div-pow2.c: disable vectorization. + * gcc.dg/vect/pr104116-round-div.c: disable vectorization. + * gcc.dg/vect/pr104116-round-mod-2.c: disable vectorization. + * gcc.dg/vect/pr104116-round-mod-pow2.c: disable vectorization. + * gcc.dg/vect/pr104116-round-mod.c: disable vectorization. + * gcc.dg/vect/pr104116-round-udiv-2.c: disable vectorization. + * gcc.dg/vect/pr104116-round-udiv-pow2.c: disable vectorization. + * gcc.dg/vect/pr104116-round-udiv.c: disable vectorization. + * gcc.dg/vect/pr104116-round-umod-2.c: disable vectorization. + * gcc.dg/vect/pr104116-round-umod-pow2.c: disable vectorization. + * gcc.dg/vect/pr104116-round-umod.c: disable vectorization. + * gcc.dg/vect/pr104116.h (init_arr): use std idiom, correct + indentation. + (init_uarr): use std idiom. + +2025-10-21 Andrew Pinski <andrew.pinski@oss.qualcomm.com> + + PR tree-optimization/95699 + PR tree-optimization/101024 + PR tree-optimization/110068 + * gcc.dg/tree-ssa/pr101024-1.c: New test. + * gcc.dg/tree-ssa/pr110068-1.c: New test. + +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/g++.target/i386/mv16.C b/gcc/testsuite/g++.target/i386/mv16.C index 75198f5..87126a0 100644 --- a/gcc/testsuite/g++.target/i386/mv16.C +++ b/gcc/testsuite/g++.target/i386/mv16.C @@ -128,6 +128,10 @@ int __attribute__ ((target("arch=diamondrapids"))) foo () { return 33; } +int __attribute__ ((target("arch=novalake"))) foo () { + return 34; +} + int main () { int val = foo (); @@ -184,6 +188,8 @@ int main () assert (val == 32); else if (__builtin_cpu_is ("diamondrapids")) assert (val == 33); + else if (__builtin_cpu_is ("novalake")) + assert (val == 34); else assert (val == 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/ipa/ipcp-cb-spec1.c b/gcc/testsuite/gcc.dg/ipa/ipcp-cb-spec1.c deleted file mode 100644 index a85e623..0000000 --- a/gcc/testsuite/gcc.dg/ipa/ipcp-cb-spec1.c +++ /dev/null @@ -1,19 +0,0 @@ -/* Test that GOMP_task is special cased when cpyfn is NULL. */ - -/* { dg-do run } */ -/* { dg-options "-O3 -fopenmp -flto -std=gnu99 -fdump-ipa-cp-details" } */ -/* { dg-require-effective-target fopenmp } */ -/* { dg-require-effective-target lto } */ - -void test(int c) { - for (int i = 0; i < c; i++) - if (!__builtin_constant_p(c)) - __builtin_abort(); -} -int main() { -#pragma omp task - test(7); - return 0; -} - -/* { dg-final { scan-wpa-ipa-dump "Creating a specialized node of main._omp_fn" "cp" } } */ diff --git a/gcc/testsuite/gcc.dg/ipa/ipcp-cb-spec2.c b/gcc/testsuite/gcc.dg/ipa/ipcp-cb-spec2.c deleted file mode 100644 index 01d7425..0000000 --- a/gcc/testsuite/gcc.dg/ipa/ipcp-cb-spec2.c +++ /dev/null @@ -1,21 +0,0 @@ -/* Check that GOMP_task doesn't produce callback edges when cpyfn is not - NULL. */ - -/* { dg-do run } */ -/* { dg-options "-O3 -fopenmp -flto -std=gnu99 -fdump-ipa-cp-details" } */ -/* { dg-require-effective-target fopenmp } */ -/* { dg-require-effective-target lto } */ - -void test(int *a) { - for (int i = 0; i < 100; i++) { - a[i] = i; - } -} -int main() { - int a[100]; - __builtin_memset (a, 0, sizeof (a)); - #pragma omp task - test (a); -} - -/* { dg-final { scan-ipa-dump-not "Created callback edge" "cp" } } */ diff --git a/gcc/testsuite/gcc.dg/ipa/ipcp-cb1.c b/gcc/testsuite/gcc.dg/ipa/ipcp-cb1.c deleted file mode 100644 index 3418b5d..0000000 --- a/gcc/testsuite/gcc.dg/ipa/ipcp-cb1.c +++ /dev/null @@ -1,25 +0,0 @@ -/* Test that we can propagate constants into outlined OpenMP kernels. - This tests the underlying callback attribute and its related edges. */ - -/* { dg-do run } */ -/* { dg-options "-O3 -fopenmp -flto -std=gnu99 -fdump-ipa-cp-details" } */ -/* { dg-require-effective-target fopenmp } */ -/* { dg-require-effective-target lto } */ - -int a[100]; -void test(int c) { -#pragma omp parallel for - for (int i = 0; i < c; i++) { - if (!__builtin_constant_p(c)) { - __builtin_abort(); - } - a[i] = i; - } -} -int main() { - test(100); - return a[5] - 5; -} - -/* { dg-final { scan-wpa-ipa-dump "Creating a specialized node of test._omp_fn" "cp" } } */ -/* { dg-final { scan-wpa-ipa-dump "Aggregate replacements: 0\\\[0]=100\\(by_ref\\)" "cp" } } */ 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-bool-9.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-bool-9.c new file mode 100644 index 0000000..4ec141c --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-bool-9.c @@ -0,0 +1,27 @@ +/* PR122365 */ +/* { dg-do compile } */ + +struct TDTI { + float V[4]; +}; +struct TDTI4D { + struct TDTI S[]; +}; +void bar(); +struct TDTI4D nii_readParRec_dti4D; +int nii_readParRec_d_0_0; +void nii_readParRec() { + for (int i;;) { + bool v1varies = false, v2varies = false, v3varies = false; + for (; i < nii_readParRec_d_0_0; i++) { + if (nii_readParRec_dti4D.S[i].V[1]) + v1varies = true; + if (nii_readParRec_dti4D.S[i].V[2]) + v2varies = true; + if (nii_readParRec_dti4D.S[i].V[3]) + v3varies = true; + } + if (v1varies || v2varies || v3varies) + bar(); + } +} 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/funcspec-56.inc b/gcc/testsuite/gcc.target/i386/funcspec-56.inc index 3d9af7a..f56b344 100644 --- a/gcc/testsuite/gcc.target/i386/funcspec-56.inc +++ b/gcc/testsuite/gcc.target/i386/funcspec-56.inc @@ -217,6 +217,7 @@ extern void test_arch_arrowlake (void) __attribute__((__target__("arch=arrowlak extern void test_arch_arrowlake_s (void) __attribute__((__target__("arch=arrowlake-s"))); extern void test_arch_pantherlake (void) __attribute__((__target__("arch=pantherlake"))); extern void test_arch_diamondrapids (void) __attribute__((__target__("arch=diamondrapids"))); +extern void test_arch_novalake (void) __attribute__((__target__("arch=novalake"))); extern void test_arch_lujiazui (void) __attribute__((__target__("arch=lujiazui"))); extern void test_arch_yongfeng (void) __attribute__((__target__("arch=yongfeng"))); extern void test_arch_shijidadao (void) __attribute__((__target__("arch=shijidadao"))); diff --git a/gcc/testsuite/gcc.target/i386/pr122320-mask16.c b/gcc/testsuite/gcc.target/i386/pr122320-mask16.c new file mode 100644 index 0000000..2796d74 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr122320-mask16.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-march=x86-64-v4 -O2" } */ +/* { dg-final { scan-assembler-not "vpcmp" } } */ + +#include <immintrin.h> + +__mmask16 dumpy_eq (__m512i vx){ + return _mm512_cmp_epi32_mask (vx, vx, 0); +} + +__mmask16 dumpy_lt (__m512i vx) +{ + return _mm512_cmp_epi32_mask (vx, vx, 1); +} + +__mmask16 dumpy_le (__m512i vx){ + return _mm512_cmp_epi32_mask (vx, vx, 2); +} + +__mmask16 dumpy_ne (__m512i vx) +{ + return _mm512_cmp_epi32_mask (vx, vx, 4); +} + +__mmask16 dumpy_nlt (__m512i vx) +{ + return _mm512_cmp_epi32_mask (vx, vx, 5); +} + +__mmask16 dumpy_nle (__m512i vx){ + return _mm512_cmp_epi32_mask (vx, vx, 6); +} diff --git a/gcc/testsuite/gcc.target/i386/pr122320-mask2.c b/gcc/testsuite/gcc.target/i386/pr122320-mask2.c new file mode 100644 index 0000000..bcbc47a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr122320-mask2.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-march=x86-64-v4 -O2" } */ +/* { dg-final { scan-assembler-not "vpcmp" } } */ + +#include <immintrin.h> + +__mmask8 dumpy_eq (__m128i vx){ + return _mm_cmp_epi64_mask (vx, vx, 0); +} + +__mmask8 dumpy_lt (__m128i vx) +{ + return _mm_cmp_epi64_mask (vx, vx, 1); +} + +__mmask8 dumpy_le (__m128i vx){ + return _mm_cmp_epi64_mask (vx, vx, 2); +} + +__mmask8 dumpy_ne (__m128i vx) +{ + return _mm_cmp_epi64_mask (vx, vx, 4); +} + +__mmask8 dumpy_nlt (__m128i vx) +{ + return _mm_cmp_epi64_mask (vx, vx, 5); +} + +__mmask8 dumpy_nle (__m128i vx){ + return _mm_cmp_epi64_mask (vx, vx, 6); +} diff --git a/gcc/testsuite/gcc.target/i386/pr122320-mask32.c b/gcc/testsuite/gcc.target/i386/pr122320-mask32.c new file mode 100644 index 0000000..d75c8b0 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr122320-mask32.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-march=x86-64-v4 -O2" } */ +/* { dg-final { scan-assembler-not "vpcmp" } } */ + +#include <immintrin.h> + +__mmask32 dumpy_eq (__m512i vx){ + return _mm512_cmp_epi16_mask (vx, vx, 0); +} + +__mmask32 dumpy_lt (__m512i vx) +{ + return _mm512_cmp_epi16_mask (vx, vx, 1); +} + +__mmask32 dumpy_le (__m512i vx){ + return _mm512_cmp_epi16_mask (vx, vx, 2); +} + +__mmask32 dumpy_ne (__m512i vx) +{ + return _mm512_cmp_epi16_mask (vx, vx, 4); +} + +__mmask32 dumpy_nlt (__m512i vx) +{ + return _mm512_cmp_epi16_mask (vx, vx, 5); +} + +__mmask32 dumpy_nle (__m512i vx){ + return _mm512_cmp_epi16_mask (vx, vx, 6); +} diff --git a/gcc/testsuite/gcc.target/i386/pr122320-mask4.c b/gcc/testsuite/gcc.target/i386/pr122320-mask4.c new file mode 100644 index 0000000..7f2ec7d --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr122320-mask4.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-march=x86-64-v4 -O2" } */ +/* { dg-final { scan-assembler-not "vpcmp" } } */ + +#include <immintrin.h> + +__mmask8 dumpy_eq (__m256i vx){ + return _mm256_cmp_epi64_mask (vx, vx, 0); +} + +__mmask8 dumpy_lt (__m256i vx) +{ + return _mm256_cmp_epi64_mask (vx, vx, 1); +} + +__mmask8 dumpy_le (__m256i vx){ + return _mm256_cmp_epi64_mask (vx, vx, 2); +} + +__mmask8 dumpy_ne (__m256i vx) +{ + return _mm256_cmp_epi64_mask (vx, vx, 4); +} + +__mmask8 dumpy_nlt (__m256i vx) +{ + return _mm256_cmp_epi64_mask (vx, vx, 5); +} + +__mmask8 dumpy_nle (__m256i vx){ + return _mm256_cmp_epi64_mask (vx, vx, 6); +} diff --git a/gcc/testsuite/gcc.target/i386/pr122320-mask64.c b/gcc/testsuite/gcc.target/i386/pr122320-mask64.c new file mode 100644 index 0000000..6a7ce51 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr122320-mask64.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-march=x86-64-v4 -O2" } */ +/* { dg-final { scan-assembler-not "vpcmp" } } */ + +#include <immintrin.h> + +__mmask64 dumpy_eq (__m512i vx){ + return _mm512_cmp_epi8_mask (vx, vx, 0); +} + +__mmask64 dumpy_lt (__m512i vx) +{ + return _mm512_cmp_epi8_mask (vx, vx, 1); +} + +__mmask64 dumpy_le (__m512i vx){ + return _mm512_cmp_epi8_mask (vx, vx, 2); +} + +__mmask64 dumpy_ne (__m512i vx) +{ + return _mm512_cmp_epi8_mask (vx, vx, 4); +} + +__mmask64 dumpy_nlt (__m512i vx) +{ + return _mm512_cmp_epi8_mask (vx, vx, 5); +} + +__mmask64 dumpy_nle (__m512i vx){ + return _mm512_cmp_epi8_mask (vx, vx, 6); +} diff --git a/gcc/testsuite/gcc.target/i386/pr122320-mask8.c b/gcc/testsuite/gcc.target/i386/pr122320-mask8.c new file mode 100644 index 0000000..e724a68 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr122320-mask8.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-march=x86-64-v4 -O2" } */ +/* { dg-final { scan-assembler-not "vpcmp" } } */ + +#include <immintrin.h> + +__mmask8 dumpy_eq (__m512i vx){ + return _mm512_cmp_epi64_mask (vx, vx, 0); +} + +__mmask8 dumpy_lt (__m512i vx) +{ + return _mm512_cmp_epi64_mask (vx, vx, 1); +} + +__mmask8 dumpy_le (__m512i vx){ + return _mm512_cmp_epi64_mask (vx, vx, 2); +} + +__mmask8 dumpy_ne (__m512i vx) +{ + return _mm512_cmp_epi64_mask (vx, vx, 4); +} + +__mmask8 dumpy_nlt (__m512i vx) +{ + return _mm512_cmp_epi64_mask (vx, vx, 5); +} + +__mmask8 dumpy_nle (__m512i vx){ + return _mm512_cmp_epi64_mask (vx, vx, 6); +} 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..fe9ad1d 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 @@ -397,6 +404,13 @@ #undef create_code #undef verify_code +/* test-sized-float.c */ +#define create_code create_code_sized_float +#define verify_code verify_code_sized_float +#include "test-sized-float.c" +#undef create_code +#undef verify_code + /* test-target-builtins.c: This can't be in the testcases array as it is target-specific. */ @@ -517,6 +531,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}, @@ -628,6 +645,9 @@ const struct testcase testcases[] = { {"sizeof", create_code_sizeof, verify_code_sizeof}, + {"sized-float", + create_code_sized_float, + verify_code_sized_float}, {"string_literal", create_code_string_literal, verify_code_string_literal}, 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/testsuite/jit.dg/test-sized-float.c b/gcc/testsuite/jit.dg/test-sized-float.c new file mode 100644 index 0000000..fc90f14 --- /dev/null +++ b/gcc/testsuite/jit.dg/test-sized-float.c @@ -0,0 +1,167 @@ +#include <stdio.h> +#include <stddef.h> +#include <stdbool.h> + +#include "libgccjit.h" + +#include "harness.h" + +struct float_zoo +{ + _Float16 m_float16; + _Float32 m_float32; + _Float64 m_float64; + __float128 m_float128; +}; + +void +create_code (gcc_jit_context *ctxt, void *user_data) +{ + /* Let's try to inject the equivalent of: + + void + test_caller (struct float_zoo *z) + { + for each fields "m_field": + z->m_field = ...some data; + } + */ + gcc_jit_type *void_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID); + +#define CREATE_FIELD(TYPE, NAME) \ + gcc_jit_context_new_field ( \ + ctxt, NULL, \ + gcc_jit_context_get_type (ctxt, TYPE), \ + NAME) + + gcc_jit_context *info_ctxt = gcc_jit_context_acquire (); + gcc_jit_target_info *target_info = gcc_jit_context_get_target_info (info_ctxt); + + enum gcc_jit_types float_type1 = GCC_JIT_TYPE_FLOAT; + if (gcc_jit_target_info_supports_target_dependent_type (target_info, GCC_JIT_TYPE_FLOAT16)) + float_type1 = GCC_JIT_TYPE_FLOAT16; + + enum gcc_jit_types float_type2 = GCC_JIT_TYPE_FLOAT; + if (gcc_jit_target_info_supports_target_dependent_type (target_info, GCC_JIT_TYPE_FLOAT32)) + float_type2 = GCC_JIT_TYPE_FLOAT32; + + enum gcc_jit_types float_type3 = GCC_JIT_TYPE_FLOAT; + if (gcc_jit_target_info_supports_target_dependent_type (target_info, GCC_JIT_TYPE_FLOAT64)) + float_type3 = GCC_JIT_TYPE_FLOAT64; + + enum gcc_jit_types float_type4 = GCC_JIT_TYPE_FLOAT; + if (gcc_jit_target_info_supports_target_dependent_type (target_info, GCC_JIT_TYPE_FLOAT128)) + float_type4 = GCC_JIT_TYPE_FLOAT128; + + gcc_jit_field *field_m_float16 = CREATE_FIELD(float_type1, "m_float16"); + gcc_jit_field *field_m_float32 = CREATE_FIELD(float_type2, "m_float32"); + gcc_jit_field *field_m_float64 = CREATE_FIELD(float_type3, "m_float64"); + gcc_jit_field *field_m_float128 = CREATE_FIELD(float_type4, "m_float128"); + +#undef CREATE_FIELD + + gcc_jit_field *zoo_fields[] = { + field_m_float16, + field_m_float32, + field_m_float64, + field_m_float128, + }; + + gcc_jit_type *zoo_type = + gcc_jit_struct_as_type ( + gcc_jit_context_new_struct_type ( + ctxt, + NULL, + "float_zoo", + sizeof (zoo_fields) / sizeof (zoo_fields[0]), + zoo_fields)); + + gcc_jit_type *zoo_ptr_type = + gcc_jit_type_get_pointer (zoo_type); + + /* Build the test_fn. */ + gcc_jit_param *param_z = + gcc_jit_context_new_param (ctxt, NULL, zoo_ptr_type, "z"); + gcc_jit_function *test_fn = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + void_type, + "test_float_types", + 1, ¶m_z, + 0); + gcc_jit_block *block = gcc_jit_function_new_block (test_fn, NULL); + + /* Write to the various fields of param "z". */ +#define ASSIGN(FIELD, EXPR) \ + gcc_jit_block_add_assignment ( \ + block, NULL, \ + gcc_jit_rvalue_dereference_field ( \ + gcc_jit_param_as_rvalue (param_z), \ + NULL, \ + (FIELD)), \ + (EXPR)); + + ASSIGN(field_m_float16, + gcc_jit_context_new_rvalue_from_double ( + ctxt, + gcc_jit_context_get_type (ctxt, float_type1), + 3.141)) + ASSIGN(field_m_float32, + gcc_jit_context_new_rvalue_from_double ( + ctxt, + gcc_jit_context_get_type (ctxt, float_type2), + 3.141)) + ASSIGN(field_m_float64, + gcc_jit_context_new_rvalue_from_double ( + ctxt, + gcc_jit_context_get_type (ctxt, float_type3), + 3.141)) + ASSIGN(field_m_float128, + gcc_jit_context_new_rvalue_from_double ( + ctxt, + gcc_jit_context_get_type (ctxt, float_type4), + 3.141)) + +#undef ASSIGN + + gcc_jit_block_end_with_void_return (block, NULL); +} + +void +verify_code (gcc_jit_context *ctxt, gcc_jit_result *result) +{ + typedef void (*fn_type) (struct float_zoo *); + CHECK_NON_NULL (result); + + fn_type test_float_types = + (fn_type)gcc_jit_result_get_code (result, "test_float_types"); + CHECK_NON_NULL (test_float_types); + + struct float_zoo z; + memset (&z, 0xf0, sizeof (z)); + + /* Call the JIT-generated function. */ + test_float_types (&z); + + /* Verify that it correctly wrote to the various fields. */ + gcc_jit_context *info_ctxt = gcc_jit_context_acquire (); + gcc_jit_target_info *target_info = gcc_jit_context_get_target_info (info_ctxt); + if (gcc_jit_target_info_supports_target_dependent_type (target_info, GCC_JIT_TYPE_FLOAT16)) + CHECK_VALUE (z.m_float16, (_Float16)3.141); + if (gcc_jit_target_info_supports_target_dependent_type (target_info, GCC_JIT_TYPE_FLOAT32)) + CHECK_VALUE (z.m_float32, (_Float32)3.141); + if (gcc_jit_target_info_supports_target_dependent_type (target_info, GCC_JIT_TYPE_FLOAT64)) + CHECK_VALUE (z.m_float64, (_Float64)3.141); + if (gcc_jit_target_info_supports_target_dependent_type (target_info, GCC_JIT_TYPE_FLOAT128)) + CHECK_VALUE (z.m_float128, (__float128)3.141); + + if (gcc_jit_target_info_supports_target_dependent_type (target_info, GCC_JIT_TYPE_FLOAT16)) + CHECK_VALUE (gcc_jit_type_get_size (gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT16)), sizeof (_Float16)); + if (gcc_jit_target_info_supports_target_dependent_type (target_info, GCC_JIT_TYPE_FLOAT32)) + CHECK_VALUE (gcc_jit_type_get_size (gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT32)), sizeof (_Float32)); + if (gcc_jit_target_info_supports_target_dependent_type (target_info, GCC_JIT_TYPE_FLOAT64)) + CHECK_VALUE (gcc_jit_type_get_size (gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT64)), sizeof (_Float64)); + if (gcc_jit_target_info_supports_target_dependent_type (target_info, GCC_JIT_TYPE_FLOAT128)) + CHECK_VALUE (gcc_jit_type_get_size (gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT128)), sizeof (__float128)); +} diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc index 6c24202..15cb220 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; } @@ -5607,13 +5616,13 @@ vect_create_epilog_for_reduction (loop_vec_info loop_vinfo, && VECT_REDUC_INFO_VECTYPE_FOR_MASK (reduc_info) && vectype != VECT_REDUC_INFO_VECTYPE_FOR_MASK (reduc_info)) { - gcc_assert (reduc_inputs.length () == 1); vectype = VECT_REDUC_INFO_VECTYPE_FOR_MASK (reduc_info); gimple_seq stmts = NULL; - reduc_inputs[0] = gimple_build (&stmts, VEC_COND_EXPR, vectype, - reduc_inputs[0], - build_one_cst (vectype), - build_zero_cst (vectype)); + for (unsigned i = 0; i < reduc_inputs.length (); ++i) + reduc_inputs[i] = gimple_build (&stmts, VEC_COND_EXPR, vectype, + reduc_inputs[i], + build_one_cst (vectype), + build_zero_cst (vectype)); gsi_insert_seq_before (&exit_gsi, stmts, GSI_SAME_STMT); } @@ -5954,25 +5963,29 @@ vect_create_epilog_for_reduction (loop_vec_info loop_vinfo, gcc_assert (exact_log2 (nunits1) != -1 && nunits1 <= nunits); } } - if (!slp_reduc - && (mode1 = targetm.vectorize.split_reduction (mode)) != mode) + else if (!slp_reduc + && (mode1 = targetm.vectorize.split_reduction (mode)) != mode) nunits1 = GET_MODE_NUNITS (mode1).to_constant (); - tree vectype1 = get_related_vectype_for_scalar_type (TYPE_MODE (vectype), - stype, nunits1); + tree vectype1 = vectype; + if (mode1 != mode) + { + vectype1 = get_related_vectype_for_scalar_type (TYPE_MODE (vectype), + stype, nunits1); + /* First reduce the vector to the desired vector size we should + do shift reduction on by combining upper and lower halves. */ + gimple_seq stmts = NULL; + new_temp = vect_create_partial_epilog (reduc_inputs[0], vectype1, + code, &stmts); + gsi_insert_seq_before (&exit_gsi, stmts, GSI_SAME_STMT); + reduc_inputs[0] = new_temp; + } + reduce_with_shift = have_whole_vector_shift (mode1); if (!VECTOR_MODE_P (mode1) || !directly_supported_p (code, vectype1)) reduce_with_shift = false; - /* First reduce the vector to the desired vector size we should - do shift reduction on by combining upper and lower halves. */ - gimple_seq stmts = NULL; - new_temp = vect_create_partial_epilog (reduc_inputs[0], vectype1, - code, &stmts); - gsi_insert_seq_before (&exit_gsi, stmts, GSI_SAME_STMT); - reduc_inputs[0] = new_temp; - if (reduce_with_shift && (!slp_reduc || group_size == 1)) { tree bitsize = TYPE_SIZE (TREE_TYPE (vectype1)); @@ -6000,7 +6013,7 @@ vect_create_epilog_for_reduction (loop_vec_info loop_vinfo, "Reduce using vector shifts\n"); gimple_seq stmts = NULL; - new_temp = gimple_convert (&stmts, vectype1, new_temp); + new_temp = gimple_convert (&stmts, vectype1, reduc_inputs[0]); for (elt_offset = nelements / 2; elt_offset >= 1; elt_offset /= 2) @@ -6044,13 +6057,13 @@ vect_create_epilog_for_reduction (loop_vec_info loop_vinfo, "Reduce using scalar code.\n"); tree compute_type = TREE_TYPE (vectype1); - tree bitsize = TYPE_SIZE (compute_type); - int vec_size_in_bits = tree_to_uhwi (TYPE_SIZE (vectype1)); - int element_bitsize = tree_to_uhwi (bitsize); + unsigned vec_size_in_bits = tree_to_uhwi (TYPE_SIZE (vectype1)); + unsigned element_bitsize = vector_element_bits (vectype1); + tree bitsize = bitsize_int (element_bitsize); gimple_seq stmts = NULL; FOR_EACH_VEC_ELT (reduc_inputs, i, vec_temp) { - int bit_offset; + unsigned bit_offset; new_temp = gimple_build (&stmts, BIT_FIELD_REF, compute_type, vec_temp, bitsize, bitsize_zero_node); @@ -8211,6 +8224,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; |