From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id C79473858020 for ; Sat, 4 Nov 2023 08:16:59 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org C79473858020 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org C79473858020 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699085823; cv=none; b=mxtcok+35AgSwqZlD6Id8kfmxUPCWVHC9nGfSTEw9fHRdBuMEwqf37RqDsQH4me/D8gKf8I9QTIh9X0ityr4NyHoAe8sUxP6yuHqsh+sYSIov5+NVllUVNXiv7w22jGcOw5qHUg+mKvWs5xgq2BefVgigfTfbE5o/tcbbecGlIY= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1699085823; c=relaxed/simple; bh=V1+9I1gQjeApv4Y4f1VSylmWcmlNJQNNGjH0mJmZwPM=; h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version; b=UVCxNPJ4nB1E8ag5sPYPvN3RqoOouPgzkumujRK3dKWNhoSY6hf/i1UBKeZnzjWUMIdEUuAeeX/q2r/RffUmzZJC0TIY/M0cxyVhqCo9brCcYusFau6JXezxfTPBGtTInNYo92PmQyVglW8tMvmmsS6MbFQOAcOj5xcijUWCfAg= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1699085819; h=from:from:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type; bh=+G1CB8zy0GLDVpYq3jk+un4yQR5lk4VQ969vVfuhtQY=; b=aK6yjmqyInjnAZrSb/qCc2/njMeWNxDF9eWVxxRDR5yvFS7bpIovc8Pj6YWm2LtoqYgIhR WZOmXrLkvDvsjgF5Gxz+B0Dq8n/RGkS5tDU4DTjcBYac/NGW6hg78Qcuf8iaSzrESCpEb9 Kt430Zkrk9qMP8OfrL7B8bY1Z3LGBms= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-434-NJYjbGHvOvG9r4CmtrzR-g-1; Sat, 04 Nov 2023 04:16:57 -0400 X-MC-Unique: NJYjbGHvOvG9r4CmtrzR-g-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id A36AE811E7B for ; Sat, 4 Nov 2023 08:16:57 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.39.192.81]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 4A2611C060BA for ; Sat, 4 Nov 2023 08:16:57 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.17.1/8.17.1) with ESMTPS id 3A48Gt0p3483320 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT) for ; Sat, 4 Nov 2023 09:16:55 +0100 Received: (from jakub@localhost) by tucnak.zalov.cz (8.17.1/8.17.1/Submit) id 3A48Gsse3483319 for gcc-patches@gcc.gnu.org; Sat, 4 Nov 2023 09:16:54 +0100 Date: Sat, 4 Nov 2023 09:16:54 +0100 From: Jakub Jelinek To: gcc-patches@gcc.gnu.org Subject: [committed] openmp: Add omp::decl support for C2X Message-ID: Reply-To: Jakub Jelinek MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.7 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=us-ascii Content-Disposition: inline X-Spam-Status: No, score=-3.7 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_NONE,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: Hi! This patch adds omp::decl support which has been added recently for C++ also to C. Bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk. 2023-11-04 Jakub Jelinek * c-parser.h (c_maybe_parse_omp_decl): Declare. * c-parser.cc (struct c_parser): Add in_omp_decl_attribute member. (c_parser_std_attribute): Uncoment omp::decl handling. (c_parser_omp_var_list_parens): If parser->in_omp_decl_attribute don't expect any arguments, instead create clause or TREE_LIST for that decl. (c_maybe_parse_omp_decl): New function. (c_parser_omp_declare_target): If parser->in_omp_decl_attribute and first token isn't name or comma invoke c_parser_omp_var_list_parens. * c-decl.cc (c_decl_attributes): Uncomment omp::decl handling and use *node rather than non-existing *decl. * gcc.dg/gomp/attrs-19.c: New test. * gcc.dg/gomp/attrs-20.c: New test. * gcc.dg/gomp/attrs-21.c: New test. --- gcc/c/c-parser.h.jj 2023-11-03 14:45:30.884543778 +0100 +++ gcc/c/c-parser.h 2023-11-03 15:24:44.859097248 +0100 @@ -204,5 +204,6 @@ extern void c_parser_declspecs (c_parser bool, bool, bool, bool, bool, enum c_lookahead_kind); extern struct c_type_name *c_parser_type_name (c_parser *, bool = false); +extern bool c_maybe_parse_omp_decl (tree, tree); #endif --- gcc/c/c-parser.cc.jj 2023-11-03 14:45:30.903543539 +0100 +++ gcc/c/c-parser.cc 2023-11-03 16:18:30.593079455 +0100 @@ -262,6 +262,10 @@ struct GTY(()) c_parser { attributes turned into pragma, vector of tokens created from that, otherwise NULL. */ vec *in_omp_attribute_pragma; + + /* Set for omp::decl attribute parsing to the decl to which it + appertains. */ + tree in_omp_decl_attribute; }; /* Return a pointer to the Nth token in PARSERs tokens_buf. */ @@ -5797,14 +5801,14 @@ c_parser_std_attribute (c_parser *parser parens.skip_until_found_close (parser); return attribute; } -/* else if (is_attribute_p ("decl", name)) + else if (is_attribute_p ("decl", name)) { TREE_VALUE (TREE_PURPOSE (attribute)) = get_identifier ("directive"); c_parser_omp_directive_args (parser, attribute, true); parens.skip_until_found_close (parser); return attribute; - } */ + } else if (is_attribute_p ("sequence", name)) { TREE_VALUE (TREE_PURPOSE (attribute)) @@ -15147,6 +15151,19 @@ c_parser_omp_var_list_parens (c_parser * /* The clauses location. */ location_t loc = c_parser_peek_token (parser)->location; + if (parser->in_omp_decl_attribute) + { + if (kind) + { + tree u = build_omp_clause (loc, kind); + OMP_CLAUSE_DECL (u) = parser->in_omp_decl_attribute; + OMP_CLAUSE_CHAIN (u) = list; + return u; + } + else + return tree_cons (parser->in_omp_decl_attribute, NULL_TREE, list); + } + matching_parens parens; if (parens.require_open (parser)) { @@ -24498,6 +24515,84 @@ c_finish_omp_declare_simd (c_parser *par clauses[0].type = CPP_PRAGMA; } +/* D should be C_TOKEN_VEC from omp::decl attribute. If it contains + a threadprivate, groupprivate, allocate or declare target directive, + return true and parse it for DECL. */ + +bool +c_maybe_parse_omp_decl (tree decl, tree d) +{ + gcc_assert (TREE_CODE (d) == C_TOKEN_VEC); + vec *toks = C_TOKEN_VEC_TOKENS (d); + c_token *first = toks->address (); + c_token *last = first + toks->length (); + const char *directive[3] = {}; + for (int j = 0; j < 3; j++) + { + tree id = NULL_TREE; + if (first + j == last) + break; + if (first[j].type == CPP_NAME) + id = first[j].value; + else if (first[j].type == CPP_KEYWORD) + id = ridpointers[(int) first[j].keyword]; + else + break; + directive[j] = IDENTIFIER_POINTER (id); + } + const c_omp_directive *dir = NULL; + if (directive[0]) + dir = c_omp_categorize_directive (directive[0], directive[1], + directive[2]); + if (dir == NULL) + { + error_at (first->location, + "unknown OpenMP directive name in " + "%qs attribute argument", "omp::decl"); + return false; + } + if (dir->id != PRAGMA_OMP_THREADPRIVATE + /* && dir->id != PRAGMA_OMP_GROUPPRIVATE */ + && dir->id != PRAGMA_OMP_ALLOCATE + && (dir->id != PRAGMA_OMP_DECLARE + || strcmp (directive[1], "target") != 0)) + return false; + + if (!flag_openmp && !dir->simd) + return true; + + c_parser *parser = the_parser; + unsigned int tokens_avail = parser->tokens_avail; + gcc_assert (parser->tokens == &parser->tokens_buf[0]); + toks = NULL; + vec_safe_reserve (toks, last - first + 2, true); + c_token tok = {}; + tok.type = CPP_PRAGMA; + tok.keyword = RID_MAX; + tok.pragma_kind = pragma_kind (dir->id); + tok.location = first->location; + toks->quick_push (tok); + while (++first < last) + toks->quick_push (*first); + tok = {}; + tok.type = CPP_PRAGMA_EOL; + tok.keyword = RID_MAX; + tok.location = last[-1].location; + toks->quick_push (tok); + tok = {}; + tok.type = CPP_EOF; + tok.keyword = RID_MAX; + tok.location = last[-1].location; + tok.flags = tokens_avail; + toks->quick_push (tok); + parser->in_omp_decl_attribute = decl; + parser->tokens = toks->address (); + parser->tokens_avail = toks->length (); + parser->in_omp_attribute_pragma = toks; + c_parser_pragma (parser, pragma_external, NULL); + parser->in_omp_decl_attribute = NULL_TREE; + return true; +} /* OpenMP 4.0: # pragma omp declare target new-line @@ -24526,7 +24621,8 @@ c_parser_omp_declare_target (c_parser *p && c_parser_peek_2nd_token (parser)->type == CPP_NAME)) clauses = c_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK, "#pragma omp declare target"); - else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) + else if (parser->in_omp_decl_attribute + || c_parser_next_token_is (parser, CPP_OPEN_PAREN)) { clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ENTER, clauses); --- gcc/c/c-decl.cc.jj 2023-11-03 14:45:30.914543400 +0100 +++ gcc/c/c-decl.cc 2023-11-03 15:52:04.409276131 +0100 @@ -5385,11 +5385,11 @@ c_decl_attributes (tree *node, tree attr { tree d = TREE_VALUE (a); gcc_assert (TREE_CODE (d) == C_TOKEN_VEC); -/* if (TREE_PUBLIC (d) - && (VAR_P (*decl) - || TREE_CODE (*decl) == FUNCTION_DECL) - && c_maybe_parse_omp_decl (*decl, d)) - continue; */ + if (TREE_PUBLIC (d) + && (VAR_P (*node) + || TREE_CODE (*node) == FUNCTION_DECL) + && c_maybe_parse_omp_decl (*node, d)) + continue; p = TREE_PUBLIC (d) ? "decl" : "directive"; } if (p && !diagnosed) --- gcc/testsuite/gcc.dg/gomp/attrs-19.c.jj 2023-11-03 15:55:55.936182600 +0100 +++ gcc/testsuite/gcc.dg/gomp/attrs-19.c 2023-11-03 16:20:36.602388351 +0100 @@ -0,0 +1,69 @@ +/* { dg-do compile } */ +/* { dg-options "-fopenmp -std=c2x" } */ + +void foo1 (); + +void +foo () +{ + [[omp::decl (declare variant (foo1) match (construct={parallel,for}))]] + extern void foo2 (); + [[omp::sequence (directive (parallel), directive (for))]] + for (int i = 0; i < 5; i++) + foo2 (); + [[omp::decl (declare simd simdlen(4) linear(l) aligned(p:4) uniform(p) inbranch), + omp::directive (declare simd simdlen(8) notinbranch)]] + extern int foo3 (int l, int *p); + [[omp::directive (declare simd simdlen(4) linear(l) aligned(p:4) uniform(p) inbranch), + omp::decl (declare simd simdlen(8) notinbranch)]] + extern int foo4 (int l, int *p); + [[omp::decl (declare simd simdlen(4) linear(l) aligned(p:4) uniform(p) inbranch), + omp::decl (declare simd simdlen(8) notinbranch)]] + extern int foo5 (int l, int *p); +} + +void bar1 (); + +void +bar () +{ + [[omp :: decl (declare variant (bar1), match (construct={parallel,for}))]] + extern void bar2 (); + [[omp::sequence (directive (parallel), directive (for))]] + for (int i = 0; i < 5; i++) + bar2 (); + [[omp::decl (declare simd, simdlen(4), linear(l), aligned(p:4),uniform(p),inbranch), + omp::directive (declare simd simdlen(8) notinbranch)]] + extern int bar3 (int l, int *p); + [[omp::directive (declare simd,simdlen(4),linear(l),aligned(p:4),uniform(p),inbranch), + omp::decl (declare simd, simdlen(8), notinbranch)]] + extern int bar4 (int l, int *p); + [[omp::decl (declare simd, simdlen(4), linear(l), aligned(p:4), uniform(p), inbranch), + omp::decl (declare simd, simdlen(8), notinbranch)]] + extern int bar5 (int l, int *p); +} + +struct S { int s; }; + +[[omp::decl (threadprivate)]] int t1, t2; +int x1, t3 [[omp::decl (threadprivate)]], x2, t4 [[omp::decl (threadprivate)]] [5]; +[[maybe_unused, omp::decl (threadprivate)]] int t5, t6; +[[omp::decl (threadprivate)]] struct S t7, t8; +[[omp::decl (declare target enter device_type (host))]] int d1, d2, d3 (int, int), d4; +int x3, d5 [[omp::decl (declare target, enter, device_type (any))]], d6 [[omp::decl (declare target link)]], x4; +int d7 [[omp::decl (declare target)]]; +[[omp::decl (declare target), omp::decl (declare target)]] int d8, d9; + +void +baz () +{ + [[omp::decl (threadprivate)]] static int t1, t2; + static int x1, t3 [[omp::decl (threadprivate)]], x2, t4 [[omp::decl (threadprivate)]] [5]; + [[maybe_unused, omp::decl (threadprivate)]] extern int t5, t6; + [[omp::decl (declare target enter)]] extern int d1, d2, d3 (int, int), d4; + static int x3, d5 [[omp::decl (declare target, enter, device_type (any))]], d6 [[omp::decl (declare target link)]], x4; + ++t1; ++t2; + ++t3; ++t4[2]; + ++t5; ++t6; + ++d1; +} --- gcc/testsuite/gcc.dg/gomp/attrs-20.c.jj 2023-11-03 15:57:40.055791401 +0100 +++ gcc/testsuite/gcc.dg/gomp/attrs-20.c 2023-11-03 16:04:14.339523175 +0100 @@ -0,0 +1,192 @@ +/* { dg-do compile } */ +/* { dg-options "-fopenmp -std=c2x -ffat-lto-objects -fdump-tree-gimple" } */ + +extern void abort (); + +[[omp::decl (declare simd, linear (l))]] extern int f1 (int l); +extern int f2 (int), f3 [[omp::decl (declare simd, uniform (m))]] (int m), f4 (int), z; +[[omp::decl (declare simd, linear (l), simdlen(4))]] extern int f5 [[omp::decl (declare simd uniform (l) simdlen (8) notinbranch)]] (int l); + +int +f1 (int l) +{ + return l; +} + +/* { dg-final { scan-assembler-times "_ZGVbM4l_f1:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVbN4l_f1:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVcM4l_f1:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVcN4l_f1:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVdM8l_f1:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVdN8l_f1:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVeM16l_f1:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVeN16l_f1:" 1 { target { i?86-*-* x86_64-*-* } } } } */ + +int +f2 (int l) +{ + return l + 1; +} + +/* { dg-final { scan-assembler-not "_ZGV\[a-zA-Z0-9]_f2:" { target { i?86-*-* x86_64-*-* } } } } */ + +int +f3 (int l) +{ + return l + 2; +} + +/* { dg-final { scan-assembler-times "_ZGVbM4u_f3:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVbN4u_f3:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVcM4u_f3:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVcN4u_f3:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVdM8u_f3:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVdN8u_f3:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVeM16u_f3:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVeN16u_f3:" 1 { target { i?86-*-* x86_64-*-* } } } } */ + +int +f4 (int l) +{ + return l + 3; +} + +/* { dg-final { scan-assembler-not "_ZGV\[a-zA-Z0-9]_f4:" { target { i?86-*-* x86_64-*-* } } } } */ + +int +f5 (int l) +{ /* { dg-warning "GCC does not currently support simdlen 8 for type 'int'" "" { target aarch64*-*-* } .-1 } */ + return l + 4; +} + +/* { dg-final { scan-assembler-times "_ZGVbM4l_f5:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVbN4l_f5:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVcM4l_f5:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVcN4l_f5:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVdM4l_f5:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVdN4l_f5:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVeM4l_f5:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVeN4l_f5:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVbN8u_f5:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVcN8u_f5:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVdN8u_f5:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVeN8u_f5:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-not "_ZGV\[bcde]M8u_f5:" { target { i?86-*-* x86_64-*-* } } } } */ + +[[omp::decl (declare simd, linear (l), simdlen(4), notinbranch), + omp::decl (declare simd, uniform (l), simdlen(4), inbranch)]] +int +f6 [[omp::decl (declare simd uniform (l) simdlen (8), notinbranch), + omp::decl (declare simd linear (l) simdlen (8) inbranch)]] (int l) +{ /* { dg-warning "GCC does not currently support simdlen 8 for type 'int'" "" { target aarch64*-*-* } .-2 } */ + return l + 5; +} + +/* { dg-final { scan-assembler-times "_ZGVbM4u_f6:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVbN4l_f6:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVbM8l_f6:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVbN8u_f6:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVcM4u_f6:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVcN4l_f6:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVcM8l_f6:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVcN8u_f6:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVdM4u_f6:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVdN4l_f6:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVdM8l_f6:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVdN8u_f6:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVeM4u_f6:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVeN4l_f6:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVeM8l_f6:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVeN8u_f6:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-not "_ZGV\[bcde]M4l_f6:" { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-not "_ZGV\[bcde]N4u_f6:" { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-not "_ZGV\[bcde]M8u_f6:" { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-not "_ZGV\[bcde]N8l_f6:" { target { i?86-*-* x86_64-*-* } } } } */ + +int +f7 (int l) +{ + return l + 6; +} + +/* { dg-final { scan-assembler-not "_ZGV\[a-zA-Z0-9]_f7:" { target { i?86-*-* x86_64-*-* } } } } */ + +int +f8 (int l) +{ + return l + 7; +} + +/* { dg-final { scan-assembler-not "_ZGV\[a-zA-Z0-9]_f8:" { target { i?86-*-* x86_64-*-* } } } } */ + +[[omp::decl (declare variant (f7), match (construct={parallel})), + omp::decl (declare simd uniform (l), simdlen(4))]] +int +f9 [[omp::decl (declare simd uniform (l) simdlen (8)), + omp::decl (declare variant (f8) match (construct={parallel,for}))]] (int l) +{ /* { dg-warning "GCC does not currently support simdlen 8 for type 'int'" "" { target aarch64*-*-* } .-2 } */ + return l + 8; +} + +/* { dg-final { scan-assembler-times "_ZGVbM4u_f9:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVbN4u_f9:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVcM4u_f9:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVcN4u_f9:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVdM4u_f9:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVdN4u_f9:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVeM4u_f9:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVeN4u_f9:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVbM8u_f9:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVbN8u_f9:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVcM8u_f9:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVcN8u_f9:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVdM8u_f9:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVdN8u_f9:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVeM8u_f9:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVeN8u_f9:" 1 { target { i?86-*-* x86_64-*-* } } } } */ + +int z; + +void +test () +{ + [[omp::directive (parallel)]] + if (f9 (3) != 9) + abort (); + [[omp::directive (parallel for)]] + for (int i = 0; i < 1; i++) + if (f9 (4) != 11) + abort (); + if (f9 (5) != 13) + abort (); +} + +/* { dg-final { scan-tree-dump-times " = f7 \\\(3\\\);" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times " = f8 \\\(4\\\);" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times " = f9 \\\(5\\\);" 1 "gimple" } } */ + +int +f10 (int x) +{ + return x; +} + +[[omp::decl (declare simd, notinbranch)]] int f10 (int); + +/* { dg-final { scan-assembler-times "_ZGVbN4v_f10:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVcN4v_f10:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVdN8v_f10:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVeN16v_f10:" 1 { target { i?86-*-* x86_64-*-* } } } } */ + +int +f11 (int x) +{ + return x + 1; +} + +int f11 [[omp::decl (declare simd inbranch linear(x))]] (int x); + +/* { dg-final { scan-assembler-times "_ZGVbM4l_f11:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVcM4l_f11:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVdM8l_f11:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVeM16l_f11:" 1 { target { i?86-*-* x86_64-*-* } } } } */ --- gcc/testsuite/gcc.dg/gomp/attrs-21.c.jj 2023-11-03 16:04:38.486200542 +0100 +++ gcc/testsuite/gcc.dg/gomp/attrs-21.c 2023-11-03 16:29:34.946165467 +0100 @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-fopenmp -std=c2x" */ + +void +foo () +{ + [[omp::decl]] int v1; /* { dg-error "'omp::decl' attribute requires argument" } */ + [[omp::decl ()]] int v2; /* { dg-error "expected OpenMP directive name" } */ + /* { dg-error "'omp::directive' not allowed to be specified in this context" "" { target *-*-* } .-1 } */ + [[omp::decl (nonexistent foobar)]] int v3; /* { dg-error "unknown OpenMP directive name in 'omp::decl' attribute argument" } */ + /* { dg-error "'omp::directive' not allowed to be specified in this context" "" { target *-*-* } .-1 } */ + [[omp::sequence(decl(threadprivate))]] int v4; /* { dg-error "expected 'directive' or 'sequence'" } */ + /* { dg-error "'omp::directive' not allowed to be specified in this context" "" { target *-*-* } .-1 } */ + [[omp::sequence(omp::decl(threadprivate))]] int v5; /* { dg-error "expected 'directive' or 'sequence'" } */ + /* { dg-error "'omp::directive' not allowed to be specified in this context" "" { target *-*-* } .-1 } */ + [[omp::decl (barrier)]]; /* { dg-error "OpenMP 'omp::decl' attribute on a statement" } */ + [[omp::decl (parallel)]] {}; /* { dg-error "OpenMP 'omp::decl' attribute on a statement" } */ + extern int [[omp::decl (threadprivate)]] *v6; /* { dg-warning "'omp::directive' scoped attribute directive ignored" } */ + [[omp::decl (threadprivate (v5))]] static int v7; /* { dg-error "expected end of line before '\\\(' token" } */ + extern int v8; + [[omp::decl (declare target (v8))]] static int v9; /* { dg-error "expected end of line before '\\\(' token" } */ + [[omp::decl (declare target enter (v8))]] static int v10; /* { dg-error "expected an OpenMP clause before '\\\(' token" } */ + [[omp::decl (declare target, link (v9))]] static int v11; /* { dg-error "expected an OpenMP clause before '\\\(' token" } */ + [[omp::decl (declare target device_type (any))]] static int v12; /* { dg-error "directive with only 'device_type' clause" } */ +} + +int i; +[[omp::decl (assume (i < 42))]]; /* { dg-error "OpenMP 'omp::decl' attribute on a statement" } */ Jakub