Commit 917dd789 by Jakub Jelinek Committed by Jakub Jelinek

omp-general.h (omp_context_selector_set_compare): Declare.

	* 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.
c-family/
	* c-omp.c (c_omp_mark_declare_variant): Use
	omp_context_selector_set_compare.
testsuite/
	* 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.

From-SVN: r277734
parent f968ef9b
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
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.
......
......@@ -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);
}
......@@ -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,15 +1285,48 @@ omp_resolve_declare_variant (tree base)
/* Needs to be deferred. */
return base;
default:
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 only. */
if there is a single variant left. */
FOR_EACH_VEC_ELT (variants, i, attr1)
if (attr1)
{
if (variant)
return base;
if (TREE_CODE (TREE_PURPOSE (TREE_VALUE (attr))) == FUNCTION_DECL)
variant = TREE_PURPOSE (TREE_VALUE (attr));
else
return base;
}
variant = TREE_PURPOSE (TREE_VALUE (attr1));
}
return variant ? variant : base;
}
......
......@@ -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);
......
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.
......
/* { 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-*-* } } } } } */
}
......@@ -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);
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment