From patchwork Thu Oct 29 11:03:34 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 537790 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 175AE140D5F for ; Thu, 29 Oct 2015 22:03:59 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=V11iaLdg; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:reply-to:mime-version :content-type; q=dns; s=default; b=D1y7zMf0FJoQ3iDoXhInkhwQt6nTs ilt+tJ9f2VT7B6z8Q5syQqJziXuuel57MQ+o51bhEWxxHPnZNIIIG5OBuuvWvVyG o5PoHObsCCUZ7LBzW24xb80OjBHOy9SJPlzUSANy4R8Ypk6ktxT6yyvxQHsHLtDE CpaLaDOaXZ9Q6I= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:reply-to:mime-version :content-type; s=default; bh=lD8KGnrsf8aX9XQmjFAi0DPjiCk=; b=V11 iaLdgDZ/rjFK/Gpo6L7I71oyFfKqlrCRP6vq6lq8HVycbZfalb9Ediz7hQAz4+in BSwf/ZkVSaxW9uRYLGNqM2nF9sr/xhlrGlOCmPc+e16ozX5f4LMLvPr8ej4xiLCe kTLTfdz9MI9ni1G0LIeDvNCbbQJjrrm534b7r1bI= Received: (qmail 118905 invoked by alias); 29 Oct 2015 11:03:48 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 118892 invoked by uid 89); 29 Oct 2015 11:03:46 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.8 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Thu, 29 Oct 2015 11:03:41 +0000 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id E4972C0DA357; Thu, 29 Oct 2015 11:03:39 +0000 (UTC) Received: from tucnak.zalov.cz (ovpn-116-121.ams2.redhat.com [10.36.116.121]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9TB3b8q013965 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Thu, 29 Oct 2015 07:03:39 -0400 Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.15.2/8.15.2) with ESMTP id t9TB3aTv022795; Thu, 29 Oct 2015 12:03:36 +0100 Received: (from jakub@localhost) by tucnak.zalov.cz (8.15.2/8.15.2/Submit) id t9TB3YHv022794; Thu, 29 Oct 2015 12:03:34 +0100 Date: Thu, 29 Oct 2015 12:03:34 +0100 From: Jakub Jelinek To: gcc-patches@gcc.gnu.org Cc: "Zamyatin, Igor" Subject: [gomp4.5] Support uniform parameter linear stride in declare simd Message-ID: <20151029110334.GQ478@tucnak.redhat.com> Reply-To: Jakub Jelinek MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) X-IsSubscribed: yes Hi! This patch adds support for uniform linear step in addition to constant linear step, where the step is the value passed in some integral (or reference to integral) argument. The vectorizer part of this isn't ready yet, but that will be just an optimization rather than part of the ABI. Regtested on x86_64-linux, committed to gomp-4_5-branch. I haven't touched Cilk+, once this makes it into the trunk (next week?), it would be nice if the Cilk+ side is changed too to accept it. 2015-10-29 Jakub Jelinek gcc/ * cgraph.h (enum cgraph_simd_clone_arg_type): Add SIMD_CLONE_ARG_TYPE_LINEAR_REF_VARIABLE_STEP, SIMD_CLONE_ARG_TYPE_LINEAR_UVAL_VARIABLE_STEP and SIMD_CLONE_ARG_TYPE_LINEAR_VAL_VARIABLE_STEP. (struct cgraph_simd_clone_arg): Adjust comment. * omp-low.c (simd_clone_clauses_extract): Handle variable step for references and arguments passed by reference. (simd_clone_mangle): Mangle ref/uval/val variable steps. (simd_clone_adjust_argument_types): Handle SIMD_CLONE_ARG_TYPE_LINEAR_UVAL_VARIABLE_STEP like SIMD_CLONE_ARG_TYPE_LINEAR_UVAL_CONSTANT_STEP and SIMD_CLONE_ARG_TYPE_LINEAR_VAL_VARIABLE_STEP like SIMD_CLONE_ARG_TYPE_LINEAR_VAL_CONSTANT_STEP. (simd_clone_linear_addend): New function. (simd_clone_adjust): Handle variable step like similarly to constant step, use simd_clone_linear_addend to determine the actual step at runtime. gcc/c-family/ * c-omp.c (c_omp_declare_simd_clauses_to_numbers): Change OMP_CLAUSE_LINEAR_VARIABLE_STRIDE OMP_CLAUSE_LINEAR_STEP into numbers. (c_omp_declare_simd_clauses_to_decls): Similarly change those from numbers to PARM_DECLs. gcc/c/ * c-typeck.c (c_finish_omp_clauses): Diagnose if linear step on declare simd is neither a constant nor a uniform parameter. gcc/cp/ * parser.c (cp_parser_omp_clause_linear): Add DECLARE_SIMD argument. Parse parameter name as linear step as id-expression rather than expression. (cp_parser_omp_all_clauses): Adjust caller. * pt.c (tsubst_omp_clauses): If OMP_CLAUSE_LINEAR_VARIABLE_STRIDE, use tsubst_omp_clause_decl instead of tsubst_expr on OMP_CLAUSE_LINEAR_STEP. * semantics.c (finish_omp_clauses): Diagnose if linear step on declare simd is neither a constant nor a uniform parameter. gcc/testsuite/ * gcc.dg/gomp/declare-simd-1.c: Add scan-assembler-times directives for expected mangling on x86_64/i?86. * gcc.dg/gomp/declare-simd-3.c: New test. * gcc.dg/gomp/declare-simd-4.c: New test. * g++.dg/gomp/declare-simd-1.C: Add dg-options. Add scan-assembler-times directives for expected mangling on x86_64/i?86. * g++.dg/gomp/declare-simd-3.C: Likewise. * g++.dg/gomp/declare-simd-4.C: New test. * g++.dg/gomp/declare-simd-5.C: New test. Jakub --- gcc/cgraph.h.jj 2015-10-14 10:24:55.000000000 +0200 +++ gcc/cgraph.h 2015-10-27 10:40:08.780100715 +0100 @@ -646,11 +646,14 @@ enum cgraph_simd_clone_arg_type /* These are only for integer/pointer arguments passed by value. */ SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP, SIMD_CLONE_ARG_TYPE_LINEAR_VARIABLE_STEP, - /* These 3 are only for reference type arguments or arguments passed + /* These 6 are only for reference type arguments or arguments passed by reference. */ SIMD_CLONE_ARG_TYPE_LINEAR_REF_CONSTANT_STEP, + SIMD_CLONE_ARG_TYPE_LINEAR_REF_VARIABLE_STEP, SIMD_CLONE_ARG_TYPE_LINEAR_UVAL_CONSTANT_STEP, + SIMD_CLONE_ARG_TYPE_LINEAR_UVAL_VARIABLE_STEP, SIMD_CLONE_ARG_TYPE_LINEAR_VAL_CONSTANT_STEP, + SIMD_CLONE_ARG_TYPE_LINEAR_VAL_VARIABLE_STEP, SIMD_CLONE_ARG_TYPE_MASK }; @@ -692,7 +695,7 @@ struct GTY(()) cgraph_simd_clone_arg { /* For arg_type SIMD_CLONE_ARG_TYPE_LINEAR_*CONSTANT_STEP this is the constant linear step, if arg_type is - SIMD_CLONE_ARG_TYPE_LINEAR_VARIABLE_STEP, this is index of + SIMD_CLONE_ARG_TYPE_LINEAR_*VARIABLE_STEP, this is index of the uniform argument holding the step, otherwise 0. */ HOST_WIDE_INT linear_step; --- gcc/omp-low.c.jj 2015-10-26 15:38:20.000000000 +0100 +++ gcc/omp-low.c 2015-10-27 17:55:05.146748148 +0100 @@ -16318,8 +16318,29 @@ simd_clone_clauses_extract (struct cgrap int argno = TREE_INT_CST_LOW (decl); if (OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (t)) { - clone_info->args[argno].arg_type - = SIMD_CLONE_ARG_TYPE_LINEAR_VARIABLE_STEP; + enum cgraph_simd_clone_arg_type arg_type; + if (TREE_CODE (args[argno]) == REFERENCE_TYPE) + switch (OMP_CLAUSE_LINEAR_KIND (t)) + { + case OMP_CLAUSE_LINEAR_REF: + arg_type + = SIMD_CLONE_ARG_TYPE_LINEAR_REF_VARIABLE_STEP; + break; + case OMP_CLAUSE_LINEAR_UVAL: + arg_type + = SIMD_CLONE_ARG_TYPE_LINEAR_UVAL_VARIABLE_STEP; + break; + case OMP_CLAUSE_LINEAR_VAL: + case OMP_CLAUSE_LINEAR_DEFAULT: + arg_type + = SIMD_CLONE_ARG_TYPE_LINEAR_VAL_VARIABLE_STEP; + break; + default: + gcc_unreachable (); + } + else + arg_type = SIMD_CLONE_ARG_TYPE_LINEAR_VARIABLE_STEP; + clone_info->args[argno].arg_type = arg_type; clone_info->args[argno].linear_step = tree_to_shwi (step); gcc_assert (clone_info->args[argno].linear_step >= 0 && clone_info->args[argno].linear_step < n); @@ -16497,7 +16518,19 @@ simd_clone_mangle (struct cgraph_node *n } break; case SIMD_CLONE_ARG_TYPE_LINEAR_VARIABLE_STEP: - pp_character (&pp, 's'); + pp_string (&pp, "ls"); + pp_unsigned_wide_integer (&pp, arg.linear_step); + break; + case SIMD_CLONE_ARG_TYPE_LINEAR_REF_VARIABLE_STEP: + pp_string (&pp, "Rs"); + pp_unsigned_wide_integer (&pp, arg.linear_step); + break; + case SIMD_CLONE_ARG_TYPE_LINEAR_VAL_VARIABLE_STEP: + pp_string (&pp, "Ls"); + pp_unsigned_wide_integer (&pp, arg.linear_step); + break; + case SIMD_CLONE_ARG_TYPE_LINEAR_UVAL_VARIABLE_STEP: + pp_string (&pp, "Us"); pp_unsigned_wide_integer (&pp, arg.linear_step); break; default: @@ -16687,6 +16720,7 @@ simd_clone_adjust_argument_types (struct adj.op = IPA_PARM_OP_COPY; break; case SIMD_CLONE_ARG_TYPE_LINEAR_UVAL_CONSTANT_STEP: + case SIMD_CLONE_ARG_TYPE_LINEAR_UVAL_VARIABLE_STEP: if (node->definition) node->simdclone->args[i].simd_array = create_tmp_simd_array (IDENTIFIER_POINTER (DECL_NAME (parm)), @@ -16695,6 +16729,7 @@ simd_clone_adjust_argument_types (struct adj.op = IPA_PARM_OP_COPY; break; case SIMD_CLONE_ARG_TYPE_LINEAR_VAL_CONSTANT_STEP: + case SIMD_CLONE_ARG_TYPE_LINEAR_VAL_VARIABLE_STEP: case SIMD_CLONE_ARG_TYPE_VECTOR: if (INTEGRAL_TYPE_P (parm_type) || POINTER_TYPE_P (parm_type)) veclen = node->simdclone->vecsize_int; @@ -17082,6 +17117,74 @@ ipa_simd_modify_function_body (struct cg } } +/* Helper function of simd_clone_adjust, return linear step addend + of Ith argument. */ + +static tree +simd_clone_linear_addend (struct cgraph_node *node, unsigned int i, + tree addtype, basic_block entry_bb) +{ + tree ptype = NULL_TREE; + switch (node->simdclone->args[i].arg_type) + { + case SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP: + case SIMD_CLONE_ARG_TYPE_LINEAR_REF_CONSTANT_STEP: + case SIMD_CLONE_ARG_TYPE_LINEAR_VAL_CONSTANT_STEP: + case SIMD_CLONE_ARG_TYPE_LINEAR_UVAL_CONSTANT_STEP: + return build_int_cst (addtype, node->simdclone->args[i].linear_step); + case SIMD_CLONE_ARG_TYPE_LINEAR_VARIABLE_STEP: + case SIMD_CLONE_ARG_TYPE_LINEAR_REF_VARIABLE_STEP: + ptype = TREE_TYPE (node->simdclone->args[i].orig_arg); + break; + case SIMD_CLONE_ARG_TYPE_LINEAR_VAL_VARIABLE_STEP: + case SIMD_CLONE_ARG_TYPE_LINEAR_UVAL_VARIABLE_STEP: + ptype = TREE_TYPE (TREE_TYPE (node->simdclone->args[i].orig_arg)); + break; + default: + gcc_unreachable (); + } + + unsigned int idx = node->simdclone->args[i].linear_step; + tree arg = node->simdclone->args[idx].orig_arg; + gcc_assert (is_gimple_reg_type (TREE_TYPE (arg))); + gimple_stmt_iterator gsi = gsi_after_labels (entry_bb); + gimple *g; + tree ret; + if (is_gimple_reg (arg)) + ret = get_or_create_ssa_default_def (cfun, arg); + else + { + g = gimple_build_assign (make_ssa_name (TREE_TYPE (arg)), arg); + gsi_insert_before (&gsi, g, GSI_SAME_STMT); + ret = gimple_assign_lhs (g); + } + if (TREE_CODE (TREE_TYPE (arg)) == REFERENCE_TYPE) + { + g = gimple_build_assign (make_ssa_name (TREE_TYPE (TREE_TYPE (arg))), + build_simple_mem_ref (ret)); + gsi_insert_before (&gsi, g, GSI_SAME_STMT); + ret = gimple_assign_lhs (g); + } + if (!useless_type_conversion_p (addtype, TREE_TYPE (ret))) + { + g = gimple_build_assign (make_ssa_name (addtype), NOP_EXPR, ret); + gsi_insert_before (&gsi, g, GSI_SAME_STMT); + ret = gimple_assign_lhs (g); + } + if (POINTER_TYPE_P (ptype)) + { + tree size = TYPE_SIZE_UNIT (TREE_TYPE (ptype)); + if (size && TREE_CODE (size) == INTEGER_CST) + { + g = gimple_build_assign (make_ssa_name (addtype), MULT_EXPR, + ret, fold_convert (addtype, size)); + gsi_insert_before (&gsi, g, GSI_SAME_STMT); + ret = gimple_assign_lhs (g); + } + } + return ret; +} + /* Adjust the argument types in NODE to their appropriate vector counterparts. */ @@ -17321,7 +17424,11 @@ simd_clone_adjust (struct cgraph_node *n else if ((node->simdclone->args[i].arg_type == SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP) || (node->simdclone->args[i].arg_type - == SIMD_CLONE_ARG_TYPE_LINEAR_REF_CONSTANT_STEP)) + == SIMD_CLONE_ARG_TYPE_LINEAR_REF_CONSTANT_STEP) + || (node->simdclone->args[i].arg_type + == SIMD_CLONE_ARG_TYPE_LINEAR_VARIABLE_STEP) + || (node->simdclone->args[i].arg_type + == SIMD_CLONE_ARG_TYPE_LINEAR_REF_VARIABLE_STEP)) { tree orig_arg = node->simdclone->args[i].orig_arg; gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (orig_arg)) @@ -17356,10 +17463,10 @@ simd_clone_adjust (struct cgraph_node *n ? PLUS_EXPR : POINTER_PLUS_EXPR; tree addtype = INTEGRAL_TYPE_P (TREE_TYPE (orig_arg)) ? TREE_TYPE (orig_arg) : sizetype; - tree addcst - = build_int_cst (addtype, node->simdclone->args[i].linear_step); - g = gimple_build_assign (iter2, code, iter1, addcst); + tree addcst = simd_clone_linear_addend (node, i, addtype, + entry_bb); gsi = gsi_last_bb (incr_bb); + g = gimple_build_assign (iter2, code, iter1, addcst); gsi_insert_before (&gsi, g, GSI_SAME_STMT); imm_use_iterator iter; @@ -17381,7 +17488,9 @@ simd_clone_adjust (struct cgraph_node *n } } else if (node->simdclone->args[i].arg_type - == SIMD_CLONE_ARG_TYPE_LINEAR_UVAL_CONSTANT_STEP) + == SIMD_CLONE_ARG_TYPE_LINEAR_UVAL_CONSTANT_STEP + || (node->simdclone->args[i].arg_type + == SIMD_CLONE_ARG_TYPE_LINEAR_UVAL_VARIABLE_STEP)) { tree orig_arg = node->simdclone->args[i].orig_arg; tree def = ssa_default_def (cfun, orig_arg); @@ -17418,8 +17527,8 @@ simd_clone_adjust (struct cgraph_node *n ? PLUS_EXPR : POINTER_PLUS_EXPR; tree addtype = INTEGRAL_TYPE_P (TREE_TYPE (iter3)) ? TREE_TYPE (iter3) : sizetype; - tree addcst - = build_int_cst (addtype, node->simdclone->args[i].linear_step); + tree addcst = simd_clone_linear_addend (node, i, addtype, + entry_bb); g = gimple_build_assign (iter5, code, iter4, addcst); gsi = gsi_last_bb (incr_bb); gsi_insert_before (&gsi, g, GSI_SAME_STMT); --- gcc/c-family/c-omp.c.jj 2015-10-22 14:35:41.000000000 +0200 +++ gcc/c-family/c-omp.c 2015-10-27 12:27:26.355609515 +0100 @@ -1349,6 +1349,23 @@ c_omp_declare_simd_clauses_to_numbers (t continue; } OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, idx); + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR + && OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (c)) + { + decl = OMP_CLAUSE_LINEAR_STEP (c); + for (arg = parms, idx = 0; arg; + arg = TREE_CHAIN (arg), idx++) + if (arg == decl) + break; + if (arg == NULL_TREE) + { + error_at (OMP_CLAUSE_LOCATION (c), + "%qD is not an function argument", decl); + continue; + } + OMP_CLAUSE_LINEAR_STEP (c) + = build_int_cst (integer_type_node, idx); + } } clvec.safe_push (c); } @@ -1386,6 +1403,17 @@ c_omp_declare_simd_clauses_to_decls (tre break; gcc_assert (arg); OMP_CLAUSE_DECL (c) = arg; + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR + && OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (c)) + { + idx = tree_to_shwi (OMP_CLAUSE_LINEAR_STEP (c)); + for (arg = DECL_ARGUMENTS (fndecl), i = 0; arg; + arg = TREE_CHAIN (arg), i++) + if (i == idx) + break; + gcc_assert (arg); + OMP_CLAUSE_LINEAR_STEP (c) = arg; + } } } --- gcc/c/c-typeck.c.jj 2015-10-19 13:02:17.000000000 +0200 +++ gcc/c/c-typeck.c 2015-10-27 15:32:03.448956552 +0100 @@ -12244,6 +12244,7 @@ c_finish_omp_clauses (tree clauses, bool tree simdlen = NULL_TREE, safelen = NULL_TREE; bool branch_seen = false; bool copyprivate_seen = false; + bool linear_variable_step_check = false; tree *nowait_clause = NULL; bool ordered_seen = false; tree schedule_clause = NULL_TREE; @@ -12527,6 +12528,27 @@ c_finish_omp_clauses (tree clauses, bool remove = true; break; } + if (declare_simd) + { + tree s = OMP_CLAUSE_LINEAR_STEP (c); + if (TREE_CODE (s) == PARM_DECL) + { + OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (c) = 1; + /* map_head bitmap is used as uniform_head if + declare_simd. */ + if (!bitmap_bit_p (&map_head, DECL_UID (s))) + linear_variable_step_check = true; + goto check_dup_generic; + } + if (TREE_CODE (s) != INTEGER_CST) + { + error_at (OMP_CLAUSE_LOCATION (c), + "% clause step %qE is neither constant " + "nor a parameter", s); + remove = true; + break; + } + } if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c))) == POINTER_TYPE) { tree s = OMP_CLAUSE_LINEAR_STEP (c); @@ -12907,6 +12929,8 @@ c_finish_omp_clauses (tree clauses, bool remove = true; break; } + /* map_head bitmap is used as uniform_head if declare_simd. */ + bitmap_set_bit (&map_head, DECL_UID (t)); goto check_dup_generic; case OMP_CLAUSE_IS_DEVICE_PTR: @@ -13110,6 +13134,28 @@ c_finish_omp_clauses (tree clauses, bool & ~OMP_CLAUSE_SCHEDULE_NONMONOTONIC); } + if (linear_variable_step_check) + for (pc = &clauses, c = clauses; c ; c = *pc) + { + bool remove = false; + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR + && OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (c) + && !bitmap_bit_p (&map_head, + DECL_UID (OMP_CLAUSE_LINEAR_STEP (c)))) + { + error_at (OMP_CLAUSE_LOCATION (c), + "% clause step is a parameter %qD not " + "specified in % clause", + OMP_CLAUSE_LINEAR_STEP (c)); + remove = true; + } + + if (remove) + *pc = OMP_CLAUSE_CHAIN (c); + else + pc = &OMP_CLAUSE_CHAIN (c); + } + bitmap_obstack_release (NULL); return clauses; } --- gcc/cp/parser.c.jj 2015-10-26 15:38:20.000000000 +0100 +++ gcc/cp/parser.c 2015-10-27 16:31:04.474074399 +0100 @@ -30749,7 +30749,7 @@ cp_parser_omp_clause_aligned (cp_parser static tree cp_parser_omp_clause_linear (cp_parser *parser, tree list, - bool is_cilk_simd_fn) + bool is_cilk_simd_fn, bool declare_simd) { tree nlist, c, step = integer_one_node; bool colon; @@ -30793,7 +30793,30 @@ cp_parser_omp_clause_linear (cp_parser * if (colon) { - step = cp_parser_expression (parser); + step = NULL_TREE; + if (declare_simd + && cp_lexer_next_token_is (parser->lexer, CPP_NAME) + && cp_lexer_nth_token_is (parser->lexer, 2, CPP_CLOSE_PAREN)) + { + cp_token *token = cp_lexer_peek_token (parser->lexer); + cp_parser_parse_tentatively (parser); + step = cp_parser_id_expression (parser, /*template_p=*/false, + /*check_dependency_p=*/true, + /*template_p=*/NULL, + /*declarator_p=*/false, + /*optional_p=*/false); + if (step != error_mark_node) + step = cp_parser_lookup_name_simple (parser, step, token->location); + if (step == error_mark_node) + { + step = NULL_TREE; + cp_parser_abort_tentative_parse (parser); + } + else if (!cp_parser_parse_definitely (parser)) + step = NULL_TREE; + } + if (!step) + step = cp_parser_expression (parser); if (is_cilk_simd_fn && TREE_CODE (step) == PARM_DECL) { @@ -31448,7 +31471,6 @@ cp_parser_omp_all_clauses (cp_parser *pa tree clauses = NULL; bool first = true; cp_token *token = NULL; - bool cilk_simd_fn = false; while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL)) { @@ -31662,9 +31684,15 @@ cp_parser_omp_all_clauses (cp_parser *pa c_name = "aligned"; break; case PRAGMA_OMP_CLAUSE_LINEAR: - if (((mask >> PRAGMA_CILK_CLAUSE_VECTORLENGTH) & 1) != 0) - cilk_simd_fn = true; - clauses = cp_parser_omp_clause_linear (parser, clauses, cilk_simd_fn); + { + bool cilk_simd_fn = false, declare_simd = false; + if (((mask >> PRAGMA_CILK_CLAUSE_VECTORLENGTH) & 1) != 0) + cilk_simd_fn = true; + else if (((mask >> PRAGMA_OMP_CLAUSE_UNIFORM) & 1) != 0) + declare_simd = true; + clauses = cp_parser_omp_clause_linear (parser, clauses, + cilk_simd_fn, declare_simd); + } c_name = "linear"; break; case PRAGMA_OMP_CLAUSE_DEPEND: --- gcc/cp/pt.c.jj 2015-10-26 15:38:20.000000000 +0100 +++ gcc/cp/pt.c 2015-10-27 17:04:36.447240807 +0100 @@ -14416,7 +14416,6 @@ tsubst_omp_clauses (tree clauses, bool d = tsubst_omp_clause_decl (OMP_CLAUSE_DECL (oc), args, complain, in_decl); break; - case OMP_CLAUSE_LINEAR: case OMP_CLAUSE_ALIGNED: OMP_CLAUSE_DECL (nc) = tsubst_omp_clause_decl (OMP_CLAUSE_DECL (oc), args, complain, @@ -14424,12 +14423,25 @@ tsubst_omp_clauses (tree clauses, bool d OMP_CLAUSE_OPERAND (nc, 1) = tsubst_expr (OMP_CLAUSE_OPERAND (oc, 1), args, complain, in_decl, /*integral_constant_expression_p=*/false); - if (OMP_CLAUSE_CODE (oc) == OMP_CLAUSE_LINEAR - && OMP_CLAUSE_LINEAR_STEP (oc) == NULL_TREE) + break; + case OMP_CLAUSE_LINEAR: + OMP_CLAUSE_DECL (nc) + = tsubst_omp_clause_decl (OMP_CLAUSE_DECL (oc), args, complain, + in_decl); + if (OMP_CLAUSE_LINEAR_STEP (oc) == NULL_TREE) { gcc_assert (!linear_no_step); linear_no_step = nc; } + else if (OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (oc)) + OMP_CLAUSE_LINEAR_STEP (nc) + = tsubst_omp_clause_decl (OMP_CLAUSE_LINEAR_STEP (oc), args, + complain, in_decl); + else + OMP_CLAUSE_LINEAR_STEP (nc) + = tsubst_expr (OMP_CLAUSE_LINEAR_STEP (oc), args, complain, + in_decl, + /*integral_constant_expression_p=*/false); break; case OMP_CLAUSE_NOWAIT: case OMP_CLAUSE_DEFAULT: --- gcc/cp/semantics.c.jj 2015-10-19 15:58:13.000000000 +0200 +++ gcc/cp/semantics.c 2015-10-27 16:39:22.188937105 +0100 @@ -5768,7 +5768,11 @@ finish_omp_clauses (tree clauses, bool a break; } else if (!type_dependent_expression_p (t) - && !INTEGRAL_TYPE_P (TREE_TYPE (t))) + && !INTEGRAL_TYPE_P (TREE_TYPE (t)) + && (!declare_simd + || TREE_CODE (t) != PARM_DECL + || TREE_CODE (TREE_TYPE (t)) != REFERENCE_TYPE + || !INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (t))))) { error ("linear step expression must be integral"); remove = true; @@ -5777,12 +5781,27 @@ finish_omp_clauses (tree clauses, bool a else { t = mark_rvalue_use (t); + if (declare_simd && TREE_CODE (t) == PARM_DECL) + { + OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (c) = 1; + goto check_dup_generic; + } if (!processing_template_decl && (VAR_P (OMP_CLAUSE_DECL (c)) || TREE_CODE (OMP_CLAUSE_DECL (c)) == PARM_DECL)) { - if (TREE_CODE (OMP_CLAUSE_DECL (c)) == PARM_DECL) - t = maybe_constant_value (t); + if (declare_simd) + { + t = maybe_constant_value (t); + if (TREE_CODE (t) != INTEGER_CST) + { + error_at (OMP_CLAUSE_LOCATION (c), + "% clause step %qE is neither " + "constant nor a parameter", t); + remove = true; + break; + } + } t = fold_build_cleanup_point_expr (TREE_TYPE (t), t); tree type = TREE_TYPE (OMP_CLAUSE_DECL (c)); if (TREE_CODE (type) == REFERENCE_TYPE) @@ -6602,6 +6621,8 @@ finish_omp_clauses (tree clauses, bool a remove = true; break; } + /* map_head bitmap is used as uniform_head if declare_simd. */ + bitmap_set_bit (&map_head, DECL_UID (t)); goto check_dup_generic; case OMP_CLAUSE_NUM_TASKS: @@ -6817,6 +6838,17 @@ finish_omp_clauses (tree clauses, bool a case OMP_CLAUSE_LINEAR: if (!declare_simd) need_implicitly_determined = true; + else if (OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (c) + && !bitmap_bit_p (&map_head, + DECL_UID (OMP_CLAUSE_LINEAR_STEP (c)))) + { + error_at (OMP_CLAUSE_LOCATION (c), + "% clause step is a parameter %qD not " + "specified in % clause", + OMP_CLAUSE_LINEAR_STEP (c)); + *pc = OMP_CLAUSE_CHAIN (c); + continue; + } break; case OMP_CLAUSE_COPYPRIVATE: need_copy_assignment = true; --- gcc/testsuite/gcc.dg/gomp/declare-simd-1.c.jj 2015-10-14 10:25:21.210143048 +0200 +++ gcc/testsuite/gcc.dg/gomp/declare-simd-1.c 2015-10-27 18:29:51.782873833 +0100 @@ -13,6 +13,13 @@ int f2 (int a, int *b, int c) return a + *b + c; } +/* { dg-final { scan-assembler-times "_ZGVbM8uva32l4_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVbN8uva32l4_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVcM8uva32l4_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVcN8uva32l4_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVdM8uva32l4_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVdN8uva32l4_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */ + #pragma omp declare simd uniform (a) aligned (b : 8 * sizeof (long long)) linear (c : 4) simdlen (8) __extension__ long long f3 (long long a, long long *b, long long c); @@ -40,6 +47,13 @@ f7 (int x) return x; } +/* { dg-final { scan-assembler-times "_ZGVbM16v_f7:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVbN16v_f7:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVcM16v_f7:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVcN16v_f7:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVdM16v_f7:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVdN16v_f7:" 1 { target { i?86-*-* x86_64-*-* } } } } */ + int f9 (int x) { @@ -62,6 +76,13 @@ f13 (int c; int *b; int a; int a, int *b return a + *b + c; } +/* { dg-final { scan-assembler-times "_ZGVbM8uva32l4_f13:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVbN8uva32l4_f13:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVcM8uva32l4_f13:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVcN8uva32l4_f13:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVdM8uva32l4_f13:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVdN8uva32l4_f13:" 1 { target { i?86-*-* x86_64-*-* } } } } */ + #pragma omp declare simd uniform (a) aligned (b : 8 * sizeof (int)) linear (c : 4) simdlen (8) int f14 (a, b, c) @@ -71,6 +92,13 @@ f14 (a, b, c) return a + *b + c; } +/* { dg-final { scan-assembler-times "_ZGVbM8uva32l4_f14:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVbN8uva32l4_f14:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVcM8uva32l4_f14:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVcN8uva32l4_f14:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVdM8uva32l4_f14:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVdN8uva32l4_f14:" 1 { target { i?86-*-* x86_64-*-* } } } } */ + #pragma omp declare simd uniform (a) aligned (b : 8 * sizeof (int)) linear (c : 4) simdlen (8) int f15 (int a, int *b, int c) @@ -78,6 +106,13 @@ f15 (int a, int *b, int c) return a + *b + c; } +/* { dg-final { scan-assembler-times "_ZGVbM8uva32l4_f15:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVbN8uva32l4_f15:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVcM8uva32l4_f15:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVcN8uva32l4_f15:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVdM8uva32l4_f15:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVdN8uva32l4_f15:" 1 { target { i?86-*-* x86_64-*-* } } } } */ + #pragma omp declare simd uniform (d) aligned (e : 8 * sizeof (int)) linear (f : 4) simdlen (8) int f15 (int d, int *e, int f); @@ -90,6 +125,19 @@ int f17 (int g, long *h) return g + h[0]; } +/* { dg-final { scan-assembler-times "_ZGVbM4l20va8_f17:" 1 { target { { i?86-*-* x86_64-*-* } && lp64 } } } } */ +/* { dg-final { scan-assembler-times "_ZGVbN4l20va8_f17:" 1 { target { { i?86-*-* x86_64-*-* } && lp64 } } } } */ +/* { dg-final { scan-assembler-times "_ZGVcM4l20va8_f17:" 1 { target { { i?86-*-* x86_64-*-* } && lp64 } } } } */ +/* { dg-final { scan-assembler-times "_ZGVcN4l20va8_f17:" 1 { target { { i?86-*-* x86_64-*-* } && lp64 } } } } */ +/* { dg-final { scan-assembler-times "_ZGVdM4l20va8_f17:" 1 { target { { i?86-*-* x86_64-*-* } && lp64 } } } } */ +/* { dg-final { scan-assembler-times "_ZGVdN4l20va8_f17:" 1 { target { { i?86-*-* x86_64-*-* } && lp64 } } } } */ +/* { dg-final { scan-assembler-times "_ZGVbM4l12va4_f17:" 1 { target { { i?86-*-* x86_64-*-* } && ilp32 } } } } */ +/* { dg-final { scan-assembler-times "_ZGVbN4l12va4_f17:" 1 { target { { i?86-*-* x86_64-*-* } && ilp32 } } } } */ +/* { dg-final { scan-assembler-times "_ZGVcM4l12va4_f17:" 1 { target { { i?86-*-* x86_64-*-* } && ilp32 } } } } */ +/* { dg-final { scan-assembler-times "_ZGVcN4l12va4_f17:" 1 { target { { i?86-*-* x86_64-*-* } && ilp32 } } } } */ +/* { dg-final { scan-assembler-times "_ZGVdM4l12va4_f17:" 1 { target { { i?86-*-* x86_64-*-* } && ilp32 } } } } */ +/* { dg-final { scan-assembler-times "_ZGVdN4l12va4_f17:" 1 { target { { i?86-*-* x86_64-*-* } && ilp32 } } } } */ + #pragma omp declare simd aligned (i : sizeof (*i)) linear (j : 2 * sizeof (i[0]) + sizeof (j)) simdlen (4) int f18 (j, i) @@ -98,3 +146,16 @@ f18 (j, i) { return j + i[0]; } + +/* { dg-final { scan-assembler-times "_ZGVbM4l20va8_f18:" 1 { target { { i?86-*-* x86_64-*-* } && lp64 } } } } */ +/* { dg-final { scan-assembler-times "_ZGVbN4l20va8_f18:" 1 { target { { i?86-*-* x86_64-*-* } && lp64 } } } } */ +/* { dg-final { scan-assembler-times "_ZGVcM4l20va8_f18:" 1 { target { { i?86-*-* x86_64-*-* } && lp64 } } } } */ +/* { dg-final { scan-assembler-times "_ZGVcN4l20va8_f18:" 1 { target { { i?86-*-* x86_64-*-* } && lp64 } } } } */ +/* { dg-final { scan-assembler-times "_ZGVdM4l20va8_f18:" 1 { target { { i?86-*-* x86_64-*-* } && lp64 } } } } */ +/* { dg-final { scan-assembler-times "_ZGVdN4l20va8_f18:" 1 { target { { i?86-*-* x86_64-*-* } && lp64 } } } } */ +/* { dg-final { scan-assembler-times "_ZGVbM4l12va4_f18:" 1 { target { { i?86-*-* x86_64-*-* } && ilp32 } } } } */ +/* { dg-final { scan-assembler-times "_ZGVbN4l12va4_f18:" 1 { target { { i?86-*-* x86_64-*-* } && ilp32 } } } } */ +/* { dg-final { scan-assembler-times "_ZGVcM4l12va4_f18:" 1 { target { { i?86-*-* x86_64-*-* } && ilp32 } } } } */ +/* { dg-final { scan-assembler-times "_ZGVcN4l12va4_f18:" 1 { target { { i?86-*-* x86_64-*-* } && ilp32 } } } } */ +/* { dg-final { scan-assembler-times "_ZGVdM4l12va4_f18:" 1 { target { { i?86-*-* x86_64-*-* } && ilp32 } } } } */ +/* { dg-final { scan-assembler-times "_ZGVdN4l12va4_f18:" 1 { target { { i?86-*-* x86_64-*-* } && ilp32 } } } } */ --- gcc/testsuite/gcc.dg/gomp/declare-simd-3.c.jj 2015-10-27 18:25:01.280033083 +0100 +++ gcc/testsuite/gcc.dg/gomp/declare-simd-3.c 2015-10-27 18:24:27.000000000 +0100 @@ -0,0 +1,24 @@ +#pragma omp declare simd linear(p:1) linear(val(q):-1) linear(s:-3) +int +f1 (int *p, int *q, short *s) +{ + return *p + *q + *s; +} + +/* { dg-final { scan-assembler-times "_ZGVbM4l4ln4ln6_f1:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVbN4l4ln4ln6_f1:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVcM4l4ln4ln6_f1:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVcN4l4ln4ln6_f1:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVdM8l4ln4ln6_f1:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVdN8l4ln4ln6_f1:" 1 { target { i?86-*-* x86_64-*-* } } } } */ + +#pragma omp declare simd linear(p:s) linear(q:t) uniform (s) linear(r:s) notinbranch simdlen(8) uniform(t) +int +f2 (int *p, short *q, int s, int r, int t) +{ + return *p + *q + r; +} + +/* { dg-final { scan-assembler-times "_ZGVbN8ls2ls4uls2u_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVcN8ls2ls4uls2u_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */ +/* { dg-final { scan-assembler-times "_ZGVdN8ls2ls4uls2u_f2:" 1 { target { i?86-*-* x86_64-*-* } } } } */ --- gcc/testsuite/gcc.dg/gomp/declare-simd-4.c.jj 2015-10-29 11:07:16.935676661 +0100 +++ gcc/testsuite/gcc.dg/gomp/declare-simd-4.c 2015-10-29 11:24:40.194596975 +0100 @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-fopenmp-simd" } */ + +#pragma omp declare simd linear(a:1 + b) uniform(b) /* { dg-error ".linear. clause step .b \\+ 1. is neither constant nor a parameter" } */ +int f1 (int a, int b); +#pragma omp declare simd linear(a:b + 1) uniform(b) /* { dg-error ".linear. clause step .b \\+ 1. is neither constant nor a parameter" } */ +int f2 (int a, int b); +#pragma omp declare simd linear(a:2 * b) uniform(b) /* { dg-error ".linear. clause step .b \\* 2. is neither constant nor a parameter" } */ +int f3 (int a, int b); +#pragma omp declare simd linear(a:b) /* { dg-error ".linear. clause step is a parameter .b. not specified in .uniform. clause" } */ +int f4 (int a, int b); +#pragma omp declare simd linear(a:b) linear(b:1) /* { dg-error ".linear. clause step is a parameter .b. not specified in .uniform. clause" } */ +int f5 (int a, int b); +#pragma omp declare simd linear(a:5 + 2 * 3) +int f6 (int a, int b); +const int c = 5; +#pragma omp declare simd linear(a:c) /* { dg-error ".linear. clause step .c. is neither constant nor a parameter" } */ +int f7 (int a, int b); +#pragma omp declare simd linear(a:2 * c + 1) /* { dg-error ".linear. clause step .\[^\n\r]*. is neither constant nor a parameter" } */ +int f8 (int a, int b); +#pragma omp declare simd linear(a:0.5) /* { dg-error ".linear. clause step expression must be integral" } */ +int f9 (int a, int b); --- gcc/testsuite/g++.dg/gomp/declare-simd-1.C.jj 2015-10-14 10:25:28.000000000 +0200 +++ gcc/testsuite/g++.dg/gomp/declare-simd-1.C 2015-10-27 17:53:39.335978787 +0100 @@ -1,5 +1,6 @@ // Test parsing of #pragma omp declare simd // { dg-do compile } +// { dg-options "-fopenmp -ffat-lto-objects" } #pragma omp declare simd uniform (a) aligned (b : 8 * sizeof (int)) \ linear (c : 4) simdlen (8) notinbranch @@ -13,6 +14,13 @@ int f2 (int a, int *b, int c) return a + *b + c; } +// { dg-final { scan-assembler-times "_ZGVbM8uva32l4__Z2f2iPii:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVbN8uva32l4__Z2f2iPii:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcM8uva32l4__Z2f2iPii:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcN8uva32l4__Z2f2iPii:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdM8uva32l4__Z2f2iPii:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdN8uva32l4__Z2f2iPii:" 1 { target { i?86-*-* x86_64-*-* } } } } + #pragma omp declare simd uniform (c) aligned (b : 4 * sizeof (int)) linear (a : 4) simdlen (4) template T f3 (int a, int *b, T c); @@ -71,6 +79,13 @@ namespace N1 } } +// { dg-final { scan-assembler-times "_ZGVbM2va16__ZN2N12N23f10EPx:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVbN2va16__ZN2N12N23f10EPx:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcM2va16__ZN2N12N23f10EPx:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcN2va16__ZN2N12N23f10EPx:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdM2va16__ZN2N12N23f10EPx:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdN2va16__ZN2N12N23f10EPx:" 1 { target { i?86-*-* x86_64-*-* } } } } + struct A { #pragma omp declare simd uniform (a) aligned (b : 8 * sizeof (int)) linear (c : 4) simdlen (8) @@ -172,6 +187,13 @@ int B::f25<7> (int a, int *b, int c return a + *b + c; } +// { dg-final { scan-assembler-times "_ZGVbM8vuva32u__ZN1BIiE3f25ILi7EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVbN8vuva32u__ZN1BIiE3f25ILi7EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcM8vuva32u__ZN1BIiE3f25ILi7EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcN8vuva32u__ZN1BIiE3f25ILi7EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdM8vuva32u__ZN1BIiE3f25ILi7EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdN8vuva32u__ZN1BIiE3f25ILi7EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } } + #pragma omp declare simd simdlen (4) aligned (b : 8 * sizeof (int)) linear (a, c : 2) template <> template <> @@ -180,6 +202,13 @@ int B::f26<-1> (int a, int *b, int return a + *b + c; } +// { dg-final { scan-assembler-times "_ZGVbM4vl2va32__ZN1BIiE3f26ILin1EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVbN4vl2va32__ZN1BIiE3f26ILin1EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcM4vl2va32__ZN1BIiE3f26ILin1EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcN4vl2va32__ZN1BIiE3f26ILin1EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdM4vl2va32__ZN1BIiE3f26ILin1EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdN4vl2va32__ZN1BIiE3f26ILin1EEEiiPii:" 1 { target { i?86-*-* x86_64-*-* } } } } + int f27 (int x) { @@ -202,6 +231,13 @@ f30 (int x) return x; } +// { dg-final { scan-assembler-times "_ZGVbM16v__Z3f30i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVbN16v__Z3f30i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcM16v__Z3f30i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcN16v__Z3f30i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdM16v__Z3f30i:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdN16v__Z3f30i:" 1 { target { i?86-*-* x86_64-*-* } } } } + template struct C { --- gcc/testsuite/g++.dg/gomp/declare-simd-3.C.jj 2015-10-14 10:25:28.000000000 +0200 +++ gcc/testsuite/g++.dg/gomp/declare-simd-3.C 2015-10-27 17:53:47.079867730 +0100 @@ -1,4 +1,5 @@ // { dg-do compile } +// { dg-options "-fopenmp -ffat-lto-objects" } #pragma omp declare simd uniform(b) linear(c, d) linear(uval(e)) linear(ref(f)) int f1 (int a, int b, int c, int &d, int &e, int &f) @@ -12,6 +13,13 @@ int f1 (int a, int b, int c, int &d, int return a + b + c + d + e + f; } +// { dg-final { scan-assembler-times "_ZGVbM4vulLUR4__Z2f1iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVbN4vulLUR4__Z2f1iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcM4vulLUR4__Z2f1iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcN4vulLUR4__Z2f1iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdM8vulLUR4__Z2f1iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdN8vulLUR4__Z2f1iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } } + #pragma omp declare simd uniform(b) linear(c, d) linear(uval(e)) linear(ref(f)) int f2 (int a, int b, int c, int &d, int &e, int &f) { @@ -30,12 +38,26 @@ int f2 (int a, int b, int c, int &d, int return a + b + c + d + e + f; } +// { dg-final { scan-assembler-times "_ZGVbM4vulLUR4__Z2f2iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVbN4vulLUR4__Z2f2iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcM4vulLUR4__Z2f2iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcN4vulLUR4__Z2f2iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdM8vulLUR4__Z2f2iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdN8vulLUR4__Z2f2iiiRiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } } + #pragma omp declare simd uniform(b) linear(c, d) linear(uval(e)) linear(ref(f)) int f3 (const int a, const int b, const int c, const int &d, const int &e, const int &f) { return a + b + c + d + e + f; } +// { dg-final { scan-assembler-times "_ZGVbM4vulLUR4__Z2f3iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVbN4vulLUR4__Z2f3iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcM4vulLUR4__Z2f3iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcN4vulLUR4__Z2f3iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdM8vulLUR4__Z2f3iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdN8vulLUR4__Z2f3iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } } + #pragma omp declare simd uniform(b) linear(c, d) linear(uval(e)) linear(ref(f)) int f4 (const int a, const int b, const int c, const int &d, const int &e, const int &f) { @@ -47,3 +69,10 @@ int f4 (const int a, const int b, const asm volatile ("" : : "r" (&f)); return a + b + c + d + e + f; } + +// { dg-final { scan-assembler-times "_ZGVbM4vulLUR4__Z2f4iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVbN4vulLUR4__Z2f4iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcM4vulLUR4__Z2f4iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcN4vulLUR4__Z2f4iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdM8vulLUR4__Z2f4iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdN8vulLUR4__Z2f4iiiRKiS0_S0_:" 1 { target { i?86-*-* x86_64-*-* } } } } --- gcc/testsuite/g++.dg/gomp/declare-simd-4.C.jj 2015-10-27 18:19:26.903820488 +0100 +++ gcc/testsuite/g++.dg/gomp/declare-simd-4.C 2015-10-27 18:19:00.000000000 +0100 @@ -0,0 +1,35 @@ +#pragma omp declare simd linear(p:1) linear(q:-1) linear(s:-3) +int +f1 (int *p, int *q, short *s) +{ + return *p + *q + *s; +} + +// { dg-final { scan-assembler-times "_ZGVbM4l4ln4ln6__Z2f1PiS_Ps:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVbN4l4ln4ln6__Z2f1PiS_Ps:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcM4l4ln4ln6__Z2f1PiS_Ps:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcN4l4ln4ln6__Z2f1PiS_Ps:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdM8l4ln4ln6__Z2f1PiS_Ps:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdN8l4ln4ln6__Z2f1PiS_Ps:" 1 { target { i?86-*-* x86_64-*-* } } } } + +#pragma omp declare simd linear(p:s) linear(q:t) uniform (s) linear(r:s) notinbranch simdlen(8) uniform(t) +int +f2 (int *p, short *q, int s, int r, int &t) +{ + return *p + *q + r; +} + +// { dg-final { scan-assembler-times "_ZGVbN8ls2ls4uls2u__Z2f2PiPsiiRi:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcN8ls2ls4uls2u__Z2f2PiPsiiRi:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdN8ls2ls4uls2u__Z2f2PiPsiiRi:" 1 { target { i?86-*-* x86_64-*-* } } } } + +#pragma omp declare simd linear(ref(p):s) linear(val(q):t) uniform (s) linear(uval(r):s) notinbranch simdlen(8) uniform(t) +int +f3 (int &p, short &q, int s, int &r, int &t) +{ + return p + q + r; +} + +// { dg-final { scan-assembler-times "_ZGVbN8Rs2Ls4uUs2u__Z2f3RiRsiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVcN8Rs2Ls4uUs2u__Z2f3RiRsiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } } +// { dg-final { scan-assembler-times "_ZGVdN8Rs2Ls4uUs2u__Z2f3RiRsiS_S_:" 1 { target { i?86-*-* x86_64-*-* } } } } --- gcc/testsuite/g++.dg/gomp/declare-simd-5.C.jj 2015-10-29 11:12:04.049533587 +0100 +++ gcc/testsuite/g++.dg/gomp/declare-simd-5.C 2015-10-29 11:23:58.779198490 +0100 @@ -0,0 +1,22 @@ +// { dg-do compile } +// { dg-options "-fopenmp-simd" } + +#pragma omp declare simd linear(a:1 + b) uniform(b) // { dg-error "use of parameter outside function body before .\\). token" } +int f1 (int a, int b); +#pragma omp declare simd linear(a:b + 1) uniform(b) // { dg-error "use of parameter outside function body before .\\+. token" } +int f2 (int a, int b); +#pragma omp declare simd linear(a:2 * b) uniform(b) // { dg-error "use of parameter outside function body before .\\). token" } +int f3 (int a, int b); +#pragma omp declare simd linear(a:b) // { dg-error ".linear. clause step is a parameter .b. not specified in .uniform. clause" } +int f4 (int a, int b); +#pragma omp declare simd linear(a:b) linear(b:1) // { dg-error ".linear. clause step is a parameter .b. not specified in .uniform. clause" } +int f5 (int a, int b); +#pragma omp declare simd linear(a:5 + 2 * 3) +int f6 (int a, int b); +const int c = 5; +#pragma omp declare simd linear(a:c) +int f7 (int a, int b); +#pragma omp declare simd linear(a:2 * c + 1) +int f8 (int a, int b); +#pragma omp declare simd linear(a:0.5) // { dg-error "linear step expression must be integral" } +int f9 (int a, int b);