diff options
author | Martin Liska <mliska@suse.cz> | 2021-05-28 14:28:40 +0200 |
---|---|---|
committer | Martin Liska <mliska@suse.cz> | 2021-05-28 14:28:40 +0200 |
commit | 282d533e86415825dc0bd6b0dda0622f3fa1bed5 (patch) | |
tree | 80c35a32bc8be30b7b882fb7111f9bae5e205031 | |
parent | d4997738800da4be5954fa1849bbf2ade74cc20e (diff) | |
parent | 359c0a86e2974a9f3036bc05b6e6c661f2c463cf (diff) | |
download | gcc-282d533e86415825dc0bd6b0dda0622f3fa1bed5.zip gcc-282d533e86415825dc0bd6b0dda0622f3fa1bed5.tar.gz gcc-282d533e86415825dc0bd6b0dda0622f3fa1bed5.tar.bz2 |
Merge branch 'master' into devel/sphinx
131 files changed, 3629 insertions, 725 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c639576..290e374 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,118 @@ +2021-05-27 Uroš Bizjak <ubizjak@gmail.com> + + * config/i386/mmx.md (addv2sf3): Do not call + ix86_fixup_binary_operands_no_copy. + (subv2sf3): Ditto. + (mulv2sf3): Ditto. + (<smaxmin:code>v2sf3): Ditto. + (<plusminus:insn><MMXMODEI:mode>3): Ditto. + (<plusminus:insn><VI_32:mode>3): Remove expander. + (<plusminus:insn><VI_32:mode>3): Rename from + "*<plusminus:insn><VI_32:mode>3". + (mulv4hi): Do not call ix86_fixup_binary_operands_no_copy. + (mulv2hi3): Remove expander. + (mulv2hi3): Rename from *mulv2hi3. + (<s>mulv2hi3_highpart): Remove expander. + (<s>mulv2hi3_highpart): Rename from *<s>mulv2hi3_highpart. + (<smaxmin:code><MMXMODE14:mode>3): Rename from + "*mmx_<smaxmin:code><MMXMODE14:mode>3". + (<smaxmin:code><SMAXMIN_MMXMODEI:mode>3): Remove expander. + (SMAXMIN_MMXMODEI): Remove mode iterator. + (<smaxmin:code>v4hi3): New expander. + (<smaxmin:code>v4qi3): Rename from *<smaxmin:code>v4qi3. + (<smaxmin:code>v2hi3): Rename from *<smaxmin:code>v2hi3. + (<smaxmin:code><SMAXMIN_VI_32:mode>3): Remove expander. + (SMAXMIN_VI_32): Remove mode iterator. + (<umaxmin:code><MMXMODE24:mode>3): Rename from + "*mmx_<umaxmin:code><MMXMODE24:mode>3". + (<umaxmin:code><UMAXMIN_MMXMODEI:mode>3): Remove expander. + (UMAXMIN_MMXMODEI): Remove mode iterator. + (<umaxmin:code>v8qi3): New expander. + (<umaxmin:code>v4qi3): Rename from *<umaxmin:code>v4qi3. + (<umaxmin:code>v2hi3): Rename from *<umaxmin:code>v2hi3. + (<umaxmin:code><SMAXMIN_VI_32:mode>3): Remove expander. + (UMAXMIN_VI_32): Remove mode iterator. + (<any_shift:insn>v2hi3): Remove expander. + (<any_shift:insn>v2hi3): Rename from *<any_shift:insn>v2hi3. + (<any_logic:code><MMXMODEI:mode>3): Do not call + ix86_fixup_binary_operands_no_copy. + (<any_logic:code><VI_32:mode>3): Remove expander. + (<any_logic:code><VI_32:mode>3): Rename from + "*<any_logic:code><VI_32:mode>3". + (uavg<mode>3_ceil): Do not call ix86_fixup_binary_operands_no_copy. + * config/i386/sse.md (div<VF2:mode>3): Do not call + ix86_fixup_binary_operands_no_copy. + (div<VF1:mode>3): Ditto. + (<maxmin:code><VI8_AVX2_AVX512F:mode>3): Ditto. + (smulhrsv4hi3): Ditto. + (smulhrsv2hi3): Ditto. + +2021-05-27 Martin Sebor <msebor@redhat.com> + + * ggc.h (gt_ggc_mx): Add overloads for all integers. + (gt_pch_nx): Same. + * hash-map.h (class hash_map): Add pch_nx_helper overloads for all + integers. + (hash_map::operator==): New function. + +2021-05-27 Uroš Bizjak <ubizjak@gmail.com> + + PR target/100637 + * config/i386/i386-expand.c (ix86_expand_int_sse_cmp): + For TARGET_XOP bypass SSE comparisons for all supported vector modes. + * config/i386/mmx.md (*xop_maskcmp<MMXMODEI:mode>3): New insn pattern. + (*xop_maskcmp<VI_32:mode>3): Ditto. + (*xop_maskcmp_uns<MMXMODEI:mode>3): Ditto. + (*xop_maskcmp_uns<VI_32:mode>3): Ditto. + +2021-05-27 Richard Earnshaw <rearnsha@arm.com> + + PR target/100767 + * config/arm/arm.c (arm_configure_build_target): Remove parameter + opts_set, directly check opts parameters for being non-null. + (arm_option_restore): Update call to arm_configure_build_target. + (arm_option_override): Likewise. + (arm_can_inline_p): Likewise. + (arm_valid_target_attribute_tree): Likewise. + * config/arm/arm-c.c (arm_pragma_target_parse): Likewise. + * config/arm/arm-protos.h (arm_configure_build_target): Adjust + prototype. + +2021-05-27 Aldy Hernandez <aldyh@redhat.com> + + * vr-values.c (simplify_conversion_using_ranges): Use + get_range_query instead of get_global_range_query. + +2021-05-27 Aldy Hernandez <aldyh@redhat.com> + + * gimple-range.cc (get_range_global): Move to value-query.cc. + (gimple_range_global): Same. + (get_global_range_query): Same. + (global_range_query::range_of_expr): Same. + * gimple-range.h (class global_range_query): Move to + value-query.h. + (gimple_range_global): Same. + * tree-ssanames.c (get_range_info): Move to value-query.cc. + (get_ptr_nonnull): Same. + * tree-ssanames.h (get_range_info): Remove. + (get_ptr_nonnull): Remove. + * value-query.cc (get_ssa_name_range_info): Move from + tree-ssanames.c. + (get_ssa_name_ptr_info_nonnull): Same. + (get_range_global): Move from gimple-range.cc. + (gimple_range_global): Same. + (get_global_range_query): Same. + (global_range_query::range_of_expr): Same. + * value-query.h (class global_range_query): Move from + gimple-range.h. + (gimple_range_global): Same. + +2021-05-27 Uroš Bizjak <ubizjak@gmail.com> + + PR target/100637 + * config/i386/mmx.md (uavgv4qi3_ceil): New insn pattern. + (uavgv2hi3_ceil): Ditto. + 2021-05-26 Eric Botcazou <ebotcazou@adacore.com> PR c/100653 diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 328fa3e..2fcc100 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20210527 +20210528 diff --git a/gcc/Makefile.in b/gcc/Makefile.in index da2ef24..4cb2966 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -2753,6 +2753,7 @@ generated_files = config.h tm.h $(TM_P_H) $(TM_D_H) $(TM_H) multilib.h \ $(ALL_GTFILES_H) gtype-desc.c gtype-desc.h version.h \ options.h target-hooks-def.h insn-opinit.h \ common/common-target-hooks-def.h pass-instances.def \ + gimple-match.c generic-match.c \ c-family/c-target-hooks-def.h d/d-target-hooks-def.h \ case-cfn-macros.h \ cfn-operators.pd omp-device-properties.h diff --git a/gcc/c-family/c-omp.c b/gcc/c-family/c-omp.c index 1b4a112..28fbb1d 100644 --- a/gcc/c-family/c-omp.c +++ b/gcc/c-family/c-omp.c @@ -1989,6 +1989,16 @@ c_omp_split_clauses (location_t loc, enum tree_code code, "%<parallel for%>, %<parallel for simd%>"); OMP_CLAUSE_REDUCTION_INSCAN (clauses) = 0; } + if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) != 0) + { + c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses), + OMP_CLAUSE_MAP); + OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses); + OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TOFROM); + OMP_CLAUSE_MAP_IMPLICIT (c) = 1; + OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET]; + cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = c; + } if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)) != 0) { if (code == OMP_SIMD) diff --git a/gcc/c-family/c-pragma.h b/gcc/c-family/c-pragma.h index 6c34ffa..e4fd3c9 100644 --- a/gcc/c-family/c-pragma.h +++ b/gcc/c-family/c-pragma.h @@ -86,6 +86,7 @@ enum pragma_kind { enum pragma_omp_clause { PRAGMA_OMP_CLAUSE_NONE = 0, + PRAGMA_OMP_CLAUSE_AFFINITY, PRAGMA_OMP_CLAUSE_ALIGNED, PRAGMA_OMP_CLAUSE_ALLOCATE, PRAGMA_OMP_CLAUSE_BIND, diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index b9930d4..d71fd0a 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -12601,7 +12601,9 @@ c_parser_omp_clause_name (c_parser *parser) switch (p[0]) { case 'a': - if (!strcmp ("aligned", p)) + if (!strcmp ("affinity", p)) + result = PRAGMA_OMP_CLAUSE_AFFINITY; + else if (!strcmp ("aligned", p)) result = PRAGMA_OMP_CLAUSE_ALIGNED; else if (!strcmp ("allocate", p)) result = PRAGMA_OMP_CLAUSE_ALLOCATE; @@ -12900,7 +12902,7 @@ c_parser_omp_variable_list (c_parser *parser, while (1) { bool array_section_p = false; - if (kind == OMP_CLAUSE_DEPEND) + if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY) { if (c_parser_next_token_is_not (parser, CPP_NAME) || c_parser_peek_token (parser)->id_kind != C_ID_ID) @@ -13040,6 +13042,7 @@ c_parser_omp_variable_list (c_parser *parser, t = build_component_ref (op_loc, t, ident, comp_loc); } /* FALLTHROUGH */ + case OMP_CLAUSE_AFFINITY: case OMP_CLAUSE_DEPEND: case OMP_CLAUSE_REDUCTION: case OMP_CLAUSE_IN_REDUCTION: @@ -13090,7 +13093,7 @@ c_parser_omp_variable_list (c_parser *parser, t = tree_cons (low_bound, length, t); } - if (kind == OMP_CLAUSE_DEPEND + if ((kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY) && t != error_mark_node && parser->tokens_avail != 2) { @@ -13130,7 +13133,7 @@ c_parser_omp_variable_list (c_parser *parser, else list = tree_cons (t, NULL_TREE, list); - if (kind == OMP_CLAUSE_DEPEND) + if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY) { parser->tokens = &parser->tokens_buf[0]; parser->tokens_avail = tokens_avail; @@ -15508,6 +15511,69 @@ c_parser_omp_iterators (c_parser *parser) return ret ? ret : error_mark_node; } +/* OpenMP 5.0: + affinity ( [aff-modifier :] variable-list ) + aff-modifier: + iterator ( iterators-definition ) */ + +static tree +c_parser_omp_clause_affinity (c_parser *parser, tree list) +{ + location_t clause_loc = c_parser_peek_token (parser)->location; + tree nl, iterators = NULL_TREE; + + matching_parens parens; + if (!parens.require_open (parser)) + return list; + + if (c_parser_next_token_is (parser, CPP_NAME)) + { + const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); + bool parse_iter = ((strcmp ("iterator", p) == 0) + && (c_parser_peek_2nd_token (parser)->type + == CPP_OPEN_PAREN)); + if (parse_iter) + { + unsigned n = 3; + parse_iter = (c_parser_check_balanced_raw_token_sequence (parser, &n) + && (c_parser_peek_nth_token_raw (parser, n)->type + == CPP_CLOSE_PAREN) + && (c_parser_peek_nth_token_raw (parser, n + 1)->type + == CPP_COLON)); + } + if (parse_iter) + { + iterators = c_parser_omp_iterators (parser); + if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")) + { + if (iterators) + pop_scope (); + parens.skip_until_found_close (parser); + return list; + } + } + } + nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_AFFINITY, + list); + if (iterators) + { + tree block = pop_scope (); + if (iterators == error_mark_node) + iterators = NULL_TREE; + else + { + TREE_VEC_ELT (iterators, 5) = block; + for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c)) + OMP_CLAUSE_DECL (c) = build_tree_list (iterators, + OMP_CLAUSE_DECL (c)); + } + } + + parens.skip_until_found_close (parser); + return nl; +} + + /* OpenMP 4.0: depend ( depend-kind: variable-list ) @@ -16474,6 +16540,10 @@ c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask, clauses = c_parser_omp_clause_linear (parser, clauses); c_name = "linear"; break; + case PRAGMA_OMP_CLAUSE_AFFINITY: + clauses = c_parser_omp_clause_affinity (parser, clauses); + c_name = "affinity"; + break; case PRAGMA_OMP_CLAUSE_DEPEND: clauses = c_parser_omp_clause_depend (parser, clauses); c_name = "depend"; @@ -19249,7 +19319,8 @@ c_parser_omp_single (location_t loc, c_parser *parser, bool *if_p) | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \ - | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DETACH)) + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DETACH) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_AFFINITY)) static tree c_parser_omp_task (location_t loc, c_parser *parser, bool *if_p) diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index fc64ef9..5f32287 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -13064,7 +13064,8 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types, if (error_operand_p (t)) return error_mark_node; ret = t; - if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND + if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_AFFINITY + && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND && TYPE_ATOMIC (strip_array_types (TREE_TYPE (t)))) { error_at (OMP_CLAUSE_LOCATION (c), "%<_Atomic%> %qE in %qs clause", @@ -13115,14 +13116,16 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types, omp_clause_code_name[OMP_CLAUSE_CODE (c)]); return error_mark_node; } - else if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND + else if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_AFFINITY + && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND && TYPE_ATOMIC (TREE_TYPE (t))) { error_at (OMP_CLAUSE_LOCATION (c), "%<_Atomic%> %qD in %qs clause", t, omp_clause_code_name[OMP_CLAUSE_CODE (c)]); return error_mark_node; } - else if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND + else if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_AFFINITY + && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND && VAR_P (t) && DECL_THREAD_LOCAL_P (t)) { @@ -13131,7 +13134,8 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types, omp_clause_code_name[OMP_CLAUSE_CODE (c)]); return error_mark_node; } - if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND + if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND) && TYPE_ATOMIC (TREE_TYPE (t)) && POINTER_TYPE_P (TREE_TYPE (t))) { @@ -13202,7 +13206,8 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types, { if (!integer_nonzerop (length)) { - if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION) @@ -13270,7 +13275,8 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types, } if (tree_int_cst_equal (size, low_bound)) { - if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION) @@ -13291,7 +13297,8 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types, } else if (length == NULL_TREE) { - if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND + if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_AFFINITY + && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_IN_REDUCTION && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_TASK_REDUCTION) @@ -13329,7 +13336,8 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types, } else if (length == NULL_TREE) { - if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND + if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_AFFINITY + && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_IN_REDUCTION && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_TASK_REDUCTION) @@ -13374,6 +13382,7 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types, /* If there is a pointer type anywhere but in the very first array-section-subscript, the array section can't be contiguous. */ if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND + && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_AFFINITY && TREE_CODE (TREE_CHAIN (t)) == TREE_LIST) { error_at (OMP_CLAUSE_LOCATION (c), @@ -13410,7 +13419,8 @@ handle_omp_array_sections (tree c, enum c_omp_region_type ort) unsigned int first_non_one = 0; auto_vec<tree, 10> types; tree *tp = &OMP_CLAUSE_DECL (c); - if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND + if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY) && TREE_CODE (*tp) == TREE_LIST && TREE_PURPOSE (*tp) && TREE_CODE (TREE_PURPOSE (*tp)) == TREE_VEC) @@ -13422,7 +13432,8 @@ handle_omp_array_sections (tree c, enum c_omp_region_type ort) return true; if (first == NULL_TREE) return false; - if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND) + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY) { tree t = *tp; tree tem = NULL_TREE; @@ -13646,6 +13657,7 @@ handle_omp_array_sections (tree c, enum c_omp_region_type ort) OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_ATTACH_DETACH); else OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_FIRSTPRIVATE_POINTER); + OMP_CLAUSE_MAP_IMPLICIT (c2) = OMP_CLAUSE_MAP_IMPLICIT (c); if (OMP_CLAUSE_MAP_KIND (c2) != GOMP_MAP_FIRSTPRIVATE_POINTER && !c_mark_addressable (t)) return false; @@ -13916,7 +13928,8 @@ tree c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) { bitmap_head generic_head, firstprivate_head, lastprivate_head; - bitmap_head aligned_head, map_head, map_field_head, oacc_reduction_head; + bitmap_head aligned_head, map_head, map_field_head, map_firstprivate_head; + bitmap_head oacc_reduction_head; tree c, t, type, *pc; tree simdlen = NULL_TREE, safelen = NULL_TREE; bool branch_seen = false; @@ -13936,7 +13949,7 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) has been seen, -2 if mixed inscan/normal reduction diagnosed. */ int reduction_seen = 0; bool allocate_seen = false; - bool firstprivate_implicit_moved = false; + bool implicit_moved = false; bitmap_obstack_initialize (NULL); bitmap_initialize (&generic_head, &bitmap_default_obstack); @@ -13946,6 +13959,7 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) /* If ort == C_ORT_OMP_DECLARE_SIMD used as uniform_head instead. */ bitmap_initialize (&map_head, &bitmap_default_obstack); bitmap_initialize (&map_field_head, &bitmap_default_obstack); + bitmap_initialize (&map_firstprivate_head, &bitmap_default_obstack); /* If ort == C_ORT_OMP used as nontemporal_head or use_device_xxx_head instead. */ bitmap_initialize (&oacc_reduction_head, &bitmap_default_obstack); @@ -14378,28 +14392,36 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) break; case OMP_CLAUSE_FIRSTPRIVATE: - if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c) - && !firstprivate_implicit_moved) + if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c) && !implicit_moved) { - firstprivate_implicit_moved = true; - /* Move firstprivate clauses with - OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT set to the end of + move_implicit: + implicit_moved = true; + /* Move firstprivate and map clauses with + OMP_CLAUSE_{FIRSTPRIVATE,MAP}_IMPLICIT set to the end of clauses chain. */ - tree cl = NULL, *pc1 = pc, *pc2 = &cl; + tree cl1 = NULL_TREE, cl2 = NULL_TREE; + tree *pc1 = pc, *pc2 = &cl1, *pc3 = &cl2; while (*pc1) if (OMP_CLAUSE_CODE (*pc1) == OMP_CLAUSE_FIRSTPRIVATE && OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (*pc1)) { + *pc3 = *pc1; + pc3 = &OMP_CLAUSE_CHAIN (*pc3); + *pc1 = OMP_CLAUSE_CHAIN (*pc1); + } + else if (OMP_CLAUSE_CODE (*pc1) == OMP_CLAUSE_MAP + && OMP_CLAUSE_MAP_IMPLICIT (*pc1)) + { *pc2 = *pc1; pc2 = &OMP_CLAUSE_CHAIN (*pc2); *pc1 = OMP_CLAUSE_CHAIN (*pc1); } else pc1 = &OMP_CLAUSE_CHAIN (*pc1); - *pc2 = NULL; - *pc1 = cl; - if (pc1 != pc) - continue; + *pc3 = NULL; + *pc2 = cl2; + *pc1 = cl1; + continue; } t = OMP_CLAUSE_DECL (c); need_complete = true; @@ -14410,6 +14432,10 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) "%qE is not a variable in clause %<firstprivate%>", t); remove = true; } + else if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c) + && !OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT_TARGET (c) + && bitmap_bit_p (&map_firstprivate_head, DECL_UID (t))) + remove = true; else if (bitmap_bit_p (&generic_head, DECL_UID (t)) || bitmap_bit_p (&firstprivate_head, DECL_UID (t))) { @@ -14531,6 +14557,7 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) } break; + case OMP_CLAUSE_AFFINITY: case OMP_CLAUSE_DEPEND: t = OMP_CLAUSE_DECL (c); if (t == NULL_TREE) @@ -14539,7 +14566,8 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) == OMP_CLAUSE_DEPEND_SOURCE); break; } - if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK) + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND + && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK) { gcc_assert (TREE_CODE (t) == TREE_LIST); for (; t; t = TREE_CHAIN (t)) @@ -14585,7 +14613,8 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) { if (handle_omp_array_sections (c, ort)) remove = true; - else if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_DEPOBJ) + else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND + && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_DEPOBJ) { error_at (OMP_CLAUSE_LOCATION (c), "%<depend%> clause with %<depobj%> dependence " @@ -14600,17 +14629,22 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) { error_at (OMP_CLAUSE_LOCATION (c), "%qE is not lvalue expression nor array section in " - "%<depend%> clause", t); + "%qs clause", t, + omp_clause_code_name[OMP_CLAUSE_CODE (c)]); remove = true; } else if (TREE_CODE (t) == COMPONENT_REF && DECL_C_BIT_FIELD (TREE_OPERAND (t, 1))) { + gcc_assert (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY); error_at (OMP_CLAUSE_LOCATION (c), - "bit-field %qE in %qs clause", t, "depend"); + "bit-field %qE in %qs clause", t, + omp_clause_code_name[OMP_CLAUSE_CODE (c)]); remove = true; } - else if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_DEPOBJ) + else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND + && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_DEPOBJ) { if (!c_omp_depend_t_p (TREE_TYPE (t))) { @@ -14621,7 +14655,8 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) remove = true; } } - else if (c_omp_depend_t_p (TREE_TYPE (t))) + else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND + && c_omp_depend_t_p (TREE_TYPE (t))) { error_at (OMP_CLAUSE_LOCATION (c), "%qE should not have %<omp_depend_t%> type in " @@ -14653,6 +14688,9 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) break; case OMP_CLAUSE_MAP: + if (OMP_CLAUSE_MAP_IMPLICIT (c) && !implicit_moved) + goto move_implicit; + /* FALLTHRU */ case OMP_CLAUSE_TO: case OMP_CLAUSE_FROM: case OMP_CLAUSE__CACHE_: @@ -14686,6 +14724,16 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) { while (TREE_CODE (t) == COMPONENT_REF) t = TREE_OPERAND (t, 0); + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP + && OMP_CLAUSE_MAP_IMPLICIT (c) + && (bitmap_bit_p (&map_head, DECL_UID (t)) + || bitmap_bit_p (&map_field_head, DECL_UID (t)) + || bitmap_bit_p (&map_firstprivate_head, + DECL_UID (t)))) + { + remove = true; + break; + } if (bitmap_bit_p (&map_field_head, DECL_UID (t))) break; if (bitmap_bit_p (&map_head, DECL_UID (t))) @@ -14840,6 +14888,12 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) remove = true; } else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP + && OMP_CLAUSE_MAP_IMPLICIT (c) + && (bitmap_bit_p (&map_head, DECL_UID (t)) + || bitmap_bit_p (&map_field_head, DECL_UID (t)) + || bitmap_bit_p (&map_firstprivate_head, DECL_UID (t)))) + remove = true; + else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER) { if (bitmap_bit_p (&generic_head, DECL_UID (t)) @@ -14860,7 +14914,10 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) remove = true; } else - bitmap_set_bit (&generic_head, DECL_UID (t)); + { + bitmap_set_bit (&generic_head, DECL_UID (t)); + bitmap_set_bit (&map_firstprivate_head, DECL_UID (t)); + } } else if (bitmap_bit_p (&map_head, DECL_UID (t)) && (ort != C_ORT_OMP diff --git a/gcc/c/gimple-parser.c b/gcc/c/gimple-parser.c index dfacf23..c8d9db6 100644 --- a/gcc/c/gimple-parser.c +++ b/gcc/c/gimple-parser.c @@ -2112,6 +2112,14 @@ c_parser_gimple_paren_condition (gimple_parser &parser) if (! c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) return error_mark_node; tree cond = c_parser_gimple_binary_expression (parser).value; + if (cond != error_mark_node + && ! COMPARISON_CLASS_P (cond) + && ! CONSTANT_CLASS_P (cond) + && ! SSA_VAR_P (cond)) + { + c_parser_error (parser, "comparison required"); + cond = error_mark_node; + } if (! c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>")) return error_mark_node; return cond; diff --git a/gcc/config/arm/arm-c.c b/gcc/config/arm/arm-c.c index 7f97b84..ae2139c 100644 --- a/gcc/config/arm/arm-c.c +++ b/gcc/config/arm/arm-c.c @@ -408,8 +408,7 @@ arm_pragma_target_parse (tree args, tree pop_target) target_option_current_node, but not handle_pragma_target. */ target_option_current_node = cur_tree; arm_configure_build_target (&arm_active_target, - TREE_TARGET_OPTION (cur_tree), - &global_options_set, false); + TREE_TARGET_OPTION (cur_tree), false); } /* Update macros if target_node changes. The global state will be restored diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index ffccaa7..9b1f613 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -243,8 +243,7 @@ extern bool arm_change_mode_p (tree); extern tree arm_valid_target_attribute_tree (tree, struct gcc_options *, struct gcc_options *); extern void arm_configure_build_target (struct arm_build_target *, - struct cl_target_option *, - struct gcc_options *, bool); + struct cl_target_option *, bool); extern void arm_option_reconfigure_globals (void); extern void arm_options_perform_arch_sanity_checks (void); extern void arm_pr_long_calls (struct cpp_reader *); diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 9377aae..7b37e1b 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -3054,9 +3054,10 @@ arm_override_options_after_change (void) /* Implement TARGET_OPTION_RESTORE. */ static void arm_option_restore (struct gcc_options */* opts */, - struct gcc_options *opts_set, struct cl_target_option *ptr) + struct gcc_options */* opts_set */, + struct cl_target_option *ptr) { - arm_configure_build_target (&arm_active_target, ptr, opts_set, false); + arm_configure_build_target (&arm_active_target, ptr, false); } /* Reset options between modes that the user has specified. */ @@ -3179,7 +3180,6 @@ static sbitmap isa_quirkbits; void arm_configure_build_target (struct arm_build_target *target, struct cl_target_option *opts, - struct gcc_options *opts_set, bool warn_compatible) { const cpu_option *arm_selected_tune = NULL; @@ -3194,7 +3194,7 @@ arm_configure_build_target (struct arm_build_target *target, target->core_name = NULL; target->arch_name = NULL; - if (opts_set->x_arm_arch_string) + if (opts->x_arm_arch_string) { arm_selected_arch = arm_parse_arch_option_name (all_architectures, "-march", @@ -3202,7 +3202,7 @@ arm_configure_build_target (struct arm_build_target *target, arch_opts = strchr (opts->x_arm_arch_string, '+'); } - if (opts_set->x_arm_cpu_string) + if (opts->x_arm_cpu_string) { arm_selected_cpu = arm_parse_cpu_option_name (all_cores, "-mcpu", opts->x_arm_cpu_string); @@ -3212,7 +3212,7 @@ arm_configure_build_target (struct arm_build_target *target, options for tuning. */ } - if (opts_set->x_arm_tune_string) + if (opts->x_arm_tune_string) { arm_selected_tune = arm_parse_cpu_option_name (all_cores, "-mtune", opts->x_arm_tune_string); @@ -3476,8 +3476,7 @@ arm_option_override (void) } cl_target_option_save (&opts, &global_options, &global_options_set); - arm_configure_build_target (&arm_active_target, &opts, &global_options_set, - true); + arm_configure_build_target (&arm_active_target, &opts, true); #ifdef SUBTARGET_OVERRIDE_OPTIONS SUBTARGET_OVERRIDE_OPTIONS; @@ -32982,10 +32981,8 @@ arm_can_inline_p (tree caller, tree callee) caller_target.isa = sbitmap_alloc (isa_num_bits); callee_target.isa = sbitmap_alloc (isa_num_bits); - arm_configure_build_target (&caller_target, caller_opts, &global_options_set, - false); - arm_configure_build_target (&callee_target, callee_opts, &global_options_set, - false); + arm_configure_build_target (&caller_target, caller_opts, false); + arm_configure_build_target (&callee_target, callee_opts, false); if (!bitmap_subset_p (callee_target.isa, caller_target.isa)) can_inline = false; @@ -33121,7 +33118,7 @@ arm_valid_target_attribute_tree (tree args, struct gcc_options *opts, return NULL_TREE; cl_target_option_save (&cl_opts, opts, opts_set); - arm_configure_build_target (&arm_active_target, &cl_opts, opts_set, false); + arm_configure_build_target (&arm_active_target, &cl_opts, false); arm_option_check_internal (opts); /* Do any overrides, such as global options arch=xxx. We do this since arm_active_target was overridden. */ diff --git a/gcc/config/csky/csky-linux-elf.h b/gcc/config/csky/csky-linux-elf.h index 58a1f39..e94eb8c 100644 --- a/gcc/config/csky/csky-linux-elf.h +++ b/gcc/config/csky/csky-linux-elf.h @@ -133,3 +133,13 @@ #ifdef IN_LIBGCC2 extern int cacheflush (void *__addr, const int __nbytes, const int __op); #endif + +/* The SYNC operations are implemented as library functions, not + INSN patterns. As a result, the HAVE defines for the patterns are + not defined. We need to define them to generate the corresponding + __GCC_HAVE_SYNC_COMPARE_AND_SWAP_* and __GCC_ATOMIC_*_LOCK_FREE + defines. */ + +#define HAVE_sync_compare_and_swapqi 1 +#define HAVE_sync_compare_and_swaphi 1 +#define HAVE_sync_compare_and_swapsi 1 diff --git a/gcc/config/i386/i386-expand.c b/gcc/config/i386/i386-expand.c index 931b336..4185f58 100644 --- a/gcc/config/i386/i386-expand.c +++ b/gcc/config/i386/i386-expand.c @@ -4124,8 +4124,8 @@ ix86_expand_int_sse_cmp (rtx dest, enum rtx_code code, rtx cop0, rtx cop1, /* XOP supports all of the comparisons on all 128-bit vector int types. */ if (TARGET_XOP - && (mode == V16QImode || mode == V8HImode - || mode == V4SImode || mode == V2DImode)) + && GET_MODE_CLASS (mode) == MODE_VECTOR_INT + && GET_MODE_SIZE (mode) <= 16) ; /* AVX512F supports all of the comparsions on all 128/256/512-bit vector int types. */ diff --git a/gcc/config/i386/mmx.md b/gcc/config/i386/mmx.md index 453e8ea..f39e062 100644 --- a/gcc/config/i386/mmx.md +++ b/gcc/config/i386/mmx.md @@ -417,8 +417,7 @@ (plus:V2SF (match_operand:V2SF 1 "register_operand") (match_operand:V2SF 2 "register_operand")))] - "TARGET_MMX_WITH_SSE" - "ix86_fixup_binary_operands_no_copy (PLUS, V2SFmode, operands);") + "TARGET_MMX_WITH_SSE") (define_insn "*mmx_addv2sf3" [(set (match_operand:V2SF 0 "register_operand" "=y,x,v") @@ -455,8 +454,7 @@ (minus:V2SF (match_operand:V2SF 1 "register_operand") (match_operand:V2SF 2 "register_operand")))] - "TARGET_MMX_WITH_SSE" - "ix86_fixup_binary_operands_no_copy (MINUS, V2SFmode, operands);") + "TARGET_MMX_WITH_SSE") (define_insn "*mmx_subv2sf3" [(set (match_operand:V2SF 0 "register_operand" "=y,y,x,v") @@ -489,8 +487,7 @@ (mult:V2SF (match_operand:V2SF 1 "register_operand") (match_operand:V2SF 2 "register_operand")))] - "TARGET_MMX_WITH_SSE" - "ix86_fixup_binary_operands_no_copy (MULT, V2SFmode, operands);") + "TARGET_MMX_WITH_SSE") (define_insn "*mmx_mulv2sf3" [(set (match_operand:V2SF 0 "register_operand" "=y,x,v") @@ -542,8 +539,6 @@ (operands[0], operands[1], operands[2])); DONE; } - else - ix86_fixup_binary_operands_no_copy (<CODE>, V2SFmode, operands); }) ;; These versions of the min/max patterns are intentionally ignorant of @@ -709,7 +704,7 @@ (vec_select:SF (match_dup 1) (parallel [(match_operand:SI 3 "const_0_to_1_operand")]))))] - "TARGET_MMX_WITH_SSE && TARGET_SSE3 + "TARGET_SSE3 && TARGET_MMX_WITH_SSE && INTVAL (operands[2]) != INTVAL (operands[3])" "@ haddps\t{%0, %0|%0, %0} @@ -747,7 +742,7 @@ (vec_select:SF (match_dup 1) (parallel [(const_int 1)]))))] - "TARGET_MMX_WITH_SSE && TARGET_SSE3" + "TARGET_SSE3 && TARGET_MMX_WITH_SSE" "@ hsubps\t{%0, %0|%0, %0} vhsubps\t{%1, %1, %0|%0, %1, %1}" @@ -1091,7 +1086,7 @@ (define_insn "fixuns_truncv2sfv2si2" [(set (match_operand:V2SI 0 "register_operand" "=v") (unsigned_fix:V2SI (match_operand:V2SF 1 "register_operand" "v")))] - "TARGET_MMX_WITH_SSE && TARGET_AVX512VL" + "TARGET_AVX512VL && TARGET_MMX_WITH_SSE" "vcvttps2udq\t{%1, %0|%0, %1}" [(set_attr "type" "ssecvt") (set_attr "prefix" "evex") @@ -1119,7 +1114,7 @@ (define_insn "floatunsv2siv2sf2" [(set (match_operand:V2SF 0 "register_operand" "=v") (unsigned_float:V2SF (match_operand:V2SI 1 "register_operand" "v")))] - "TARGET_MMX_WITH_SSE && TARGET_AVX512VL" + "TARGET_AVX512VL && TARGET_MMX_WITH_SSE" "vcvtudq2ps\t{%1, %0|%0, %1}" [(set_attr "type" "ssecvt") (set_attr "prefix" "evex") @@ -1361,8 +1356,7 @@ (plusminus:MMXMODEI (match_operand:MMXMODEI 1 "register_operand") (match_operand:MMXMODEI 2 "register_operand")))] - "TARGET_MMX_WITH_SSE" - "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);") + "TARGET_MMX_WITH_SSE") (define_insn "*mmx_<insn><mode>3" [(set (match_operand:MMXMODEI8 0 "register_operand" "=y,x,<Yv_Yw>") @@ -1390,21 +1384,12 @@ "TARGET_SSE2" "operands[2] = force_reg (<MODE>mode, CONST0_RTX (<MODE>mode));") -(define_expand "<insn><mode>3" - [(set (match_operand:VI_32 0 "register_operand") - (plusminus:VI_32 - (match_operand:VI_32 1 "register_operand") - (match_operand:VI_32 2 "register_operand")))] - "TARGET_SSE2" - "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);") - -(define_insn "*<insn><mode>3" +(define_insn "<insn><mode>3" [(set (match_operand:VI_32 0 "register_operand" "=x,Yw") (plusminus:VI_32 (match_operand:VI_32 1 "register_operand" "<comm>0,Yw") (match_operand:VI_32 2 "register_operand" "x,Yw")))] - "TARGET_SSE2 - && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" + "TARGET_SSE2" "@ p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2} vp<plusminus_mnemonic><mmxvecsize>\t{%2, %1, %0|%0, %1, %2}" @@ -1441,8 +1426,7 @@ (sat_plusminus:VI_32 (match_operand:VI_32 1 "register_operand" "<comm>0,Yw") (match_operand:VI_32 2 "register_operand" "x,Yw")))] - "TARGET_SSE2 - && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" + "TARGET_SSE2" "@ p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2} vp<plusminus_mnemonic><mmxvecsize>\t{%2, %1, %0|%0, %1, %2}" @@ -1461,8 +1445,7 @@ [(set (match_operand:V4HI 0 "register_operand") (mult:V4HI (match_operand:V4HI 1 "register_operand") (match_operand:V4HI 2 "register_operand")))] - "TARGET_MMX_WITH_SSE" - "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);") + "TARGET_MMX_WITH_SSE") (define_insn "*mmx_mulv4hi3" [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yw") @@ -1479,19 +1462,11 @@ (set_attr "type" "mmxmul,ssemul,ssemul") (set_attr "mode" "DI,TI,TI")]) -(define_expand "mulv2hi3" - [(set (match_operand:V2HI 0 "register_operand") - (mult:V2HI (match_operand:V2HI 1 "register_operand") - (match_operand:V2HI 2 "register_operand")))] - "TARGET_SSE2" - "ix86_fixup_binary_operands_no_copy (MULT, V2HImode, operands);") - -(define_insn "*mulv2hi3" +(define_insn "mulv2hi3" [(set (match_operand:V2HI 0 "register_operand" "=x,Yw") (mult:V2HI (match_operand:V2HI 1 "register_operand" "%0,Yw") (match_operand:V2HI 2 "register_operand" "x,Yw")))] - "TARGET_SSE2 - && ix86_binary_operator_ok (MULT, V2HImode, operands)" + "TARGET_SSE2" "@ pmullw\t{%2, %0|%0, %2} vpmullw\t{%2, %1, %0|%0, %1, %2}" @@ -1579,10 +1554,9 @@ (any_extend:V4SI (match_operand:V4HI 2 "register_operand"))) (const_int 16))))] - "TARGET_MMX_WITH_SSE" - "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);") + "TARGET_MMX_WITH_SSE") -(define_insn "*<s>mulv2hi3_highpart" +(define_insn "<s>mulv2hi3_highpart" [(set (match_operand:V2HI 0 "register_operand" "=x,Yw") (truncate:V2HI (lshiftrt:V2SI @@ -1592,8 +1566,7 @@ (any_extend:V2SI (match_operand:V2HI 2 "register_operand" "x,Yw"))) (const_int 16))))] - "TARGET_SSE2 - && ix86_binary_operator_ok (MULT, V2HImode, operands)" + "TARGET_SSE2" "@ pmulh<u>w\t{%2, %0|%0, %2} vpmulh<u>w\t{%2, %1, %0|%0, %1, %2}" @@ -1601,19 +1574,6 @@ (set_attr "type" "ssemul") (set_attr "mode" "TI")]) -(define_expand "<s>mulv2hi3_highpart" - [(set (match_operand:V2HI 0 "register_operand") - (truncate:V2HI - (lshiftrt:V2SI - (mult:V2SI - (any_extend:V2SI - (match_operand:V2HI 1 "register_operand")) - (any_extend:V2SI - (match_operand:V2HI 2 "register_operand"))) - (const_int 16))))] - "TARGET_SSE2" - "ix86_fixup_binary_operands_no_copy (MULT, V2HImode, operands);") - (define_expand "mmx_pmaddwd" [(set (match_operand:V2SI 0 "register_operand") (plus:V2SI @@ -1744,13 +1704,12 @@ ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(define_insn "*mmx_<code><mode>3" +(define_insn "<code><mode>3" [(set (match_operand:MMXMODE14 0 "register_operand" "=Yr,*x,Yv") (smaxmin:MMXMODE14 (match_operand:MMXMODE14 1 "register_operand" "%0,0,Yv") (match_operand:MMXMODE14 2 "register_operand" "Yr,*x,Yv")))] - "TARGET_MMX_WITH_SSE && TARGET_SSE4_1 - && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" + "TARGET_SSE4_1 && TARGET_MMX_WITH_SSE" "@ p<maxmin_int><mmxvecsize>\t{%2, %0|%0, %2} p<maxmin_int><mmxvecsize>\t{%2, %0|%0, %2} @@ -1787,24 +1746,19 @@ (set_attr "type" "mmxadd,sseiadd,sseiadd") (set_attr "mode" "DI,TI,TI")]) -(define_mode_iterator SMAXMIN_MMXMODEI - [(V8QI "TARGET_SSE4_1") V4HI (V2SI "TARGET_SSE4_1")]) - -(define_expand "<code><mode>3" - [(set (match_operand:SMAXMIN_MMXMODEI 0 "register_operand") - (smaxmin:SMAXMIN_MMXMODEI - (match_operand:SMAXMIN_MMXMODEI 1 "register_operand") - (match_operand:SMAXMIN_MMXMODEI 2 "register_operand")))] - "TARGET_MMX_WITH_SSE" - "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);") +(define_expand "<code>v4hi3" + [(set (match_operand:V4HI 0 "register_operand") + (smaxmin:V4HI + (match_operand:V4HI 1 "register_operand") + (match_operand:V4HI 2 "register_operand")))] + "TARGET_MMX_WITH_SSE") -(define_insn "*<code>v4qi3" +(define_insn "<code>v4qi3" [(set (match_operand:V4QI 0 "register_operand" "=Yr,*x,Yv") (smaxmin:V4QI (match_operand:V4QI 1 "register_operand" "%0,0,Yv") (match_operand:V4QI 2 "register_operand" "Yr,*x,Yv")))] - "TARGET_SSE4_1 - && ix86_binary_operator_ok (<CODE>, V4QImode, operands)" + "TARGET_SSE4_1" "@ p<maxmin_int>b\t{%2, %0|%0, %2} p<maxmin_int>b\t{%2, %0|%0, %2} @@ -1815,13 +1769,12 @@ (set_attr "prefix" "orig,orig,vex") (set_attr "mode" "TI")]) -(define_insn "*<code>v2hi3" +(define_insn "<code>v2hi3" [(set (match_operand:V2HI 0 "register_operand" "=x,Yw") (smaxmin:V2HI (match_operand:V2HI 1 "register_operand" "%0,Yw") (match_operand:V2HI 2 "register_operand" "x,Yw")))] - "TARGET_SSE2 - && ix86_binary_operator_ok (<CODE>, V2HImode, operands)" + "TARGET_SSE2" "@ p<maxmin_int>w\t{%2, %0|%0, %2} vp<maxmin_int>w\t{%2, %1, %0|%0, %1, %2}" @@ -1829,23 +1782,12 @@ (set_attr "type" "sseiadd") (set_attr "mode" "TI")]) -(define_mode_iterator SMAXMIN_VI_32 [(V4QI "TARGET_SSE4_1") V2HI]) - -(define_expand "<code><mode>3" - [(set (match_operand:SMAXMIN_VI_32 0 "register_operand") - (smaxmin:SMAXMIN_VI_32 - (match_operand:SMAXMIN_VI_32 1 "register_operand") - (match_operand:SMAXMIN_VI_32 2 "register_operand")))] - "TARGET_SSE2" - "ix86_fixup_binary_operands_no_copy (<CODE>, V4HImode, operands);") - -(define_insn "*mmx_<code><mode>3" +(define_insn "<code><mode>3" [(set (match_operand:MMXMODE24 0 "register_operand" "=Yr,*x,Yv") (umaxmin:MMXMODE24 (match_operand:MMXMODE24 1 "register_operand" "%0,0,Yv") (match_operand:MMXMODE24 2 "register_operand" "Yr,*x,Yv")))] - "TARGET_MMX_WITH_SSE && TARGET_SSE4_1 - && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" + "TARGET_SSE4_1 && TARGET_MMX_WITH_SSE" "@ p<maxmin_int><mmxvecsize>\t{%2, %0|%0, %2} p<maxmin_int><mmxvecsize>\t{%2, %0|%0, %2} @@ -1882,24 +1824,19 @@ (set_attr "type" "mmxadd,sseiadd,sseiadd") (set_attr "mode" "DI,TI,TI")]) -(define_mode_iterator UMAXMIN_MMXMODEI - [V8QI (V4HI "TARGET_SSE4_1") (V2SI "TARGET_SSE4_1")]) - -(define_expand "<code><mode>3" - [(set (match_operand:UMAXMIN_MMXMODEI 0 "register_operand") - (umaxmin:UMAXMIN_MMXMODEI - (match_operand:UMAXMIN_MMXMODEI 1 "register_operand") - (match_operand:UMAXMIN_MMXMODEI 2 "register_operand")))] - "TARGET_MMX_WITH_SSE" - "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);") +(define_expand "<code>v8qi3" + [(set (match_operand:V8QI 0 "register_operand") + (umaxmin:V8QI + (match_operand:V8QI 1 "register_operand") + (match_operand:V8QI 2 "register_operand")))] + "TARGET_MMX_WITH_SSE") -(define_insn "*<code>v4qi3" +(define_insn "<code>v4qi3" [(set (match_operand:V4QI 0 "register_operand" "=x,Yw") (umaxmin:V4QI (match_operand:V4QI 1 "register_operand" "%0,Yw") (match_operand:V4QI 2 "register_operand" "x,Yw")))] - "TARGET_SSE2 - && ix86_binary_operator_ok (<CODE>, V4QImode, operands)" + "TARGET_SSE2" "@ p<maxmin_int>b\t{%2, %0|%0, %2} vp<maxmin_int>b\t{%2, %1, %0|%0, %1, %2}" @@ -1907,13 +1844,12 @@ (set_attr "type" "sseiadd") (set_attr "mode" "TI")]) -(define_insn "*<code>v2hi3" +(define_insn "<code>v2hi3" [(set (match_operand:V2HI 0 "register_operand" "=Yr,*x,Yv") (umaxmin:V2HI (match_operand:V2HI 1 "register_operand" "%0,0,Yv") (match_operand:V2HI 2 "register_operand" "Yr,*x,Yv")))] - "TARGET_SSE4_1 - && ix86_binary_operator_ok (<CODE>, V2HImode, operands)" + "TARGET_SSE4_1" "@ p<maxmin_int>w\t{%2, %0|%0, %2} p<maxmin_int>w\t{%2, %0|%0, %2} @@ -1924,16 +1860,6 @@ (set_attr "prefix" "orig,orig,vex") (set_attr "mode" "TI")]) -(define_mode_iterator UMAXMIN_VI_32 [V4QI (V2HI "TARGET_SSE4_1")]) - -(define_expand "<code><mode>3" - [(set (match_operand:UMAXMIN_VI_32 0 "register_operand") - (umaxmin:UMAXMIN_VI_32 - (match_operand:UMAXMIN_VI_32 1 "register_operand") - (match_operand:UMAXMIN_VI_32 2 "register_operand")))] - "TARGET_SSE2" - "ix86_fixup_binary_operands_no_copy (<CODE>, V4HImode, operands);") - (define_insn "ssse3_abs<mode>2" [(set (match_operand:MMXMODEI 0 "register_operand" "=y,Yv") (abs:MMXMODEI @@ -1953,7 +1879,7 @@ [(set (match_operand:MMXMODEI 0 "register_operand") (abs:MMXMODEI (match_operand:MMXMODEI 1 "register_operand")))] - "TARGET_MMX_WITH_SSE && TARGET_SSSE3") + "TARGET_SSSE3 && TARGET_MMX_WITH_SSE") (define_insn "abs<mode>2" [(set (match_operand:VI_32 0 "register_operand" "=Yv") @@ -2025,7 +1951,7 @@ (match_operand:DI 2 "nonmemory_operand")))] "TARGET_MMX_WITH_SSE") -(define_insn "*<insn>v2hi3" +(define_insn "<insn>v2hi3" [(set (match_operand:V2HI 0 "register_operand" "=x,Yw") (any_shift:V2HI (match_operand:V2HI 1 "register_operand" "0,Yw") @@ -2042,13 +1968,6 @@ (const_string "0"))) (set_attr "mode" "TI")]) -(define_expand "<insn>v2hi3" - [(set (match_operand:V2HI 0 "register_operand") - (any_shift:V2HI - (match_operand:V2HI 1 "register_operand") - (match_operand:DI 2 "nonmemory_operand")))] - "TARGET_SSE2") - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Parallel integral comparisons @@ -2084,8 +2003,7 @@ (eq:VI_32 (match_operand:VI_32 1 "register_operand" "%0,x") (match_operand:VI_32 2 "register_operand" "x,x")))] - "TARGET_SSE2 - && ix86_binary_operator_ok (EQ, <MODE>mode, operands)" + "TARGET_SSE2" "@ pcmpeq<mmxvecsize>\t{%2, %0|%0, %2} vpcmpeq<mmxvecsize>\t{%2, %1, %0|%0, %1, %2}" @@ -2121,6 +2039,62 @@ (set_attr "type" "ssecmp") (set_attr "mode" "TI")]) +(define_insn "*xop_maskcmp<mode>3" + [(set (match_operand:MMXMODEI 0 "register_operand" "=x") + (match_operator:MMXMODEI 1 "ix86_comparison_int_operator" + [(match_operand:MMXMODEI 2 "register_operand" "x") + (match_operand:MMXMODEI 3 "register_operand" "x")]))] + "TARGET_XOP" + "vpcom%Y1<mmxvecsize>\t{%3, %2, %0|%0, %2, %3}" + [(set_attr "type" "sse4arg") + (set_attr "prefix_data16" "0") + (set_attr "prefix_rep" "0") + (set_attr "prefix_extra" "2") + (set_attr "length_immediate" "1") + (set_attr "mode" "TI")]) + +(define_insn "*xop_maskcmp<mode>3" + [(set (match_operand:VI_32 0 "register_operand" "=x") + (match_operator:VI_32 1 "ix86_comparison_int_operator" + [(match_operand:VI_32 2 "register_operand" "x") + (match_operand:VI_32 3 "register_operand" "x")]))] + "TARGET_XOP" + "vpcom%Y1<mmxvecsize>\t{%3, %2, %0|%0, %2, %3}" + [(set_attr "type" "sse4arg") + (set_attr "prefix_data16" "0") + (set_attr "prefix_rep" "0") + (set_attr "prefix_extra" "2") + (set_attr "length_immediate" "1") + (set_attr "mode" "TI")]) + +(define_insn "*xop_maskcmp_uns<mode>3" + [(set (match_operand:MMXMODEI 0 "register_operand" "=x") + (match_operator:MMXMODEI 1 "ix86_comparison_uns_operator" + [(match_operand:MMXMODEI 2 "register_operand" "x") + (match_operand:MMXMODEI 3 "register_operand" "x")]))] + "TARGET_XOP" + "vpcom%Y1u<mmxvecsize>\t{%3, %2, %0|%0, %2, %3}" + [(set_attr "type" "ssecmp") + (set_attr "prefix_data16" "0") + (set_attr "prefix_rep" "0") + (set_attr "prefix_extra" "2") + (set_attr "length_immediate" "1") + (set_attr "mode" "TI")]) + +(define_insn "*xop_maskcmp_uns<mode>3" + [(set (match_operand:VI_32 0 "register_operand" "=x") + (match_operator:VI_32 1 "ix86_comparison_uns_operator" + [(match_operand:VI_32 2 "register_operand" "x") + (match_operand:VI_32 3 "register_operand" "x")]))] + "TARGET_XOP" + "vpcom%Y1u<mmxvecsize>\t{%3, %2, %0|%0, %2, %3}" + [(set_attr "type" "ssecmp") + (set_attr "prefix_data16" "0") + (set_attr "prefix_rep" "0") + (set_attr "prefix_extra" "2") + (set_attr "length_immediate" "1") + (set_attr "mode" "TI")]) + (define_expand "vec_cmp<mode><mode>" [(set (match_operand:MMXMODEI 0 "register_operand") (match_operator:MMXMODEI 1 "" @@ -2385,8 +2359,7 @@ (any_logic:MMXMODEI (match_operand:MMXMODEI 1 "register_operand") (match_operand:MMXMODEI 2 "register_operand")))] - "TARGET_MMX_WITH_SSE" - "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);") + "TARGET_MMX_WITH_SSE") (define_insn "*mmx_<code><mode>3" [(set (match_operand:MMXMODEI 0 "register_operand" "=y,x,x,v") @@ -2405,21 +2378,12 @@ (set_attr "type" "mmxadd,sselog,sselog,sselog") (set_attr "mode" "DI,TI,TI,TI")]) -(define_expand "<code><mode>3" - [(set (match_operand:VI_32 0 "register_operand") - (any_logic:VI_32 - (match_operand:VI_32 1 "register_operand") - (match_operand:VI_32 2 "register_operand")))] - "TARGET_SSE2" - "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);") - -(define_insn "*<code><mode>3" +(define_insn "<code><mode>3" [(set (match_operand:VI_32 0 "register_operand" "=x,x,v") (any_logic:VI_32 (match_operand:VI_32 1 "register_operand" "%0,x,v") (match_operand:VI_32 2 "register_operand" "x,x,v")))] - "TARGET_SSE2 - && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" + "TARGET_SSE2" "@ p<logic>\t{%2, %0|%0, %2} vp<logic>\t{%2, %1, %0|%0, %1, %2} @@ -2616,7 +2580,7 @@ (match_operand:SI 2 "nonimmediate_operand" "rm,rm")) (match_operand:V2SI 1 "register_operand" "0,Yv") (match_operand:SI 3 "const_int_operand")))] - "TARGET_MMX_WITH_SSE && TARGET_SSE4_1 + "TARGET_SSE4_1 && TARGET_MMX_WITH_SSE && ((unsigned) exact_log2 (INTVAL (operands[3])) < GET_MODE_NUNITS (V2SImode))" { @@ -2696,7 +2660,7 @@ (match_operand:QI 2 "nonimmediate_operand" "rm,rm")) (match_operand:V8QI 1 "register_operand" "0,YW") (match_operand:SI 3 "const_int_operand")))] - "TARGET_MMX_WITH_SSE && TARGET_SSE4_1 + "TARGET_SSE4_1 && TARGET_MMX_WITH_SSE && ((unsigned) exact_log2 (INTVAL (operands[3])) < GET_MODE_NUNITS (V8QImode))" { @@ -2766,7 +2730,7 @@ (vec_select:QI (match_operand:V8QI 1 "register_operand" "YW,YW") (parallel [(match_operand:SI 2 "const_0_to_7_operand" "n,n")])))] - "TARGET_MMX_WITH_SSE && TARGET_SSE4_1" + "TARGET_SSE4_1 && TARGET_MMX_WITH_SSE" "@ %vpextrb\t{%2, %1, %k0|%k0, %1, %2} %vpextrb\t{%2, %1, %0|%0, %1, %2}" @@ -2783,7 +2747,7 @@ (vec_select:QI (match_operand:V8QI 1 "register_operand" "YW") (parallel [(match_operand:SI 2 "const_0_to_7_operand" "n")]))))] - "TARGET_MMX_WITH_SSE && TARGET_SSE4_1" + "TARGET_SSE4_1 && TARGET_MMX_WITH_SSE" "%vpextrb\t{%2, %1, %k0|%k0, %1, %2}" [(set_attr "type" "sselog1") (set_attr "prefix_data16" "1") @@ -3265,10 +3229,48 @@ (match_dup 3)) (const_int 1))))] "TARGET_MMX_WITH_SSE" -{ - operands[3] = CONST1_RTX(<mmxdoublemode>mode); - ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands); -}) + "operands[3] = CONST1_RTX(<mmxdoublemode>mode);") + +(define_insn "uavgv4qi3_ceil" + [(set (match_operand:V4QI 0 "register_operand" "=x,Yw") + (truncate:V4QI + (lshiftrt:V4HI + (plus:V4HI + (plus:V4HI + (zero_extend:V4HI + (match_operand:V4QI 1 "register_operand" "%0,Yw")) + (zero_extend:V4HI + (match_operand:V4QI 2 "register_operand" "x,Yw"))) + (const_vector:V4HI [(const_int 1) (const_int 1) + (const_int 1) (const_int 1)])) + (const_int 1))))] + "TARGET_SSE2" + "@ + pavgb\t{%2, %0|%0, %2} + vpavgb\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "isa" "noavx,avx") + (set_attr "type" "sseiadd") + (set_attr "mode" "TI")]) + +(define_insn "uavgv2hi3_ceil" + [(set (match_operand:V2HI 0 "register_operand" "=x,Yw") + (truncate:V2HI + (lshiftrt:V2SI + (plus:V2SI + (plus:V2SI + (zero_extend:V2SI + (match_operand:V2HI 1 "register_operand" "%0,Yw")) + (zero_extend:V2SI + (match_operand:V2HI 2 "register_operand" "x,Yw"))) + (const_vector:V2SI [(const_int 1) (const_int 1)])) + (const_int 1))))] + "TARGET_SSE2" + "@ + pavgw\t{%2, %0|%0, %2} + vpavgw\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "isa" "noavx,avx") + (set_attr "type" "sseiadd") + (set_attr "mode" "TI")]) (define_insn "mmx_psadbw" [(set (match_operand:V1DI 0 "register_operand" "=y,x,Yw") diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 7269147..1b3df21 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -1999,8 +1999,7 @@ [(set (match_operand:VF2 0 "register_operand") (div:VF2 (match_operand:VF2 1 "register_operand") (match_operand:VF2 2 "vector_operand")))] - "TARGET_SSE2" - "ix86_fixup_binary_operands_no_copy (DIV, <MODE>mode, operands);") + "TARGET_SSE2") (define_expand "div<mode>3" [(set (match_operand:VF1 0 "register_operand") @@ -2008,8 +2007,6 @@ (match_operand:VF1 2 "vector_operand")))] "TARGET_SSE" { - ix86_fixup_binary_operands_no_copy (DIV, <MODE>mode, operands); - if (TARGET_SSE_MATH && TARGET_RECIP_VEC_DIV && !optimize_insn_for_size_p () @@ -12801,7 +12798,7 @@ { if (TARGET_AVX512F && (<MODE>mode == V8DImode || TARGET_AVX512VL)) - ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands); + ; else { enum rtx_code code; @@ -17186,10 +17183,7 @@ (match_dup 3)) (const_int 1))))] "TARGET_MMX_WITH_SSE && TARGET_SSSE3" -{ - operands[3] = CONST1_RTX(V4HImode); - ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands); -}) + "operands[3] = CONST1_RTX(V4HImode);") (define_expand "ssse3_pmulhrswv4hi3" [(set (match_operand:V4HI 0 "register_operand") @@ -17254,10 +17248,7 @@ (match_dup 3)) (const_int 1))))] "TARGET_SSSE3" -{ - operands[3] = CONST1_RTX(V2HImode); - ix86_fixup_binary_operands_no_copy (MULT, V2HImode, operands); -}) + "operands[3] = CONST1_RTX(V2HImode);") (define_insn "*smulhrsv2hi3" [(set (match_operand:V2HI 0 "register_operand" "=x,Yv") diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7c13a6e..d4aa545 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,47 @@ +2021-05-27 Matthias Kretz <kretz@kde.org> + + PR c++/100716 + * error.c (dump_template_bindings): Include code to print + "[with" and ']', conditional on whether anything is printed at + all. This is tied to whether a semicolon is needed to separate + multiple template parameters. If the template argument repeats + the template parameter (T = T), then skip the parameter. + (dump_substitution): Moved code to print "[with" and ']' to + dump_template_bindings. + (dump_function_decl): Partial revert of PR50828, which masked + TFF_TEMPLATE_NAME for all of dump_function_decl. Now + TFF_TEMPLATE_NAME is masked for the scope of the function and + only carries through to dump_function_name. + (dump_function_name): Avoid calling dump_template_parms if + TFF_TEMPLATE_NAME is set. + +2021-05-27 Matthias Kretz <kretz@kde.org> + + PR c++/100763 + * error.c: Call dump_scope when printing a typedef. + +2021-05-27 Patrick Palka <ppalka@redhat.com> + + PR c++/99893 + * tree.c (cp_walk_subtrees) <case STATIC_ASSERT>: New case. + +2021-05-27 Jason Merrill <jason@redhat.com> + + PR c++/86355 + * pt.c (use_pack_expansion_extra_args_p): Don't compare + args from the same argument pack. + +2021-05-27 Patrick Palka <ppalka@redhat.com> + + DR 1315 + PR c++/67593 + PR c++/96555 + * pt.c (process_partial_specialization): Don't error on a + non-simple non-type template argument that involves template + parameters. + (for_each_template_parm_r): Don't walk TRAIT_EXPR, PLUS_EXPR, + MULT_EXPR, or SCOPE_REF when include_nondeduced_p is false. + 2021-05-26 Patrick Palka <ppalka@redhat.com> PR c++/100502 diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 3d5eebd..4a89b34 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -371,7 +371,35 @@ static void dump_template_bindings (cxx_pretty_printer *pp, tree parms, tree args, vec<tree, va_gc> *typenames) { - bool need_semicolon = false; + /* Print "[with" and ']', conditional on whether anything is printed at all. + This is tied to whether a semicolon is needed to separate multiple template + parameters. */ + struct prepost_semicolon + { + cxx_pretty_printer *pp; + bool need_semicolon; + + void operator() () + { + if (need_semicolon) + pp_separate_with_semicolon (pp); + else + { + pp_cxx_whitespace (pp); + pp_cxx_left_bracket (pp); + pp->translate_string ("with"); + pp_cxx_whitespace (pp); + need_semicolon = true; + } + } + + ~prepost_semicolon () + { + if (need_semicolon) + pp_cxx_right_bracket (pp); + } + } semicolon_or_introducer = {pp, false}; + int i; tree t; @@ -395,10 +423,20 @@ dump_template_bindings (cxx_pretty_printer *pp, tree parms, tree args, if (lvl_args && NUM_TMPL_ARGS (lvl_args) > arg_idx) arg = TREE_VEC_ELT (lvl_args, arg_idx); - if (need_semicolon) - pp_separate_with_semicolon (pp); - dump_template_parameter (pp, TREE_VEC_ELT (p, i), - TFF_PLAIN_IDENTIFIER); + tree parm_i = TREE_VEC_ELT (p, i); + /* If the template argument repeats the template parameter (T = T), + skip the parameter.*/ + if (arg && TREE_CODE (arg) == TEMPLATE_TYPE_PARM + && TREE_CODE (parm_i) == TREE_LIST + && TREE_CODE (TREE_VALUE (parm_i)) == TYPE_DECL + && TREE_CODE (TREE_TYPE (TREE_VALUE (parm_i))) + == TEMPLATE_TYPE_PARM + && DECL_NAME (TREE_VALUE (parm_i)) + == DECL_NAME (TREE_CHAIN (arg))) + continue; + + semicolon_or_introducer (); + dump_template_parameter (pp, parm_i, TFF_PLAIN_IDENTIFIER); pp_cxx_whitespace (pp); pp_equal (pp); pp_cxx_whitespace (pp); @@ -414,7 +452,6 @@ dump_template_bindings (cxx_pretty_printer *pp, tree parms, tree args, pp_string (pp, M_("<missing>")); ++arg_idx; - need_semicolon = true; } parms = TREE_CHAIN (parms); @@ -436,8 +473,7 @@ dump_template_bindings (cxx_pretty_printer *pp, tree parms, tree args, FOR_EACH_VEC_SAFE_ELT (typenames, i, t) { - if (need_semicolon) - pp_separate_with_semicolon (pp); + semicolon_or_introducer (); dump_type (pp, t, TFF_PLAIN_IDENTIFIER); pp_cxx_whitespace (pp); pp_equal (pp); @@ -501,6 +537,8 @@ dump_type (cxx_pretty_printer *pp, tree t, int flags) else { pp_cxx_cv_qualifier_seq (pp, t); + if (! (flags & TFF_UNQUALIFIED_NAME)) + dump_scope (pp, CP_DECL_CONTEXT (decl), flags); pp_cxx_tree_identifier (pp, TYPE_IDENTIFIER (t)); return; } @@ -1597,12 +1635,7 @@ dump_substitution (cxx_pretty_printer *pp, && !(flags & TFF_NO_TEMPLATE_BINDINGS)) { vec<tree, va_gc> *typenames = t ? find_typenames (t) : NULL; - pp_cxx_whitespace (pp); - pp_cxx_left_bracket (pp); - pp->translate_string ("with"); - pp_cxx_whitespace (pp); dump_template_bindings (pp, template_parms, template_args, typenames); - pp_cxx_right_bracket (pp); } } @@ -1643,7 +1676,8 @@ dump_function_decl (cxx_pretty_printer *pp, tree t, int flags) bool constexpr_p; tree ret = NULL_TREE; - flags &= ~(TFF_UNQUALIFIED_NAME | TFF_TEMPLATE_NAME); + int dump_function_name_flags = flags & ~TFF_UNQUALIFIED_NAME; + flags = dump_function_name_flags & ~TFF_TEMPLATE_NAME; if (TREE_CODE (t) == TEMPLATE_DECL) t = DECL_TEMPLATE_RESULT (t); @@ -1721,7 +1755,7 @@ dump_function_decl (cxx_pretty_printer *pp, tree t, int flags) else dump_scope (pp, CP_DECL_CONTEXT (t), flags); - dump_function_name (pp, t, flags); + dump_function_name (pp, t, dump_function_name_flags); if (!(flags & TFF_NO_FUNCTION_ARGUMENTS)) { @@ -1935,6 +1969,7 @@ dump_function_name (cxx_pretty_printer *pp, tree t, int flags) dump_module_suffix (pp, t); if (DECL_TEMPLATE_INFO (t) + && !(flags & TFF_TEMPLATE_NAME) && !DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (t) && (TREE_CODE (DECL_TI_TEMPLATE (t)) != TEMPLATE_DECL || PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t)))) diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 48b83d6..84c6be8 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -35117,7 +35117,9 @@ cp_parser_omp_clause_name (cp_parser *parser) switch (p[0]) { case 'a': - if (!strcmp ("aligned", p)) + if (!strcmp ("affinity", p)) + result = PRAGMA_OMP_CLAUSE_AFFINITY; + else if (!strcmp ("aligned", p)) result = PRAGMA_OMP_CLAUSE_ALIGNED; else if (!strcmp ("allocate", p)) result = PRAGMA_OMP_CLAUSE_ALLOCATE; @@ -35376,7 +35378,7 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind, { tree name, decl; - if (kind == OMP_CLAUSE_DEPEND) + if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY) cp_parser_parse_tentatively (parser); token = cp_lexer_peek_token (parser->lexer); if (kind != 0 @@ -35405,7 +35407,7 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind, /*optional_p=*/false); if (name == error_mark_node) { - if (kind == OMP_CLAUSE_DEPEND + if ((kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY) && cp_parser_simulate_error (parser)) goto depend_lvalue; goto skip_comma; @@ -35417,7 +35419,7 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind, decl = name; if (decl == error_mark_node) { - if (kind == OMP_CLAUSE_DEPEND + if ((kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY) && cp_parser_simulate_error (parser)) goto depend_lvalue; cp_parser_name_lookup_error (parser, name, decl, NLE_NULL, @@ -35463,6 +35465,7 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind, &idk, loc); } /* FALLTHROUGH. */ + case OMP_CLAUSE_AFFINITY: case OMP_CLAUSE_DEPEND: case OMP_CLAUSE_REDUCTION: case OMP_CLAUSE_IN_REDUCTION: @@ -35489,12 +35492,12 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind, /* Look for `:'. */ if (!cp_parser_require (parser, CPP_COLON, RT_COLON)) { - if (kind == OMP_CLAUSE_DEPEND + if ((kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY) && cp_parser_simulate_error (parser)) goto depend_lvalue; goto skip_comma; } - if (kind == OMP_CLAUSE_DEPEND) + if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY) cp_parser_commit_to_tentative_parse (parser); if (!cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_SQUARE)) @@ -35508,7 +35511,7 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind, if (!cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE)) { - if (kind == OMP_CLAUSE_DEPEND + if ((kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY) && cp_parser_simulate_error (parser)) goto depend_lvalue; goto skip_comma; @@ -35521,7 +35524,7 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind, break; } - if (kind == OMP_CLAUSE_DEPEND) + if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY) { if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA) && cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN) @@ -37761,6 +37764,66 @@ cp_parser_omp_iterators (cp_parser *parser) return ret ? ret : error_mark_node; } +/* OpenMP 5.0: + affinity ( [aff-modifier :] variable-list ) + aff-modifier: + iterator ( iterators-definition ) */ + +static tree +cp_parser_omp_clause_affinity (cp_parser *parser, tree list) +{ + tree nlist, c, iterators = NULL_TREE; + + matching_parens parens; + if (!parens.require_open (parser)) + return list; + + if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)) + { + tree id = cp_lexer_peek_token (parser->lexer)->u.value; + const char *p = IDENTIFIER_POINTER (id); + bool parse_iter = ((strcmp ("iterator", p) == 0) + && (cp_lexer_nth_token_is (parser->lexer, 2, + CPP_OPEN_PAREN))); + if (parse_iter) + { + size_t n = cp_parser_skip_balanced_tokens (parser, 2); + parse_iter = cp_lexer_nth_token_is (parser->lexer, n, CPP_COLON); + } + if (parse_iter) + { + begin_scope (sk_omp, NULL); + iterators = cp_parser_omp_iterators (parser); + if (!cp_parser_require (parser, CPP_COLON, RT_COLON)) + { + if (iterators) + poplevel (0, 1, 0); + cp_parser_skip_to_closing_parenthesis (parser, + /*recovering=*/true, + /*or_comma=*/false, + /*consume_paren=*/true); + return list; + } + } + } + nlist = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_AFFINITY, + list, NULL); + if (iterators) + { + tree block = poplevel (1, 1, 0); + if (iterators == error_mark_node) + iterators = NULL_TREE; + else + { + TREE_VEC_ELT (iterators, 5) = block; + for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c)) + OMP_CLAUSE_DECL (c) = build_tree_list (iterators, + OMP_CLAUSE_DECL (c)); + } + } + return nlist; +} + /* OpenMP 4.0: depend ( depend-kind : variable-list ) @@ -38753,6 +38816,10 @@ cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask, } c_name = "linear"; break; + case PRAGMA_OMP_CLAUSE_AFFINITY: + clauses = cp_parser_omp_clause_affinity (parser, clauses); + c_name = "affinity"; + break; case PRAGMA_OMP_CLAUSE_DEPEND: clauses = cp_parser_omp_clause_depend (parser, clauses, token->location); @@ -41349,7 +41416,8 @@ cp_parser_omp_single (cp_parser *parser, cp_token *pragma_tok, bool *if_p) | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \ - | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DETACH)) + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DETACH) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_AFFINITY)) static tree cp_parser_omp_task (cp_parser *parser, cp_token *pragma_tok, bool *if_p) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index f3fa9c1..bb22d68 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -5157,11 +5157,7 @@ process_partial_specialization (tree decl) maintmpl); } - /* [temp.class.spec] - - A partially specialized non-type argument expression shall not - involve template parameters of the partial specialization except - when the argument expression is a simple identifier. + /* [temp.spec.partial] The type of a template parameter corresponding to a specialized non-type argument shall not be dependent on a parameter of the @@ -5222,63 +5218,55 @@ process_partial_specialization (tree decl) || TREE_CODE (arg) == VIEW_CONVERT_EXPR) && TREE_CODE (TREE_OPERAND (arg, 0)) == TEMPLATE_PARM_INDEX)) { - if ((!packed_args && tpd.arg_uses_template_parms[i]) - || (packed_args && uses_template_parms (arg))) - error_at (cp_expr_loc_or_input_loc (arg), - "template argument %qE involves template " - "parameter(s)", arg); - else - { - /* Look at the corresponding template parameter, - marking which template parameters its type depends - upon. */ - tree type = TREE_TYPE (parm); + /* Look at the corresponding template parameter, + marking which template parameters its type depends + upon. */ + tree type = TREE_TYPE (parm); - if (!tpd2.parms) - { - /* We haven't yet initialized TPD2. Do so now. */ - tpd2.arg_uses_template_parms = XALLOCAVEC (int, nargs); - /* The number of parameters here is the number in the - main template, which, as checked in the assertion - above, is NARGS. */ - tpd2.parms = XALLOCAVEC (int, nargs); - tpd2.level = - TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (maintmpl)); - } + if (!tpd2.parms) + { + /* We haven't yet initialized TPD2. Do so now. */ + tpd2.arg_uses_template_parms = XALLOCAVEC (int, nargs); + /* The number of parameters here is the number in the + main template, which, as checked in the assertion + above, is NARGS. */ + tpd2.parms = XALLOCAVEC (int, nargs); + tpd2.level = + TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (maintmpl)); + } - /* Mark the template parameters. But this time, we're - looking for the template parameters of the main - template, not in the specialization. */ - tpd2.current_arg = i; - tpd2.arg_uses_template_parms[i] = 0; - memset (tpd2.parms, 0, sizeof (int) * nargs); - for_each_template_parm (type, - &mark_template_parm, - &tpd2, - NULL, - /*include_nondeduced_p=*/false); - - if (tpd2.arg_uses_template_parms [i]) - { - /* The type depended on some template parameters. - If they are fully specialized in the - specialization, that's OK. */ - int j; - int count = 0; - for (j = 0; j < nargs; ++j) - if (tpd2.parms[j] != 0 - && tpd.arg_uses_template_parms [j]) - ++count; - if (count != 0) - error_n (input_location, count, - "type %qT of template argument %qE depends " - "on a template parameter", - "type %qT of template argument %qE depends " - "on template parameters", - type, - arg); - } - } + /* Mark the template parameters. But this time, we're + looking for the template parameters of the main + template, not in the specialization. */ + tpd2.current_arg = i; + tpd2.arg_uses_template_parms[i] = 0; + memset (tpd2.parms, 0, sizeof (int) * nargs); + for_each_template_parm (type, + &mark_template_parm, + &tpd2, + NULL, + /*include_nondeduced_p=*/false); + + if (tpd2.arg_uses_template_parms [i]) + { + /* The type depended on some template parameters. + If they are fully specialized in the + specialization, that's OK. */ + int j; + int count = 0; + for (j = 0; j < nargs; ++j) + if (tpd2.parms[j] != 0 + && tpd.arg_uses_template_parms [j]) + ++count; + if (count != 0) + error_n (input_location, count, + "type %qT of template argument %qE depends " + "on a template parameter", + "type %qT of template argument %qE depends " + "on template parameters", + type, + arg); + } } } } @@ -10502,6 +10490,15 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d) return error_mark_node; break; + case TRAIT_EXPR: + case PLUS_EXPR: + case MULT_EXPR: + case SCOPE_REF: + /* These are non-deduced contexts. */ + if (!pfd->include_nondeduced_p) + *walk_subtrees = 0; + break; + case MODOP_EXPR: case CAST_EXPR: case IMPLICIT_CONV_EXPR: @@ -10517,11 +10514,6 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d) return error_mark_node; break; - case SCOPE_REF: - if (pfd->include_nondeduced_p) - WALK_SUBTREE (TREE_OPERAND (t, 0)); - break; - case REQUIRES_EXPR: { if (!fn) @@ -12430,9 +12422,9 @@ use_pack_expansion_extra_args_p (tree parm_packs, return false; } - bool has_expansion_arg = false; for (int i = 0 ; i < arg_pack_len; ++i) { + bool has_expansion_arg = false; bool has_non_expansion_arg = false; for (tree parm_pack = parm_packs; parm_pack; @@ -12452,7 +12444,10 @@ use_pack_expansion_extra_args_p (tree parm_packs, } if (has_expansion_arg && has_non_expansion_arg) - return true; + { + gcc_checking_assert (false); + return true; + } } return false; } diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index fffbe40..fe370a2 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -4993,7 +4993,8 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types, " clauses"); return error_mark_node; } - else if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND + else if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_AFFINITY + && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND && VAR_P (t) && CP_DECL_THREAD_LOCAL_P (t)) { error_at (OMP_CLAUSE_LOCATION (c), @@ -5080,7 +5081,8 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types, { if (!integer_nonzerop (length)) { - if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION) @@ -5148,7 +5150,8 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types, } if (tree_int_cst_equal (size, low_bound)) { - if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION) @@ -5169,7 +5172,8 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types, } else if (length == NULL_TREE) { - if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND + if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_AFFINITY + && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_IN_REDUCTION && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_TASK_REDUCTION) @@ -5207,7 +5211,8 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types, } else if (length == NULL_TREE) { - if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND + if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_AFFINITY + && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_IN_REDUCTION && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_TASK_REDUCTION) @@ -5251,7 +5256,8 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types, } /* If there is a pointer type anywhere but in the very first array-section-subscript, the array section can't be contiguous. */ - if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND + if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_AFFINITY + && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND && TREE_CODE (TREE_CHAIN (t)) == TREE_LIST) { error_at (OMP_CLAUSE_LOCATION (c), @@ -5299,7 +5305,8 @@ handle_omp_array_sections (tree c, enum c_omp_region_type ort) unsigned int first_non_one = 0; auto_vec<tree, 10> types; tree *tp = &OMP_CLAUSE_DECL (c); - if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND + if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY) && TREE_CODE (*tp) == TREE_LIST && TREE_PURPOSE (*tp) && TREE_CODE (TREE_PURPOSE (*tp)) == TREE_VEC) @@ -5311,7 +5318,8 @@ handle_omp_array_sections (tree c, enum c_omp_region_type ort) return true; if (first == NULL_TREE) return false; - if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND) + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY) { tree t = *tp; tree tem = NULL_TREE; @@ -5540,6 +5548,7 @@ handle_omp_array_sections (tree c, enum c_omp_region_type ort) } else OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_FIRSTPRIVATE_POINTER); + OMP_CLAUSE_MAP_IMPLICIT (c2) = OMP_CLAUSE_MAP_IMPLICIT (c); if (OMP_CLAUSE_MAP_KIND (c2) != GOMP_MAP_FIRSTPRIVATE_POINTER && !cxx_mark_addressable (t)) return false; @@ -5566,6 +5575,7 @@ handle_omp_array_sections (tree c, enum c_omp_region_type ort) tree c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP); OMP_CLAUSE_SET_MAP_KIND (c3, OMP_CLAUSE_MAP_KIND (c2)); + OMP_CLAUSE_MAP_IMPLICIT (c2) = OMP_CLAUSE_MAP_IMPLICIT (c); OMP_CLAUSE_DECL (c3) = ptr; if (OMP_CLAUSE_MAP_KIND (c2) == GOMP_MAP_ALWAYS_POINTER || OMP_CLAUSE_MAP_KIND (c2) == GOMP_MAP_ATTACH_DETACH) @@ -6502,7 +6512,8 @@ tree finish_omp_clauses (tree clauses, enum c_omp_region_type ort) { bitmap_head generic_head, firstprivate_head, lastprivate_head; - bitmap_head aligned_head, map_head, map_field_head, oacc_reduction_head; + bitmap_head aligned_head, map_head, map_field_head, map_firstprivate_head; + bitmap_head oacc_reduction_head; tree c, t, *pc; tree safelen = NULL_TREE; bool branch_seen = false; @@ -6519,7 +6530,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) bool allocate_seen = false; tree detach_seen = NULL_TREE; bool mergeable_seen = false; - bool firstprivate_implicit_moved = false; + bool implicit_moved = false; bitmap_obstack_initialize (NULL); bitmap_initialize (&generic_head, &bitmap_default_obstack); @@ -6529,6 +6540,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) /* If ort == C_ORT_OMP_DECLARE_SIMD used as uniform_head instead. */ bitmap_initialize (&map_head, &bitmap_default_obstack); bitmap_initialize (&map_field_head, &bitmap_default_obstack); + bitmap_initialize (&map_firstprivate_head, &bitmap_default_obstack); /* If ort == C_ORT_OMP used as nontemporal_head or use_device_xxx_head instead. */ bitmap_initialize (&oacc_reduction_head, &bitmap_default_obstack); @@ -6844,28 +6856,36 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) break; case OMP_CLAUSE_FIRSTPRIVATE: - if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c) - && !firstprivate_implicit_moved) + if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c) && !implicit_moved) { - firstprivate_implicit_moved = true; - /* Move firstprivate clauses with - OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT set to the end of + move_implicit: + implicit_moved = true; + /* Move firstprivate and map clauses with + OMP_CLAUSE_{FIRSTPRIVATE,MAP}_IMPLICIT set to the end of clauses chain. */ - tree cl = NULL, *pc1 = pc, *pc2 = &cl; + tree cl1 = NULL_TREE, cl2 = NULL_TREE; + tree *pc1 = pc, *pc2 = &cl1, *pc3 = &cl2; while (*pc1) if (OMP_CLAUSE_CODE (*pc1) == OMP_CLAUSE_FIRSTPRIVATE && OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (*pc1)) { + *pc3 = *pc1; + pc3 = &OMP_CLAUSE_CHAIN (*pc3); + *pc1 = OMP_CLAUSE_CHAIN (*pc1); + } + else if (OMP_CLAUSE_CODE (*pc1) == OMP_CLAUSE_MAP + && OMP_CLAUSE_MAP_IMPLICIT (*pc1)) + { *pc2 = *pc1; pc2 = &OMP_CLAUSE_CHAIN (*pc2); *pc1 = OMP_CLAUSE_CHAIN (*pc1); } else pc1 = &OMP_CLAUSE_CHAIN (*pc1); - *pc2 = NULL; - *pc1 = cl; - if (pc1 != pc) - continue; + *pc3 = NULL; + *pc2 = cl2; + *pc1 = cl1; + continue; } t = omp_clause_decl_field (OMP_CLAUSE_DECL (c)); if (t) @@ -6896,6 +6916,10 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) t); remove = true; } + else if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c) + && !OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT_TARGET (c) + && bitmap_bit_p (&map_firstprivate_head, DECL_UID (t))) + remove = true; else if (bitmap_bit_p (&generic_head, DECL_UID (t)) || bitmap_bit_p (&firstprivate_head, DECL_UID (t))) { @@ -7445,6 +7469,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) } goto handle_field_decl; + case OMP_CLAUSE_AFFINITY: case OMP_CLAUSE_DEPEND: t = OMP_CLAUSE_DECL (c); if (t == NULL_TREE) @@ -7453,7 +7478,8 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) == OMP_CLAUSE_DEPEND_SOURCE); break; } - if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK) + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND + && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK) { if (cp_finish_omp_clause_depend_sink (c)) remove = true; @@ -7478,7 +7504,9 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) { if (handle_omp_array_sections (c, ort)) remove = true; - else if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_DEPOBJ) + else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND + && (OMP_CLAUSE_DEPEND_KIND (c) + == OMP_CLAUSE_DEPEND_DEPOBJ)) { error_at (OMP_CLAUSE_LOCATION (c), "%<depend%> clause with %<depobj%> dependence " @@ -7503,22 +7531,28 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) if (DECL_P (t)) error_at (OMP_CLAUSE_LOCATION (c), "%qD is not lvalue expression nor array section " - "in %<depend%> clause", t); + "in %qs clause", t, + omp_clause_code_name[OMP_CLAUSE_CODE (c)]); else error_at (OMP_CLAUSE_LOCATION (c), "%qE is not lvalue expression nor array section " - "in %<depend%> clause", t); + "in %qs clause", t, + omp_clause_code_name[OMP_CLAUSE_CODE (c)]); remove = true; } else if (TREE_CODE (t) == COMPONENT_REF && TREE_CODE (TREE_OPERAND (t, 1)) == FIELD_DECL && DECL_BIT_FIELD (TREE_OPERAND (t, 1))) { + gcc_assert (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY); error_at (OMP_CLAUSE_LOCATION (c), - "bit-field %qE in %qs clause", t, "depend"); + "bit-field %qE in %qs clause", t, + omp_clause_code_name[OMP_CLAUSE_CODE (c)]); remove = true; } - else if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_DEPOBJ) + else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND + && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_DEPOBJ) { if (!c_omp_depend_t_p (TYPE_REF_P (TREE_TYPE (t)) ? TREE_TYPE (TREE_TYPE (t)) @@ -7531,9 +7565,10 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) remove = true; } } - else if (c_omp_depend_t_p (TYPE_REF_P (TREE_TYPE (t)) - ? TREE_TYPE (TREE_TYPE (t)) - : TREE_TYPE (t))) + else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND + && c_omp_depend_t_p (TYPE_REF_P (TREE_TYPE (t)) + ? TREE_TYPE (TREE_TYPE (t)) + : TREE_TYPE (t))) { error_at (OMP_CLAUSE_LOCATION (c), "%qE should not have %<omp_depend_t%> type in " @@ -7601,6 +7636,9 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) break; case OMP_CLAUSE_MAP: + if (OMP_CLAUSE_MAP_IMPLICIT (c) && !implicit_moved) + goto move_implicit; + /* FALLTHRU */ case OMP_CLAUSE_TO: case OMP_CLAUSE_FROM: case OMP_CLAUSE__CACHE_: @@ -7632,6 +7670,16 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) t = TREE_OPERAND (t, 0); if (REFERENCE_REF_P (t)) t = TREE_OPERAND (t, 0); + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP + && OMP_CLAUSE_MAP_IMPLICIT (c) + && (bitmap_bit_p (&map_head, DECL_UID (t)) + || bitmap_bit_p (&map_field_head, DECL_UID (t)) + || bitmap_bit_p (&map_firstprivate_head, + DECL_UID (t)))) + { + remove = true; + break; + } if (bitmap_bit_p (&map_field_head, DECL_UID (t))) break; if (bitmap_bit_p (&map_head, DECL_UID (t))) @@ -7813,6 +7861,13 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) remove = true; } else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP + && OMP_CLAUSE_MAP_IMPLICIT (c) + && (bitmap_bit_p (&map_head, DECL_UID (t)) + || bitmap_bit_p (&map_field_head, DECL_UID (t)) + || bitmap_bit_p (&map_firstprivate_head, + DECL_UID (t)))) + remove = true; + else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER) { if (bitmap_bit_p (&generic_head, DECL_UID (t)) @@ -7833,7 +7888,10 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) remove = true; } else - bitmap_set_bit (&generic_head, DECL_UID (t)); + { + bitmap_set_bit (&generic_head, DECL_UID (t)); + bitmap_set_bit (&map_firstprivate_head, DECL_UID (t)); + } } else if (bitmap_bit_p (&map_head, DECL_UID (t)) && !bitmap_bit_p (&map_field_head, DECL_UID (t))) diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 372d89f..fec5afa 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -5446,6 +5446,11 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func, } break; + case STATIC_ASSERT: + WALK_SUBTREE (STATIC_ASSERT_CONDITION (*tp)); + WALK_SUBTREE (STATIC_ASSERT_MESSAGE (*tp)); + break; + default: return NULL_TREE; } diff --git a/gcc/doc/gcov.texi b/gcc/doc/gcov.texi index d076721..32b51f9 100644 --- a/gcc/doc/gcov.texi +++ b/gcc/doc/gcov.texi @@ -887,8 +887,7 @@ Long-running applications can use the @code{__gcov_reset} and @code{__gcov_dump} facilities to restrict profile collection to the program region of interest. Calling @code{__gcov_reset(void)} will clear all run-time profile counters to zero, and calling @code{__gcov_dump(void)} will cause the profile -information collected at that point to be dumped to @file{.gcda} output files -(the function can be called just once). +information collected at that point to be dumped to @file{.gcda} output files. Instrumented applications use a static destructor with priority 99 to invoke the @code{__gcov_dump} function. Thus @code{__gcov_dump} is executed after all user defined static destructors, diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index b30db1c..d261101 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,16 @@ +2021-05-27 Harald Anlauf <anlauf@gmx.de> + + PR fortran/100602 + * trans-intrinsic.c (gfc_conv_intrinsic_size): Use CLASS data + attributes for CLASS arrays for generation of runtime error. + +2021-05-27 Harald Anlauf <anlauf@gmx.de> + + PR fortran/100656 + * trans-array.c (gfc_conv_ss_startstride): Do not call check for + presence of a dummy argument when a symbol actually refers to a + non-dummy. + 2021-05-25 Tobias Burnus <tobias@codesourcery.com> Johannes Nendwich <a08727063@unet.univie.ac.at> diff --git a/gcc/fortran/dump-parse-tree.c b/gcc/fortran/dump-parse-tree.c index 874e6d4..93ff572 100644 --- a/gcc/fortran/dump-parse-tree.c +++ b/gcc/fortran/dump-parse-tree.c @@ -1298,10 +1298,55 @@ show_code (int level, gfc_code *c) } static void +show_iterator (gfc_namespace *ns) +{ + for (gfc_symbol *sym = ns->proc_name; sym; sym = sym->tlink) + { + gfc_constructor *c; + if (sym != ns->proc_name) + fputc (',', dumpfile); + fputs (sym->name, dumpfile); + fputc ('=', dumpfile); + c = gfc_constructor_first (sym->value->value.constructor); + show_expr (c->expr); + fputc (':', dumpfile); + c = gfc_constructor_next (c); + show_expr (c->expr); + c = gfc_constructor_next (c); + if (c) + { + fputc (':', dumpfile); + show_expr (c->expr); + } + } +} + +static void show_omp_namelist (int list_type, gfc_omp_namelist *n) { + gfc_namespace *ns_iter = NULL, *ns_curr = gfc_current_ns; + gfc_omp_namelist *n2 = n; for (; n; n = n->next) { + gfc_current_ns = ns_curr; + if (list_type == OMP_LIST_AFFINITY || list_type == OMP_LIST_DEPEND) + { + gfc_current_ns = n->u2.ns ? n->u2.ns : ns_curr; + if (n->u2.ns != ns_iter) + { + if (n != n2) + fputs (list_type == OMP_LIST_AFFINITY + ? ") AFFINITY(" : ") DEPEND(", dumpfile); + if (n->u2.ns) + { + fputs ("ITERATOR(", dumpfile); + show_iterator (n->u2.ns); + fputc (')', dumpfile); + fputc (list_type == OMP_LIST_AFFINITY ? ':' : ',', dumpfile); + } + } + ns_iter = n->u2.ns; + } if (list_type == OMP_LIST_REDUCTION) switch (n->u.reduction_op) { @@ -1321,8 +1366,8 @@ show_omp_namelist (int list_type, gfc_omp_namelist *n) case OMP_REDUCTION_IOR: fputs ("ior:", dumpfile); break; case OMP_REDUCTION_IEOR: fputs ("ieor:", dumpfile); break; case OMP_REDUCTION_USER: - if (n->udr) - fprintf (dumpfile, "%s:", n->udr->udr->name); + if (n->u2.udr) + fprintf (dumpfile, "%s:", n->u2.udr->udr->name); break; default: break; } @@ -1387,6 +1432,7 @@ show_omp_namelist (int list_type, gfc_omp_namelist *n) if (n->next) fputc (',', dumpfile); } + gfc_current_ns = ns_curr; } @@ -1610,6 +1656,7 @@ show_omp_clauses (gfc_omp_clauses *omp_clauses) case OMP_LIST_SHARED: type = "SHARED"; break; case OMP_LIST_COPYIN: type = "COPYIN"; break; case OMP_LIST_UNIFORM: type = "UNIFORM"; break; + case OMP_LIST_AFFINITY: type = "AFFINITY"; break; case OMP_LIST_ALIGNED: type = "ALIGNED"; break; case OMP_LIST_LINEAR: type = "LINEAR"; break; case OMP_LIST_DEPEND: type = "DEPEND"; break; diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index bab785b..55fba04 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -1257,7 +1257,11 @@ typedef struct gfc_omp_namelist struct gfc_common_head *common; bool lastprivate_conditional; } u; - struct gfc_omp_namelist_udr *udr; + union + { + struct gfc_omp_namelist_udr *udr; + gfc_namespace *ns; + } u2; struct gfc_omp_namelist *next; locus where; } @@ -1275,6 +1279,7 @@ enum OMP_LIST_SHARED, OMP_LIST_COPYIN, OMP_LIST_UNIFORM, + OMP_LIST_AFFINITY, OMP_LIST_ALIGNED, OMP_LIST_LINEAR, OMP_LIST_DEPEND, @@ -3321,7 +3326,7 @@ void gfc_free_iterator (gfc_iterator *, int); void gfc_free_forall_iterator (gfc_forall_iterator *); void gfc_free_alloc_list (gfc_alloc *); void gfc_free_namelist (gfc_namelist *); -void gfc_free_omp_namelist (gfc_omp_namelist *); +void gfc_free_omp_namelist (gfc_omp_namelist *, bool); void gfc_free_equiv (gfc_equiv *); void gfc_free_equiv_until (gfc_equiv *, gfc_equiv *); void gfc_free_data (gfc_data *); diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c index 393755e..2946201 100644 --- a/gcc/fortran/match.c +++ b/gcc/fortran/match.c @@ -5470,20 +5470,22 @@ gfc_free_namelist (gfc_namelist *name) /* Free an OpenMP namelist structure. */ void -gfc_free_omp_namelist (gfc_omp_namelist *name) +gfc_free_omp_namelist (gfc_omp_namelist *name, bool free_ns) { gfc_omp_namelist *n; for (; name; name = n) { gfc_free_expr (name->expr); - if (name->udr) - { - if (name->udr->combiner) - gfc_free_statement (name->udr->combiner); - if (name->udr->initializer) - gfc_free_statement (name->udr->initializer); - free (name->udr); + if (free_ns) + gfc_free_namespace (name->u2.ns); + else if (name->u2.udr) + { + if (name->u2.udr->combiner) + gfc_free_statement (name->u2.udr->combiner); + if (name->u2.udr->initializer) + gfc_free_statement (name->u2.udr->initializer); + free (name->u2.udr); } n = name->next; free (name); diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c index cf4d7ba..4ed6a0d 100644 --- a/gcc/fortran/openmp.c +++ b/gcc/fortran/openmp.c @@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see #include "arith.h" #include "match.h" #include "parse.h" +#include "constructor.h" #include "diagnostic.h" #include "gomp-constants.h" @@ -103,7 +104,8 @@ gfc_free_omp_clauses (gfc_omp_clauses *c) gfc_free_expr (c->num_workers_expr); gfc_free_expr (c->vector_length_expr); for (i = 0; i < OMP_LIST_NUM; i++) - gfc_free_omp_namelist (c->lists[i]); + gfc_free_omp_namelist (c->lists[i], + i == OMP_LIST_AFFINITY || i == OMP_LIST_DEPEND); gfc_free_expr_list (c->wait_list); gfc_free_expr_list (c->tile_list); free (CONST_CAST (char *, c->critical_name)); @@ -355,7 +357,7 @@ syntax: gfc_error ("Syntax error in OpenMP variable list at %C"); cleanup: - gfc_free_omp_namelist (head); + gfc_free_omp_namelist (head, false); gfc_current_locus = old_loc; return MATCH_ERROR; } @@ -445,7 +447,7 @@ syntax: gfc_error ("Syntax error in OpenMP variable list at %C"); cleanup: - gfc_free_omp_namelist (head); + gfc_free_omp_namelist (head, false); gfc_current_locus = old_loc; return MATCH_ERROR; } @@ -552,7 +554,7 @@ syntax: gfc_error ("Syntax error in OpenMP DEPEND SINK list at %C"); cleanup: - gfc_free_omp_namelist (head); + gfc_free_omp_namelist (head, false); gfc_current_locus = old_loc; return MATCH_ERROR; } @@ -843,6 +845,7 @@ enum omp_mask1 OMP_CLAUSE_CAPTURE, /* OpenMP 5.0. */ OMP_CLAUSE_MEMORDER, /* OpenMP 5.0. */ OMP_CLAUSE_DETACH, /* OpenMP 5.0. */ + OMP_CLAUSE_AFFINITY, /* OpenMP 5.0. */ OMP_CLAUSE_NOWAIT, /* This must come last. */ OMP_MASK1_LAST @@ -996,6 +999,132 @@ gfc_match_omp_map_clause (gfc_omp_namelist **list, gfc_omp_map_op map_op, return false; } +static match +gfc_match_iterator (gfc_namespace **ns, bool permit_var) +{ + locus old_loc = gfc_current_locus; + + if (gfc_match ("iterator ( ") != MATCH_YES) + return MATCH_NO; + + gfc_typespec ts; + gfc_symbol *last = NULL; + gfc_expr *begin, *end, *step; + *ns = gfc_build_block_ns (gfc_current_ns); + char name[GFC_MAX_SYMBOL_LEN + 1]; + while (true) + { + locus prev_loc = gfc_current_locus; + if (gfc_match_type_spec (&ts) == MATCH_YES + && gfc_match (" :: ") == MATCH_YES) + { + if (ts.type != BT_INTEGER) + { + gfc_error ("Expected INTEGER type at %L", &prev_loc); + return MATCH_ERROR; + } + permit_var = false; + } + else + { + ts.type = BT_INTEGER; + ts.kind = gfc_default_integer_kind; + gfc_current_locus = prev_loc; + } + prev_loc = gfc_current_locus; + if (gfc_match_name (name) != MATCH_YES) + { + gfc_error ("Expected identifier at %C"); + goto failed; + } + if (gfc_find_symtree ((*ns)->sym_root, name)) + { + gfc_error ("Same identifier %qs specified again at %C", name); + goto failed; + } + + gfc_symbol *sym = gfc_new_symbol (name, *ns); + if (last) + last->tlink = sym; + else + (*ns)->proc_name = sym; + last = sym; + sym->declared_at = prev_loc; + sym->ts = ts; + sym->attr.flavor = FL_VARIABLE; + sym->attr.artificial = 1; + sym->attr.referenced = 1; + sym->refs++; + gfc_symtree *st = gfc_new_symtree (&(*ns)->sym_root, name); + st->n.sym = sym; + + prev_loc = gfc_current_locus; + if (gfc_match (" = ") != MATCH_YES) + goto failed; + permit_var = false; + begin = end = step = NULL; + if (gfc_match ("%e : ", &begin) != MATCH_YES + || gfc_match ("%e ", &end) != MATCH_YES) + { + gfc_error ("Expected range-specification at %C"); + gfc_free_expr (begin); + gfc_free_expr (end); + return MATCH_ERROR; + } + if (':' == gfc_peek_ascii_char ()) + { + step = gfc_get_expr (); + if (gfc_match (": %e ", &step) != MATCH_YES) + { + gfc_free_expr (begin); + gfc_free_expr (end); + gfc_free_expr (step); + goto failed; + } + } + + gfc_expr *e = gfc_get_expr (); + e->where = prev_loc; + e->expr_type = EXPR_ARRAY; + e->ts = ts; + e->rank = 1; + e->shape = gfc_get_shape (1); + mpz_init_set_ui (e->shape[0], step ? 3 : 2); + gfc_constructor_append_expr (&e->value.constructor, begin, &begin->where); + gfc_constructor_append_expr (&e->value.constructor, end, &end->where); + if (step) + gfc_constructor_append_expr (&e->value.constructor, step, &step->where); + sym->value = e; + + if (gfc_match (") ") == MATCH_YES) + break; + if (gfc_match (", ") != MATCH_YES) + goto failed; + } + return MATCH_YES; + +failed: + gfc_namespace *prev_ns = NULL; + for (gfc_namespace *it = gfc_current_ns->contained; it; it = it->sibling) + { + if (it == *ns) + { + if (prev_ns) + prev_ns->sibling = it->sibling; + else + gfc_current_ns->contained = it->sibling; + gfc_free_namespace (it); + break; + } + prev_ns = it; + } + *ns = NULL; + if (!permit_var) + return MATCH_ERROR; + gfc_current_locus = old_loc; + return MATCH_NO; +} + /* reduction ( reduction-modifier, reduction-operator : variable-list ) in_reduction ( reduction-operator : variable-list ) task_reduction ( reduction-operator : variable-list ) */ @@ -1138,7 +1267,7 @@ gfc_match_omp_clause_reduction (char pc, gfc_omp_clauses *c, bool openacc, *head = NULL; gfc_error_now ("!$OMP DECLARE REDUCTION %s not found at %L", buffer, &old_loc); - gfc_free_omp_namelist (n); + gfc_free_omp_namelist (n, false); } else for (n = *head; n; n = n->next) @@ -1146,8 +1275,8 @@ gfc_match_omp_clause_reduction (char pc, gfc_omp_clauses *c, bool openacc, n->u.reduction_op = rop; if (udr) { - n->udr = gfc_get_omp_namelist_udr (); - n->udr->udr = udr; + n->u2.udr = gfc_get_omp_namelist_udr (); + n->u2.udr->udr = udr; } } return MATCH_YES; @@ -1202,7 +1331,7 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask, if (end_colon && gfc_match (" %e )", &alignment) != MATCH_YES) { - gfc_free_omp_namelist (*head); + gfc_free_omp_namelist (*head, false); gfc_current_locus = old_loc; *head = NULL; break; @@ -1230,6 +1359,36 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask, needs_space = true; continue; } + if ((mask & OMP_CLAUSE_AFFINITY) + && gfc_match ("affinity ( ") == MATCH_YES) + { + gfc_namespace *ns_iter = NULL, *ns_curr = gfc_current_ns; + match m = gfc_match_iterator (&ns_iter, true); + if (m == MATCH_ERROR) + break; + if (m == MATCH_YES && gfc_match (" : ") != MATCH_YES) + { + gfc_error ("Expected %<:%> at %C"); + break; + } + if (ns_iter) + gfc_current_ns = ns_iter; + head = NULL; + m = gfc_match_omp_variable_list ("", &c->lists[OMP_LIST_AFFINITY], + false, NULL, &head, true); + gfc_current_ns = ns_curr; + if (m == MATCH_ERROR) + break; + if (ns_iter) + { + for (gfc_omp_namelist *n = *head; n; n = n->next) + { + n->u2.ns = ns_iter; + ns_iter->refs++; + } + } + continue; + } if ((mask & OMP_CLAUSE_ASYNC) && !c->async && gfc_match ("async") == MATCH_YES) @@ -1374,6 +1533,12 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask, if ((mask & OMP_CLAUSE_DEPEND) && gfc_match ("depend ( ") == MATCH_YES) { + gfc_namespace *ns_iter = NULL, *ns_curr = gfc_current_ns; + match m_it = gfc_match_iterator (&ns_iter, false); + if (m_it == MATCH_ERROR) + break; + if (m_it == MATCH_YES && gfc_match (" , ") != MATCH_YES) + break; match m = MATCH_YES; gfc_omp_depend_op depend_op = OMP_DEPEND_OUT; if (gfc_match ("inout") == MATCH_YES) @@ -1389,11 +1554,24 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask, else if (!c->depend_source && gfc_match ("source )") == MATCH_YES) { + if (m_it == MATCH_YES) + { + gfc_error ("ITERATOR may not be combined with SOURCE " + "at %C"); + gfc_free_omp_clauses (c); + return MATCH_ERROR; + } c->depend_source = true; continue; } else if (gfc_match ("sink : ") == MATCH_YES) { + if (m_it == MATCH_YES) + { + gfc_error ("ITERATOR may not be combined with SINK " + "at %C"); + break; + } if (gfc_match_omp_depend_sink (&c->lists[OMP_LIST_DEPEND]) == MATCH_YES) continue; @@ -1402,19 +1580,26 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask, else m = MATCH_NO; head = NULL; - if (m == MATCH_YES - && gfc_match_omp_variable_list (" : ", - &c->lists[OMP_LIST_DEPEND], - false, NULL, &head, - true) == MATCH_YES) + if (ns_iter) + gfc_current_ns = ns_iter; + if (m == MATCH_YES) + m = gfc_match_omp_variable_list (" : ", + &c->lists[OMP_LIST_DEPEND], + false, NULL, &head, true); + gfc_current_ns = ns_curr; + if (m == MATCH_YES) { gfc_omp_namelist *n; for (n = *head; n; n = n->next) - n->u.depend_op = depend_op; + { + n->u.depend_op = depend_op; + n->u2.ns = ns_iter; + if (ns_iter) + ns_iter->refs++; + } continue; } - else - gfc_current_locus = old_loc; + break; } if ((mask & OMP_CLAUSE_DETACH) && !openacc @@ -1666,7 +1851,7 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask, end_colon = true; else if (gfc_match (" )") != MATCH_YES) { - gfc_free_omp_namelist (*head); + gfc_free_omp_namelist (*head, false); gfc_current_locus = old_loc; *head = NULL; break; @@ -1674,7 +1859,7 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask, } if (end_colon && gfc_match (" %e )", &step) != MATCH_YES) { - gfc_free_omp_namelist (*head); + gfc_free_omp_namelist (*head, false); gfc_current_locus = old_loc; *head = NULL; break; @@ -2844,7 +3029,7 @@ cleanup: | OMP_CLAUSE_SHARED | OMP_CLAUSE_IF | OMP_CLAUSE_DEFAULT \ | OMP_CLAUSE_UNTIED | OMP_CLAUSE_FINAL | OMP_CLAUSE_MERGEABLE \ | OMP_CLAUSE_DEPEND | OMP_CLAUSE_PRIORITY | OMP_CLAUSE_IN_REDUCTION \ - | OMP_CLAUSE_DETACH) + | OMP_CLAUSE_DETACH | OMP_CLAUSE_AFFINITY) #define OMP_TASKLOOP_CLAUSES \ (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \ | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_SHARED | OMP_CLAUSE_IF \ @@ -3097,14 +3282,14 @@ gfc_match_omp_flush (void) { gfc_error ("List specified together with memory order clause in FLUSH " "directive at %C"); - gfc_free_omp_namelist (list); + gfc_free_omp_namelist (list, false); gfc_free_omp_clauses (c); return MATCH_ERROR; } if (gfc_match_omp_eos () != MATCH_YES) { gfc_error ("Unexpected junk after $OMP FLUSH statement at %C"); - gfc_free_omp_namelist (list); + gfc_free_omp_namelist (list, false); gfc_free_omp_clauses (c); return MATCH_ERROR; } @@ -4252,14 +4437,13 @@ gfc_match_omp_taskloop_simd (void) match gfc_match_omp_taskwait (void) { - if (gfc_match_omp_eos () != MATCH_YES) + if (gfc_match_omp_eos () == MATCH_YES) { - gfc_error ("Unexpected junk after TASKWAIT clause at %C"); - return MATCH_ERROR; + new_st.op = EXEC_OMP_TASKWAIT; + new_st.ext.omp_clauses = NULL; + return MATCH_YES; } - new_st.op = EXEC_OMP_TASKWAIT; - new_st.ext.omp_clauses = NULL; - return MATCH_YES; + return match_omp (EXEC_OMP_TASKWAIT, omp_mask (OMP_CLAUSE_DEPEND)); } @@ -4825,7 +5009,7 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses, gfc_omp_linear_op linear_op = OMP_LINEAR_DEFAULT; static const char *clause_names[] = { "PRIVATE", "FIRSTPRIVATE", "LASTPRIVATE", "COPYPRIVATE", "SHARED", - "COPYIN", "UNIFORM", "ALIGNED", "LINEAR", "DEPEND", "MAP", + "COPYIN", "UNIFORM", "AFFINITY", "ALIGNED", "LINEAR", "DEPEND", "MAP", "TO", "FROM", "INCLUSIVE", "EXCLUSIVE", "REDUCTION", "REDUCTION" /*inscan*/, "REDUCTION" /*task*/, "IN_REDUCTION", "TASK_REDUCTION", @@ -5273,6 +5457,7 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses, } } break; + case OMP_LIST_AFFINITY: case OMP_LIST_DEPEND: case OMP_LIST_MAP: case OMP_LIST_TO: @@ -5280,6 +5465,40 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses, case OMP_LIST_CACHE: for (; n != NULL; n = n->next) { + if ((list == OMP_LIST_DEPEND || list == OMP_LIST_AFFINITY) + && n->u2.ns && !n->u2.ns->resolved) + { + n->u2.ns->resolved = 1; + for (gfc_symbol *sym = n->u2.ns->proc_name; sym; + sym = sym->tlink) + { + gfc_constructor *c; + c = gfc_constructor_first (sym->value->value.constructor); + if (!gfc_resolve_expr (c->expr) + || c->expr->ts.type != BT_INTEGER + || c->expr->rank != 0) + gfc_error ("Scalar integer expression for range begin" + " expected at %L", &c->expr->where); + c = gfc_constructor_next (c); + if (!gfc_resolve_expr (c->expr) + || c->expr->ts.type != BT_INTEGER + || c->expr->rank != 0) + gfc_error ("Scalar integer expression for range end " + "expected at %L", &c->expr->where); + c = gfc_constructor_next (c); + if (c && (!gfc_resolve_expr (c->expr) + || c->expr->ts.type != BT_INTEGER + || c->expr->rank != 0)) + gfc_error ("Scalar integer expression for range step " + "expected at %L", &c->expr->where); + else if (c + && c->expr->expr_type == EXPR_CONSTANT + && mpz_cmp_si (c->expr->value.integer, 0) == 0) + gfc_error ("Nonzero range step expected at %L", + &c->expr->where); + } + } + if (list == OMP_LIST_DEPEND) { if (n->u.depend_op == OMP_DEPEND_SINK_FIRST @@ -5421,7 +5640,8 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses, n->sym->name, name, &n->where); break; } - else if (list == OMP_LIST_DEPEND + else if ((list == OMP_LIST_DEPEND + || list == OMP_LIST_AFFINITY) && ar->start[i] && ar->start[i]->expr_type == EXPR_CONSTANT && ar->end[i] @@ -5429,9 +5649,11 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses, && mpz_cmp (ar->start[i]->value.integer, ar->end[i]->value.integer) > 0) { - gfc_error ("%qs in DEPEND clause at %L is a " + gfc_error ("%qs in %s clause at %L is a " "zero size array section", - n->sym->name, &n->where); + n->sym->name, + list == OMP_LIST_DEPEND + ? "DEPEND" : "AFFINITY", &n->where); break; } } @@ -5675,23 +5897,23 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses, break; } if (!bad) - n->udr = NULL; + n->u2.udr = NULL; else { const char *udr_name = NULL; - if (n->udr) + if (n->u2.udr) { - udr_name = n->udr->udr->name; - n->udr->udr + udr_name = n->u2.udr->udr->name; + n->u2.udr->udr = gfc_find_omp_udr (NULL, udr_name, &n->sym->ts); - if (n->udr->udr == NULL) + if (n->u2.udr->udr == NULL) { - free (n->udr); - n->udr = NULL; + free (n->u2.udr); + n->u2.udr = NULL; } } - if (n->udr == NULL) + if (n->u2.udr == NULL) { if (udr_name == NULL) switch (n->u.reduction_op) @@ -5730,14 +5952,14 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses, } else { - gfc_omp_udr *udr = n->udr->udr; + gfc_omp_udr *udr = n->u2.udr->udr; n->u.reduction_op = OMP_REDUCTION_USER; - n->udr->combiner + n->u2.udr->combiner = resolve_omp_udr_clause (n, udr->combiner_ns, udr->omp_out, udr->omp_in); if (udr->initializer_ns) - n->udr->initializer + n->u2.udr->initializer = resolve_omp_udr_clause (n, udr->initializer_ns, udr->omp_priv, @@ -7369,6 +7591,7 @@ gfc_resolve_omp_directive (gfc_code *code, gfc_namespace *ns) case EXEC_OMP_TARGET_PARALLEL: case EXEC_OMP_TARGET_TEAMS: case EXEC_OMP_TASK: + case EXEC_OMP_TASKWAIT: case EXEC_OMP_TEAMS: case EXEC_OMP_WORKSHARE: case EXEC_OMP_DEPOBJ: diff --git a/gcc/fortran/st.c b/gcc/fortran/st.c index 02a81da..7d0e2c1 100644 --- a/gcc/fortran/st.c +++ b/gcc/fortran/st.c @@ -268,7 +268,7 @@ gfc_free_statement (gfc_code *p) break; case EXEC_OMP_FLUSH: - gfc_free_omp_namelist (p->ext.omp_namelist); + gfc_free_omp_namelist (p->ext.omp_namelist, false); break; case EXEC_OMP_BARRIER: diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index 6d38ea7..7eeef55 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -4718,8 +4718,9 @@ done: /* For optional arguments, only check bounds if the argument is present. */ - if (expr->symtree->n.sym->attr.optional - || expr->symtree->n.sym->attr.not_always_present) + if ((expr->symtree->n.sym->attr.optional + || expr->symtree->n.sym->attr.not_always_present) + && expr->symtree->n.sym->attr.dummy) tmp = build3_v (COND_EXPR, gfc_conv_expr_present (expr->symtree->n.sym), tmp, build_empty_stmt (input_location)); diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c index db9248c..98fa28d 100644 --- a/gcc/fortran/trans-intrinsic.c +++ b/gcc/fortran/trans-intrinsic.c @@ -8004,7 +8004,14 @@ gfc_conv_intrinsic_size (gfc_se * se, gfc_expr * expr) tree temp; tree cond; - attr = sym ? sym->attr : gfc_expr_attr (e); + if (e->symtree->n.sym && IS_CLASS_ARRAY (e->symtree->n.sym)) + { + attr = CLASS_DATA (e->symtree->n.sym)->attr; + attr.pointer = attr.class_pointer; + } + else + attr = gfc_expr_attr (e); + if (attr.allocatable) msg = xasprintf ("Allocatable argument '%s' is not allocated", e->symtree->n.sym->name); diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c index 44542d9..7ea7aa3 100644 --- a/gcc/fortran/trans-openmp.c +++ b/gcc/fortran/trans-openmp.c @@ -35,6 +35,7 @@ along with GCC; see the file COPYING3. If not see #include "trans-array.h" #include "trans-const.h" #include "arith.h" +#include "constructor.h" #include "gomp-constants.h" #include "omp-general.h" #include "omp-low.h" @@ -1910,7 +1911,7 @@ gfc_trans_omp_array_reduction_or_udr (tree c, gfc_omp_namelist *n, locus where) locus old_loc = gfc_current_locus; const char *iname; bool t; - gfc_omp_udr *udr = n->udr ? n->udr->udr : NULL; + gfc_omp_udr *udr = n->u2.udr ? n->u2.udr->udr : NULL; decl = OMP_CLAUSE_DECL (c); gfc_current_locus = where; @@ -2029,9 +2030,9 @@ gfc_trans_omp_array_reduction_or_udr (tree c, gfc_omp_namelist *n, locus where) t = gfc_resolve_expr (e2); gcc_assert (t); } - else if (n->udr->initializer->op == EXEC_ASSIGN) + else if (n->u2.udr->initializer->op == EXEC_ASSIGN) { - e2 = gfc_copy_expr (n->udr->initializer->expr2); + e2 = gfc_copy_expr (n->u2.udr->initializer->expr2); t = gfc_resolve_expr (e2); gcc_assert (t); } @@ -2040,7 +2041,7 @@ gfc_trans_omp_array_reduction_or_udr (tree c, gfc_omp_namelist *n, locus where) struct omp_udr_find_orig_data cd; cd.omp_udr = udr; cd.omp_orig_seen = false; - gfc_code_walker (&n->udr->initializer, + gfc_code_walker (&n->u2.udr->initializer, gfc_dummy_code_callback, omp_udr_find_orig, &cd); if (cd.omp_orig_seen) OMP_CLAUSE_REDUCTION_OMP_ORIG_REF (c) = 1; @@ -2090,11 +2091,11 @@ gfc_trans_omp_array_reduction_or_udr (tree c, gfc_omp_namelist *n, locus where) iname = "ieor"; break; case ERROR_MARK: - if (n->udr->combiner->op == EXEC_ASSIGN) + if (n->u2.udr->combiner->op == EXEC_ASSIGN) { gfc_free_expr (e3); - e3 = gfc_copy_expr (n->udr->combiner->expr1); - e4 = gfc_copy_expr (n->udr->combiner->expr2); + e3 = gfc_copy_expr (n->u2.udr->combiner->expr1); + e4 = gfc_copy_expr (n->u2.udr->combiner->expr2); t = gfc_resolve_expr (e3); gcc_assert (t); t = gfc_resolve_expr (e4); @@ -2144,7 +2145,7 @@ gfc_trans_omp_array_reduction_or_udr (tree c, gfc_omp_namelist *n, locus where) if (e2) stmt = gfc_trans_assignment (e1, e2, false, false); else - stmt = gfc_trans_call (n->udr->initializer, false, + stmt = gfc_trans_call (n->u2.udr->initializer, false, NULL_TREE, NULL_TREE, false); if (TREE_CODE (stmt) != BIND_EXPR) stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0)); @@ -2157,7 +2158,7 @@ gfc_trans_omp_array_reduction_or_udr (tree c, gfc_omp_namelist *n, locus where) if (e4) stmt = gfc_trans_assignment (e3, e4, false, true); else - stmt = gfc_trans_call (n->udr->combiner, false, + stmt = gfc_trans_call (n->u2.udr->combiner, false, NULL_TREE, NULL_TREE, false); if (TREE_CODE (stmt) != BIND_EXPR) stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0)); @@ -2433,13 +2434,76 @@ gfc_trans_omp_array_section (stmtblock_t *block, gfc_omp_namelist *n, } static tree +handle_iterator (gfc_namespace *ns, stmtblock_t *iter_block, tree block) +{ + tree list = NULL_TREE; + for (gfc_symbol *sym = ns->proc_name; sym; sym = sym->tlink) + { + gfc_constructor *c; + gfc_se se; + + tree last = make_tree_vec (6); + tree iter_var = gfc_get_symbol_decl (sym); + tree type = TREE_TYPE (iter_var); + TREE_VEC_ELT (last, 0) = iter_var; + DECL_CHAIN (iter_var) = BLOCK_VARS (block); + BLOCK_VARS (block) = iter_var; + + /* begin */ + c = gfc_constructor_first (sym->value->value.constructor); + gfc_init_se (&se, NULL); + gfc_conv_expr (&se, c->expr); + gfc_add_block_to_block (iter_block, &se.pre); + gfc_add_block_to_block (iter_block, &se.post); + TREE_VEC_ELT (last, 1) = fold_convert (type, + gfc_evaluate_now (se.expr, + iter_block)); + /* end */ + c = gfc_constructor_next (c); + gfc_init_se (&se, NULL); + gfc_conv_expr (&se, c->expr); + gfc_add_block_to_block (iter_block, &se.pre); + gfc_add_block_to_block (iter_block, &se.post); + TREE_VEC_ELT (last, 2) = fold_convert (type, + gfc_evaluate_now (se.expr, + iter_block)); + /* step */ + c = gfc_constructor_next (c); + tree step; + if (c) + { + gfc_init_se (&se, NULL); + gfc_conv_expr (&se, c->expr); + gfc_add_block_to_block (iter_block, &se.pre); + gfc_add_block_to_block (iter_block, &se.post); + gfc_conv_expr (&se, c->expr); + step = fold_convert (type, + gfc_evaluate_now (se.expr, + iter_block)); + } + else + step = build_int_cst (type, 1); + TREE_VEC_ELT (last, 3) = step; + /* orig_step */ + TREE_VEC_ELT (last, 4) = save_expr (step); + TREE_CHAIN (last) = list; + list = last; + } + return list; +} + +static tree gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, locus where, bool declare_simd = false, bool openacc = false) { - tree omp_clauses = NULL_TREE, chunk_size, c; + tree omp_clauses = NULL_TREE, prev_clauses, chunk_size, c; + tree iterator = NULL_TREE; + tree tree_block = NULL_TREE; + stmtblock_t iter_block; int list, ifc; enum omp_clause_code clause_code; + gfc_omp_namelist *prev = NULL; gfc_se se; if (clauses == NULL) @@ -2642,10 +2706,38 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, } } break; + case OMP_LIST_AFFINITY: case OMP_LIST_DEPEND: + iterator = NULL_TREE; + prev = NULL; + prev_clauses = omp_clauses; for (; n != NULL; n = n->next) { - if (n->u.depend_op == OMP_DEPEND_SINK_FIRST) + if (iterator && prev->u2.ns != n->u2.ns) + { + BLOCK_SUBBLOCKS (tree_block) = gfc_finish_block (&iter_block); + TREE_VEC_ELT (iterator, 5) = tree_block; + for (tree c = omp_clauses; c != prev_clauses; + c = OMP_CLAUSE_CHAIN (c)) + OMP_CLAUSE_DECL (c) = build_tree_list (iterator, + OMP_CLAUSE_DECL (c)); + prev_clauses = omp_clauses; + iterator = NULL_TREE; + } + if (n->u2.ns && (!prev || prev->u2.ns != n->u2.ns)) + { + gfc_init_block (&iter_block); + tree_block = make_node (BLOCK); + TREE_USED (tree_block) = 1; + BLOCK_VARS (tree_block) = NULL_TREE; + iterator = handle_iterator (n->u2.ns, block, + tree_block); + } + if (!iterator) + gfc_init_block (&iter_block); + prev = n; + if (list == OMP_LIST_DEPEND + && n->u.depend_op == OMP_DEPEND_SINK_FIRST) { tree vec = NULL_TREE; unsigned int i; @@ -2699,7 +2791,10 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, if (!n->sym->attr.referenced) continue; - tree node = build_omp_clause (input_location, OMP_CLAUSE_DEPEND); + tree node = build_omp_clause (input_location, + list == OMP_LIST_DEPEND + ? OMP_CLAUSE_DEPEND + : OMP_CLAUSE_AFFINITY); if (n->expr == NULL || n->expr->ref->u.ar.type == AR_FULL) { tree decl = gfc_trans_omp_variable (n->sym, false); @@ -2733,35 +2828,47 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, gfc_conv_expr_descriptor (&se, n->expr); ptr = gfc_conv_array_data (se.expr); } - gfc_add_block_to_block (block, &se.pre); - gfc_add_block_to_block (block, &se.post); + gfc_add_block_to_block (&iter_block, &se.pre); + gfc_add_block_to_block (&iter_block, &se.post); ptr = fold_convert (build_pointer_type (char_type_node), ptr); OMP_CLAUSE_DECL (node) = build_fold_indirect_ref (ptr); } - switch (n->u.depend_op) - { - case OMP_DEPEND_IN: - OMP_CLAUSE_DEPEND_KIND (node) = OMP_CLAUSE_DEPEND_IN; - break; - case OMP_DEPEND_OUT: - OMP_CLAUSE_DEPEND_KIND (node) = OMP_CLAUSE_DEPEND_OUT; - break; - case OMP_DEPEND_INOUT: - OMP_CLAUSE_DEPEND_KIND (node) = OMP_CLAUSE_DEPEND_INOUT; - break; - case OMP_DEPEND_MUTEXINOUTSET: - OMP_CLAUSE_DEPEND_KIND (node) - = OMP_CLAUSE_DEPEND_MUTEXINOUTSET; - break; - case OMP_DEPEND_DEPOBJ: - OMP_CLAUSE_DEPEND_KIND (node) = OMP_CLAUSE_DEPEND_DEPOBJ; - break; - default: - gcc_unreachable (); - } + if (list == OMP_LIST_DEPEND) + switch (n->u.depend_op) + { + case OMP_DEPEND_IN: + OMP_CLAUSE_DEPEND_KIND (node) = OMP_CLAUSE_DEPEND_IN; + break; + case OMP_DEPEND_OUT: + OMP_CLAUSE_DEPEND_KIND (node) = OMP_CLAUSE_DEPEND_OUT; + break; + case OMP_DEPEND_INOUT: + OMP_CLAUSE_DEPEND_KIND (node) = OMP_CLAUSE_DEPEND_INOUT; + break; + case OMP_DEPEND_MUTEXINOUTSET: + OMP_CLAUSE_DEPEND_KIND (node) + = OMP_CLAUSE_DEPEND_MUTEXINOUTSET; + break; + case OMP_DEPEND_DEPOBJ: + OMP_CLAUSE_DEPEND_KIND (node) = OMP_CLAUSE_DEPEND_DEPOBJ; + break; + default: + gcc_unreachable (); + } + if (!iterator) + gfc_add_block_to_block (block, &iter_block); omp_clauses = gfc_trans_add_clause (node, omp_clauses); } + if (iterator) + { + BLOCK_SUBBLOCKS (tree_block) = gfc_finish_block (&iter_block); + TREE_VEC_ELT (iterator, 5) = tree_block; + for (tree c = omp_clauses; c != prev_clauses; + c = OMP_CLAUSE_CHAIN (c)) + OMP_CLAUSE_DECL (c) = build_tree_list (iterator, + OMP_CLAUSE_DECL (c)); + } break; case OMP_LIST_MAP: for (; n != NULL; n = n->next) @@ -5857,10 +5964,23 @@ gfc_trans_omp_taskgroup (gfc_code *code) } static tree -gfc_trans_omp_taskwait (void) +gfc_trans_omp_taskwait (gfc_code *code) { - tree decl = builtin_decl_explicit (BUILT_IN_GOMP_TASKWAIT); - return build_call_expr_loc (input_location, decl, 0); + if (!code->ext.omp_clauses) + { + tree decl = builtin_decl_explicit (BUILT_IN_GOMP_TASKWAIT); + return build_call_expr_loc (input_location, decl, 0); + } + stmtblock_t block; + gfc_start_block (&block); + tree stmt = make_node (OMP_TASK); + TREE_TYPE (stmt) = void_type_node; + OMP_TASK_BODY (stmt) = NULL_TREE; + OMP_TASK_CLAUSES (stmt) = gfc_trans_omp_clauses (&block, + code->ext.omp_clauses, + code->loc); + gfc_add_expr_to_block (&block, stmt); + return gfc_finish_block (&block); } static tree @@ -6492,7 +6612,7 @@ gfc_trans_omp_directive (gfc_code *code) case EXEC_OMP_TASKLOOP_SIMD: return gfc_trans_omp_taskloop (code); case EXEC_OMP_TASKWAIT: - return gfc_trans_omp_taskwait (); + return gfc_trans_omp_taskwait (code); case EXEC_OMP_TASKYIELD: return gfc_trans_omp_taskyield (); case EXEC_OMP_TEAMS: diff --git a/gcc/gensupport.c b/gcc/gensupport.c index e1ca06d..2cb760f 100644 --- a/gcc/gensupport.c +++ b/gcc/gensupport.c @@ -1230,6 +1230,7 @@ alter_predicate_for_insn (rtx pattern, int alt, int max_op, case MATCH_OPERATOR: case MATCH_SCRATCH: case MATCH_PARALLEL: + case MATCH_DUP: XINT (pattern, 0) += max_op; break; @@ -1291,6 +1292,9 @@ alter_constraints (rtx pattern, int n_dup, constraints_handler_t alter) case MATCH_OPERAND: XSTR (pattern, 2) = alter (XSTR (pattern, 2), n_dup); break; + case MATCH_SCRATCH: + XSTR (pattern, 1) = alter (XSTR (pattern, 1), n_dup); + break; default: break; @@ -332,19 +332,30 @@ gt_pch_nx (const char *) { } -inline void -gt_ggc_mx (int) -{ -} - -inline void -gt_pch_nx (int) -{ -} - -inline void -gt_pch_nx (unsigned int) -{ -} +inline void gt_pch_nx (bool) { } +inline void gt_pch_nx (char) { } +inline void gt_pch_nx (signed char) { } +inline void gt_pch_nx (unsigned char) { } +inline void gt_pch_nx (short) { } +inline void gt_pch_nx (unsigned short) { } +inline void gt_pch_nx (int) { } +inline void gt_pch_nx (unsigned int) { } +inline void gt_pch_nx (long int) { } +inline void gt_pch_nx (unsigned long int) { } +inline void gt_pch_nx (long long int) { } +inline void gt_pch_nx (unsigned long long int) { } + +inline void gt_ggc_mx (bool) { } +inline void gt_ggc_mx (char) { } +inline void gt_ggc_mx (signed char) { } +inline void gt_ggc_mx (unsigned char) { } +inline void gt_ggc_mx (short) { } +inline void gt_ggc_mx (unsigned short) { } +inline void gt_ggc_mx (int) { } +inline void gt_ggc_mx (unsigned int) { } +inline void gt_ggc_mx (long int) { } +inline void gt_ggc_mx (unsigned long int) { } +inline void gt_ggc_mx (long long int) { } +inline void gt_ggc_mx (unsigned long long int) { } #endif diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc index e351a84..b4dfaa9 100644 --- a/gcc/gimple-range.cc +++ b/gcc/gimple-range.cc @@ -1441,109 +1441,6 @@ trace_ranger::range_of_expr (irange &r, tree name, gimple *s) return trailer (idx, "range_of_expr", res, name, r); } -// Return the legacy global range for NAME if it has one, otherwise -// return VARYING. - -static void -get_range_global (irange &r, tree name) -{ - tree type = TREE_TYPE (name); - - if (SSA_NAME_IS_DEFAULT_DEF (name)) - { - tree sym = SSA_NAME_VAR (name); - // Adapted from vr_values::get_lattice_entry(). - // Use a range from an SSA_NAME's available range. - if (TREE_CODE (sym) == PARM_DECL) - { - // Try to use the "nonnull" attribute to create ~[0, 0] - // anti-ranges for pointers. Note that this is only valid with - // default definitions of PARM_DECLs. - if (POINTER_TYPE_P (type) - && ((cfun && nonnull_arg_p (sym)) || get_ptr_nonnull (name))) - r.set_nonzero (type); - else if (INTEGRAL_TYPE_P (type)) - { - get_range_info (name, r); - if (r.undefined_p ()) - r.set_varying (type); - } - else - r.set_varying (type); - } - // If this is a local automatic with no definition, use undefined. - else if (TREE_CODE (sym) != RESULT_DECL) - r.set_undefined (); - else - r.set_varying (type); - } - else if (!POINTER_TYPE_P (type) && SSA_NAME_RANGE_INFO (name)) - { - get_range_info (name, r); - if (r.undefined_p ()) - r.set_varying (type); - } - else if (POINTER_TYPE_P (type) && SSA_NAME_PTR_INFO (name)) - { - if (get_ptr_nonnull (name)) - r.set_nonzero (type); - else - r.set_varying (type); - } - else - r.set_varying (type); -} - -// ?? Like above, but only for default definitions of NAME. This is -// so VRP passes using ranger do not start with known ranges, -// otherwise we'd eliminate builtin_unreachables too early because of -// inlining. -// -// Without this restriction, the test in g++.dg/tree-ssa/pr61034.C has -// all of its unreachable calls removed too early. We should -// investigate whether we should just adjust the test above. - -value_range -gimple_range_global (tree name) -{ - gcc_checking_assert (gimple_range_ssa_p (name)); - tree type = TREE_TYPE (name); - - if (SSA_NAME_IS_DEFAULT_DEF (name)) - { - value_range vr; - get_range_global (vr, name); - return vr; - } - return value_range (type); -} - -// ---------------------------------------------- -// global_range_query implementation. - -global_range_query global_ranges; - -// Like get_range_query, but for accessing global ranges. - -range_query * -get_global_range_query () -{ - return &global_ranges; -} - -bool -global_range_query::range_of_expr (irange &r, tree expr, gimple *) -{ - tree type = TREE_TYPE (expr); - - if (!irange::supports_type_p (type) || !gimple_range_ssa_p (expr)) - return get_tree_range (r, expr); - - get_range_global (r, expr); - - return true; -} - gimple_ranger * enable_ranger (struct function *fun) { diff --git a/gcc/gimple-range.h b/gcc/gimple-range.h index 23734c6..ecd332a 100644 --- a/gcc/gimple-range.h +++ b/gcc/gimple-range.h @@ -252,17 +252,6 @@ private: // Flag to enable debugging the various internal Caches. #define DEBUG_RANGE_CACHE (dump_file && (param_evrp_mode & EVRP_MODE_DEBUG)) -// Global ranges for SSA names using SSA_NAME_RANGE_INFO. - -class global_range_query : public range_query -{ -public: - bool range_of_expr (irange &r, tree expr, gimple * = NULL) OVERRIDE; -}; - -extern global_range_query global_ranges; -extern value_range gimple_range_global (tree name); - extern gimple_ranger *enable_ranger (struct function *); extern void disable_ranger (struct function *); diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 54bf59a..d60fc95 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -7841,6 +7841,131 @@ find_decl_expr (tree *tp, int *walk_subtrees, void *data) return NULL_TREE; } + +/* Gimplify the affinity clause but effectively ignore it. + Generate: + var = begin; + if ((step > 1) ? var <= end : var > end) + locatator_var_expr; */ + +static void +gimplify_omp_affinity (tree *list_p, gimple_seq *pre_p) +{ + tree last_iter = NULL_TREE; + tree last_bind = NULL_TREE; + tree label = NULL_TREE; + tree *last_body = NULL; + for (tree c = *list_p; c; c = OMP_CLAUSE_CHAIN (c)) + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY) + { + tree t = OMP_CLAUSE_DECL (c); + if (TREE_CODE (t) == TREE_LIST + && TREE_PURPOSE (t) + && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC) + { + if (TREE_VALUE (t) == null_pointer_node) + continue; + if (TREE_PURPOSE (t) != last_iter) + { + if (last_bind) + { + append_to_statement_list (label, last_body); + gimplify_and_add (last_bind, pre_p); + last_bind = NULL_TREE; + } + for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it)) + { + if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL, + is_gimple_val, fb_rvalue) == GS_ERROR + || gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL, + is_gimple_val, fb_rvalue) == GS_ERROR + || gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL, + is_gimple_val, fb_rvalue) == GS_ERROR + || (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL, + is_gimple_val, fb_rvalue) + == GS_ERROR)) + return; + } + last_iter = TREE_PURPOSE (t); + tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 5); + last_bind = build3 (BIND_EXPR, void_type_node, BLOCK_VARS (block), + NULL, block); + last_body = &BIND_EXPR_BODY (last_bind); + tree cond = NULL_TREE; + location_t loc = OMP_CLAUSE_LOCATION (c); + for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it)) + { + tree var = TREE_VEC_ELT (it, 0); + tree begin = TREE_VEC_ELT (it, 1); + tree end = TREE_VEC_ELT (it, 2); + tree step = TREE_VEC_ELT (it, 3); + loc = DECL_SOURCE_LOCATION (var); + tree tem = build2_loc (loc, MODIFY_EXPR, void_type_node, + var, begin); + append_to_statement_list_force (tem, last_body); + + tree cond1 = fold_build2_loc (loc, GT_EXPR, boolean_type_node, + step, build_zero_cst (TREE_TYPE (step))); + tree cond2 = fold_build2_loc (loc, LE_EXPR, boolean_type_node, + var, end); + tree cond3 = fold_build2_loc (loc, GT_EXPR, boolean_type_node, + var, end); + cond1 = fold_build3_loc (loc, COND_EXPR, boolean_type_node, + cond1, cond2, cond3); + if (cond) + cond = fold_build2_loc (loc, TRUTH_AND_EXPR, + boolean_type_node, cond, cond1); + else + cond = cond1; + } + tree cont_label = create_artificial_label (loc); + label = build1 (LABEL_EXPR, void_type_node, cont_label); + tree tem = fold_build3_loc (loc, COND_EXPR, void_type_node, cond, + void_node, + build_and_jump (&cont_label)); + append_to_statement_list_force (tem, last_body); + } + if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR) + { + append_to_statement_list (TREE_OPERAND (TREE_VALUE (t), 0), + last_body); + TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1); + } + if (error_operand_p (TREE_VALUE (t))) + return; + append_to_statement_list_force (TREE_VALUE (t), last_body); + TREE_VALUE (t) = null_pointer_node; + } + else + { + if (last_bind) + { + append_to_statement_list (label, last_body); + gimplify_and_add (last_bind, pre_p); + last_bind = NULL_TREE; + } + if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR) + { + gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p, + NULL, is_gimple_val, fb_rvalue); + OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1); + } + if (error_operand_p (OMP_CLAUSE_DECL (c))) + return; + if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL, + is_gimple_val, fb_rvalue) == GS_ERROR) + return; + gimplify_and_add (OMP_CLAUSE_DECL (c), pre_p); + } + } + if (last_bind) + { + append_to_statement_list (label, last_body); + gimplify_and_add (last_bind, pre_p); + } + return; +} + /* If *LIST_P contains any OpenMP depend clauses with iterators, lower all the depend clauses by populating corresponding depend array. Returns 0 if there are no such depend clauses, or @@ -9527,6 +9652,10 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, goto do_add; + case OMP_CLAUSE_AFFINITY: + gimplify_omp_affinity (list_p, pre_p); + remove = true; + break; case OMP_CLAUSE_DEPEND: if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK) { diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog index 7cc756b..b6ec83c 100644 --- a/gcc/go/ChangeLog +++ b/gcc/go/ChangeLog @@ -1,3 +1,7 @@ +2021-05-27 Ian Lance Taylor <iant@golang.org> + + * gccgo.texi (Function Names): Don't HTML quote ampersand. + 2021-05-24 Ian Lance Taylor <iant@golang.org> PR go/100537 diff --git a/gcc/go/gccgo.texi b/gcc/go/gccgo.texi index b7d3e8e..0aaba19 100644 --- a/gcc/go/gccgo.texi +++ b/gcc/go/gccgo.texi @@ -494,7 +494,7 @@ like (after importing the @code{os} package): @smallexample var name = [4]byte@{'f', 'o', 'o', 0@}; -i := c_open(&name[0], os.O_RDONLY, 0); +i := c_open(&name[0], os.O_RDONLY, 0); @end smallexample Note that this serves as an example only. To open a file in Go please diff --git a/gcc/hash-map.h b/gcc/hash-map.h index 0779c93..dd039f1 100644 --- a/gcc/hash-map.h +++ b/gcc/hash-map.h @@ -107,27 +107,31 @@ class GTY((user)) hash_map gt_pch_nx (&x, op, cookie); } - static void - pch_nx_helper (int, gt_pointer_operator, void *) - { - } - - static void - pch_nx_helper (unsigned int, gt_pointer_operator, void *) - { - } - - static void - pch_nx_helper (bool, gt_pointer_operator, void *) - { - } - template<typename T> static void pch_nx_helper (T *&x, gt_pointer_operator op, void *cookie) { op (&x, cookie); } + + /* The overloads below should match those in ggc.h. */ +#define DEFINE_PCH_HELPER(T) \ + static void pch_nx_helper (T, gt_pointer_operator, void *) { } + + DEFINE_PCH_HELPER (bool); + DEFINE_PCH_HELPER (char); + DEFINE_PCH_HELPER (signed char); + DEFINE_PCH_HELPER (unsigned char); + DEFINE_PCH_HELPER (short); + DEFINE_PCH_HELPER (unsigned short); + DEFINE_PCH_HELPER (int); + DEFINE_PCH_HELPER (unsigned int); + DEFINE_PCH_HELPER (long); + DEFINE_PCH_HELPER (unsigned long); + DEFINE_PCH_HELPER (long long); + DEFINE_PCH_HELPER (unsigned long long); + +#undef DEFINE_PCH_HELPER }; public: @@ -273,8 +277,12 @@ public: return reference_pair (e.m_key, e.m_value); } - bool - operator != (const iterator &other) const + bool operator== (const iterator &other) const + { + return m_iter == other.m_iter; + } + + bool operator != (const iterator &other) const { return m_iter != other.m_iter; } diff --git a/gcc/match.pd b/gcc/match.pd index b60e270..d06ff17 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -6642,10 +6642,31 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) && tree_to_uhwi (@3) == c2 && tree_to_uhwi (@9) == c3 && tree_to_uhwi (@7) == c3 - && tree_to_uhwi (@11) == c4 - && direct_internal_fn_supported_p (IFN_POPCOUNT, type, - OPTIMIZE_FOR_BOTH)) - (convert (IFN_POPCOUNT:type @0))))) + && tree_to_uhwi (@11) == c4) + (if (direct_internal_fn_supported_p (IFN_POPCOUNT, type, + OPTIMIZE_FOR_BOTH)) + (convert (IFN_POPCOUNT:type @0)) + /* Try to do popcount in two halves. PREC must be at least + five bits for this to work without extension before adding. */ + (with { + tree half_type = NULL_TREE; + opt_machine_mode m = mode_for_size ((prec + 1) / 2, MODE_INT, 1); + int half_prec = 8; + if (m.exists () + && m.require () != TYPE_MODE (type)) + { + half_prec = GET_MODE_PRECISION (as_a <scalar_int_mode> (m)); + half_type = build_nonstandard_integer_type (half_prec, 1); + } + gcc_assert (half_prec > 2); + } + (if (half_type != NULL_TREE + && direct_internal_fn_supported_p (IFN_POPCOUNT, half_type, + OPTIMIZE_FOR_BOTH)) + (convert (plus + (IFN_POPCOUNT:half_type (convert @0)) + (IFN_POPCOUNT:half_type (convert (rshift @0 + { build_int_cst (integer_type_node, half_prec); } ))))))))))) /* __builtin_ffs needs to deal on many targets with the possible zero argument. If we know the argument is always non-zero, __builtin_ctz + 1 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b62a557..27e5f67 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,56 @@ +2021-05-27 Matthias Kretz <kretz@kde.org> + + PR c++/100716 + * g++.dg/diagnostic/pr100716.C: New test. + * g++.dg/diagnostic/pr100716-1.C: Same test with + -fno-pretty-templates. + +2021-05-27 Patrick Palka <ppalka@redhat.com> + + PR c++/99893 + * g++.dg/cpp0x/static_assert17.C: New test. + +2021-05-27 Jason Merrill <jason@redhat.com> + + PR c++/86355 + * g++.dg/cpp0x/alias-decl-variadic2.C: New test. + +2021-05-27 Patrick Palka <ppalka@redhat.com> + + DR 1315 + PR c++/67593 + PR c++/96555 + * g++.dg/template/partial16.C: New test. + * g++.dg/template/partial17.C: New test. + * g++.dg/template/partial18.C: New test. + * g++.dg/template/partial19.C: New test. + * g++.dg/cpp0x/pr68724.C: Adjust expected diagnostic for + ill-formed partial specialization. + * g++.dg/cpp0x/variadic38.C: Likewise. + * g++.dg/cpp1z/pr81016.C: Likewise. + * g++.dg/template/partial5.C: Likewise. + * g++.old-deja/g++.pt/spec21.C: Likewise. + +2021-05-27 Harald Anlauf <anlauf@gmx.de> + + PR fortran/100602 + * gfortran.dg/pointer_check_14.f90: New test. + +2021-05-27 Harald Anlauf <anlauf@gmx.de> + + PR fortran/100656 + * gfortran.dg/bounds_check_22.f90: New test. + +2021-05-27 Aldy Hernandez <aldyh@redhat.com> + + * gcc.dg/Wstringop-overflow-55.c: Pass -fno-ipa-icf. + +2021-05-27 Uroš Bizjak <ubizjak@gmail.com> + + PR target/100637 + * gcc.target/i386/pr100637-3b.c (avgu): New test. + * gcc.target/i386/pr100637-3w.c (avgu): Ditto. + 2021-05-26 Patrick Palka <ppalka@redhat.com> PR c++/100502 diff --git a/gcc/testsuite/c-c++-common/gomp/affinity-1.c b/gcc/testsuite/c-c++-common/gomp/affinity-1.c new file mode 100644 index 0000000..4af52f4 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/affinity-1.c @@ -0,0 +1,24 @@ +void +foo(int x) +{ + int a = 1; + int b[5] = {1, 0, 1, 1, 0}; + int cc = 7; + int d[5][5] = {{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}, {1, 2, 3, 4, 5}, + {6, 7, 8, 9, 10}, {-1, -2, -3, -4,-5}}; +#pragma omp taskgroup + { + #pragma omp task affinity(a) + ; + #pragma omp task affinity(iterator(i=(int)__builtin_cos(1.0+a):5, jj =2:5:2) : b[i], d[i][jj]) + ; + #pragma omp task affinity(iterator(i=(int)__builtin_cos(1.0+a):5) : b[i], d[i][i]) + ; + #pragma omp task affinity (iterator(i=1:5): a) + ; + #pragma omp task affinity (iterator(i=1:5): a) affinity(iterator(i=1:5) : x) + ; + #pragma omp task affinity (iterator(unsigned long j=1:5, k=7:4:-1) : b[j+k],a) affinity (cc) + ; + } +} diff --git a/gcc/testsuite/c-c++-common/gomp/affinity-2.c b/gcc/testsuite/c-c++-common/gomp/affinity-2.c new file mode 100644 index 0000000..7f30296 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/affinity-2.c @@ -0,0 +1,232 @@ +/* { dg-do compile } */ +/* { dg-options "-fopenmp" } */ + +extern int a[][10], a2[][10]; +int b[10], c[10][2], d[10], e[10], f[10]; +int b2[10], c2[10][2], d2[10], e2[10], f2[10]; +int k[10], l[10], m[10], n[10], o; +int *p; +void bar (void); +int t[10]; +#pragma omp threadprivate (t) + +void +foo (int g[3][10], int h[4][8], int i[2][10], int j[][9], + int g2[3][10], int h2[4][8], int i2[2][10], int j2[][9]) +{ + #pragma omp task affinity( bar[2:5]) /* { dg-error "is not a variable" } */ + ; + #pragma omp task affinity( t[2:5]) + ; + #pragma omp task affinity( k[0.5:]) /* { dg-error "low bound \[^\n\r]* of array section does not have integral type" } */ + ; + #pragma omp task affinity( l[:7.5f]) /* { dg-error "length \[^\n\r]* of array section does not have integral type" } */ + ; + #pragma omp task affinity( m[p:]) /* { dg-error "low bound \[^\n\r]* of array section does not have integral type" } */ + ; + #pragma omp task affinity( n[:p]) /* { dg-error "length \[^\n\r]* of array section does not have integral type" } */ + ; + #pragma omp task affinity( o[2:5]) /* { dg-error "does not have pointer or array type" } */ + ; + #pragma omp task affinity( a[:][2:4]) /* { dg-error "array type length expression must be specified" } */ + ; + #pragma omp task affinity( b[-1:]) /* { dg-error "negative low bound in array section" } */ + ; + #pragma omp task affinity( c[:-3][1:1]) /* { dg-error "negative length in array section" } */ + ; + #pragma omp task affinity( d[11:]) /* { dg-error "low bound \[^\n\r]* above array section size" } */ + ; + #pragma omp task affinity( e[:11]) /* { dg-error "length \[^\n\r]* above array section size" } */ + ; + #pragma omp task affinity( f[1:10]) /* { dg-error "high bound \[^\n\r]* above array section size" } */ + ; + #pragma omp task affinity( g[:][2:4]) /* { dg-error "for array function parameter length expression must be specified" } */ + ; + #pragma omp task affinity( h[2:2][-1:]) /* { dg-error "negative low bound in array section" } */ + ; + #pragma omp task affinity( h[:1][:-3]) /* { dg-error "negative length in array section" } */ + ; + #pragma omp task affinity( i[:1][11:]) /* { dg-error "low bound \[^\n\r]* above array section size" } */ + ; + #pragma omp task affinity( j[3:4][:10]) /* { dg-error "length \[^\n\r]* above array section size" } */ + ; + #pragma omp task affinity( j[30:10][5:5]) /* { dg-error "high bound \[^\n\r]* above array section size" } */ + ; + #pragma omp task affinity( a2[:3][2:4]) + ; + #pragma omp task affinity( b2[0:]) + ; + #pragma omp task affinity( c2[:3][1:1]) + ; + #pragma omp task affinity( d2[9:]) + ; + #pragma omp task affinity( e2[:10]) + ; + #pragma omp task affinity( f2[1:9]) + ; + #pragma omp task affinity( g2[:2][2:4]) + ; + #pragma omp task affinity( h2[2:2][0:]) + ; + #pragma omp task affinity( h2[:1][:3]) + ; + #pragma omp task affinity( i2[:1][9:]) + ; + #pragma omp task affinity( j2[3:4][:9]) + ; + #pragma omp task affinity( j2[30:10][5:4]) + ; +} + +void bar2 (int a[10][10][10]); + +void +foo2 (int a[10][10][10], int **b) +{ + int c[10][10][10]; + #pragma omp task affinity( a[2:4][3:][:7], b[1:7][2:8]) + bar2 (a); + int i = 1, j = 3, k = 2, l = 6; + #pragma omp task affinity( a[++i:++j][++k:][:++l]) + bar2 (a); + #pragma omp task affinity( a[7:2][:][:], c[5:2][:][:]) + { + bar2 (c); + bar2 (a); + } +} + +void +foo3 (int a[10][10][10], int **b, int x) +{ + int c[10][10][10]; + #pragma omp task affinity( a[2:4][3:0][:7]) /* { dg-error "zero length array section" } */ + bar2 (a); + #pragma omp task affinity( b[:7][0:0][:0]) /* { dg-error "zero length array section" } */ + bar2 (a); + #pragma omp task affinity( c[:][:][10:]) /* { dg-error "zero length array section" } */ + bar2 (c); + #pragma omp task affinity( a[2:4][3:0][:x]) /* { dg-error "zero length array section" } */ + bar2 (a); + #pragma omp task affinity( b[:x][0:0][:0]) /* { dg-error "zero length array section" } */ + bar2 (a); + #pragma omp task affinity( c[:][x-2:x][10:]) /* { dg-error "zero length array section" } */ + bar2 (c); +} + +void +foo4 (int *p, int (*q)[10], int r[10], int s[10][10]) +{ + int a[10], b[10][10]; + #pragma omp task affinity ( p[-1:2]) + ; + #pragma omp task affinity ( q[-1:2][2:4]) + ; + #pragma omp task affinity ( q[-1:2][-2:4]) /* { dg-error "negative low bound in array section in" } */ + ; + #pragma omp task affinity ( r[-1:2]) + ; + #pragma omp task affinity ( s[-1:2][2:4]) + ; + #pragma omp task affinity ( s[-1:2][-2:4]) /* { dg-error "negative low bound in array section in" } */ + ; + #pragma omp task affinity ( a[-1:2]) /* { dg-error "negative low bound in array section in" } */ + ; + #pragma omp task affinity ( b[-1:2][2:4]) /* { dg-error "negative low bound in array section in" } */ + ; + #pragma omp task affinity ( b[1:2][-2:4]) /* { dg-error "negative low bound in array section in" } */ + ; + #pragma omp task affinity ( p[2:-3]) /* { dg-error "negative length in array section in" } */ + ; + #pragma omp task affinity ( q[2:-3][:]) /* { dg-error "negative length in array section in" } */ + ; + #pragma omp task affinity ( q[2:3][0:-1]) /* { dg-error "negative length in array section in" } */ + ; + #pragma omp task affinity ( r[2:-5]) /* { dg-error "negative length in array section in" } */ + ; + #pragma omp task affinity ( s[2:-5][:]) /* { dg-error "negative length in array section in" } */ + ; + #pragma omp task affinity ( s[2:5][0:-4]) /* { dg-error "negative length in array section in" } */ + ; + #pragma omp task affinity ( a[2:-5]) /* { dg-error "negative length in array section in" } */ + ; + #pragma omp task affinity ( b[2:-5][0:10]) /* { dg-error "negative length in array section in" } */ + ; + #pragma omp task affinity ( b[2:5][0:-4]) /* { dg-error "negative length in array section in" } */ + ; +} + +struct T { int c[3]; }; +struct S { int a; struct T *b; struct T g; }; +struct S sd[10]; +struct S *se[10]; +struct S *sf; +struct S sh; +struct U { int a : 5; }; +struct U si; + + +void +foo5 (void) +{ + #pragma omp task affinity( sd) + ; + #pragma omp task affinity( sd[2]) + ; + #pragma omp task affinity( sd[:]) + ; + #pragma omp task affinity( sd[2:2]) + ; + #pragma omp task affinity( sd[:2]) + ; + #pragma omp task affinity( sd[1].b->c[2]) + ; + #pragma omp task affinity( sd[0].a) + ; + #pragma omp task affinity( se[3]->a) + ; + #pragma omp task affinity( se[2]->b->c) + ; + #pragma omp task affinity( se[1]->b->c[2]) + ; + #pragma omp task affinity( (*sf).a) + ; + #pragma omp task affinity( sf->b->c[0]) + ; + #pragma omp task affinity( sf) + ; + #pragma omp task affinity( *sf) + ; + #pragma omp task affinity( sf[0]) + ; + #pragma omp task affinity( sf[0].a) + ; + #pragma omp task affinity( sh.g.c[2]) + ; +} + +void +foo6 (void) +{ + #pragma omp task affinity( sd[:2].b->c[2]) /* { dg-error "expected" } */ + ; + #pragma omp task affinity( sd[1:].b->c[2]) /* { dg-error "expected" } */ + ; + #pragma omp task affinity( sd[0:1].a) /* { dg-error "expected" } */ + ; + #pragma omp task affinity( se[3:2]->a) /* { dg-error "expected" } */ + ; + #pragma omp task affinity( se[2:2]->b->c) /* { dg-error "expected" } */ + ; + #pragma omp task affinity( se[1]->b->c[2:1]) /* { dg-error "expected" } */ + ; + #pragma omp task affinity( sf + 0) /* { dg-error "'sf' is not lvalue expression nor array section in 'affinity' clause" } */ + ; + #pragma omp task affinity( sf[0:1].a) /* { dg-error "expected" } */ + ; + #pragma omp task affinity( sh.g.c[2:1]) /* { dg-error "expected" } */ + ; + #pragma omp task affinity( si.a) /* { dg-error "bit-field 'si\\..*a' in 'affinity' clause" } */ + ; +} +/* { dg-additional-options "-Wno-volatile" { target c++ } } */ diff --git a/gcc/testsuite/c-c++-common/gomp/affinity-3.c b/gcc/testsuite/c-c++-common/gomp/affinity-3.c new file mode 100644 index 0000000..1a47654 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/affinity-3.c @@ -0,0 +1,77 @@ +/* { dg-additional-options "-Wno-volatile" { target c++ } } */ + +int arr[64], arr2[64]; +struct S { int a[4]; } k; +short arr4[4]; +volatile int v; +#define TEST_EQ(x,y) ({ int o[x == y ? 1 : -1]; 0; }) + +void +foo (unsigned char i, signed char j) +{ + #pragma omp task affinity (iterator (j=6:2:-2) : \ + arr[TEST_EQ (sizeof (j), sizeof (int)), \ + TEST_EQ (sizeof (i), sizeof (unsigned char)), \ + TEST_EQ (sizeof (k), sizeof (struct S)), j], \ + arr2[TEST_EQ (((__typeof (j)) -1) < 0, 1), \ + TEST_EQ (((__typeof (i)) -1) < 0, 0), \ + TEST_EQ (((__typeof (k.a[0])) -1) < 0, 1), j]) \ + affinity(arr[0]) \ + affinity (iterator (long long i=__LONG_LONG_MAX__ - 4:__LONG_LONG_MAX__ - 2:2, \ + unsigned short j=~0U-16:~0U-8:3, \ + short *k=&arr4[1]:&arr4[2]:1) : \ + arr[TEST_EQ (sizeof (i), sizeof (long long)), \ + TEST_EQ (sizeof (j), sizeof (unsigned short)), \ + TEST_EQ (sizeof (k), sizeof (short *)), \ + TEST_EQ (sizeof (*k), sizeof (short)), i - __LONG_LONG_MAX__ + 4], \ + arr2[TEST_EQ (((__typeof (i)) -1) < 0, 1), \ + TEST_EQ (((__typeof (j)) -1) < 0, 0), \ + TEST_EQ (((__typeof (*k)) -1) < 0, 1), j - (~0U-16)], \ + arr2[k - &arr4[0]]) \ + affinity( k) + v++; +} + +void +bar (unsigned char i, signed char j) +{ + int m = j; + int n = j + 2; + #pragma omp task affinity (iterator (j=6:2:m) : \ + arr[TEST_EQ (sizeof (j), sizeof (int)), \ + TEST_EQ (sizeof (i), sizeof (unsigned char)), \ + TEST_EQ (sizeof (k), sizeof (struct S)), j], \ + arr2[TEST_EQ (((__typeof (j)) -1) < 0, 1), \ + TEST_EQ (((__typeof (i)) -1) < 0, 0), \ + TEST_EQ (((__typeof (k.a[0])) -1) < 0, 1), j]) \ + affinity( arr[0]) \ + affinity (iterator (long long i=__LONG_LONG_MAX__ - 4 - n:__LONG_LONG_MAX__ - 2:2, \ + unsigned short j=~0U-16:~0U-8-n:3, \ + short *k=&arr4[1]:&arr4[n + 2]:1) : \ + arr[TEST_EQ (sizeof (i), sizeof (long long)), \ + TEST_EQ (sizeof (j), sizeof (unsigned short)), \ + TEST_EQ (sizeof (k), sizeof (short *)), \ + TEST_EQ (sizeof (*k), sizeof (short)), i - __LONG_LONG_MAX__ + 4], \ + arr2[TEST_EQ (((__typeof (i)) -1) < 0, 1), \ + TEST_EQ (((__typeof (j)) -1) < 0, 0), \ + TEST_EQ (((__typeof (*k)) -1) < 0, 1), j - (~0U-16)], \ + arr2[k - &arr4[0]:10]) \ + affinity( k) + v++; +} + +void +baz (void) +{ + #pragma omp parallel + #pragma omp master + { + #pragma omp task affinity(iterator(unsigned long int k = 0 : 2) : \ + arr[TEST_EQ (sizeof (k), sizeof (unsigned long)), \ + TEST_EQ (((__typeof (k)) -1) < 0, 0), k]) \ + affinity(iterator(signed char s = -3 : -12 : -1) : \ + arr[TEST_EQ (sizeof (s), sizeof (signed char)), \ + TEST_EQ (((__typeof (s)) -1) < 0, 1), s + 12]) + v++; + } +} diff --git a/gcc/testsuite/c-c++-common/gomp/affinity-4.c b/gcc/testsuite/c-c++-common/gomp/affinity-4.c new file mode 100644 index 0000000..dee3ed9 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/affinity-4.c @@ -0,0 +1,103 @@ +int a, b[64]; +struct S { int c; } *d, *e; +struct T; +struct T *f, *g; +int *h; + +void +f1 (void) +{ + #pragma omp task affinity (iterator : a) + ; + /* { dg-error "'iterator' undeclared " "" { target c } .-2 } */ + /* { dg-error "found ':' in nested-name-specifier, expected '::'" "" { target c++ } .-3 } */ + /* { dg-error "'iterator' has not been declared" "" { target c++ } .-4 } */ +} + +void +f2 (void) +{ + #pragma omp task affinity (iterator (for = 0 : 2) : a) /* { dg-error "expected" } */ + ; + #pragma omp task affinity (iterator (5 = 0 : 2) : a) /* { dg-error "expected" } */ + ; + #pragma omp task affinity (iterator (i : 0 : 2) : a) /* { dg-error "expected '='|name a type|expected" } */ + ; + #pragma omp task affinity (iterator (i = 0, 1 : 2) : a) /* { dg-error "expected" } */ + ; + #pragma omp task affinity (iterator (i = (0, 1) : 2) : a) + ; + #pragma omp task affinity (iterator (i = 0 : 1 : 2 : 3) : a) /* { dg-error "expected '.'" } */ + ; + #pragma omp task affinity (iterator (i = 0 : 2, 3) : a) /* { dg-error "expected" } */ + ; + #pragma omp task affinity (iterator (i = 0 : 10 : 2, 3) : a) /* { dg-error "expected" } */ + ; + #pragma omp task affinity (iterator (i = 0:1), iterator (j = 0:1) : a) + ; + /* { dg-error "'iterator' undeclared " "" { target c } .-2 } */ + /* { dg-error "'i' was not declared in this scope" "" { target c++ } .-3 } */ + /* { dg-error "'iterator' was not declared in this scope" "" { target c++ } .-4 } */ + /* { dg-error "'j' was not declared in this scope" "" { target c++ } .-5 } */ + /* { dg-error "expected '\\)' before ':' token" "" { target c++ } .-6 } */ +} + +void +f3 (void) +{ + #pragma omp task affinity (iterator (i = 0:32) : b[i*2:2]) + ; + #pragma omp task affinity (iterator (struct S i = 0:1) : a) /* { dg-error "iterator 'i' has neither integral nor pointer type" } */ + ; + #pragma omp task affinity (iterator (void i = 0:1) : a) /* { dg-error "iterator 'i' has neither integral nor pointer type" } */ + ; + #pragma omp task affinity (iterator (float f = 0.2:0.4) : a) /* { dg-error "iterator 'f' has neither integral nor pointer type" } */ + ; + #pragma omp task affinity (iterator (struct S *p = d:e:2) : a) + ; + #pragma omp task affinity (iterator (struct T *p = f:g) , a) + ; + /* { dg-error "'iterator' undeclared " "" { target c } .-2 } */ + /* { dg-error "expected primary-expression before 'struct'" "" { target c++ } .-3 } */ + /* { dg-error "'iterator' was not declared in this scope" "" { target c++ } .-4 } */ +} + +void +f4 (void) +{ + #pragma omp task affinity (iterator (int i = 0:4, \ + struct U { int (*p)[i + 2]; } *p = 0:2) : a) /* { dg-error "type of iterator 'p' refers to outer iterator 'i'" "" { target c } } */ + ; /* { dg-error "types may not be defined in iterator type|not an integral constant" "" { target c++ } .-1 } */ + #pragma omp task affinity (iterator (i = 0:4, j = i:16) : a) /* { dg-error "begin expression refers to outer iterator 'i'" } */ + ; + #pragma omp task affinity (iterator (i = 0:4, j = 2:i:1) : a) /* { dg-error "end expression refers to outer iterator 'i'" } */ + ; + #pragma omp task affinity (iterator (i = 0:4, j = 2:8:i) : a) /* { dg-error "step expression refers to outer iterator 'i'" } */ + ; + #pragma omp task affinity (iterator (i = *d:2) : a) /* { dg-error "aggregate value used where an integer was expected" "" { target c } } */ + ; /* { dg-error "invalid cast from type 'S' to type 'int'" "" { target c++ } .-1 } */ + #pragma omp task affinity (iterator (i = 2:*d:2) : a) /* { dg-error "aggregate value used where an integer was expected" "" { target c } } */ + ; /* { dg-error "invalid cast from type 'S' to type 'int'" "" { target c++ } .-1 } */ + #pragma omp task affinity (iterator (i = 2:4:*d) : a) /* { dg-error "iterator step with non-integral type" } */ + ; + #pragma omp task affinity (iterator (i = 1.25:2.5:3) : a) + ; + #pragma omp task affinity (iterator (i = 1:2:3.5) : a) /* { dg-error "iterator step with non-integral type" } */ + ; + #pragma omp task affinity (iterator (int *p = 23 : h) : a) + ; + #pragma omp task affinity (iterator (short i=1:3:0) : a) /* { dg-error "iterator 'i' has zero step" } */ + ; + #pragma omp task affinity (iterator (i = 1 : 3 : 3 - 3) : a) /* { dg-error "iterator 'i' has zero step" } */ + ; + #pragma omp task affinity (iterator (int *p = &b[6]:&b[9]:4 - 4) : a) /* { dg-error "iterator 'p' has zero step" } */ + ; + #pragma omp task affinity (iterator (const int i = 0 : 2) : a) /* { dg-error "const qualified" } */ + ; + #pragma omp task affinity (iterator (const long long unsigned i = 0 : 2) : a) /* { dg-error "const qualified" } */ + ; +#if !defined (__cplusplus) && __STDC_VERSION__ >= 201112L + #pragma omp task affinity (iterator (_Atomic unsigned i = 0 : 2) : a) /* { dg-error "_Atomic" "" { target c } } */ + ; +#endif +} diff --git a/gcc/testsuite/c-c++-common/gomp/affinity-5.c b/gcc/testsuite/c-c++-common/gomp/affinity-5.c new file mode 100644 index 0000000..194286d --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/affinity-5.c @@ -0,0 +1,32 @@ +/* { dg-additional-options "-fdump-tree-gimple" } */ +int bar (int); +int bar2 (int); + +void foobar() +{ + int d[64], e[64], f[64]; +#pragma omp task affinity (d, e[bar(5)], f[4:10]) + ; +} + +void +foo (void) +{ + int a[64]; +#pragma omp task affinity (iterator (j=bar(0):bar(1):bar(2)) : a[bar(j)]) + ; +} +void +qux (void) +{ + int a[64], b[64], c[64]; +#pragma omp task affinity (iterator (j=bar(0):bar(1):bar(2)) : a[bar(j+1)], b[bar(j+2)], c[bar(j+3)]) + ; +} + +/* { dg-final { scan-tree-dump-times "= bar \\(5\\);" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "= bar \\(0\\);" 2 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "= bar \\(1\\);" 2 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "= bar \\(2\\);" 2 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "= bar \\(j\\);" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "= bar \\(_.\\);" 3 "gimple" } } */ diff --git a/gcc/testsuite/c-c++-common/gomp/affinity-6.c b/gcc/testsuite/c-c++-common/gomp/affinity-6.c new file mode 100644 index 0000000..0c9cd59 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/affinity-6.c @@ -0,0 +1,36 @@ +/* { dg-additional-options "-fdump-tree-gimple" } */ +int bar (int); +int bar2 (int); + +void foobar() +{ + int d[64], e[64], f[64]; +#pragma omp parallel default(none) /* { dg-note "enclosing 'parallel'" } */ +#pragma omp task affinity (d, e[bar(5)], f[4:10]) + ; +/* { dg-error "'f' not specified in enclosing 'parallel'" "" { target *-*-* } .-2 } */ +/* { dg-error "'e' not specified in enclosing 'parallel'" "" { target *-*-* } .-3 } */ +/* { dg-error "'d' not specified in enclosing 'parallel'" "" { target *-*-* } .-4 } */ +} + +void +foo (void) +{ + int a[64]; +#pragma omp parallel default(none) /* { dg-note "enclosing 'parallel'" } */ +#pragma omp task affinity (iterator (j=bar(0):bar(1):bar(2)) : a[bar(j)]) + ; +/* { dg-error "'a' not specified in enclosing 'parallel'" "" { target *-*-* } .-2 } */ +} + +void +qux (void) +{ + int a[64], b[64], c[64]; +#pragma omp parallel default(none) /* { dg-note "enclosing 'parallel'" } */ +#pragma omp task affinity (iterator (j=bar(0):bar(1):bar(2)) : a[bar(j+1)], b[bar(j+2)], c[bar(j+3)]) + ; +/* { dg-error "'a' not specified in enclosing 'parallel'" "" { target *-*-* } .-2 } */ +/* { dg-error "'c' not specified in enclosing 'parallel'" "" { target *-*-* } .-3 } */ +/* { dg-error "'b' not specified in enclosing 'parallel'" "" { target *-*-* } .-4 } */ +} diff --git a/gcc/testsuite/c-c++-common/gomp/affinity-7.c b/gcc/testsuite/c-c++-common/gomp/affinity-7.c new file mode 100644 index 0000000..11684f5 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/affinity-7.c @@ -0,0 +1,37 @@ +/* { dg-additional-options "-fdump-tree-original" } */ +int var[20]; + +int * +iterator(int i) +{ + return &var[i]; +} + +void +foo (void) +{ + int iterator[10], i; + #pragma omp task affinity(iterator(i=4:2) : iterator[i] ) + ; + #pragma omp task affinity(iterator) + ; + #pragma omp task affinity(iterator[4:3]) + ; +} + +void +bar (void) +{ + int j = 3; + ; + #pragma omp task affinity(iterator(i=4:2) : iterator(i)[2] ) + ; + #pragma omp task affinity(iterator(j)[4]) + ; +} + +/* { dg-final { scan-tree-dump-times "#pragma omp task affinity\\(iterator\\(int i=4:2:1\\):iterator\\\[SAVE_EXPR <i>\\\]\\)" 1 "original" } } */ +/* { dg-final { scan-tree-dump-times "#pragma omp task affinity\\(iterator\\)" 1 "original" } } */ +/* { dg-final { scan-tree-dump-times "#pragma omp task affinity\\(iterator\\\[4\\\]\\)" 1 "original" } } */ +/* { dg-final { scan-tree-dump-times "#pragma omp task affinity\\(iterator\\(int i=4:2:1\\):\\*\\(iterator \\(i\\) \\+ 8\\)\\)" 1 "original" } } */ +/* { dg-final { scan-tree-dump-times "#pragma omp task affinity\\(\\*\\(iterator \\(j\\) \\+ 16\\)\\)" 1 "original" } } */ diff --git a/gcc/testsuite/c-c++-common/gomp/pr99928-10.c b/gcc/testsuite/c-c++-common/gomp/pr99928-10.c index d2987a1..6c44600 100644 --- a/gcc/testsuite/c-c++-common/gomp/pr99928-10.c +++ b/gcc/testsuite/c-c++-common/gomp/pr99928-10.c @@ -95,22 +95,22 @@ bar (void) #pragma omp section r12[1]++; } - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:\\\*_\[0-9]* \\\[len: 60\\\]" "gimple" { xfail *-*-* } } } */ - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(firstprivate:r13 \\\[pointer assign, bias: 4\\\]\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:\\\*_\[0-9]* \\\[len: 60\\\]" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(firstprivate:r13 \\\[pointer assign, bias: 4\\\]\\)" "gimple" } } */ /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r13\\)" "gimple" } } */ /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r13 \\+ 4" "gimple" } } */ #pragma omp target parallel reduction(+:r13[1:15]) r13[1]++; - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:\\\*_\[0-9]* \\\[len: 64\\\]" "gimple" { xfail *-*-* } } } */ - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(firstprivate:r14 \\\[pointer assign, bias: 4\\\]\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:\\\*_\[0-9]* \\\[len: 64\\\]" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(firstprivate:r14 \\\[pointer assign, bias: 4\\\]\\)" "gimple" } } */ /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r14" "gimple" } } */ /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r14 \\+ 4" "gimple" } } *//* FIXME: This should be on for instead. */ /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r14 \\+ 4" "gimple" } } *//* FIXME. */ #pragma omp target parallel for reduction(+:r14[1:16]) for (int i = 0; i < 64; i++) r14[1]++; - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:\\\*_\[0-9]* \\\[len: 68\\\]" "gimple" { xfail *-*-* } } } */ - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(firstprivate:r15 \\\[pointer assign, bias: 4\\\]\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:\\\*_\[0-9]* \\\[len: 68\\\]" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(firstprivate:r15 \\\[pointer assign, bias: 4\\\]\\)" "gimple" } } */ /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r15\\)" "gimple" } } */ /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r15 \\+ 4" "gimple" } } *//* FIXME: This should be on for instead. */ /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r15 \\+ 4" "gimple" } } *//* FIXME. */ @@ -118,31 +118,31 @@ bar (void) #pragma omp target parallel for simd reduction(+:r15[1:17]) for (int i = 0; i < 64; i++) r15[1]++; - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:\\\*_\[0-9]* \\\[len: 72\\\]" "gimple" { xfail *-*-* } } } */ - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(firstprivate:r16 \\\[pointer assign, bias: 4\\\]\\)" "gimple" { xfail *-*-* } } } */ - /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r16\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:\\\*_\[0-9]* \\\[len: 72\\\]" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(firstprivate:r16 \\\[pointer assign, bias: 4\\\]\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r16\\)" "gimple" } } */ /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(r16\\)" "gimple" } } *//* FIXME: Should be shared, but firstprivate is an optimization. */ /* { dg-final { scan-tree-dump "omp for\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r16 \\+ 4" "gimple" } } *//* NOTE: This is implementation detail. */ /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r16 \\+ 4" "gimple" } } *//* NOTE: This is implementation detail. */ #pragma omp target parallel loop reduction(+:r16[1:18]) for (int i = 0; i < 64; i++) r16[1]++; - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:\\\*_\[0-9]* \\\[len: 76\\\]" "gimple" { xfail *-*-* } } } */ - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(firstprivate:r17 \\\[pointer assign, bias: 4\\\]\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:\\\*_\[0-9]* \\\[len: 76\\\]" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(firstprivate:r17 \\\[pointer assign, bias: 4\\\]\\)" "gimple" } } */ /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r17\\)" "gimple" } } */ /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r17 \\+ 4" "gimple" } } */ #pragma omp target teams reduction(+:r17[1:19]) r17[1]++; - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:\\\*_\[0-9]* \\\[len: 80\\\]" "gimple" { xfail *-*-* } } } */ - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(firstprivate:r18 \\\[pointer assign, bias: 4\\\]\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:\\\*_\[0-9]* \\\[len: 80\\\]" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(firstprivate:r18 \\\[pointer assign, bias: 4\\\]\\)" "gimple" } } */ /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r18\\)" "gimple" } } */ /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r18 \\+ 4" "gimple" } } */ /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r18 \\+ 4" "gimple" } } */ #pragma omp target teams distribute reduction(+:r18[1:20]) for (int i = 0; i < 64; i++) r18[1]++; - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:\\\*_\[0-9]* \\\[len: 84\\\]" "gimple" { xfail *-*-* } } } */ - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(firstprivate:r19 \\\[pointer assign, bias: 4\\\]\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:\\\*_\[0-9]* \\\[len: 84\\\]" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(firstprivate:r19 \\\[pointer assign, bias: 4\\\]\\)" "gimple" } } */ /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r19\\)" "gimple" } } */ /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r19 \\+ 4" "gimple" } } */ /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r19 \\+ 4" "gimple" } } */ @@ -151,8 +151,8 @@ bar (void) #pragma omp target teams distribute parallel for reduction(+:r19[1:21]) for (int i = 0; i < 64; i++) r19[1]++; - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:\\\*_\[0-9]* \\\[len: 88\\\]" "gimple" { xfail *-*-* } } } */ - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(firstprivate:r20 \\\[pointer assign, bias: 4\\\]\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:\\\*_\[0-9]* \\\[len: 88\\\]" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(firstprivate:r20 \\\[pointer assign, bias: 4\\\]\\)" "gimple" } } */ /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r20\\)" "gimple" } } */ /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r20 \\+ 4" "gimple" } } */ /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r20 \\+ 4" "gimple" } } */ @@ -162,8 +162,8 @@ bar (void) #pragma omp target teams distribute parallel for simd reduction(+:r20[1:22]) for (int i = 0; i < 64; i++) r20[1]++; - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:\\\*_\[0-9]* \\\[len: 92\\\]" "gimple" { xfail *-*-* } } } */ - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(firstprivate:r21 \\\[pointer assign, bias: 4\\\]\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:\\\*_\[0-9]* \\\[len: 92\\\]" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(firstprivate:r21 \\\[pointer assign, bias: 4\\\]\\)" "gimple" } } */ /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r21\\)" "gimple" } } */ /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r21 \\+ 4" "gimple" } } */ /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r21 \\+ 4" "gimple" } } */ @@ -171,9 +171,9 @@ bar (void) #pragma omp target teams distribute simd reduction(+:r21[1:23]) for (int i = 0; i < 64; i++) r21[1]++; - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:\\\*_\[0-9]* \\\[len: 96\\\]" "gimple" { xfail *-*-* } } } */ - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(firstprivate:r22 \\\[pointer assign, bias: 4\\\]\\)" "gimple" { xfail *-*-* } } } */ - /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r22\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:\\\*_\[0-9]* \\\[len: 96\\\]" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(firstprivate:r22 \\\[pointer assign, bias: 4\\\]\\)" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r22\\)" "gimple" } } */ /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*firstprivate\\(r22\\)" "gimple" } } *//* FIXME: Should be shared, but firstprivate is an optimization. */ /* { dg-final { scan-tree-dump "omp distribute\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r22 \\+ 4" "gimple" } } *//* NOTE: This is implementation detail. */ /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(r22\\)" "gimple" } } *//* NOTE: This is implementation detail. */ @@ -182,8 +182,8 @@ bar (void) #pragma omp target teams loop reduction(+:r22[1:24]) for (int i = 0; i < 64; i++) r22[1]++; - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:\\\*_\[0-9]* \\\[len: 100\\\]" "gimple" { xfail *-*-* } } } */ - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(firstprivate:r23 \\\[pointer assign, bias: 4\\\]\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:\\\*_\[0-9]* \\\[len: 100\\\]" "gimple" } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(firstprivate:r23 \\\[pointer assign, bias: 4\\\]\\)" "gimple" } } */ /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r23\\)" "gimple" } } */ /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*\\)r23 \\+ 4" "gimple" } } */ #pragma omp target simd reduction(+:r23[1:25]) diff --git a/gcc/testsuite/c-c++-common/gomp/pr99928-16.c b/gcc/testsuite/c-c++-common/gomp/pr99928-16.c new file mode 100644 index 0000000..84cd85d --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/pr99928-16.c @@ -0,0 +1,16 @@ +/* PR middle-end/99928 */ + +void +foo (void) +{ + int a[6] = {}; + #pragma omp target simd reduction(+:a[:3]) + for (int i = 0; i < 6; i++) + a[0]++; + #pragma omp target simd reduction(+:a[:3]) map(always, tofrom: a) + for (int i = 0; i < 6; i++) + a[0]++; + #pragma omp target simd reduction(+:a[:3]) map(always, tofrom: a[:6]) + for (int i = 0; i < 6; i++) + a[0]++; +} diff --git a/gcc/testsuite/c-c++-common/gomp/pr99928-8.c b/gcc/testsuite/c-c++-common/gomp/pr99928-8.c index fc57573..27e6ad1 100644 --- a/gcc/testsuite/c-c++-common/gomp/pr99928-8.c +++ b/gcc/testsuite/c-c++-common/gomp/pr99928-8.c @@ -94,48 +94,48 @@ bar (void) #pragma omp section r12++; } - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r13" "gimple" { xfail *-*-* } } } */ - /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r13\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r13" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r13\\)" "gimple" } } */ /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:r13\\)" "gimple" } } */ #pragma omp target parallel reduction(+:r13) r13++; - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r14" "gimple" { xfail *-*-* } } } */ - /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r14\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r14" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r14\\)" "gimple" } } */ /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:r14\\)" "gimple" } } *//* FIXME: This should be on for instead. */ /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:r14\\)" "gimple" } } *//* FIXME. */ #pragma omp target parallel for reduction(+:r14) for (int i = 0; i < 64; i++) r14++; - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r15" "gimple" { xfail *-*-* } } } */ - /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r15\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r15" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r15\\)" "gimple" } } */ /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:r15\\)" "gimple" } } *//* FIXME: This should be on for instead. */ /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:r15\\)" "gimple" } } *//* FIXME. */ /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:r15\\)" "gimple" } } */ #pragma omp target parallel for simd reduction(+:r15) for (int i = 0; i < 64; i++) r15++; - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r16" "gimple" { xfail *-*-* } } } */ - /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r16\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r16" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r16\\)" "gimple" } } */ /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(r16\\)" "gimple" } } */ /* { dg-final { scan-tree-dump "omp for\[^\n\r]*reduction\\(\\+:r16\\)" "gimple" } } *//* NOTE: This is implementation detail. */ /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:r16\\)" "gimple" } } *//* NOTE: This is implementation detail. */ #pragma omp target parallel loop reduction(+:r16) for (int i = 0; i < 64; i++) r16++; - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r17" "gimple" { xfail *-*-* } } } */ - /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r17\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r17" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r17\\)" "gimple" } } */ /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:r17\\)" "gimple" } } */ #pragma omp target teams reduction(+:r17) r17++; - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r18" "gimple" { xfail *-*-* } } } */ - /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r18\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r18" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r18\\)" "gimple" } } */ /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:r18\\)" "gimple" } } */ /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:r18\\)" "gimple" } } */ #pragma omp target teams distribute reduction(+:r18) for (int i = 0; i < 64; i++) r18++; - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r19" "gimple" { xfail *-*-* } } } */ - /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r19\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r19" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r19\\)" "gimple" } } */ /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:r19\\)" "gimple" } } */ /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:r19\\)" "gimple" } } */ /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:r19\\)" "gimple" } } *//* FIXME: This should be on for instead. */ @@ -143,8 +143,8 @@ bar (void) #pragma omp target teams distribute parallel for reduction(+:r19) for (int i = 0; i < 64; i++) r19++; - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r20" "gimple" { xfail *-*-* } } } */ - /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r20\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r20" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r20\\)" "gimple" } } */ /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:r20\\)" "gimple" } } */ /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:r20\\)" "gimple" } } */ /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:r20\\)" "gimple" } } *//* FIXME: This should be on for instead. */ @@ -153,16 +153,16 @@ bar (void) #pragma omp target teams distribute parallel for simd reduction(+:r20) for (int i = 0; i < 64; i++) r20++; - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r21" "gimple" { xfail *-*-* } } } */ - /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r21\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r21" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r21\\)" "gimple" } } */ /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:r21\\)" "gimple" } } */ /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:r21\\)" "gimple" } } */ /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:r21\\)" "gimple" } } */ #pragma omp target teams distribute simd reduction(+:r21) for (int i = 0; i < 64; i++) r21++; - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r22" "gimple" { xfail *-*-* } } } */ - /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r22\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r22" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r22\\)" "gimple" } } */ /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(r22\\)" "gimple" } } */ /* { dg-final { scan-tree-dump "omp distribute\[^\n\r]*reduction\\(\\+:r22\\)" "gimple" } } *//* NOTE: This is implementation detail. */ /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(r22\\)" "gimple" } } *//* NOTE: This is implementation detail. */ @@ -171,8 +171,8 @@ bar (void) #pragma omp target teams loop reduction(+:r22) for (int i = 0; i < 64; i++) r22++; - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r23" "gimple" { xfail *-*-* } } } */ - /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r23\\)" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r23" "gimple" } } */ + /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r23\\)" "gimple" } } */ /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:r23\\)" "gimple" } } */ #pragma omp target simd reduction(+:r23) for (int i = 0; i < 64; i++) diff --git a/gcc/testsuite/c-c++-common/gomp/pr99928-9.c b/gcc/testsuite/c-c++-common/gomp/pr99928-9.c index c049bb0..8623527 100644 --- a/gcc/testsuite/c-c++-common/gomp/pr99928-9.c +++ b/gcc/testsuite/c-c++-common/gomp/pr99928-9.c @@ -94,19 +94,19 @@ bar (void) #pragma omp section r12[1]++; } - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r13\\\[1\\\] \\\[len: 8\\\]" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r13\\\[1\\\] \\\[len: 8\\\]" "gimple" } } */ /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r13\\)" "gimple" } } */ /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r13 \\+ 4" "gimple" } } */ #pragma omp target parallel reduction(+:r13[1:2]) r13[1]++; - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r14\\\[1\\\] \\\[len: 8\\\]" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r14\\\[1\\\] \\\[len: 8\\\]" "gimple" } } */ /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r14" "gimple" } } */ /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r14 \\+ 4" "gimple" } } *//* FIXME: This should be on for instead. */ /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r14 \\+ 4" "gimple" } } *//* FIXME. */ #pragma omp target parallel for reduction(+:r14[1:2]) for (int i = 0; i < 64; i++) r14[1]++; - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r15\\\[1\\\] \\\[len: 8\\\]" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r15\\\[1\\\] \\\[len: 8\\\]" "gimple" } } */ /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r15\\)" "gimple" } } */ /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r15 \\+ 4" "gimple" } } *//* FIXME: This should be on for instead. */ /* { dg-final { scan-tree-dump-not "omp for\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r15 \\+ 4" "gimple" } } *//* FIXME. */ @@ -114,7 +114,7 @@ bar (void) #pragma omp target parallel for simd reduction(+:r15[1:2]) for (int i = 0; i < 64; i++) r15[1]++; - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r16\\\[1\\\] \\\[len: 8\\\]" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r16\\\[1\\\] \\\[len: 8\\\]" "gimple" } } */ /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r16\\)" "gimple" } } */ /* { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(r16\\)" "gimple" } } */ /* { dg-final { scan-tree-dump "omp for\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r16 \\+ 4" "gimple" } } *//* NOTE: This is implementation detail. */ @@ -122,19 +122,19 @@ bar (void) #pragma omp target parallel loop reduction(+:r16[1:2]) for (int i = 0; i < 64; i++) r16[1]++; - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r17\\\[1\\\] \\\[len: 8\\\]" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r17\\\[1\\\] \\\[len: 8\\\]" "gimple" } } */ /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r17\\)" "gimple" } } */ /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r17 \\+ 4" "gimple" } } */ #pragma omp target teams reduction(+:r17[1:2]) r17[1]++; - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r18\\\[1\\\] \\\[len: 8\\\]" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r18\\\[1\\\] \\\[len: 8\\\]" "gimple" } } */ /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r18\\)" "gimple" } } */ /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r18 \\+ 4" "gimple" } } */ /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r18 \\+ 4" "gimple" } } */ #pragma omp target teams distribute reduction(+:r18[1:2]) for (int i = 0; i < 64; i++) r18[1]++; - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r19\\\[1\\\] \\\[len: 8\\\]" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r19\\\[1\\\] \\\[len: 8\\\]" "gimple" } } */ /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r19\\)" "gimple" } } */ /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r19 \\+ 4" "gimple" } } */ /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r19 \\+ 4" "gimple" } } */ @@ -143,7 +143,7 @@ bar (void) #pragma omp target teams distribute parallel for reduction(+:r19[1:2]) for (int i = 0; i < 64; i++) r19[1]++; - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r20\\\[1\\\] \\\[len: 8\\\]" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r20\\\[1\\\] \\\[len: 8\\\]" "gimple" } } */ /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r20\\)" "gimple" } } */ /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r20 \\+ 4" "gimple" } } */ /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r20 \\+ 4" "gimple" } } */ @@ -153,7 +153,7 @@ bar (void) #pragma omp target teams distribute parallel for simd reduction(+:r20[1:2]) for (int i = 0; i < 64; i++) r20[1]++; - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r21\\\[1\\\] \\\[len: 8\\\]" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r21\\\[1\\\] \\\[len: 8\\\]" "gimple" } } */ /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r21\\)" "gimple" } } */ /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r21 \\+ 4" "gimple" } } */ /* { dg-final { scan-tree-dump-not "omp distribute\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r21 \\+ 4" "gimple" } } */ @@ -161,7 +161,7 @@ bar (void) #pragma omp target teams distribute simd reduction(+:r21[1:2]) for (int i = 0; i < 64; i++) r21[1]++; - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r22\\\[1\\\] \\\[len: 8\\\]" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r22\\\[1\\\] \\\[len: 8\\\]" "gimple" } } */ /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r22\\)" "gimple" } } */ /* { dg-final { scan-tree-dump "omp teams\[^\n\r]*shared\\(r22\\)" "gimple" } } */ /* { dg-final { scan-tree-dump "omp distribute\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r22 \\+ 4" "gimple" } } *//* NOTE: This is implementation detail. */ @@ -171,7 +171,7 @@ bar (void) #pragma omp target teams loop reduction(+:r22[1:2]) for (int i = 0; i < 64; i++) r22[1]++; - /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r23\\\[1\\\] \\\[len: 8\\\]" "gimple" { xfail *-*-* } } } */ + /* { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:r23\\\[1\\\] \\\[len: 8\\\]" "gimple" } } */ /* { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(r23\\)" "gimple" } } */ /* { dg-final { scan-tree-dump "omp simd\[^\n\r]*reduction\\(\\+:MEM\[^\n\r]*&r23 \\+ 4" "gimple" } } */ #pragma omp target simd reduction(+:r23[1:2]) diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-variadic2.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-variadic2.C new file mode 100644 index 0000000..4299c7e --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-variadic2.C @@ -0,0 +1,13 @@ +// PR c++/86355 +// { dg-do compile { target c++11 } } + +template <int...> struct integral_constant { + static const int value = 1; +}; +template <class... T> using mp_all = integral_constant<T::value...>; +template <class... T> using check2 = mp_all<mp_all<T..., integral_constant<0>>>; +check2<> x; + +template <class T, class U> struct assert_same; +template <class T> struct assert_same<T,T> { }; +assert_same<decltype(x),integral_constant<1>> a; diff --git a/gcc/testsuite/g++.dg/cpp0x/pr68724.C b/gcc/testsuite/g++.dg/cpp0x/pr68724.C index 4e99d53..6df7f71 100644 --- a/gcc/testsuite/g++.dg/cpp0x/pr68724.C +++ b/gcc/testsuite/g++.dg/cpp0x/pr68724.C @@ -9,7 +9,7 @@ struct integral_constant integral_constant<bool, true> inst; template <typename _Tp> -struct integral_constant<bool, __is_enum(_Tp)> // { dg-error "32:template argument" } +struct integral_constant<bool, __is_enum(_Tp)> // { dg-error "not deducible" } { }; diff --git a/gcc/testsuite/g++.dg/cpp0x/static_assert17.C b/gcc/testsuite/g++.dg/cpp0x/static_assert17.C new file mode 100644 index 0000000..28cbebe --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/static_assert17.C @@ -0,0 +1,9 @@ +// PR c++/99893 +// { dg-do compile { target c++11 } } + +void f(...); + +template<class... Ts> +void g() { + f([] { static_assert(Ts::value, ""); }...); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic38.C b/gcc/testsuite/g++.dg/cpp0x/variadic38.C index b569404..49fa48c3 100644 --- a/gcc/testsuite/g++.dg/cpp0x/variadic38.C +++ b/gcc/testsuite/g++.dg/cpp0x/variadic38.C @@ -3,4 +3,4 @@ template<int... Values> struct int_vec {}; template<int... Values> -struct int_vec<0, (Values+1)...> {}; // { dg-error "26:template argument" } +struct int_vec<0, (Values+1)...> {}; // { dg-error "not deducible" } diff --git a/gcc/testsuite/g++.dg/cpp1z/pr81016.C b/gcc/testsuite/g++.dg/cpp1z/pr81016.C index 358b120..a17afcc 100644 --- a/gcc/testsuite/g++.dg/cpp1z/pr81016.C +++ b/gcc/testsuite/g++.dg/cpp1z/pr81016.C @@ -1,4 +1,4 @@ // { dg-do compile { target c++17 } } template <typename a, a> struct b; -template <typename c> struct b<bool, c::d>; // { dg-error "template parameter" } +template <typename c> struct b<bool, c::d>; // { dg-error "not deducible" } diff --git a/gcc/testsuite/g++.dg/diagnostic/pr100716-1.C b/gcc/testsuite/g++.dg/diagnostic/pr100716-1.C new file mode 100644 index 0000000..93490da --- /dev/null +++ b/gcc/testsuite/g++.dg/diagnostic/pr100716-1.C @@ -0,0 +1,54 @@ +// { dg-options "-fno-pretty-templates" } + +template<typename T> + struct A + { + template<typename U> + void f() {} // { dg-line Af } + + template<typename U> + void g(U) {} // { dg-line Ag } + }; + +template<typename T> + struct B + { + template<typename U> + void f(U) {} // { dg-line Bf } + + template<typename U> + void g(U, T) {} // { dg-line Bg } + }; + +struct C +{ + template<typename U> + void f(U) {} // { dg-line Cf } + + template<typename U> + void g() {} // { dg-line Cg } +}; + +int main() +{ + A<int>().f(0); // { dg-error "no matching function for call to 'A<int>::f\\(int\\)'" } + // { dg-message "candidate: 'template<class U> void A<int>::f\\(\\)'" "" { target *-*-* } Af } + + A<int>().g(); // { dg-error "no matching function for call to 'A<int>::g\\(\\)'" } + // { dg-message "candidate: 'template<class U> void A<int>::g\\(U\\)'" "" { target *-*-* } Ag } + + B<int>().f(); // { dg-error "no matching function for call to 'B<int>::f\\(\\)'" } + // { dg-message "candidate: 'template<class U> void B<int>::f\\(U\\)'" "" { target *-*-* } Bf } + + B<int>().g(); // { dg-error "no matching function for call to 'B<int>::g\\(\\)'" } + // { dg-message "candidate: 'template<class U> void B<int>::g\\(U, int\\)'" "" { target *-*-* } Bg } + + B<float>().g(0); // { dg-error "no matching function for call to 'B<float>::g\\(int\\)'" } + // { dg-message "candidate: 'template<class U> void B<float>::g\\(U, float\\)'" "" { target *-*-* } Bg } + + C().f(); // { dg-error "no matching function for call to 'C::f\\(\\)'" } + // { dg-message "candidate: 'template<class U> void C::f\\(U\\)'" "" { target *-*-* } Cf } + + C().g(0); // { dg-error "no matching function for call to 'C::g\\(int\\)'" } + // { dg-message "candidate: 'template<class U> void C::g\\(\\)'" "" { target *-*-* } Cg } +} diff --git a/gcc/testsuite/g++.dg/diagnostic/pr100716.C b/gcc/testsuite/g++.dg/diagnostic/pr100716.C new file mode 100644 index 0000000..4a1f0a4 --- /dev/null +++ b/gcc/testsuite/g++.dg/diagnostic/pr100716.C @@ -0,0 +1,54 @@ +// { dg-options "-fpretty-templates" } + +template<typename T> + struct A + { + template<typename U> + void f() {} // { dg-line Af } + + template<typename U> + void g(U) {} // { dg-line Ag } + }; + +template<typename T> + struct B + { + template<typename U> + void f(U) {} // { dg-line Bf } + + template<typename U> + void g(U, T) {} // { dg-line Bg } + }; + +struct C +{ + template<typename U> + void f(U) {} // { dg-line Cf } + + template<typename U> + void g() {} // { dg-line Cg } +}; + +int main() +{ + A<int>().f(0); // { dg-error "no matching function for call to 'A<int>::f\\(int\\)'" } + // { dg-message "candidate: 'template<class U> void A<T>::f\\(\\) \\\[with T = int\\\]'" "" { target *-*-* } Af } + + A<int>().g(); // { dg-error "no matching function for call to 'A<int>::g\\(\\)'" } + // { dg-message "candidate: 'template<class U> void A<T>::g\\(U\\) \\\[with T = int\\\]'" "" { target *-*-* } Ag } + + B<int>().f(); // { dg-error "no matching function for call to 'B<int>::f\\(\\)'" } + // { dg-message "candidate: 'template<class U> void B<T>::f\\(U\\) \\\[with T = int\\\]'" "" { target *-*-* } Bf } + + B<int>().g(); // { dg-error "no matching function for call to 'B<int>::g\\(\\)'" } + // { dg-message "candidate: 'template<class U> void B<T>::g\\(U, T\\) \\\[with T = int\\\]'" "" { target *-*-* } Bg } + + B<float>().g(0); // { dg-error "no matching function for call to 'B<float>::g\\(int\\)'" } + // { dg-message "candidate: 'template<class U> void B<T>::g\\(U, T\\) \\\[with T = float\\\]'" "" { target *-*-* } Bg } + + C().f(); // { dg-error "no matching function for call to 'C::f\\(\\)'" } + // { dg-message "candidate: 'template<class U> void C::f\\(U\\)'" "" { target *-*-* } Cf } + + C().g(0); // { dg-error "no matching function for call to 'C::g\\(int\\)'" } + // { dg-message "candidate: 'template<class U> void C::g\\(\\)'" "" { target *-*-* } Cg } +} diff --git a/gcc/testsuite/g++.dg/template/partial16.C b/gcc/testsuite/g++.dg/template/partial16.C new file mode 100644 index 0000000..30c34c3 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/partial16.C @@ -0,0 +1,8 @@ +// [temp.spec.partial.general]/9 + +template <class T, T t> struct C {}; +template <class T> struct C<T, 1>; // { dg-error "depends on a template parameter" } + +template< int X, int (*array_ptr)[X] > class A {}; +int array[5]; +template< int X > class A<X,&array> { }; // { dg-error "depends on a template parameter" } diff --git a/gcc/testsuite/g++.dg/template/partial17.C b/gcc/testsuite/g++.dg/template/partial17.C new file mode 100644 index 0000000..d5c82d2 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/partial17.C @@ -0,0 +1,14 @@ +// [temp.spec.partial.match]/3 + +template <int I, int J> struct A; +template <int I> struct A<I+5, I*2> {}; // { dg-error "not deducible" } + +template <int I> struct A<I, I> {}; // OK + +template <int I, int J, int K> struct B; +template <int I> struct B<I, I*2, I> {}; // OK +template <int I> struct B<I, I*2, 2> { typedef int type; }; // OK + +B<1, 2, 1> b1; +B<1, 2, 2>::type b2; +B<1, 2, 3> b3; // { dg-error "incomplete" } diff --git a/gcc/testsuite/g++.dg/template/partial18.C b/gcc/testsuite/g++.dg/template/partial18.C new file mode 100644 index 0000000..7b7614e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/partial18.C @@ -0,0 +1,19 @@ +// PR c++/96555 + +template<class T, int i> +struct X; + +template<class T> +struct X<T, sizeof(T)> {}; + +X<int, sizeof(int)> x1; +X<int, sizeof(int)+1> x2; // { dg-error "incomplete" } + + +struct A { int x; } a; +template<int, int> struct B; +template<int y> +struct B<y, sizeof(a.x)> { }; + +B<0, sizeof(int)> b1; +B<0, sizeof(int)+1> b2; // { dg-error "incomplete" } diff --git a/gcc/testsuite/g++.dg/template/partial19.C b/gcc/testsuite/g++.dg/template/partial19.C new file mode 100644 index 0000000..39149d2 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/partial19.C @@ -0,0 +1,11 @@ +// PR c++/67593 +// { dg-do compile { target c++11 } } + +template<class T> +struct outer { + template<T...> struct inner; + template<T... Vs> struct inner<T{}, Vs...> {}; +}; + +outer<int>::inner<0, 0> x1; +outer<int>::inner<1, 0> x2; // { dg-error "incomplete" } diff --git a/gcc/testsuite/g++.dg/template/partial5.C b/gcc/testsuite/g++.dg/template/partial5.C index 40d8c45..037f684 100644 --- a/gcc/testsuite/g++.dg/template/partial5.C +++ b/gcc/testsuite/g++.dg/template/partial5.C @@ -21,4 +21,4 @@ template<typename T, T V> struct Z { }; template<typename T> -struct Z<T, (T)0> { }; // { dg-error "13:template argument" } +struct Z<T, (T)0> { }; // { dg-error "depends on a template parameter" } diff --git a/gcc/testsuite/g++.old-deja/g++.pt/spec21.C b/gcc/testsuite/g++.old-deja/g++.pt/spec21.C index cf89d6b..bf25c0e 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/spec21.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/spec21.C @@ -4,8 +4,7 @@ template <class T> struct S {}; template <class T = int> struct S<T*> {}; // { dg-error "" } default argument template <int I, int J> struct A {}; -template <int I> struct A<I+5, I*2> {}; // { dg-error "28:template argument" } -// { dg-error "33:template argument" "" { target *-*-* } .-1 } +template <int I> struct A<I+5, I*2> {}; // { dg-error "not deducible" } template <class T, T t> struct C {}; template <class T> struct C<T, 1>; // { dg-error "" } type depends on parameter int i; diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-55.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-55.c index 8df5cb6..c3c2dbe 100644 --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-55.c +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-55.c @@ -1,6 +1,6 @@ /* Verify that offsets in "anti-ranges" are handled correctly. { dg-do compile } - { dg-options "-O2 -Wall -ftrack-macro-expansion=0" } */ + { dg-options "-O2 -Wall -ftrack-macro-expansion=0 -fno-ipa-icf" } */ typedef __PTRDIFF_TYPE__ ptrdiff_t; typedef __SIZE_TYPE__ size_t; diff --git a/gcc/testsuite/gcc.dg/gimplefe-error-11.c b/gcc/testsuite/gcc.dg/gimplefe-error-11.c new file mode 100644 index 0000000..9c29717 --- /dev/null +++ b/gcc/testsuite/gcc.dg/gimplefe-error-11.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-fgimple" } */ + +int bar(); +__GIMPLE +int foo() +{ + if (bar()) /* { dg-error "comparison required" } */ + goto bb1; + else + goto bb2; +} diff --git a/gcc/testsuite/gcc.dg/pr100791.c b/gcc/testsuite/gcc.dg/pr100791.c new file mode 100644 index 0000000..96cf34f --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr100791.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "" } */ + +static inline int __attribute__((__always_inline__)) +foo () +{ + return log_bad_request(0, __builtin_va_arg_pack()); /* { dg-warning "implicit" } */ +} +void log_bad_request() { foo (0); } /* { dg-warning "conflicting types" } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/popcount4l.c b/gcc/testsuite/gcc.dg/tree-ssa/popcount4l.c index 69fb2d1..269e56e 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/popcount4l.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/popcount4l.c @@ -25,6 +25,7 @@ int popcount64c(unsigned long x) return (x * h01) >> shift; } -/* { dg-final { scan-tree-dump-times "\.POPCOUNT" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "\.POPCOUNT" 1 "optimized" { target int32plus } } } */ +/* { dg-final { scan-tree-dump "\.POPCOUNT" "optimized" { target { ! int32plus } } } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/popcount4ll.c b/gcc/testsuite/gcc.dg/tree-ssa/popcount4ll.c index c1588be..7abadf6 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/popcount4ll.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/popcount4ll.c @@ -1,4 +1,4 @@ -/* { dg-do compile { target { lp64 } } } */ +/* { dg-do compile } */ /* { dg-require-effective-target popcountll } */ /* { dg-options "-O2 -fdump-tree-optimized" } */ @@ -16,4 +16,5 @@ int popcount64c(unsigned long long x) return (x * h01) >> shift; } -/* { dg-final { scan-tree-dump-times "\.POPCOUNT" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "\.POPCOUNT" 1 "optimized" { target { lp64 } } } } */ +/* { dg-final { scan-tree-dump-times "\.POPCOUNT" 2 "optimized" { target { ! lp64 } } } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/popcount5ll.c b/gcc/testsuite/gcc.dg/tree-ssa/popcount5ll.c index edb191b..2afe081 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/popcount5ll.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/popcount5ll.c @@ -1,5 +1,5 @@ /* PR tree-optimization/94800 */ -/* { dg-do compile { target { lp64 } } } */ +/* { dg-do compile } */ /* { dg-require-effective-target popcountll } */ /* { dg-options "-O2 -fdump-tree-optimized" } */ @@ -19,4 +19,5 @@ int popcount64c(unsigned long long x) return x >> shift; } -/* { dg-final { scan-tree-dump-times "\.POPCOUNT" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "\.POPCOUNT" 1 "optimized" { target { lp64 } } } } */ +/* { dg-final { scan-tree-dump-times "\.POPCOUNT" 2 "optimized" { target { ! lp64 } } } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr100637-3b.c b/gcc/testsuite/gcc.target/i386/pr100637-3b.c index 16df700..b17f8b8 100644 --- a/gcc/testsuite/gcc.target/i386/pr100637-3b.c +++ b/gcc/testsuite/gcc.target/i386/pr100637-3b.c @@ -54,3 +54,13 @@ void _abs (void) } /* { dg-final { scan-assembler "pabsb" } } */ + +void avgu (void) +{ + int i; + + for (i = 0; i < 4; i++) + ur[i] = (ua[i] + ub[i] + 1) >> 1; +} + +/* { dg-final { scan-assembler "pavgb" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr100637-3w.c b/gcc/testsuite/gcc.target/i386/pr100637-3w.c index 7f1882e..b951f30 100644 --- a/gcc/testsuite/gcc.target/i386/pr100637-3w.c +++ b/gcc/testsuite/gcc.target/i386/pr100637-3w.c @@ -84,3 +84,13 @@ void _abs (void) } /* { dg-final { scan-assembler "pabsw" } } */ + +void avgu (void) +{ + int i; + + for (i = 0; i < 2; i++) + ur[i] = (ua[i] + ub[i] + 1) >> 1; +} + +/* { dg-final { scan-assembler "pavgw" } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/vec-perm-ctor-run.c b/gcc/testsuite/gcc.target/powerpc/vec-perm-ctor-run.c new file mode 100644 index 0000000..987d6db --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vec-perm-ctor-run.c @@ -0,0 +1,124 @@ +/* { dg-do run } */ +/* { dg-require-effective-target vsx_hw } */ +/* { dg-options "-O2 -mvsx" } */ + +#include "vec-perm-ctor.h" + +#include <stdlib.h> + +int +main () +{ + du a_du = 100ULL; + du b_du = 200ULL; + + di a_di = -100; + di b_di = 200; + + df a_df = 10.0; + df b_df = 20.0; + + si a_si = 12; + si b_si = -25; + si c_si = -37; + si d_si = 50; + + sf a_sf = 30.0f; + sf b_sf = 40.0f; + sf c_sf = 50.0f; + sf d_sf = 60.0f; + + hu a_hu = 10; + hu b_hu = 20; + hu c_hu = 30; + hu d_hu = 40; + hu e_hu = 50; + hu f_hu = 60; + hu g_hu = 70; + hu h_hu = 80; + + qi a_qi = 10; + qi b_qi = 20; + qi c_qi = -30; + qi d_qi = 40; + qi e_qi = -50; + qi f_qi = 60; + qi g_qi = 70; + qi h_qi = -80; + + v2du res1 = test_ctor_ctor_same_du (a_du, b_du); + if (res1[0] != a_du || res1[1] != b_du) + abort (); + + v2df res2 = test_ctor_ctor_same_df (a_df, b_df); + if (res2[0] != a_df || res2[1] != b_df) + abort (); + + v4si res3 = test_ctor_ctor_same_si (a_si, b_si, c_si, d_si); + if (res3[0] != a_si || res3[1] != b_si || res3[2] != c_si || res3[3] != d_si) + abort (); + + v4sf res4 = test_ctor_ctor_same_sf (a_sf, b_sf, c_sf, d_sf); + if (res4[0] != a_sf || res4[1] != b_sf || res4[2] != c_sf || res4[3] != d_sf) + abort (); + + v8hu res5 + = test_ctor_ctor_same_hu (a_hu, b_hu, c_hu, d_hu, e_hu, f_hu, g_hu, h_hu); + + if (res5[0] != a_hu || res5[1] != b_hu || res5[2] != c_hu || res5[3] != d_hu + || res5[4] != e_hu || res5[5] != f_hu || res5[6] != g_hu + || res5[7] != h_hu) + abort (); + + v16qi res6 + = test_ctor_ctor_same_qi (a_qi, b_qi, c_qi, d_qi, e_qi, f_qi, g_qi, h_qi); + + if (res6[0] != a_qi || res6[1] != b_qi || res6[2] != c_qi || res6[3] != d_qi + || res6[4] != a_qi || res6[5] != b_qi || res6[6] != c_qi + || res6[7] != d_qi || res6[8] != e_qi || res6[9] != f_qi + || res6[10] != g_qi || res6[11] != h_qi || res6[12] != e_qi + || res6[13] != f_qi || res6[14] != g_qi || res6[15] != h_qi) + abort (); + + v2du res7 = test_ctor_cst_same_du (a_du, b_du); + if (res7[0] != a_du || res7[1] != 100) + abort (); + + v4sf res8 = test_ctor_cst_same_sf (a_sf, b_sf); + if (res8[0] != a_sf || res8[1] != 2.0f || res8[2] != b_sf || res8[3] != 4.0f) + abort (); + + v2df res9 = test_ctor_cst_same_df (a_df, b_df); + if (res9[0] != b_df || res9[1] != 200.0) + abort (); + + v4si res10 = test_cst_ctor_same_si (a_si, b_si); + if (res10[0] != 1 || res10[1] != 3 || res10[2] != a_si || res10[3] != b_si) + abort (); + + v2di res11 = test_ctor_cst_diff_di_si (a_di, b_di); + /* Need to take care of the endianness since the function converts vector + const to one different vector type (element size), the endianness + determines the reinterpreted layout. Same reason for res12 below. */ + if (res11[0] != -100 || +#ifdef __LITTLE_ENDIAN__ + res11[1] != 3 +#else + res11[1] != 0x300000000LL +#endif + ) + abort (); + + v2du res12 = test_cst_ctor_diff_sf_du (a_du, b_du); + if ( +#ifdef __LITTLE_ENDIAN__ + res12[0] != 0x400000003f800000ULL +#else + res12[0] != 0x3f80000040000000ULL +#endif + || res12[1] != 100) + abort (); + + return 0; +} + diff --git a/gcc/testsuite/gcc.target/powerpc/vec-perm-ctor.c b/gcc/testsuite/gcc.target/powerpc/vec-perm-ctor.c new file mode 100644 index 0000000..cc59e60 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vec-perm-ctor.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target powerpc_vsx_ok } */ +/* { dg-options "-O2 -mvsx -fdump-tree-optimized" } */ + +/* To test all permutations fed by CTOR and CST can be optimized away. */ + +#include "vec-perm-ctor.h" + +/* { dg-final { scan-tree-dump-not "VIEW_CONVERT_EXPR" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/vec-perm-ctor.h b/gcc/testsuite/gcc.target/powerpc/vec-perm-ctor.h new file mode 100644 index 0000000..1878270 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vec-perm-ctor.h @@ -0,0 +1,163 @@ +#include "altivec.h" + +typedef vector unsigned long long v2du; +typedef vector signed long long v2di; +typedef vector unsigned int v4su; +typedef vector signed int v4si; +typedef vector unsigned short v8hu; +typedef vector signed short v8hi; +typedef vector unsigned char v16qu; +typedef vector signed char v16qi; +typedef vector double v2df; +typedef vector float v4sf; + +typedef unsigned long long du; +typedef signed long long di; +typedef unsigned int su; +typedef signed int si; +typedef unsigned short hu; +typedef signed short hi; +typedef unsigned char qu; +typedef signed char qi; +typedef double df; +typedef float sf; + +/* To test whether we can optimize vector permutation away when + the two inputs are same type CTOR or one input is CTOR and the + other is CST. */ + +/* CTOR + CTOR part (only same type supported). */ + +/* Test both operands are same type CTOR (type unsigned long long). */ +__attribute__ ((noipa)) v2du +test_ctor_ctor_same_du (du a, du b) +{ + v2du v1 = {a, 0}; + v2du v2 = {b, 0}; + v16qu vc = {0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23}; + v2du vres = (v2du) vec_perm ((v16qu) v1, (v16qu) v2, vc); + return vres; +} + +/* Test both operands are same type CTOR (type double). */ +__attribute__ ((noipa)) v2df +test_ctor_ctor_same_df (df a, df b) +{ + v2df v1 = {0.0, a}; + v2df v2 = {0.0, b}; + v16qu vc = {8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, 31}; + v2df vres = (v2df) vec_perm ((v16qu) v1, (v16qu) v2, vc); + return vres; +} + +/* Test both operands are same type CTOR (type signed int). */ +__attribute__ ((noipa)) v4si +test_ctor_ctor_same_si (si a, si b, si c, si d) +{ + v4si v1 = {0, a, 0, c}; + v4si v2 = {0, b, 0, d}; + v16qu vc = {4, 5, 6, 7, 20, 21, 22, 23, 12, 13, 14, 15, 28, 29, 30, 31}; + v4si vres = (v4si) vec_perm ((v16qu) v1, (v16qu) v2, vc); + return vres; +} + +/* Test both operands are same type CTOR (type float). */ +__attribute__ ((noipa)) v4sf +test_ctor_ctor_same_sf (sf a, sf b, sf c, sf d) +{ + v4sf v1 = {c, 0.0f, d, 0.0f}; + v4sf v2 = {a, 0.0f, b, 0.0f}; + v16qu vc = {16, 17, 18, 19, 24, 25, 26, 27, 0, 1, 2, 3, 8, 9, 10, 11}; + v4sf vres = (v4sf) vec_perm ((v16qu) v1, (v16qu) v2, vc); + return vres; +} + +/* Test both operands are same type CTOR (type unsigned short). */ +__attribute__ ((noipa)) v8hu +test_ctor_ctor_same_hu (hu a, hu b, hu c, hu d, hu e, hu f, hu g, hu h) +{ + v8hu v1 = {0, a, 0, b, 0, c, 0, d}; + v8hu v2 = {0, e, 0, f, 0, g, 0, h}; + v16qu vc = {2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27, 30, 31}; + v8hu vres = (v8hu) vec_perm ((v16qu) v1, (v16qu) v2, vc); + return vres; +} + +/* Test both operands are same type CTOR (type signed char). */ +__attribute__ ((noipa)) v16qi +test_ctor_ctor_same_qi (qi a, qi b, qi c, qi d, qi e, qi f, qi g, qi h) +{ + v16qi v1 = {0, a, 0, b, 0, c, 0, d, 0, a, 0, b, 0, c, 0, d}; + v16qi v2 = {0, e, 0, f, 0, g, 0, h, 0, e, 0, f, 0, g, 0, h}; + v16qu vc = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31}; + v16qi vres = (v16qi) vec_perm ((v16qu) v1, (v16qu) v2, vc); + return vres; +} + +/* CTOR + CST part (same type). */ + +__attribute__ ((noipa)) v2du +test_ctor_cst_same_du (du a, du b) +{ + v2du v1 = {a, b}; + v2du v2 = {100, 200}; + v16qu vc = {0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23}; + v2du vres = (v2du) vec_perm ((v16qu) v1, (v16qu) v2, vc); + return vres; +} + +__attribute__ ((noipa)) v4sf +test_ctor_cst_same_sf (sf a, sf b) +{ + v4sf v1 = {0.0f, a, 0.0f, b}; + v4sf v2 = {1.0f, 2.0f, 3.0f, 4.0f}; + v16qu vc = {4, 5, 6, 7, 20, 21, 22, 23, 12, 13, 14, 15, 28, 29, 30, 31}; + v4sf vres = (v4sf) vec_perm ((v16qu) v1, (v16qu) v2, vc); + return vres; +} + +/* CST + CTOR part (same type). */ + +__attribute__ ((noipa)) v2df +test_ctor_cst_same_df (df a, df b) +{ + v2df v1 = {a, b}; + v2df v2 = {100.0, 200.0}; + v16qu vc = {8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, 31}; + v2df vres = (v2df) vec_perm ((v16qu) v1, (v16qu) v2, vc); + return vres; +} + +__attribute__ ((noipa)) v4si +test_cst_ctor_same_si (si a, si b) +{ + v4si v1 = {a, 0, b, 0}; + v4si v2 = {1, 2, 3, 4}; + v16qu vc = {16, 17, 18, 19, 24, 25, 26, 27, 0, 1, 2, 3, 8, 9, 10, 11}; + v4si vres = (v4si) vec_perm ((v16qu) v1, (v16qu) v2, vc); + return vres; +} + +/* CTOR + CST part (different types). */ + +__attribute__ ((noipa)) v2di +test_ctor_cst_diff_di_si (di a, di b) +{ + v2di v1 = {a, b}; + v4si v2 = {3, 0, 4, 0}; + v16qu vc = {0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23}; + v2di vres = (v2di) vec_perm ((v16qu) v1, (v16qu) v2, vc); + return vres; +} + +/* CST + CTOR part (different types). */ + +__attribute__ ((noipa)) v2du +test_cst_ctor_diff_sf_du (du a, du b) +{ + v4sf v1 = {1.0f, 2.0f, 3.0f, 4.0f}; + v2du v2 = {a, b}; + v16qu vc = {0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23}; + v2du vres = (v2du) vec_perm ((v16qu) v1, (v16qu) v2, vc); + return vres; +} diff --git a/gcc/testsuite/gfortran.dg/bounds_check_22.f90 b/gcc/testsuite/gfortran.dg/bounds_check_22.f90 new file mode 100644 index 0000000..a84e3dd --- /dev/null +++ b/gcc/testsuite/gfortran.dg/bounds_check_22.f90 @@ -0,0 +1,12 @@ +! { dg-do compile } +! { dg-options "-fcheck=bounds" } +! PR fortran/100656 - ICE in gfc_conv_expr_present + +subroutine s(x) + character(:), allocatable, optional :: x(:) + if ( present(x) ) then + if ( allocated(x) ) then + x = 'a' // x // 'e' + end if + end if +end diff --git a/gcc/testsuite/gfortran.dg/gomp/affinity-clause-1.f90 b/gcc/testsuite/gfortran.dg/gomp/affinity-clause-1.f90 new file mode 100644 index 0000000..13bdd36 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/affinity-clause-1.f90 @@ -0,0 +1,33 @@ +! { dg-additional-options "-fdump-tree-original" } +subroutine foo(x) + integer :: x + integer :: a, b(5), cc, d(5,5) + !$omp taskgroup + !$omp task affinity(a) + !$omp end task + !$omp task affinity(iterator(i=int(cos(1.0+a)):5, jj =2:5:2) : b(i), d(i,jj)) + !$omp end task + !$omp task affinity(iterator(i=int(cos(1.0+a)):5) : b(i), d(i,i)) + !$omp end task + !$omp task affinity (iterator(i=1:5): a) + !$omp end task + !$omp task affinity (iterator(i=1:5): a) affinity(iterator(i=1:5) : x) + !$omp end task + !$omp task affinity (iterator(integer(8) :: j=1:5, k=7:4:-1) : b(j+k),a) affinity (cc) + !$omp end task + !$omp end taskgroup +end + +! { dg-final { scan-tree-dump-times "#pragma omp task affinity\\(a\\)" 1 "original" } } + +! { dg-final { scan-tree-dump-times "D\\.\[0-9\]+ = .integer.kind=4.. __builtin_cosf ..real.kind=4.. a \\+ 1.0e\\+0\\);" 2 "original" } } + +! { dg-final { scan-tree-dump-times "#pragma omp task affinity\\(iterator\\(integer\\(kind=4\\) jj=2:5:2, integer\\(kind=4\\) i=D\\.\[0-9\]+:5:1\\):\\*\\(c_char \\*\\) &b\\\[.* <?i>? \\+ -1\\\]\\) affinity\\(iterator\\(integer\\(kind=4\\) jj=2:5:2, integer\\(kind=4\\) i=D\\.\[0-9\]+:5:1\\):\\*\\(c_char \\*\\) &d\\\[\\(.*jj \\* 5 \\+ .* <?i>?\\) \\+ -6\\\]\\)" 1 "original" } } + +! { dg final { scan-tree-dump-times "#pragma omp task affinity\\(iterator\\(integer\\(kind=4\\) i=D.3938:5:1\\):\\*\\(c_char \\*\\) &b\\\[\\(.* <?i>? \\+ -1\\\]\\) affinity\\(iterator\\(integer\\(kind=4\\) i=D\\.\[0-9\]+:5:1\\):\\*\\(c_char \\*\\) &d\\\[\\(\\(integer\\(kind=8\\)\\) i \\+ -1\\) \\* 6\\\]\\)" 1 "original" } } + +! { dg-final { scan-tree-dump-times "#pragma omp task affinity\\(iterator\\(integer\\(kind=4\\) i=1:5:1\\):a\\)\[^ \]" 1 "original" } } + +! { dg-final { scan-tree-dump-times "#pragma omp task affinity\\(iterator\\(integer\\(kind=4\\) i=1:5:1\\):a\\) affinity\\(iterator\\(integer\\(kind=4\\) i=1:5:1\\):\\*x\\)" 1 "original" } } + +! { dg-final { scan-tree-dump-times "#pragma omp task affinity\\(iterator\\(integer\\(kind=4\\) k=7:4:-1, integer\\(kind=8\\) j=1:5:1\\):\\*\\(c_char \\*\\) &b\\\[\\(?\\(integer\\(kind=.\\).* \[jk\] \\+ .*\[kj\]\\) \\+ -1\\\]\\) affinity\\(iterator\\(integer\\(kind=4\\) k=7:4:-1, integer\\(kind=8\\) j=1:5:1\\):a\\) affinity\\(cc\\)" 1 "original" } } diff --git a/gcc/testsuite/gfortran.dg/gomp/affinity-clause-2.f90 b/gcc/testsuite/gfortran.dg/gomp/affinity-clause-2.f90 new file mode 100644 index 0000000..54768a8 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/affinity-clause-2.f90 @@ -0,0 +1,27 @@ +subroutine foo + implicit none + external bar + integer :: i, b(10) + !$omp task affinity(bar(1)) ! { dg-error "not a variable" } + !!$omp end task + !$omp task affinity(b(1.0)) ! { dg-warning "Legacy Extension: REAL array index" } + !$omp end task + !$omp task affinity( iterator( real :: i=1.0:5:1) : b(i)) ! { dg-error "Expected INTEGER type" } + !!$omp end task + !$omp task affinity(iterator(i=1.0:5:1) : b(i)) ! { dg-error "Scalar integer expression for range begin expected" } + !$omp end task + !$omp task affinity(iterator(i=1:5.0:1) : b(i)) ! { dg-error "Scalar integer expression for range end expected" } + !$omp end task + !$omp task affinity(iterator(i=1:5:1.0) : b(i)) ! { dg-error "Scalar integer expression for range step expected" } + !$omp end task + !$omp task affinity(iterator(j=1:3:5, i=1:5:0) : b(i)) ! { dg-error "Nonzero range step expected" } + !$omp end task + !$omp task affinity(iterator(=1:5:0) : b(i)) ! { dg-error "31:Syntax error in OpenMP variable list" } + !!$omp end task + !$omp task affinity(iterator(b(2)=1:5:0) : b(i)) ! { dg-error "31:Syntax error in OpenMP variable list" } + !!$omp end task + !$omp task affinity(iterator(i=1:5:0, i=4:6) : b(i)) ! { dg-error "Same identifier 'i' specified again" } + !!$omp end task + !$omp task affinity(iterator(i=1) : b(i)) ! { dg-error "Expected range-specification" } + !!$omp end task +end diff --git a/gcc/testsuite/gfortran.dg/gomp/affinity-clause-3.f90 b/gcc/testsuite/gfortran.dg/gomp/affinity-clause-3.f90 new file mode 100644 index 0000000..3fd39fe --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/affinity-clause-3.f90 @@ -0,0 +1,14 @@ +! { dg-additional-options "-fdump-tree-gimple" } +subroutine foo + integer :: A(10), B(10), C(10) + interface + integer function ibar(x) + integer :: x + end function ibar + end interface + + !$omp task affinity (iterator(j=ibar(0):ibar(1):ibar(2)) : a(ibar(j)), b(j), c(j)) + !$omp end task +end +! { dg-final { scan-tree-dump-times "= ibar \\(&C\\." 3 "gimple" } } +! { dg-final { scan-tree-dump-times "= ibar \\(j\\." 1 "gimple" } } diff --git a/gcc/testsuite/gfortran.dg/gomp/affinity-clause-4.f90 b/gcc/testsuite/gfortran.dg/gomp/affinity-clause-4.f90 new file mode 100644 index 0000000..0d07efd --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/affinity-clause-4.f90 @@ -0,0 +1,16 @@ +subroutine foo + integer :: A(10), B(10), C(10) + interface + integer function ibar(x) + integer :: x + end function ibar + end interface + + !$omp parallel default(none) ! { dg-note "enclosing 'parallel'" } + !$omp task affinity (iterator(j=ibar(0):ibar(1):ibar(2)) : a(ibar(j)), b(j), c(j)) + !$omp end task + !$omp end parallel +! { dg-error "'a' not specified in enclosing 'parallel'" "" { target *-*-* } .-3 } +! { dg-error "'b' not specified in enclosing 'parallel'" "" { target *-*-* } .-4 } +! { dg-error "'c' not specified in enclosing 'parallel'" "" { target *-*-* } .-5 } +end diff --git a/gcc/testsuite/gfortran.dg/gomp/affinity-clause-5.f90 b/gcc/testsuite/gfortran.dg/gomp/affinity-clause-5.f90 new file mode 100644 index 0000000..538b5a5 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/affinity-clause-5.f90 @@ -0,0 +1,23 @@ +! { dg-additional-options "-fdump-tree-original" } +implicit none +integer :: iterator(10), i + +!$omp taskgroup + !$omp task affinity(iterator) + !$omp end task + + !$omp task affinity(iterator(3)) + !$omp end task + + !$omp task affinity(iterator(i=1:10) : iterator(i)) + !$omp end task + +!$omp end taskgroup + +end + +! { dg-final { scan-tree-dump-times "pragma omp task affinity\\(iterator\\)" 1 "original" } } + +! { dg-final { scan-tree-dump-times "#pragma omp task affinity\\(\\*\\(c_char \\*\\) &iterator\\\[2\\\]\\)" 1 "original" } } + +! { dg-final { scan-tree-dump-times "#pragma omp task affinity\\(iterator\\(integer\\(kind=4\\) i=1:10:1\\):\\*\\(c_char \\*\\) &iterator\\\[.* <?i>? \\+ -1\\\]\\)" 1 "original" } } diff --git a/gcc/testsuite/gfortran.dg/gomp/affinity-clause-6.f90 b/gcc/testsuite/gfortran.dg/gomp/affinity-clause-6.f90 new file mode 100644 index 0000000..90ec0ac --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/affinity-clause-6.f90 @@ -0,0 +1,24 @@ +implicit none +integer :: iterator(10), i + +!$omp taskgroup + !$omp task affinity(iterator) + !$omp end task + + !$omp task affinity(iterator(3)) + !$omp end task + + !$omp task affinity(iterator(i=1:10) : iterator(i)) + !$omp end task + + !$omp task affinity(iterator(integer :: i)) ! { dg-error "Failed to match clause at" } + !!$omp end task + + !$omp task affinity(iterator(integer :: i=1:1)) ! { dg-error "Expected ':' at" } + !!$omp end task + + !$omp task affinity(iterator(i=)) ! { dg-error "Expected range-specification at" } +! !$omp end task +!$omp end taskgroup + +end diff --git a/gcc/testsuite/gfortran.dg/gomp/depend-iterator-1.f90 b/gcc/testsuite/gfortran.dg/gomp/depend-iterator-1.f90 new file mode 100644 index 0000000..cad36aa --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/depend-iterator-1.f90 @@ -0,0 +1,45 @@ +! { dg-do run } + +module mymod + implicit none (type, external) + integer, target :: var(0:5) = [0,1,2,3,4,5] +end module mymod + +program main + use mymod + implicit none + + type t + integer :: x(0:64) + integer :: y + end type t + type(t) :: dep2(0:64) + integer :: dep1(0:64) + + integer arr(0:63) + !$omp parallel + !$omp master + block + integer :: i + do i = 0, 63 + !$omp task depend (iterator (j=i:i+1) , out : dep1 (j)) + arr(i) = i + !$omp end task + !$omp task depend (iterator (j=i:i+1) , out : dep2 (j)) + arr(i) = i + !$omp end task + !$omp task depend (iterator (j=i:i+1) , out : dep2 (j)%y) + arr(i) = i + !$omp end task + !$omp task depend (iterator (j=i:i+1) , out : dep2 (j)%x(j)) + arr(i) = i + !$omp end task + !$omp task depend (out : dep2 (:4)) + arr(i) = i + !$omp end task + !$omp taskwait depend(out: dep1(1)) + end do + end block + !$omp end master + !$omp end parallel +end diff --git a/gcc/testsuite/gfortran.dg/gomp/depend-iterator-2.f90 b/gcc/testsuite/gfortran.dg/gomp/depend-iterator-2.f90 new file mode 100644 index 0000000..fa826a7 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/depend-iterator-2.f90 @@ -0,0 +1,44 @@ +! { dg-do run } + +module mymod + implicit none (type, external) + integer, target :: var(0:5) = [0,1,2,3,4,5] +contains + function foo (i) + integer :: i + integer, pointer :: foo + foo => var(mod(i, 6)) + end +end module mymod + +program main + use mymod + implicit none + + type t + integer :: x(0:64) + integer :: y + end type t + type(t) :: dep2(0:64) + integer :: dep1(0:64) + + integer arr(0:63) + !$omp parallel + !$omp master + block + integer :: i + do i = 0, 63 + ! NB: Revoking foo (pointer returning function) as in 'foo(i)' is a variable in the Fortran sense + !$omp task depend (iterator (j=i:i+1) , out : foo (j)) ! { dg-error "is not a variable" } + arr(i) = i + !!$omp end task + !$omp task depend(iterator(i=1:5), source ) ! { dg-error "ITERATOR may not be combined with SOURCE" } + !!$omp end task + !$omp task affinity (iterator(i=1:5): a) depend(iterator(i=1:5), sink : x) ! { dg-error "ITERATOR may not be combined with SINK" } + !!$omp end task + + end do + end block + !$omp end master + !$omp end parallel +end diff --git a/gcc/testsuite/gfortran.dg/gomp/depend-iterator-3.f90 b/gcc/testsuite/gfortran.dg/gomp/depend-iterator-3.f90 new file mode 100644 index 0000000..85465ee --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/depend-iterator-3.f90 @@ -0,0 +1,27 @@ +subroutine foo + implicit none + external bar + integer :: i, b(10) + !$omp task depend(in : bar(1)) ! { dg-error "not a variable" } + !!$omp end task + !$omp task depend(out : b(1.0)) ! { dg-warning "Legacy Extension: REAL array index" } + !$omp end task + !$omp task depend( iterator( real :: i=1.0:5:1), in : b(i)) ! { dg-error "Expected INTEGER type" } + !!$omp end task + !$omp task depend(iterator(i=1.0:5:1), out : b(i)) ! { dg-error "Scalar integer expression for range begin expected" } + !$omp end task + !$omp task depend(iterator(i=1:5.0:1), in : b(i)) ! { dg-error "Scalar integer expression for range end expected" } + !$omp end task + !$omp task depend(iterator(i=1:5:1.0), in : b(i)) ! { dg-error "Scalar integer expression for range step expected" } + !$omp end task + !$omp task depend(iterator(j=1:3:5, i=1:5:0), out : b(i)) ! { dg-error "Nonzero range step expected" } + !$omp end task + !$omp task depend(iterator(=1:5:0), in : b(i)) ! { dg-error "Expected identifier" } + !!$omp end task + !$omp task depend(iterator(b(2)=1:5:1), in : b(i)) ! { dg-error "Failed to match clause" } + !!$omp end task + !$omp task depend(iterator(i=1:5:0, i=4:6), out: b(i)) ! { dg-error "Same identifier 'i' specified again" } + !!$omp end task + !$omp task depend(iterator(i=1) ,out: b(i)) ! { dg-error "Expected range-specification" } + !!$omp end task +end diff --git a/gcc/testsuite/gfortran.dg/gomp/taskwait.f90 b/gcc/testsuite/gfortran.dg/gomp/taskwait.f90 new file mode 100644 index 0000000..80ae24a --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/taskwait.f90 @@ -0,0 +1,7 @@ +! { dg-additional-options "-fdump-tree-original" } +!$omp taskwait +!$omp taskwait depend(out:foo) +end + +! { dg-final { scan-tree-dump-times "__builtin_GOMP_taskwait \\(\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp taskwait depend\\(out:foo\\)" 1 "original" } } diff --git a/gcc/testsuite/gfortran.dg/pointer_check_14.f90 b/gcc/testsuite/gfortran.dg/pointer_check_14.f90 new file mode 100644 index 0000000..8ef6b36 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pointer_check_14.f90 @@ -0,0 +1,28 @@ +! { dg-do run } +! { dg-options "-fcheck=pointer -fdump-tree-original" } +! PR100602 - Erroneous "pointer argument is not associated" runtime error + +module m + type :: T + end type +contains + subroutine f(this) + class(T), intent(in) :: this(:) + class(T), allocatable :: ca(:) + class(T), pointer :: cp(:) + if (size (this) == 0) return + write(*,*) size (this) + stop 1 + write(*,*) size (ca) ! Check #1 + write(*,*) size (cp) ! Check #2 + end subroutine f +end module + +program main + use m + call f([T::]) +end program + +! { dg-final { scan-tree-dump-times "_gfortran_runtime_error_at" 2 "original" } } +! { dg-final { scan-tree-dump-times "Allocatable argument .*ca" 1 "original" } } +! { dg-final { scan-tree-dump-times "Pointer argument .*cp" 1 "original" } } diff --git a/gcc/tree-core.h b/gcc/tree-core.h index 07ddf91..e15e6c6 100644 --- a/gcc/tree-core.h +++ b/gcc/tree-core.h @@ -277,6 +277,9 @@ enum omp_clause_code { /* OpenMP clause: linear (variable-list[:linear-step]). */ OMP_CLAUSE_LINEAR, + /* OpenMP clause: affinity([depend-modifier :] variable-list). */ + OMP_CLAUSE_AFFINITY, + /* OpenMP clause: aligned (variable-list[:alignment]). */ OMP_CLAUSE_ALIGNED, diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 1d13e7f..d38e861 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -2100,6 +2100,7 @@ copy_bb (copy_body_data *id, basic_block bb, GF_CALL_VA_ARG_PACK. */ gimple_call_copy_flags (new_call, call_stmt); gimple_call_set_va_arg_pack (new_call, false); + gimple_call_set_fntype (new_call, gimple_call_fntype (call_stmt)); /* location includes block. */ gimple_set_location (new_call, gimple_location (stmt)); gimple_call_set_lhs (new_call, gimple_call_lhs (call_stmt)); diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c index 0a575eb..d8a4f55 100644 --- a/gcc/tree-pretty-print.c +++ b/gcc/tree-pretty-print.c @@ -743,6 +743,22 @@ dump_omp_clause (pretty_printer *pp, tree clause, int spc, dump_flags_t flags) pp_right_paren (pp); break; + case OMP_CLAUSE_AFFINITY: + pp_string (pp, "affinity("); + { + tree t = OMP_CLAUSE_DECL (clause); + if (TREE_CODE (t) == TREE_LIST + && TREE_PURPOSE (t) + && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC) + { + dump_omp_iterators (pp, TREE_PURPOSE (t), spc, flags); + pp_colon (pp); + t = TREE_VALUE (t); + } + dump_generic_node (pp, t, spc, flags, false); + } + pp_right_paren (pp); + break; case OMP_CLAUSE_DEPEND: pp_string (pp, "depend("); switch (OMP_CLAUSE_DEPEND_KIND (clause)) @@ -803,8 +819,11 @@ dump_omp_clause (pretty_printer *pp, tree clause, int spc, dump_flags_t flags) pp_colon (pp); t = TREE_VALUE (t); } - pp_string (pp, name); - pp_colon (pp); + if (name[0]) + { + pp_string (pp, name); + pp_colon (pp); + } dump_generic_node (pp, t, spc, flags, false); pp_right_paren (pp); } diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c index 0706fd8..beb2702 100644 --- a/gcc/tree-ssa-forwprop.c +++ b/gcc/tree-ssa-forwprop.c @@ -2120,9 +2120,9 @@ static int simplify_permutation (gimple_stmt_iterator *gsi) { gimple *stmt = gsi_stmt (*gsi); - gimple *def_stmt; + gimple *def_stmt = NULL; tree op0, op1, op2, op3, arg0, arg1; - enum tree_code code; + enum tree_code code, code2 = ERROR_MARK; bool single_use_op0 = false; gcc_checking_assert (gimple_assign_rhs_code (stmt) == VEC_PERM_EXPR); @@ -2142,10 +2142,28 @@ simplify_permutation (gimple_stmt_iterator *gsi) else if (TREE_CODE (op0) == SSA_NAME) { def_stmt = get_prop_source_stmt (op0, false, &single_use_op0); - if (!def_stmt || !can_propagate_from (def_stmt)) + if (!def_stmt) return 0; - code = gimple_assign_rhs_code (def_stmt); + if (code == VIEW_CONVERT_EXPR) + { + tree rhs = gimple_assign_rhs1 (def_stmt); + tree name = TREE_OPERAND (rhs, 0); + if (TREE_CODE (name) != SSA_NAME) + return 0; + if (!has_single_use (name)) + single_use_op0 = false; + /* Here we update the def_stmt through this VIEW_CONVERT_EXPR, + but still keep the code to indicate it comes from + VIEW_CONVERT_EXPR. */ + def_stmt = SSA_NAME_DEF_STMT (name); + if (!def_stmt || !is_gimple_assign (def_stmt)) + return 0; + if (gimple_assign_rhs_code (def_stmt) != CONSTRUCTOR) + return 0; + } + if (!can_propagate_from (def_stmt)) + return 0; arg0 = gimple_assign_rhs1 (def_stmt); } else @@ -2173,12 +2191,10 @@ simplify_permutation (gimple_stmt_iterator *gsi) update_stmt (stmt); return remove_prop_source_from_use (op0) ? 2 : 1; } - - /* Shuffle of a constructor. */ - else if (code == CONSTRUCTOR || code == VECTOR_CST) + else if (code == CONSTRUCTOR + || code == VECTOR_CST + || code == VIEW_CONVERT_EXPR) { - tree opt; - bool ret = false; if (op0 != op1) { if (TREE_CODE (op0) == SSA_NAME && !single_use_op0) @@ -2188,14 +2204,27 @@ simplify_permutation (gimple_stmt_iterator *gsi) arg1 = op1; else if (TREE_CODE (op1) == SSA_NAME) { - enum tree_code code2; - gimple *def_stmt2 = get_prop_source_stmt (op1, true, NULL); - if (!def_stmt2 || !can_propagate_from (def_stmt2)) + if (!def_stmt2) return 0; - code2 = gimple_assign_rhs_code (def_stmt2); - if (code2 != CONSTRUCTOR && code2 != VECTOR_CST) + if (code2 == VIEW_CONVERT_EXPR) + { + tree rhs = gimple_assign_rhs1 (def_stmt2); + tree name = TREE_OPERAND (rhs, 0); + if (TREE_CODE (name) != SSA_NAME) + return 0; + if (!has_single_use (name)) + return 0; + def_stmt2 = SSA_NAME_DEF_STMT (name); + if (!def_stmt2 || !is_gimple_assign (def_stmt2)) + return 0; + if (gimple_assign_rhs_code (def_stmt2) != CONSTRUCTOR) + return 0; + } + else if (code2 != CONSTRUCTOR && code2 != VECTOR_CST) + return 0; + if (!can_propagate_from (def_stmt2)) return 0; arg1 = gimple_assign_rhs1 (def_stmt2); } @@ -2209,10 +2238,92 @@ simplify_permutation (gimple_stmt_iterator *gsi) return 0; arg1 = arg0; } - opt = fold_ternary (VEC_PERM_EXPR, TREE_TYPE (op0), arg0, arg1, op2); + + /* If there are any VIEW_CONVERT_EXPRs found when finding permutation + operands source, check whether it's valid to transform and prepare + the required new operands. */ + if (code == VIEW_CONVERT_EXPR || code2 == VIEW_CONVERT_EXPR) + { + /* Figure out the target vector type to which operands should be + converted. If both are CONSTRUCTOR, the types should be the + same, otherwise, use the one of CONSTRUCTOR. */ + tree tgt_type = NULL_TREE; + if (code == VIEW_CONVERT_EXPR) + { + gcc_assert (gimple_assign_rhs_code (def_stmt) == CONSTRUCTOR); + code = CONSTRUCTOR; + tgt_type = TREE_TYPE (arg0); + } + if (code2 == VIEW_CONVERT_EXPR) + { + tree arg1_type = TREE_TYPE (arg1); + if (tgt_type == NULL_TREE) + tgt_type = arg1_type; + else if (tgt_type != arg1_type) + return 0; + } + + if (!VECTOR_TYPE_P (tgt_type)) + return 0; + tree op2_type = TREE_TYPE (op2); + /* Should have folded this before. */ + gcc_assert (op2_type != tgt_type); + + /* Figure out the shrunk factor. */ + poly_uint64 tgt_units = TYPE_VECTOR_SUBPARTS (tgt_type); + poly_uint64 op2_units = TYPE_VECTOR_SUBPARTS (op2_type); + if (maybe_gt (tgt_units, op2_units)) + return 0; + unsigned int factor; + if (!constant_multiple_p (op2_units, tgt_units, &factor)) + return 0; + + /* Build the new permutation control vector as target vector. */ + vec_perm_builder builder; + if (!tree_to_vec_perm_builder (&builder, op2)) + return 0; + vec_perm_indices indices (builder, 2, op2_units); + vec_perm_indices new_indices; + if (new_indices.new_shrunk_vector (indices, factor)) + { + tree mask_type = tgt_type; + if (!VECTOR_INTEGER_TYPE_P (mask_type)) + { + tree elem_type = TREE_TYPE (mask_type); + unsigned elem_size = TREE_INT_CST_LOW (TYPE_SIZE (elem_type)); + tree int_type = build_nonstandard_integer_type (elem_size, 0); + mask_type = build_vector_type (int_type, tgt_units); + } + op2 = vec_perm_indices_to_tree (mask_type, new_indices); + } + else + return 0; + + /* Convert the VECTOR_CST to the appropriate vector type. */ + if (tgt_type != TREE_TYPE (arg0)) + arg0 = fold_build1 (VIEW_CONVERT_EXPR, tgt_type, arg0); + else if (tgt_type != TREE_TYPE (arg1)) + arg1 = fold_build1 (VIEW_CONVERT_EXPR, tgt_type, arg1); + } + + /* VIEW_CONVERT_EXPR should be updated to CONSTRUCTOR before. */ + gcc_assert (code == CONSTRUCTOR || code == VECTOR_CST); + + /* Shuffle of a constructor. */ + bool ret = false; + tree res_type = TREE_TYPE (arg0); + tree opt = fold_ternary (VEC_PERM_EXPR, res_type, arg0, arg1, op2); if (!opt || (TREE_CODE (opt) != CONSTRUCTOR && TREE_CODE (opt) != VECTOR_CST)) return 0; + /* Found VIEW_CONVERT_EXPR before, need one explicit conversion. */ + if (res_type != TREE_TYPE (op0)) + { + tree name = make_ssa_name (TREE_TYPE (opt)); + gimple *ass_stmt = gimple_build_assign (name, opt); + gsi_insert_before (gsi, ass_stmt, GSI_SAME_STMT); + opt = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (op0), name); + } gimple_assign_set_rhs_from_tree (gsi, opt); update_stmt (gsi_stmt (*gsi)); if (TREE_CODE (op0) == SSA_NAME) diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c index 5329c0a..2165ad7 100644 --- a/gcc/tree-ssanames.c +++ b/gcc/tree-ssanames.c @@ -423,31 +423,6 @@ set_range_info (tree name, const value_range &vr) set_range_info (name, vr.kind (), min, max); } -/* Gets range information corresponding to ssa_name NAME and stores it - in a value_range VR. Returns the value_range_kind. */ - -enum value_range_kind -get_range_info (const_tree name, irange &vr) -{ - tree type = TREE_TYPE (name); - gcc_checking_assert (!POINTER_TYPE_P (type)); - gcc_checking_assert (TREE_CODE (name) == SSA_NAME); - - range_info_def *ri = SSA_NAME_RANGE_INFO (name); - - /* Return VR_VARYING for SSA_NAMEs with NULL RANGE_INFO or SSA_NAMEs - with integral types width > 2 * HOST_BITS_PER_WIDE_INT precision. */ - if (!ri || (GET_MODE_PRECISION (SCALAR_INT_TYPE_MODE (TREE_TYPE (name))) - > 2 * HOST_BITS_PER_WIDE_INT)) - vr.set_varying (type); - else - vr.set (wide_int_to_tree (type, ri->get_min ()), - wide_int_to_tree (type, ri->get_max ()), - SSA_NAME_RANGE_TYPE (name)); - - return vr.kind (); -} - /* Set nonnull attribute to pointer NAME. */ void @@ -458,25 +433,6 @@ set_ptr_nonnull (tree name) pi->pt.null = 0; } -/* Return nonnull attribute of pointer NAME. */ -bool -get_ptr_nonnull (const_tree name) -{ - gcc_assert (POINTER_TYPE_P (TREE_TYPE (name))); - struct ptr_info_def *pi = SSA_NAME_PTR_INFO (name); - if (pi == NULL) - return false; - /* TODO Now pt->null is conservatively set to true in PTA - analysis. vrp is the only pass (including ipa-vrp) - that clears pt.null via set_ptr_nonull when it knows - for sure. PTA will preserves the pt.null value set by VRP. - - When PTA analysis is improved, pt.anything, pt.nonlocal - and pt.escaped may also has to be considered before - deciding that pointer cannot point to NULL. */ - return !pi->pt.null; -} - /* Change non-zero bits bitmask of NAME. */ void diff --git a/gcc/tree-ssanames.h b/gcc/tree-ssanames.h index 166f921..ac880f3 100644 --- a/gcc/tree-ssanames.h +++ b/gcc/tree-ssanames.h @@ -70,8 +70,6 @@ struct GTY ((variable_size)) range_info_def { extern void set_range_info (tree, enum value_range_kind, const wide_int_ref &, const wide_int_ref &); extern void set_range_info (tree, const value_range &); -/* Gets the value range from SSA. */ -extern enum value_range_kind get_range_info (const_tree, irange &); extern void set_nonzero_bits (tree, const wide_int_ref &); extern wide_int get_nonzero_bits (const_tree); extern bool ssa_name_has_boolean_range (tree); @@ -90,7 +88,6 @@ extern void set_ptr_info_alignment (struct ptr_info_def *, unsigned int, extern void adjust_ptr_info_misalignment (struct ptr_info_def *, poly_uint64); extern struct ptr_info_def *get_ptr_info (tree); extern void set_ptr_nonnull (tree); -extern bool get_ptr_nonnull (const_tree); extern tree copy_ssa_name_fn (struct function *, tree, gimple *); extern void duplicate_ssa_name_ptr_info (tree, struct ptr_info_def *); @@ -289,6 +289,7 @@ unsigned const char omp_clause_num_ops[] = 1, /* OMP_CLAUSE_COPYIN */ 1, /* OMP_CLAUSE_COPYPRIVATE */ 3, /* OMP_CLAUSE_LINEAR */ + 1, /* OMP_CLAUSE_AFFINITY */ 2, /* OMP_CLAUSE_ALIGNED */ 2, /* OMP_CLAUSE_ALLOCATE */ 1, /* OMP_CLAUSE_DEPEND */ @@ -375,6 +376,7 @@ const char * const omp_clause_code_name[] = "copyin", "copyprivate", "linear", + "affinity", "aligned", "allocate", "depend", @@ -11091,6 +11093,7 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data, WALK_SUBTREE (OMP_CLAUSE_OPERAND (*tp, 1)); /* FALLTHRU */ + case OMP_CLAUSE_AFFINITY: case OMP_CLAUSE_ASYNC: case OMP_CLAUSE_WAIT: case OMP_CLAUSE_WORKER: @@ -1654,6 +1654,11 @@ class auto_suppress_location_wrappers variable. */ #define OMP_CLAUSE_MAP_IN_REDUCTION(NODE) \ TREE_PRIVATE (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_MAP)) +/* Nonzero on map clauses added implicitly for reduction clauses on combined + or composite constructs. They shall be removed if there is an explicit + map clause. */ +#define OMP_CLAUSE_MAP_IMPLICIT(NODE) \ + (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_MAP)->base.default_def_flag) /* True on an OMP_CLAUSE_USE_DEVICE_PTR with an OpenACC 'if_present' clause. */ diff --git a/gcc/value-query.cc b/gcc/value-query.cc index 509d2d3..f8b457d 100644 --- a/gcc/value-query.cc +++ b/gcc/value-query.cc @@ -31,6 +31,7 @@ along with GCC; see the file COPYING3. If not see #include "value-range-equiv.h" #include "value-query.h" #include "alloc-pool.h" +#include "gimple-range.h" // value_query default methods. @@ -180,3 +181,149 @@ range_query::~range_query () equiv_alloc->release (); delete equiv_alloc; } + +// Return the range for NAME from SSA_NAME_RANGE_INFO. + +static inline void +get_ssa_name_range_info (irange &r, const_tree name) +{ + tree type = TREE_TYPE (name); + gcc_checking_assert (!POINTER_TYPE_P (type)); + gcc_checking_assert (TREE_CODE (name) == SSA_NAME); + + range_info_def *ri = SSA_NAME_RANGE_INFO (name); + + // Return VR_VARYING for SSA_NAMEs with NULL RANGE_INFO or SSA_NAMEs + // with integral types width > 2 * HOST_BITS_PER_WIDE_INT precision. + if (!ri || (GET_MODE_PRECISION (SCALAR_INT_TYPE_MODE (TREE_TYPE (name))) + > 2 * HOST_BITS_PER_WIDE_INT)) + r.set_varying (type); + else + r.set (wide_int_to_tree (type, ri->get_min ()), + wide_int_to_tree (type, ri->get_max ()), + SSA_NAME_RANGE_TYPE (name)); +} + +// Return nonnull attribute of pointer NAME from SSA_NAME_PTR_INFO. + +static inline bool +get_ssa_name_ptr_info_nonnull (const_tree name) +{ + gcc_assert (POINTER_TYPE_P (TREE_TYPE (name))); + struct ptr_info_def *pi = SSA_NAME_PTR_INFO (name); + if (pi == NULL) + return false; + /* TODO Now pt->null is conservatively set to true in PTA + analysis. vrp is the only pass (including ipa-vrp) + that clears pt.null via set_ptr_nonull when it knows + for sure. PTA will preserves the pt.null value set by VRP. + + When PTA analysis is improved, pt.anything, pt.nonlocal + and pt.escaped may also has to be considered before + deciding that pointer cannot point to NULL. */ + return !pi->pt.null; +} + +// Return the legacy global range for NAME if it has one, otherwise +// return VARYING. + +static void +get_range_global (irange &r, tree name) +{ + tree type = TREE_TYPE (name); + + if (SSA_NAME_IS_DEFAULT_DEF (name)) + { + tree sym = SSA_NAME_VAR (name); + // Adapted from vr_values::get_lattice_entry(). + // Use a range from an SSA_NAME's available range. + if (TREE_CODE (sym) == PARM_DECL) + { + // Try to use the "nonnull" attribute to create ~[0, 0] + // anti-ranges for pointers. Note that this is only valid with + // default definitions of PARM_DECLs. + if (POINTER_TYPE_P (type) + && ((cfun && nonnull_arg_p (sym)) + || get_ssa_name_ptr_info_nonnull (name))) + r.set_nonzero (type); + else if (INTEGRAL_TYPE_P (type)) + { + get_ssa_name_range_info (r, name); + if (r.undefined_p ()) + r.set_varying (type); + } + else + r.set_varying (type); + } + // If this is a local automatic with no definition, use undefined. + else if (TREE_CODE (sym) != RESULT_DECL) + r.set_undefined (); + else + r.set_varying (type); + } + else if (!POINTER_TYPE_P (type) && SSA_NAME_RANGE_INFO (name)) + { + get_ssa_name_range_info (r, name); + if (r.undefined_p ()) + r.set_varying (type); + } + else if (POINTER_TYPE_P (type) && SSA_NAME_PTR_INFO (name)) + { + if (get_ssa_name_ptr_info_nonnull (name)) + r.set_nonzero (type); + else + r.set_varying (type); + } + else + r.set_varying (type); +} + +// ?? Like above, but only for default definitions of NAME. This is +// so VRP passes using ranger do not start with known ranges, +// otherwise we'd eliminate builtin_unreachables too early because of +// inlining. +// +// Without this restriction, the test in g++.dg/tree-ssa/pr61034.C has +// all of its unreachable calls removed too early. We should +// investigate whether we should just adjust the test above. + +value_range +gimple_range_global (tree name) +{ + gcc_checking_assert (gimple_range_ssa_p (name)); + tree type = TREE_TYPE (name); + + if (SSA_NAME_IS_DEFAULT_DEF (name)) + { + value_range vr; + get_range_global (vr, name); + return vr; + } + return value_range (type); +} + +// ---------------------------------------------- +// global_range_query implementation. + +global_range_query global_ranges; + +// Like get_range_query, but for accessing global ranges. + +range_query * +get_global_range_query () +{ + return &global_ranges; +} + +bool +global_range_query::range_of_expr (irange &r, tree expr, gimple *) +{ + tree type = TREE_TYPE (expr); + + if (!irange::supports_type_p (type) || !gimple_range_ssa_p (expr)) + return get_tree_range (r, expr); + + get_range_global (r, expr); + + return true; +} diff --git a/gcc/value-query.h b/gcc/value-query.h index 5eff931..97da663 100644 --- a/gcc/value-query.h +++ b/gcc/value-query.h @@ -105,4 +105,15 @@ private: class equiv_allocator *equiv_alloc; }; +// Global ranges for SSA names using SSA_NAME_RANGE_INFO. + +class global_range_query : public range_query +{ +public: + bool range_of_expr (irange &r, tree expr, gimple * = NULL) OVERRIDE; +}; + +extern global_range_query global_ranges; +extern value_range gimple_range_global (tree name); + #endif // GCC_QUERY_H diff --git a/gcc/vec-perm-indices.c b/gcc/vec-perm-indices.c index ede590d..31b32ea 100644 --- a/gcc/vec-perm-indices.c +++ b/gcc/vec-perm-indices.c @@ -101,6 +101,65 @@ vec_perm_indices::new_expanded_vector (const vec_perm_indices &orig, m_encoding.finalize (); } +/* Check whether we can switch to a new permutation vector that + selects the same input elements as ORIG, but with each element + built up from FACTOR pieces. Return true if yes, otherwise + return false. Every FACTOR permutation indexes should be + continuous separately and the first one of each batch should + be able to exactly modulo FACTOR. For example, if ORIG is + { 2, 3, 4, 5, 0, 1, 6, 7 } and FACTOR is 2, the new permutation + is { 1, 2, 0, 3 }. */ + +bool +vec_perm_indices::new_shrunk_vector (const vec_perm_indices &orig, + unsigned int factor) +{ + gcc_assert (factor > 0); + + if (maybe_lt (orig.m_nelts_per_input, factor)) + return false; + + poly_uint64 nelts; + /* Invalid if vector units number isn't multiple of factor. */ + if (!multiple_p (orig.m_nelts_per_input, factor, &nelts)) + return false; + + /* Only handle the case that npatterns is multiple of factor. + FIXME: Try to see whether we can reshape it by factor npatterns. */ + if (orig.m_encoding.npatterns () % factor != 0) + return false; + + unsigned int encoded_nelts = orig.m_encoding.encoded_nelts (); + auto_vec<element_type, 32> encoding (encoded_nelts); + /* Separate all encoded elements into batches by size factor, + then ensure the first element of each batch is multiple of + factor and all elements in each batch is consecutive from + the first one. */ + for (unsigned int i = 0; i < encoded_nelts; i += factor) + { + element_type first = orig.m_encoding[i]; + element_type new_index; + if (!multiple_p (first, factor, &new_index)) + return false; + for (unsigned int j = 1; j < factor; ++j) + if (maybe_ne (first + j, orig.m_encoding[i + j])) + return false; + encoding.quick_push (new_index); + } + + m_ninputs = orig.m_ninputs; + m_nelts_per_input = nelts; + poly_uint64 full_nelts = exact_div (orig.m_encoding.full_nelts (), factor); + unsigned int npatterns = orig.m_encoding.npatterns () / factor; + + m_encoding.new_vector (full_nelts, npatterns, + orig.m_encoding.nelts_per_pattern ()); + m_encoding.splice (encoding); + m_encoding.finalize (); + + return true; +} + /* Rotate the inputs of the permutation right by DELTA inputs. This changes the values of the permutation vector but it doesn't change the way that the elements are encoded. */ diff --git a/gcc/vec-perm-indices.h b/gcc/vec-perm-indices.h index bc70ecd..98d27f0 100644 --- a/gcc/vec-perm-indices.h +++ b/gcc/vec-perm-indices.h @@ -57,6 +57,7 @@ public: void new_vector (const vec_perm_builder &, unsigned int, poly_uint64); void new_expanded_vector (const vec_perm_indices &, unsigned int); + bool new_shrunk_vector (const vec_perm_indices &, unsigned int); void rotate_inputs (int delta); /* Return the underlying vector encoding. */ diff --git a/gcc/vr-values.c b/gcc/vr-values.c index d283108..3d0be8e 100644 --- a/gcc/vr-values.c +++ b/gcc/vr-values.c @@ -3837,7 +3837,7 @@ simplify_conversion_using_ranges (gimple_stmt_iterator *gsi, gimple *stmt) value_range vr; if (!INTEGRAL_TYPE_P (TREE_TYPE (innerop))) return false; - get_global_range_query ()->range_of_expr (vr, innerop, stmt); + get_range_query (cfun)->range_of_expr (vr, innerop, stmt); if (vr.undefined_p () || vr.varying_p ()) return false; innermin = widest_int::from (vr.lower_bound (), TYPE_SIGN (TREE_TYPE (innerop))); diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog index 67bf1f0..5f6adc5 100644 --- a/libgomp/ChangeLog +++ b/libgomp/ChangeLog @@ -1,3 +1,43 @@ +2021-05-27 Jakub Jelinek <jakub@redhat.com> + + * testsuite/lib/libgomp.exp (check_effective_target_openacc_cuda, + check_effective_target_openacc_cublas, + check_effective_target_openacc_cudart): New. + * testsuite/libgomp.oacc-fortran/host_data-4.f90: Require effective + target openacc_cublas. + * testsuite/libgomp.oacc-fortran/host_data-2.f90: Likewise. + * testsuite/libgomp.oacc-fortran/host_data-3.f: Likewise. + * testsuite/libgomp.oacc-c-c++-common/lib-91.c: Require effective + target openacc_cuda. + * testsuite/libgomp.oacc-c-c++-common/lib-70.c: Likewise. + * testsuite/libgomp.oacc-c-c++-common/lib-90.c: Likewise. + * testsuite/libgomp.oacc-c-c++-common/lib-75.c: Likewise. + * testsuite/libgomp.oacc-c-c++-common/lib-69.c: Likewise. + * testsuite/libgomp.oacc-c-c++-common/lib-74.c: Likewise. + * testsuite/libgomp.oacc-c-c++-common/lib-81.c: Likewise. + * testsuite/libgomp.oacc-c-c++-common/lib-72.c: Likewise. + * testsuite/libgomp.oacc-c-c++-common/lib-85.c: Likewise. + * testsuite/libgomp.oacc-c-c++-common/pr87835.c: Likewise. + * testsuite/libgomp.oacc-c-c++-common/lib-82.c: Likewise. + * testsuite/libgomp.oacc-c-c++-common/lib-73.c: Likewise. + * testsuite/libgomp.oacc-c-c++-common/lib-83.c: Likewise. + * testsuite/libgomp.oacc-c-c++-common/lib-78.c: Likewise. + * testsuite/libgomp.oacc-c-c++-common/lib-76.c: Likewise. + * testsuite/libgomp.oacc-c-c++-common/lib-84.c: Likewise. + * testsuite/libgomp.oacc-c-c++-common/lib-79.c: Likewise. + * testsuite/libgomp.oacc-c-c++-common/host_data-1.c: Require effective + targets openacc_cublas and openacc_cudart. + * testsuite/libgomp.oacc-c-c++-common/context-1.c: Likewise. + * testsuite/libgomp.oacc-c-c++-common/context-2.c: Likewise. + * testsuite/libgomp.oacc-c-c++-common/context-3.c: Likewise. + * testsuite/libgomp.oacc-c-c++-common/context-4.c: Likewise. + * testsuite/libgomp.oacc-c-c++-common/acc_get_property-nvptx.c: + Require effective target openacc_cudart. + * testsuite/libgomp.oacc-c-c++-common/asyncwait-1.c: Add -DUSE_CUDA_H + for effective target openacc_cuda and add && defined USE_CUDA_H to + preprocessor conditionals. Guard -lcuda also on openacc_cuda + effective target. + 2021-05-26 Jakub Jelinek <jakub@redhat.com> PR libgomp/100573 diff --git a/libgomp/testsuite/lib/libgomp.exp b/libgomp/testsuite/lib/libgomp.exp index 089c2bb..0f4eb6f 100644 --- a/libgomp/testsuite/lib/libgomp.exp +++ b/libgomp/testsuite/lib/libgomp.exp @@ -479,3 +479,56 @@ proc check_effective_target_openacc_radeon_accel_selected { } { return 0; } +# Return 1 if cuda.h and -lcuda are available. + +proc check_effective_target_openacc_cuda { } { + return [check_no_compiler_messages openacc_cuda executable { +#include <cuda.h> +int main() { + CUdevice dev; + CUresult r = cuDeviceGet (&dev, 0); + if (r != CUDA_SUCCESS) + return 1; + return 0; +} } "-lcuda" ] +} + +# Return 1 if cublas_v2.h and -lcublas are available. + +proc check_effective_target_openacc_cublas { } { + return [check_no_compiler_messages openacc_cublas executable { +#include <cuda.h> +#include <cublas_v2.h> +int main() { + cublasStatus_t s; + cublasHandle_t h; + CUdevice dev; + CUresult r = cuDeviceGet (&dev, 0); + if (r != CUDA_SUCCESS) + return 1; + s = cublasCreate (&h); + if (s != CUBLAS_STATUS_SUCCESS) + return 1; + return 0; +} } "-lcuda -lcublas" ] +} + +# Return 1 if cuda_runtime_api.h and -lcudart are available. + +proc check_effective_target_openacc_cudart { } { + return [check_no_compiler_messages openacc_cudart executable { +#include <cuda.h> +#include <cuda_runtime_api.h> +int main() { + cudaError_t e; + int devn; + CUdevice dev; + CUresult r = cuDeviceGet (&dev, 0); + if (r != CUDA_SUCCESS) + return 1; + e = cudaGetDevice (&devn); + if (e != cudaSuccess) + return 1; + return 0; +} } "-lcuda -lcudart" ] +} diff --git a/libgomp/testsuite/libgomp.fortran/depend-iterator-2.f90 b/libgomp/testsuite/libgomp.fortran/depend-iterator-2.f90 new file mode 100644 index 0000000..05090d3 --- /dev/null +++ b/libgomp/testsuite/libgomp.fortran/depend-iterator-2.f90 @@ -0,0 +1,89 @@ +module m + implicit none (type, external) + integer, volatile :: v +contains +subroutine foo (p, i) + integer :: p(0:*) + integer :: i + !$omp task depend (out: p(0)) + v = v + 1 + !$omp end task + !$omp task depend (in: p(0)) + v = v + 1 + !$omp end task + !$omp task depend (inout: p(0)) + v = v + 1 + !$omp end task + !$omp task depend (mutexinoutset: p(0)) + v = v + 1 + !$omp end task + !$omp task depend (out: p(0)) depend (in: p(1)) + v = v + 1 + !$omp end task + !$omp task depend (in: p(0)) depend (inout: p(1)) + v = v + 1 + !$omp end task + !$omp task depend (inout: p(0)) depend (mutexinoutset: p(1)) + v = v + 1 + !$omp end task + !$omp task depend (mutexinoutset: p(0)) depend (out: p(1)) + v = v + 1 + !$omp end task + !$omp task depend (iterator (j=0:2) , out : p(j)) + v = v + 1 + !$omp end task + !$omp task depend (iterator (j=0:2) , in : p(j)) + v = v + 1 + !$omp end task + !$omp task depend (iterator (j=0:2) , inout : p(j)) + v = v + 1 + !$omp end task + !$omp task depend (iterator (j=0:2) , mutexinoutset : p(j)) + v = v + 1 + !$omp end task + !$omp task depend (iterator (j=0:2) , out : p(j)) depend (iterator (j=0:2) , in : p(j + 2)) + v = v + 1 + !$omp end task + !$omp task depend (iterator (j=0:2) , in : p(j)) depend (iterator (j=0:2) , inout : p(j + 2)) + v = v + 1 + !$omp end task + !$omp task depend (iterator (j=0:2) , inout : p(j)) depend (iterator (j=0:2) , mutexinoutset : p(j + 2)) + v = v + 1 + !$omp end task + !$omp task depend (iterator (j=0:2) , mutexinoutset : p(j)) depend (iterator (j=0:2) , out : p(j + 2)) + v = v + 1 + !$omp end task + !$omp task depend (iterator (j=0:i) , out : p(j)) + v = v + 1 + !$omp end task + !$omp task depend (iterator (j=0:i) , in : p(j)) + v = v + 1 + !$omp end task + !$omp task depend (iterator (j=0:i) , inout : p(j)) + v = v + 1 + !$omp end task + !$omp task depend (iterator (j=0:i) , mutexinoutset : p(j)) + v = v + 1 + !$omp end task + !$omp task depend (iterator (j=0:i) , out : p(j)) depend (iterator (j=0:i) , in : p(j + 2)) + v = v + 1 + !$omp end task + !$omp task depend (iterator (j=0:i) , in : p(j)) depend (iterator (j=0:i) , inout : p(j + 2)) + v = v + 1 + !$omp end task + !$omp task depend (iterator (j=0:i) , inout : p(j)) depend (iterator (j=0:i) , mutexinoutset : p(j + 2)) + v = v + 1 + !$omp end task + !$omp task depend (iterator (j=0:i) , mutexinoutset : p(j)) depend (iterator (j=0:i) , out : p(j + 2)) + v = v + 1 + !$omp end task +end +end module + +program main + use m + implicit none (external, type) + integer p(4) + call foo (p, 2) + call foo (p, -1) +end diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_get_property-nvptx.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_get_property-nvptx.c index 6334cfd..8223901 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_get_property-nvptx.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_get_property-nvptx.c @@ -4,6 +4,7 @@ /* { dg-additional-sources acc_get_property-aux.c } */ /* { dg-additional-options "-lcuda -lcudart" } */ /* { dg-do run { target openacc_nvidia_accel_selected } } */ +/* { dg-require-effective-target openacc_cudart } */ #include <openacc.h> #include <cuda.h> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/asyncwait-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/asyncwait-1.c index e780845..e91642c 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/asyncwait-1.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/asyncwait-1.c @@ -1,9 +1,10 @@ /* { dg-do run } */ -/* { dg-additional-options "-lcuda" { target openacc_nvidia_accel_selected } } */ +/* { dg-additional-options "-DUSE_CUDA_H" { target openacc_cuda } } */ +/* { dg-additional-options "-lcuda" { target { openacc_nvidia_accel_selected && openacc_cuda } } } */ #include <openacc.h> #include <stdlib.h> -#if defined ACC_DEVICE_TYPE_nvidia +#if defined ACC_DEVICE_TYPE_nvidia && defined USE_CUDA_H #include "cuda.h" #endif @@ -13,7 +14,7 @@ int main (int argc, char **argv) { -#if defined ACC_DEVICE_TYPE_nvidia +#if defined ACC_DEVICE_TYPE_nvidia && defined USE_CUDA_H CUresult r; CUstream stream1; #endif @@ -22,7 +23,7 @@ main (int argc, char **argv) int i; int nbytes; -#if defined ACC_DEVICE_TYPE_nvidia +#if defined ACC_DEVICE_TYPE_nvidia && defined USE_CUDA_H acc_init (acc_device_nvidia); #endif @@ -216,7 +217,7 @@ main (int argc, char **argv) } -#if defined ACC_DEVICE_TYPE_nvidia +#if defined ACC_DEVICE_TYPE_nvidia && defined USE_CUDA_H r = cuStreamCreate (&stream1, CU_STREAM_NON_BLOCKING); if (r != CUDA_SUCCESS) { @@ -650,7 +651,7 @@ main (int argc, char **argv) } -#if defined ACC_DEVICE_TYPE_nvidia +#if defined ACC_DEVICE_TYPE_nvidia && defined USE_CUDA_H r = cuStreamCreate (&stream1, CU_STREAM_NON_BLOCKING); if (r != CUDA_SUCCESS) { @@ -902,7 +903,7 @@ main (int argc, char **argv) abort (); } -#if defined ACC_DEVICE_TYPE_nvidia +#if defined ACC_DEVICE_TYPE_nvidia && defined USE_CUDA_H acc_shutdown (acc_device_nvidia); #endif diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/context-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/context-1.c index 2e3b62e..3479fc7 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/context-1.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/context-1.c @@ -1,5 +1,7 @@ /* { dg-do run { target openacc_nvidia_accel_selected } } */ /* { dg-additional-options "-lcuda -lcublas -lcudart" } */ +/* { dg-require-effective-target openacc_cublas } */ +/* { dg-require-effective-target openacc_cudart } */ #include <stdio.h> #include <stdlib.h> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/context-2.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/context-2.c index 6bdcfe7..db82b90 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/context-2.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/context-2.c @@ -1,5 +1,7 @@ /* { dg-do run { target openacc_nvidia_accel_selected } } */ /* { dg-additional-options "-lcuda -lcublas -lcudart" } */ +/* { dg-require-effective-target openacc_cublas } */ +/* { dg-require-effective-target openacc_cudart } */ #include <stdio.h> #include <stdlib.h> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/context-3.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/context-3.c index 8f14560..b96f661 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/context-3.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/context-3.c @@ -1,5 +1,7 @@ /* { dg-do run { target openacc_nvidia_accel_selected } } */ /* { dg-additional-options "-lcuda -lcublas -lcudart" } */ +/* { dg-require-effective-target openacc_cublas } */ +/* { dg-require-effective-target openacc_cudart } */ #include <stdio.h> #include <stdlib.h> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/context-4.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/context-4.c index b403a5c..7bfd216 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/context-4.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/context-4.c @@ -1,5 +1,7 @@ /* { dg-do run { target openacc_nvidia_accel_selected } } */ /* { dg-additional-options "-lcuda -lcublas -lcudart" } */ +/* { dg-require-effective-target openacc_cublas } */ +/* { dg-require-effective-target openacc_cudart } */ #include <stdio.h> #include <stdlib.h> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/host_data-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/host_data-1.c index 21d2139..20f7f04 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/host_data-1.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/host_data-1.c @@ -1,5 +1,7 @@ /* { dg-do run { target openacc_nvidia_accel_selected } } */ /* { dg-additional-options "-lm -lcuda -lcublas -lcudart -Wall -Wextra" } */ +/* { dg-require-effective-target openacc_cublas } */ +/* { dg-require-effective-target openacc_cudart } */ #include <stdlib.h> #include <math.h> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-69.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-69.c index c10beba..00e0ca8 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-69.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-69.c @@ -1,5 +1,6 @@ /* { dg-do run { target openacc_nvidia_accel_selected } } */ /* { dg-additional-options "-lcuda" } */ +/* { dg-require-effective-target openacc_cuda } */ #include <stdio.h> #include <unistd.h> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-70.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-70.c index 912b266..a2918c0 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-70.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-70.c @@ -1,5 +1,6 @@ /* { dg-do run { target openacc_nvidia_accel_selected } } */ /* { dg-additional-options "-lcuda" } */ +/* { dg-require-effective-target openacc_cuda } */ #include <stdio.h> #include <stdlib.h> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-72.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-72.c index e383ba0..99b62f1 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-72.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-72.c @@ -1,5 +1,6 @@ /* { dg-do run { target openacc_nvidia_accel_selected } } */ /* { dg-additional-options "-lcuda" } */ +/* { dg-require-effective-target openacc_cuda } */ #include <stdio.h> #include <unistd.h> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-73.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-73.c index 43a8b7e..5b4b3fd 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-73.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-73.c @@ -1,5 +1,6 @@ /* { dg-do run { target openacc_nvidia_accel_selected } } */ /* { dg-additional-options "-lcuda" } */ +/* { dg-require-effective-target openacc_cuda } */ #include <stdio.h> #include <unistd.h> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-74.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-74.c index 0efcf0d..939f255 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-74.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-74.c @@ -1,5 +1,6 @@ /* { dg-do run { target openacc_nvidia_accel_selected } } */ /* { dg-additional-options "-lcuda" } */ +/* { dg-require-effective-target openacc_cuda } */ #include <stdio.h> #include <stdlib.h> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-75.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-75.c index 1942211..804ee39 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-75.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-75.c @@ -1,5 +1,6 @@ /* { dg-do run { target openacc_nvidia_accel_selected } } */ /* { dg-additional-options "-lcuda" } */ +/* { dg-require-effective-target openacc_cuda } */ #include <stdio.h> #include <unistd.h> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-76.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-76.c index 11d9d62..f904526 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-76.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-76.c @@ -1,5 +1,6 @@ /* { dg-do run { target openacc_nvidia_accel_selected } } */ /* { dg-additional-options "-lcuda" } */ +/* { dg-require-effective-target openacc_cuda } */ #include <stdio.h> #include <stdlib.h> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-78.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-78.c index 4f58fb2..d8cba4d 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-78.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-78.c @@ -1,5 +1,6 @@ /* { dg-do run { target openacc_nvidia_accel_selected } } */ /* { dg-additional-options "-lcuda" } */ +/* { dg-require-effective-target openacc_cuda } */ #include <stdio.h> #include <stdlib.h> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-79.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-79.c index b2e2687..b805d5f 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-79.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-79.c @@ -1,5 +1,6 @@ /* { dg-do run { target openacc_nvidia_accel_selected } } */ /* { dg-additional-options "-lcuda" } */ +/* { dg-require-effective-target openacc_cuda } */ #include <stdio.h> #include <stdlib.h> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-81.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-81.c index d5f18f0..958672c 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-81.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-81.c @@ -1,5 +1,6 @@ /* { dg-do run { target openacc_nvidia_accel_selected } } */ /* { dg-additional-options "-lcuda" } */ +/* { dg-require-effective-target openacc_cuda } */ #include <stdio.h> #include <stdlib.h> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-82.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-82.c index 9cf73b3..a36f8e6 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-82.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-82.c @@ -1,5 +1,6 @@ /* { dg-do run { target openacc_nvidia_accel_selected } } */ /* { dg-additional-options "-lcuda" } */ +/* { dg-require-effective-target openacc_cuda } */ #include <stdio.h> #include <stdlib.h> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-83.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-83.c index 51b7ee7..44ef1db 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-83.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-83.c @@ -1,5 +1,6 @@ /* { dg-do run { target openacc_nvidia_accel_selected } } */ /* { dg-additional-options "-lcuda" } */ +/* { dg-require-effective-target openacc_cuda } */ #include <stdio.h> #include <stdlib.h> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-84.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-84.c index d793c74..c1ff763 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-84.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-84.c @@ -1,5 +1,6 @@ /* { dg-do run { target openacc_nvidia_accel_selected } } */ /* { dg-additional-options "-lcuda" } */ +/* { dg-require-effective-target openacc_cuda } */ #include <stdlib.h> #include <unistd.h> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-85.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-85.c index 141c83b..db25065 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-85.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-85.c @@ -1,5 +1,6 @@ /* { dg-do run { target openacc_nvidia_accel_selected } } */ /* { dg-additional-options "-lcuda" } */ +/* { dg-require-effective-target openacc_cuda } */ #include <stdlib.h> #include <unistd.h> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-90.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-90.c index d17755b..5ca5505 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-90.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-90.c @@ -1,5 +1,6 @@ /* { dg-do run { target openacc_nvidia_accel_selected } } */ /* { dg-additional-options "-lcuda" } */ +/* { dg-require-effective-target openacc_cuda } */ #include <pthread.h> #include <stdio.h> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-91.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-91.c index 36fff08..d14226c 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-91.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-91.c @@ -1,5 +1,6 @@ /* { dg-do run { target openacc_nvidia_accel_selected } } */ /* { dg-additional-options "-lcuda" } */ +/* { dg-require-effective-target openacc_cuda } */ #include <stdlib.h> #include <unistd.h> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/pr87835.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/pr87835.c index 88c2c77..e48f307 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/pr87835.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/pr87835.c @@ -1,5 +1,6 @@ /* { dg-do run { target openacc_nvidia_accel_selected } } */ /* { dg-additional-options "-lcuda" } */ +/* { dg-require-effective-target openacc_cuda } */ #include <openacc.h> #include <stdlib.h> diff --git a/libgomp/testsuite/libgomp.oacc-fortran/host_data-2.f90 b/libgomp/testsuite/libgomp.oacc-fortran/host_data-2.f90 index ab70e4e..fe1ae8a 100644 --- a/libgomp/testsuite/libgomp.oacc-fortran/host_data-2.f90 +++ b/libgomp/testsuite/libgomp.oacc-fortran/host_data-2.f90 @@ -3,6 +3,7 @@ ! { dg-do run { target openacc_nvidia_accel_selected } } ! { dg-additional-options "-lcublas -Wall -Wextra" } +! { dg-require-effective-target openacc_cublas } program test implicit none diff --git a/libgomp/testsuite/libgomp.oacc-fortran/host_data-3.f b/libgomp/testsuite/libgomp.oacc-fortran/host_data-3.f index 434c18c..912bac6 100644 --- a/libgomp/testsuite/libgomp.oacc-fortran/host_data-3.f +++ b/libgomp/testsuite/libgomp.oacc-fortran/host_data-3.f @@ -2,6 +2,7 @@ ! { dg-do run { target openacc_nvidia_accel_selected } } ! { dg-additional-options "-lcublas -Wall -Wextra" } +! { dg-require-effective-target openacc_cublas } include "cublas-fixed.h" diff --git a/libgomp/testsuite/libgomp.oacc-fortran/host_data-4.f90 b/libgomp/testsuite/libgomp.oacc-fortran/host_data-4.f90 index e81a8b2..0daba8b 100644 --- a/libgomp/testsuite/libgomp.oacc-fortran/host_data-4.f90 +++ b/libgomp/testsuite/libgomp.oacc-fortran/host_data-4.f90 @@ -2,6 +2,7 @@ ! { dg-do run { target openacc_nvidia_accel_selected } } ! { dg-additional-options "-lcublas -Wall -Wextra" } +! { dg-require-effective-target openacc_cublas } module cublas interface |