diff options
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/c-family/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/c-family/c-omp.c | 113 | ||||
-rw-r--r-- | gcc/omp-general.c | 366 | ||||
-rw-r--r-- | gcc/omp-general.h | 1 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/gomp/declare-variant-11.c | 83 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/gomp/declare-variant-6.c | 12 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/gomp/declare-variant-7.c | 10 |
9 files changed, 475 insertions, 127 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 796f5e9..17beb66 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2019-11-02 Jakub Jelinek <jakub@redhat.com> + + * omp-general.h (omp_context_selector_set_compare): Declare. + * omp-general.c (omp_construct_simd_compare, + omp_context_selector_props_compare, omp_context_selector_set_compare, + omp_context_selector_compare): New functions. + (omp_resolve_declare_variant): Prune variants that are strict subset + of another variant. + 2019-11-01 Martin Sebor <msebor@redhat.com> PR middle-end/91679 diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 9bc2190..dfc78a4 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,5 +1,8 @@ 2019-11-02 Jakub Jelinek <jakub@redhat.com> + * c-omp.c (c_omp_mark_declare_variant): Use + omp_context_selector_set_compare. + PR c++/88335 - Implement P1073R3: Immediate functions * c-common.h (enum rid): Add RID_CONSTEVAL. * c-common.c (c_common_reswords): Add consteval. diff --git a/gcc/c-family/c-omp.c b/gcc/c-family/c-omp.c index 4f5a6ed..fdf778f 100644 --- a/gcc/c-family/c-omp.c +++ b/gcc/c-family/c-omp.c @@ -2275,113 +2275,10 @@ c_omp_mark_declare_variant (location_t loc, tree variant, tree construct) DECL_ATTRIBUTES (variant) = attr; return; } - tree t1 = TREE_VALUE (attr); - tree t2 = construct; - tree simd = get_identifier ("simd"); - while (t1 && t2) - { - if (TREE_PURPOSE (t1) != TREE_PURPOSE (t2)) - break; - if (TREE_PURPOSE (t1) == simd) - { - if ((TREE_VALUE (t1) == NULL_TREE) - != (TREE_VALUE (t2) == NULL_TREE)) - break; - if (TREE_VALUE (t1)) - { - struct declare_variant_simd_data { - bool inbranch, notinbranch; - tree simdlen; - auto_vec<tree,16> data_sharing; - auto_vec<tree,16> aligned; - declare_variant_simd_data () - : inbranch(false), notinbranch(false), simdlen(NULL_TREE) {} - } data[2]; - unsigned int i; - for (i = 0; i < 2; i++) - for (tree c = TREE_VALUE (i ? t2 : t1); - c; c = OMP_CLAUSE_CHAIN (c)) - { - vec<tree> *v; - switch (OMP_CLAUSE_CODE (c)) - { - case OMP_CLAUSE_INBRANCH: - data[i].inbranch = true; - continue; - case OMP_CLAUSE_NOTINBRANCH: - data[i].notinbranch = true; - continue; - case OMP_CLAUSE_SIMDLEN: - data[i].simdlen = OMP_CLAUSE_SIMDLEN_EXPR (c); - continue; - case OMP_CLAUSE_UNIFORM: - case OMP_CLAUSE_LINEAR: - v = &data[i].data_sharing; - break; - case OMP_CLAUSE_ALIGNED: - v = &data[i].aligned; - break; - default: - gcc_unreachable (); - } - unsigned HOST_WIDE_INT argno - = tree_to_uhwi (OMP_CLAUSE_DECL (c)); - if (argno >= v->length ()) - v->safe_grow_cleared (argno + 1); - (*v)[argno] = c; - } - if (data[0].inbranch != data[1].inbranch - || data[0].notinbranch != data[1].notinbranch - || !simple_cst_equal (data[0].simdlen, - data[1].simdlen) - || (data[0].data_sharing.length () - != data[1].data_sharing.length ()) - || (data[0].aligned.length () - != data[1].aligned.length ())) - break; - tree c1, c2; - FOR_EACH_VEC_ELT (data[0].data_sharing, i, c1) - { - c2 = data[1].data_sharing[i]; - if ((c1 == NULL_TREE) != (c2 == NULL_TREE)) - break; - if (c1 == NULL_TREE) - continue; - if (OMP_CLAUSE_CODE (c1) != OMP_CLAUSE_CODE (c2)) - break; - if (OMP_CLAUSE_CODE (c1) != OMP_CLAUSE_LINEAR) - continue; - if (OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (c1) - != OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (c2)) - break; - if (OMP_CLAUSE_LINEAR_KIND (c1) - != OMP_CLAUSE_LINEAR_KIND (c2)) - break; - if (!simple_cst_equal (OMP_CLAUSE_LINEAR_STEP (c1), - OMP_CLAUSE_LINEAR_STEP (c2))) - break; - } - if (i < data[0].data_sharing.length ()) - break; - FOR_EACH_VEC_ELT (data[0].aligned, i, c1) - { - c2 = data[1].aligned[i]; - if ((c1 == NULL_TREE) != (c2 == NULL_TREE)) - break; - if (c1 == NULL_TREE) - continue; - if (!simple_cst_equal (OMP_CLAUSE_ALIGNED_ALIGNMENT (c1), - OMP_CLAUSE_ALIGNED_ALIGNMENT (c2))) - break; - } - if (i < data[0].aligned.length ()) - break; - } - } - t1 = TREE_CHAIN (t1); - t2 = TREE_CHAIN (t2); - } - if (t1 || t2) - error_at (loc, "%qD used as a variant with incompatible %<constructor%> " + if ((TREE_VALUE (attr) != NULL_TREE) != (construct != NULL_TREE) + || (construct != NULL_TREE + && omp_context_selector_set_compare ("construct", TREE_VALUE (attr), + construct))) + error_at (loc, "%qD used as a variant with incompatible %<construct%> " "selector sets", variant); } diff --git a/gcc/omp-general.c b/gcc/omp-general.c index 82f4746..6700e7f 100644 --- a/gcc/omp-general.c +++ b/gcc/omp-general.c @@ -947,6 +947,320 @@ omp_context_selector_matches (tree ctx) return ret; } +/* Compare construct={simd} CLAUSES1 with CLAUSES2, return 0/-1/1/2 as + in omp_context_selector_set_compare. */ + +static int +omp_construct_simd_compare (tree clauses1, tree clauses2) +{ + if (clauses1 == NULL_TREE) + return clauses2 == NULL_TREE ? 0 : -1; + if (clauses2 == NULL_TREE) + return 1; + + int r = 0; + struct declare_variant_simd_data { + bool inbranch, notinbranch; + tree simdlen; + auto_vec<tree,16> data_sharing; + auto_vec<tree,16> aligned; + declare_variant_simd_data () + : inbranch(false), notinbranch(false), simdlen(NULL_TREE) {} + } data[2]; + unsigned int i; + for (i = 0; i < 2; i++) + for (tree c = i ? clauses2 : clauses1; c; c = OMP_CLAUSE_CHAIN (c)) + { + vec<tree> *v; + switch (OMP_CLAUSE_CODE (c)) + { + case OMP_CLAUSE_INBRANCH: + data[i].inbranch = true; + continue; + case OMP_CLAUSE_NOTINBRANCH: + data[i].notinbranch = true; + continue; + case OMP_CLAUSE_SIMDLEN: + data[i].simdlen = OMP_CLAUSE_SIMDLEN_EXPR (c); + continue; + case OMP_CLAUSE_UNIFORM: + case OMP_CLAUSE_LINEAR: + v = &data[i].data_sharing; + break; + case OMP_CLAUSE_ALIGNED: + v = &data[i].aligned; + break; + default: + gcc_unreachable (); + } + unsigned HOST_WIDE_INT argno = tree_to_uhwi (OMP_CLAUSE_DECL (c)); + if (argno >= v->length ()) + v->safe_grow_cleared (argno + 1); + (*v)[argno] = c; + } + /* Here, r is used as a bitmask, 2 is set if CLAUSES1 has something + CLAUSES2 doesn't, 1 is set if CLAUSES2 has something CLAUSES1 + doesn't. Thus, r == 3 implies return value 2, r == 1 implies + -1, r == 2 implies 1 and r == 0 implies 0. */ + if (data[0].inbranch != data[1].inbranch) + r |= data[0].inbranch ? 2 : 1; + if (data[0].notinbranch != data[1].notinbranch) + r |= data[0].notinbranch ? 2 : 1; + if (!simple_cst_equal (data[0].simdlen, data[1].simdlen)) + { + if (data[0].simdlen && data[1].simdlen) + return 2; + r |= data[0].simdlen ? 2 : 1; + } + if (data[0].data_sharing.length () < data[1].data_sharing.length () + || data[0].aligned.length () < data[1].aligned.length ()) + r |= 1; + tree c1, c2; + FOR_EACH_VEC_ELT (data[0].data_sharing, i, c1) + { + c2 = (i < data[1].data_sharing.length () + ? data[1].data_sharing[i] : NULL_TREE); + if ((c1 == NULL_TREE) != (c2 == NULL_TREE)) + { + r |= c1 != NULL_TREE ? 2 : 1; + continue; + } + if (c1 == NULL_TREE) + continue; + if (OMP_CLAUSE_CODE (c1) != OMP_CLAUSE_CODE (c2)) + return 2; + if (OMP_CLAUSE_CODE (c1) != OMP_CLAUSE_LINEAR) + continue; + if (OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (c1) + != OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (c2)) + return 2; + if (OMP_CLAUSE_LINEAR_KIND (c1) != OMP_CLAUSE_LINEAR_KIND (c2)) + return 2; + if (!simple_cst_equal (OMP_CLAUSE_LINEAR_STEP (c1), + OMP_CLAUSE_LINEAR_STEP (c2))) + return 2; + } + FOR_EACH_VEC_ELT (data[0].aligned, i, c1) + { + c2 = i < data[1].aligned.length () ? data[1].aligned[i] : NULL_TREE; + if ((c1 == NULL_TREE) != (c2 == NULL_TREE)) + { + r |= c1 != NULL_TREE ? 2 : 1; + continue; + } + if (c1 == NULL_TREE) + continue; + if (!simple_cst_equal (OMP_CLAUSE_ALIGNED_ALIGNMENT (c1), + OMP_CLAUSE_ALIGNED_ALIGNMENT (c2))) + return 2; + } + switch (r) + { + case 0: return 0; + case 1: return -1; + case 2: return 1; + case 3: return 2; + default: gcc_unreachable (); + } +} + +/* Compare properties of selectors SEL from SET other than construct. + Return 0/-1/1/2 as in omp_context_selector_set_compare. + Unlike set names or selector names, properties can have duplicates. */ + +static int +omp_context_selector_props_compare (const char *set, const char *sel, + tree ctx1, tree ctx2) +{ + int ret = 0; + for (int pass = 0; pass < 2; pass++) + for (tree t1 = pass ? ctx2 : ctx1; t1; t1 = TREE_CHAIN (t1)) + { + tree t2; + for (t2 = pass ? ctx1 : ctx2; t2; t2 = TREE_CHAIN (t2)) + if (TREE_PURPOSE (t1) == TREE_PURPOSE (t2)) + { + if (TREE_PURPOSE (t1) == NULL_TREE) + { + if (set[0] == 'u' && strcmp (sel, "condition") == 0) + { + if (integer_zerop (TREE_VALUE (t1)) + != integer_zerop (TREE_VALUE (t2))) + return 2; + break; + } + if (simple_cst_equal (TREE_VALUE (t1), TREE_VALUE (t2))) + break; + } + else if (strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t1)), + " score") == 0) + { + if (!simple_cst_equal (TREE_VALUE (t1), TREE_VALUE (t2))) + return 2; + break; + } + else + break; + } + if (t2 == NULL_TREE) + { + int r = pass ? -1 : 1; + if (ret && ret != r) + return 2; + else if (pass) + return r; + else + { + ret = r; + break; + } + } + } + return ret; +} + +/* Compare single context selector sets CTX1 and CTX2 with SET name. + Return 0 if CTX1 is equal to CTX2, + -1 if CTX1 is a strict subset of CTX2, + 1 if CTX2 is a strict subset of CTX1, or + 2 if neither context is a subset of another one. */ + +int +omp_context_selector_set_compare (const char *set, tree ctx1, tree ctx2) +{ + bool swapped = false; + int ret = 0; + int len1 = list_length (ctx1); + int len2 = list_length (ctx2); + int cnt = 0; + if (len1 < len2) + { + swapped = true; + std::swap (ctx1, ctx2); + std::swap (len1, len2); + } + if (set[0] == 'c') + { + tree t1; + tree t2 = ctx2; + tree simd = get_identifier ("simd"); + /* Handle construct set specially. In this case the order + of the selector matters too. */ + for (t1 = ctx1; t1; t1 = TREE_CHAIN (t1)) + if (TREE_PURPOSE (t1) == TREE_PURPOSE (t2)) + { + int r = 0; + if (TREE_PURPOSE (t1) == simd) + r = omp_construct_simd_compare (TREE_VALUE (t1), + TREE_VALUE (t2)); + if (r == 2 || (ret && r && (ret < 0) != (r < 0))) + return 2; + if (ret == 0) + ret = r; + t2 = TREE_CHAIN (t2); + if (t2 == NULL_TREE) + { + t1 = TREE_CHAIN (t1); + break; + } + } + else if (ret < 0) + return 2; + else + ret = 1; + if (t2 != NULL_TREE) + return 2; + if (t1 != NULL_TREE) + { + if (ret < 0) + return 2; + ret = 1; + } + if (ret == 0) + return 0; + return swapped ? -ret : ret; + } + for (tree t1 = ctx1; t1; t1 = TREE_CHAIN (t1)) + { + tree t2; + for (t2 = ctx2; t2; t2 = TREE_CHAIN (t2)) + if (TREE_PURPOSE (t1) == TREE_PURPOSE (t2)) + { + const char *sel = IDENTIFIER_POINTER (TREE_PURPOSE (t1)); + int r = omp_context_selector_props_compare (set, sel, + TREE_VALUE (t1), + TREE_VALUE (t2)); + if (r == 2 || (ret && r && (ret < 0) != (r < 0))) + return 2; + if (ret == 0) + ret = r; + cnt++; + break; + } + if (t2 == NULL_TREE) + { + if (ret == -1) + return 2; + ret = 1; + } + } + if (cnt < len2) + return 2; + if (ret == 0) + return 0; + return swapped ? -ret : ret; +} + +/* Compare whole context selector specification CTX1 and CTX2. + Return 0 if CTX1 is equal to CTX2, + -1 if CTX1 is a strict subset of CTX2, + 1 if CTX2 is a strict subset of CTX1, or + 2 if neither context is a subset of another one. */ + +static int +omp_context_selector_compare (tree ctx1, tree ctx2) +{ + bool swapped = false; + int ret = 0; + int len1 = list_length (ctx1); + int len2 = list_length (ctx2); + int cnt = 0; + if (len1 < len2) + { + swapped = true; + std::swap (ctx1, ctx2); + std::swap (len1, len2); + } + for (tree t1 = ctx1; t1; t1 = TREE_CHAIN (t1)) + { + tree t2; + for (t2 = ctx2; t2; t2 = TREE_CHAIN (t2)) + if (TREE_PURPOSE (t1) == TREE_PURPOSE (t2)) + { + const char *set = IDENTIFIER_POINTER (TREE_PURPOSE (t1)); + int r = omp_context_selector_set_compare (set, TREE_VALUE (t1), + TREE_VALUE (t2)); + if (r == 2 || (ret && r && (ret < 0) != (r < 0))) + return 2; + if (ret == 0) + ret = r; + cnt++; + break; + } + if (t2 == NULL_TREE) + { + if (ret == -1) + return 2; + ret = 1; + } + } + if (cnt < len2) + return 2; + if (ret == 0) + return 0; + return swapped ? -ret : ret; +} + /* Try to resolve declare variant, return the variant decl if it should be used instead of base, or base otherwise. */ @@ -954,11 +1268,14 @@ tree omp_resolve_declare_variant (tree base) { tree variant = NULL_TREE; + auto_vec <tree, 16> variants; for (tree attr = DECL_ATTRIBUTES (base); attr; attr = TREE_CHAIN (attr)) { attr = lookup_attribute ("omp declare variant base", attr); if (attr == NULL_TREE) break; + if (TREE_CODE (TREE_PURPOSE (TREE_VALUE (attr))) != FUNCTION_DECL) + continue; switch (omp_context_selector_matches (TREE_VALUE (TREE_VALUE (attr)))) { case 0: @@ -968,16 +1285,49 @@ omp_resolve_declare_variant (tree base) /* Needs to be deferred. */ return base; default: - /* FIXME: Scoring not implemented yet, so just resolve it - if there is a single variant only. */ - if (variant) - return base; - if (TREE_CODE (TREE_PURPOSE (TREE_VALUE (attr))) == FUNCTION_DECL) - variant = TREE_PURPOSE (TREE_VALUE (attr)); - else - return base; + variants.safe_push (attr); } } + if (variants.length () == 0) + return base; + if (variants.length () == 1) + return TREE_PURPOSE (TREE_VALUE (variants[0])); + + /* A context selector that is a strict subset of another context selector has a score + of zero. */ + tree attr1, attr2; + unsigned int i, j; + FOR_EACH_VEC_ELT (variants, i, attr1) + if (attr1) + { + tree ctx1 = TREE_VALUE (TREE_VALUE (attr1)); + FOR_EACH_VEC_ELT_FROM (variants, j, attr2, i + 1) + if (attr2) + { + tree ctx2 = TREE_VALUE (TREE_VALUE (attr2)); + int r = omp_context_selector_compare (ctx1, ctx2); + if (r == -1) + { + /* ctx1 is a strict subset of ctx2, remove + attr1 from the vector. */ + variants[i] = NULL_TREE; + break; + } + else if (r == 1) + /* ctx2 is a strict subset of ctx1, remove attr2 + from the vector. */ + variants[j] = NULL_TREE; + } + } + /* FIXME: Scoring not implemented yet, so just resolve it + if there is a single variant left. */ + FOR_EACH_VEC_ELT (variants, i, attr1) + if (attr1) + { + if (variant) + return base; + variant = TREE_PURPOSE (TREE_VALUE (attr1)); + } return variant ? variant : base; } diff --git a/gcc/omp-general.h b/gcc/omp-general.h index c0c294d..c6f95eb 100644 --- a/gcc/omp-general.h +++ b/gcc/omp-general.h @@ -86,6 +86,7 @@ extern poly_uint64 omp_max_vf (void); extern int omp_max_simt_vf (void); extern int omp_constructor_traits_to_codes (tree, enum tree_code *); extern int omp_context_selector_matches (tree); +extern int omp_context_selector_set_compare (const char *, tree, tree); extern tree omp_resolve_declare_variant (tree); extern tree oacc_launch_pack (unsigned code, tree device, unsigned op); extern tree oacc_replace_fn_attrib_attr (tree attribs, tree dims); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5473b25..e8a3856 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2019-11-02 Jakub Jelinek <jakub@redhat.com> + * c-c++-common/gomp/declare-variant-6.c: Expect construct rather than + constructor in diagnostic messages. + * c-c++-common/gomp/declare-variant-7.c: Likewise. + * c-c++-common/gomp/declare-variant-11.c: New test. + PR c++/88335 - Implement P1073R3: Immediate functions * g++.dg/cpp2a/consteval1.C: New test. * g++.dg/cpp2a/consteval2.C: New test. diff --git a/gcc/testsuite/c-c++-common/gomp/declare-variant-11.c b/gcc/testsuite/c-c++-common/gomp/declare-variant-11.c new file mode 100644 index 0000000..9879a9b --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/declare-variant-11.c @@ -0,0 +1,83 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-foffload=disable -fdump-tree-gimple" } */ +/* { dg-additional-options "-mavx512bw -mavx512vl" { target { i?86-*-* x86_64-*-* } } } */ + +void f01 (void); +void f02 (void); +#pragma omp declare variant (f01) match (device={isa(avx512f,avx512vl)}) +#pragma omp declare variant (f02) match (device={isa(avx512bw,avx512vl,avx512f)}) +void f03 (void); +void f04 (void); +void f05 (void); +#pragma omp declare variant (f04) match (device={isa(avx512f,avx512vl)}) +#pragma omp declare variant (f05) match (device={isa(avx512bw,avx512vl,avx512f)}) +void f06 (void); +void f07 (void); +void f08 (void); +#pragma omp declare variant (f07) match (device={isa(sse4,sse3,avx)}) +#pragma omp declare variant (f08) match (device={isa(avx,sse3)}) +void f09 (void); +void f10 (void); +void f11 (void); +void f12 (void); +#pragma omp declare variant (f10) match (device={isa(avx512f)}) +#pragma omp declare variant (f11) match (user={condition(1)},device={isa(avx512f)},implementation={vendor(gnu)}) +#pragma omp declare variant (f12) match (user={condition(2 + 1)},device={isa(avx512f)}) +void f13 (void); +void f14 (void); +void f15 (void); +void f16 (void); +void f17 (void); +#pragma omp declare variant (f14) match (construct={teams,for}) +#pragma omp declare variant (f15) match (construct={teams,parallel,for}) +#pragma omp declare variant (f16) match (construct={for}) +#pragma omp declare variant (f17) match (construct={parallel,for}) +void f18 (void); +void f19 (void); +void f20 (void); +void f21 (void); +void f22 (void); +#pragma omp declare variant (f19) match (construct={teams,for}) +#pragma omp declare variant (f20) match (construct={teams,parallel,for}) +#pragma omp declare variant (f21) match (construct={for}) +#pragma omp declare variant (f22) match (construct={parallel,for}) +void f23 (void); +void f24 (void); +void f25 (void); +void f26 (void); +#pragma omp declare variant (f24) match (device={kind(cpu)}) +#pragma omp declare variant (f25) match (device={kind(cpu),isa(avx512f),arch(x86_64)}) +#pragma omp declare variant (f26) match (device={arch(x86_64),kind(cpu)}) +void f27 (void); + +void +test1 (void) +{ + int i; + f03 (); /* { dg-final { scan-tree-dump-times "f02 \\\(\\\);" 1 "gimple" { target i?86-*-* x86_64-*-* } } } */ + /* { dg-final { scan-tree-dump-times "f03 \\\(\\\);" 1 "gimple" { target { ! { i?86-*-* x86_64-*-* } } } } } */ + f09 (); /* { dg-final { scan-tree-dump-times "f07 \\\(\\\);" 1 "gimple" { target i?86-*-* x86_64-*-* } } } */ + /* { dg-final { scan-tree-dump-times "f09 \\\(\\\);" 1 "gimple" { target { ! { i?86-*-* x86_64-*-* } } } } } */ + f13 (); /* { dg-final { scan-tree-dump-times "f11 \\\(\\\);" 1 "gimple" { target i?86-*-* x86_64-*-* } } } */ + /* { dg-final { scan-tree-dump-times "f13 \\\(\\\);" 1 "gimple" { target { ! { i?86-*-* x86_64-*-* } } } } } */ + #pragma omp teams distribute parallel for + for (i = 0; i < 1; i++) + f18 (); /* { dg-final { scan-tree-dump-times "f15 \\\(\\\);" 1 "gimple" } } */ + #pragma omp parallel for + for (i = 0; i < 1; i++) + f23 (); /* { dg-final { scan-tree-dump-times "f22 \\\(\\\);" 1 "gimple" } } */ + f27 (); /* { dg-final { scan-tree-dump-times "f25 \\\(\\\);" 1 "gimple" { target { { i?86-*-* x86_64-*-* } && lp64 } } } } */ + /* { dg-final { scan-tree-dump-times "f24 \\\(\\\);" 1 "gimple" { target { { i?86-*-* x86_64-*-* } && { ! lp64 } } } } } */ + /* { dg-final { scan-tree-dump-times "f24 \\\(\\\);" 1 "gimple" { target { ! { nvptx*-*-* amdgcn*-*-* i?86-*-* x86_64-*-* } } } } } */ + /* { dg-final { scan-tree-dump-times "f27 \\\(\\\);" 1 "gimple" { target { nvptx*-*-* amdgcn*-*-* } } } } */ +} + +#if defined(__i386__) || defined(__x86_64__) +__attribute__((target ("no-avx512bw,avx512f,avx512vl"))) +#endif +void +test2 (void) +{ + f06 (); /* { dg-final { scan-tree-dump-times "f04 \\\(\\\);" 1 "gimple" { target i?86-*-* x86_64-*-* } } } */ + /* { dg-final { scan-tree-dump-times "f06 \\\(\\\);" 1 "gimple" { target { ! { i?86-*-* x86_64-*-* } } } } } */ +} diff --git a/gcc/testsuite/c-c++-common/gomp/declare-variant-6.c b/gcc/testsuite/c-c++-common/gomp/declare-variant-6.c index 9ccfd0f..159da07 100644 --- a/gcc/testsuite/c-c++-common/gomp/declare-variant-6.c +++ b/gcc/testsuite/c-c++-common/gomp/declare-variant-6.c @@ -7,29 +7,29 @@ double f4 (int, long, float); double f5 (int, long, float); #pragma omp declare variant (f5) match (user={condition(0)}) double f6 (int, long, float); -#pragma omp declare variant (f5) match (construct={parallel},user={condition(score(1):1)}) /* { dg-error "'\[^'\n\r]*f5\[^'\n\r]*' used as a variant with incompatible 'constructor' selector sets" } */ +#pragma omp declare variant (f5) match (construct={parallel},user={condition(score(1):1)}) /* { dg-error "'\[^'\n\r]*f5\[^'\n\r]*' used as a variant with incompatible 'construct' selector sets" } */ double f7 (int, long, float); double f8 (int, long, float); #pragma omp declare variant (f8) match (user={condition(0)},construct={for}) double f9 (int, long, float); -#pragma omp declare variant (f8) match (user={condition(1)}) /* { dg-error "'\[^'\n\r]*f8\[^'\n\r]*' used as a variant with incompatible 'constructor' selector sets" } */ +#pragma omp declare variant (f8) match (user={condition(1)}) /* { dg-error "'\[^'\n\r]*f8\[^'\n\r]*' used as a variant with incompatible 'construct' selector sets" } */ double f10 (int, long, float); double f11 (int, long, float); #pragma omp declare variant (f11) match (construct={target,teams,parallel,for}) double f12 (int, long, float); #pragma omp declare variant (f11) match (user={condition(score(1):1)},construct={target,teams,parallel,for}) double f13 (int, long, float); -#pragma omp declare variant (f11) match (implementation={vendor(gnu)},construct={target,teams,parallel}) /* { dg-error "'\[^'\n\r]*f11\[^'\n\r]*' used as a variant with incompatible 'constructor' selector sets" } */ +#pragma omp declare variant (f11) match (implementation={vendor(gnu)},construct={target,teams,parallel}) /* { dg-error "'\[^'\n\r]*f11\[^'\n\r]*' used as a variant with incompatible 'construct' selector sets" } */ double f14 (int, long, float); -#pragma omp declare variant (f11) match (device={kind(any)},construct={teams,parallel}) /* { dg-error "'\[^'\n\r]*f11\[^'\n\r]*' used as a variant with incompatible 'constructor' selector sets" } */ +#pragma omp declare variant (f11) match (device={kind(any)},construct={teams,parallel}) /* { dg-error "'\[^'\n\r]*f11\[^'\n\r]*' used as a variant with incompatible 'construct' selector sets" } */ double f15 (int, long, float); double f16 (int, long, float); #pragma omp declare variant (f16) match (construct={teams,parallel}) double f17 (int, long, float); -#pragma omp declare variant (f16) match(construct={teams,parallel,for}) /* { dg-error "'\[^'\n\r]*f16\[^'\n\r]*' used as a variant with incompatible 'constructor' selector sets" } */ +#pragma omp declare variant (f16) match(construct={teams,parallel,for}) /* { dg-error "'\[^'\n\r]*f16\[^'\n\r]*' used as a variant with incompatible 'construct' selector sets" } */ double f18 (int, long, float); double f19 (int, long, float); #pragma omp declare variant (f19) match (construct={parallel}) double f20 (int, long, float); -#pragma omp declare variant (f19) match (construct={for},implementation={vendor(gnu,llvm)}) /* { dg-error "'\[^'\n\r]*f19\[^'\n\r]*' used as a variant with incompatible 'constructor' selector sets" } */ +#pragma omp declare variant (f19) match (construct={for},implementation={vendor(gnu,llvm)}) /* { dg-error "'\[^'\n\r]*f19\[^'\n\r]*' used as a variant with incompatible 'construct' selector sets" } */ double f21 (int, long, float); diff --git a/gcc/testsuite/c-c++-common/gomp/declare-variant-7.c b/gcc/testsuite/c-c++-common/gomp/declare-variant-7.c index 1df6338..4eebcbc 100644 --- a/gcc/testsuite/c-c++-common/gomp/declare-variant-7.c +++ b/gcc/testsuite/c-c++-common/gomp/declare-variant-7.c @@ -13,23 +13,23 @@ __v4si f3 (__v4si, int, __v4si); int f4 (float x, float y, float *z); #pragma omp declare variant (f1) match (construct={parallel,for,simd(uniform(w),simdlen(8*2-12),aligned(w:4*sizeof (float)),notinbranch)}) int f5 (float u, float v, float *w); -#pragma omp declare variant (f1) match (construct={parallel,for,simd(linear(w),notinbranch,simdlen(4),aligned(w:4*sizeof (float)))}) /* { dg-error "'f1' used as a variant with incompatible 'constructor' selector sets" "" { target c } } */ +#pragma omp declare variant (f1) match (construct={parallel,for,simd(linear(w),notinbranch,simdlen(4),aligned(w:4*sizeof (float)))}) /* { dg-error "'f1' used as a variant with incompatible 'construct' selector sets" "" { target c } } */ int f6 (float u, float v, float *w); -#pragma omp declare variant (f1) match (construct={parallel,for,simd(uniform(w),notinbranch,simdlen(4),aligned(w:2*sizeof (float)))}) /* { dg-error "'f1' used as a variant with incompatible 'constructor' selector sets" "" { target c } } */ +#pragma omp declare variant (f1) match (construct={parallel,for,simd(uniform(w),notinbranch,simdlen(4),aligned(w:2*sizeof (float)))}) /* { dg-error "'f1' used as a variant with incompatible 'construct' selector sets" "" { target c } } */ int f7 (float u, float v, float *w); -#pragma omp declare variant (f1) match (construct={parallel,for,simd(uniform(w),notinbranch,simdlen(4),aligned(w))}) /* { dg-error "'f1' used as a variant with incompatible 'constructor' selector sets" "" { target c } } */ +#pragma omp declare variant (f1) match (construct={parallel,for,simd(uniform(w),notinbranch,simdlen(4),aligned(w))}) /* { dg-error "'f1' used as a variant with incompatible 'construct' selector sets" "" { target c } } */ int f8 (float u, float v, float *w); #pragma omp declare variant (f2) match (construct={for,simd(uniform(z),simdlen(8),notinbranch)}) int f9 (float x, float y, float *z); #pragma omp declare variant (f2) match (construct={for,simd(notinbranch,simdlen(2+2+4),uniform (q))}) int f10 (float x, float y, float *q); -#pragma omp declare variant (f2) match (construct={for,simd(linear(z:2),simdlen(8),notinbranch)}) /* { dg-error "'f2' used as a variant with incompatible 'constructor' selector sets" "" { target c } } */ +#pragma omp declare variant (f2) match (construct={for,simd(linear(z:2),simdlen(8),notinbranch)}) /* { dg-error "'f2' used as a variant with incompatible 'construct' selector sets" "" { target c } } */ int f11 (float x, float y, float *z); #pragma omp declare variant (f3) match (construct={simd(simdlen(4),inbranch,linear(y:1))}) int f12 (int x, int y); #pragma omp declare variant (f3) match (construct={simd(inbranch, simdlen (5-1), linear (q:4-3))}) int f13 (int x, int q); -#pragma omp declare variant (f3) match (construct={simd(inbranch,simdlen(4),linear(q:2))}) /* { dg-error "'f3' used as a variant with incompatible 'constructor' selector sets" "" { target c } } */ +#pragma omp declare variant (f3) match (construct={simd(inbranch,simdlen(4),linear(q:2))}) /* { dg-error "'f3' used as a variant with incompatible 'construct' selector sets" "" { target c } } */ int f14 (int x, int q); #pragma omp declare variant (f3) match (construct={simd(inbranch simdlen (4) linear (q:1))}) /* { dg-error "clauses in 'simd' trait should be separated by ','" } */ int f15 (int x, int q); |