From patchwork Tue Jun 4 12:50:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 1109834 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-502294-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="ctAn6n7c"; dkim-atps=neutral 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 45JBcY5dgFz9s9y for ; Tue, 4 Jun 2019 22:51:07 +1000 (AEST) 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:subject:message-id:reply-to:mime-version:content-type; q=dns; s=default; b=uTQaq+gcgaAFnbJMWHBdfpWZHA/mlTVA3E8uKyW09N1 VXr+Ed48yDT0YRo7TqW1TCMY6DetjxwcE18mbd7UipaLUF2M/SYERyAjccSaN2R6 gRmkE3X3H5D7doNDBqoZ/nkIjZ90JsGrOCDVqyCx1OdqaoOptvMLP4Ojk0NFr/ZY = 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:subject:message-id:reply-to:mime-version:content-type; s=default; bh=7yDMTC1r9/K1EZF2OmvhTliNBOM=; b=ctAn6n7cHsNls5G4h 3GHnhTBK4BgBv+z2mvYomcNObzXNAxQynpn2vgmP3u0AipALFUucKnOSMXitYoKS 7NAeC7PoOpdVf8jJKrCZw3V+jp39CuqJ0eM0JtxOH3/uAz/rfeqwI4vh9hC4/Wup gqk2ez7DP355cO1TxAsKakA+KY= Received: (qmail 17461 invoked by alias); 4 Jun 2019 12:50:59 -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 17453 invoked by uid 89); 4 Jun 2019 12:50:58 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-7.3 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, SPF_HELO_PASS autolearn=ham version=3.3.1 spammy=collapse, fold_convert, build_int_cst 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 ESMTP; Tue, 04 Jun 2019 12:50:56 +0000 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id BED4A3092407 for ; Tue, 4 Jun 2019 12:50:54 +0000 (UTC) Received: from tucnak.zalov.cz (ovpn-116-52.ams2.redhat.com [10.36.116.52]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 3C4B95B684 for ; Tue, 4 Jun 2019 12:50:53 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.15.2/8.15.2) with ESMTP id x54CojN1026973 for ; Tue, 4 Jun 2019 14:50:50 +0200 Received: (from jakub@localhost) by tucnak.zalov.cz (8.15.2/8.15.2/Submit) id x54CoimQ026763 for gcc-patches@gcc.gnu.org; Tue, 4 Jun 2019 14:50:44 +0200 Date: Tue, 4 Jun 2019 14:50:44 +0200 From: Jakub Jelinek To: gcc-patches@gcc.gnu.org Subject: [committed] Support lastprivate(conditional:) on combined for simd Message-ID: <20190604125044.GW19695@tucnak> Reply-To: Jakub Jelinek MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.11.3 (2019-02-01) X-IsSubscribed: yes Hi! The following patch adds support for lastprivate(conditional:) on for simd. Bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk. 2019-06-04 Jakub Jelinek * gimplify.c (gimplify_scan_omp_clauses): Don't sorry_at on lastprivate conditional on combined for simd. * omp-low.c (struct omp_context): Add combined_into_simd_safelen0 member. (lower_rec_input_clauses): For gimple_omp_for_combined_into_p max_vf 1 constructs, don't remove lastprivate_conditional_map, but instead set ctx->combined_into_simd_safelen0 and adjust hash_map, so that it points to parent construct temporaries. (lower_lastprivate_clauses): Handle ctx->combined_into_simd_safelen0 like !ctx->lastprivate_conditional_map. (lower_omp_1) : If up->combined_into_simd_safelen0, use up->outer context instead of up. * omp-expand.c (expand_omp_for_generic): Perform cond_var bump even if gimple_omp_for_combined_p. (expand_omp_for_static_nochunk): Likewise. (expand_omp_for_static_chunk): Add forgotten cond_var bump that was probably moved over into expand_omp_for_generic rather than being copied there. gcc/cp/ * cp-tree.h (CP_OMP_CLAUSE_INFO): Allow for any clauses up to _condvar_ instead of only up to linear. gcc/testsuite/ * c-c++-common/gomp/lastprivate-conditional-2.c (foo): Don't expect a sorry_at on any of the clauses. libgomp/ * testsuite/libgomp.c-c++-common/lastprivate-conditional-7.c: New test. * testsuite/libgomp.c-c++-common/lastprivate-conditional-8.c: New test. * testsuite/libgomp.c-c++-common/lastprivate-conditional-9.c: New test. * testsuite/libgomp.c-c++-common/lastprivate-conditional-10.c: New test. Jakub --- gcc/gimplify.c.jj 2019-05-31 23:37:51.066938833 +0200 +++ gcc/gimplify.c 2019-06-03 10:22:30.272829191 +0200 @@ -8145,31 +8145,7 @@ gimplify_scan_omp_clauses (tree *list_p, OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0; } if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)) - { - splay_tree_node n = NULL; - if (code == OMP_SIMD - && outer_ctx - && outer_ctx->region_type == ORT_WORKSHARE) - { - n = splay_tree_lookup (outer_ctx->variables, - (splay_tree_key) decl); - if (n == NULL - && outer_ctx->outer_context - && (outer_ctx->outer_context->region_type - == ORT_COMBINED_PARALLEL)) - n = splay_tree_lookup (outer_ctx->outer_context->variables, - (splay_tree_key) decl); - } - if (n && (n->value & GOVD_LASTPRIVATE_CONDITIONAL) != 0) - { - sorry_at (OMP_CLAUSE_LOCATION (c), - "% modifier on % " - "clause not supported yet"); - OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0; - } - else - flags |= GOVD_LASTPRIVATE_CONDITIONAL; - } + flags |= GOVD_LASTPRIVATE_CONDITIONAL; if (outer_ctx && (outer_ctx->region_type == ORT_COMBINED_PARALLEL || ((outer_ctx->region_type & ORT_COMBINED_TEAMS) --- gcc/omp-low.c.jj 2019-05-31 23:37:51.069938786 +0200 +++ gcc/omp-low.c 2019-06-03 15:12:45.535613313 +0200 @@ -137,6 +137,10 @@ struct omp_context /* True if this construct can be cancelled. */ bool cancellable; + + /* True if lower_omp_1 should look up lastprivate conditional in parent + context. */ + bool combined_into_simd_safelen0; }; static splay_tree all_contexts; @@ -4816,6 +4820,8 @@ lower_rec_input_clauses (tree clauses, g void_node); gimple_seq tseq = NULL; gimplify_and_add (x, &tseq); + if (ctx->outer) + lower_omp (&tseq, ctx->outer); gimple_seq_add_seq (&llist[1], tseq); } if (y) @@ -5278,11 +5284,31 @@ lower_rec_input_clauses (tree clauses, g sctx.is_simt = false; if (ctx->lastprivate_conditional_map) { - /* When not vectorized, treat lastprivate(conditional:) like - normal lastprivate, as there will be just one simd lane - writing the privatized variable. */ - delete ctx->lastprivate_conditional_map; - ctx->lastprivate_conditional_map = NULL; + if (gimple_omp_for_combined_into_p (ctx->stmt)) + { + /* Signal to lower_omp_1 that it should use parent context. */ + ctx->combined_into_simd_safelen0 = true; + for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c)) + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE + && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)) + { + tree o = lookup_decl (OMP_CLAUSE_DECL (c), ctx); + tree *v + = ctx->lastprivate_conditional_map->get (o); + tree po = lookup_decl (OMP_CLAUSE_DECL (c), ctx->outer); + tree *pv + = ctx->outer->lastprivate_conditional_map->get (po); + *v = *pv; + } + } + else + { + /* When not vectorized, treat lastprivate(conditional:) like + normal lastprivate, as there will be just one simd lane + writing the privatized variable. */ + delete ctx->lastprivate_conditional_map; + ctx->lastprivate_conditional_map = NULL; + } } } @@ -5652,7 +5678,8 @@ lower_lastprivate_clauses (tree clauses, if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) - && ctx->lastprivate_conditional_map) + && ctx->lastprivate_conditional_map + && !ctx->combined_into_simd_safelen0) { gcc_assert (body_p); if (simduid) @@ -10812,6 +10839,8 @@ lower_omp_1 (gimple_stmt_iterator *gsi_p if (tree *v = up->lastprivate_conditional_map->get (lhs)) { tree clauses; + if (up->combined_into_simd_safelen0) + up = up->outer; if (gimple_code (up->stmt) == GIMPLE_OMP_FOR) clauses = gimple_omp_for_clauses (up->stmt); else --- gcc/omp-expand.c.jj 2019-05-31 23:37:51.071938754 +0200 +++ gcc/omp-expand.c 2019-06-03 12:04:20.342277395 +0200 @@ -3257,6 +3257,25 @@ expand_omp_for_generic (struct omp_regio vmain = gimple_omp_continue_control_use (cont_stmt); vback = gimple_omp_continue_control_def (cont_stmt); + if (cond_var) + { + tree itype = TREE_TYPE (cond_var); + tree t2; + if ((fd->ordered && fd->collapse == 1) + || bias + || POINTER_TYPE_P (type) + || TREE_CODE (fd->loop.n1) != INTEGER_CST + || fd->loop.cond_code != LT_EXPR) + t2 = build_int_cst (itype, 1); + else + t2 = fold_convert (itype, fd->loop.step); + t2 = fold_build2 (PLUS_EXPR, itype, cond_var, t2); + t2 = force_gimple_operand_gsi (&gsi, t2, false, + NULL_TREE, true, GSI_SAME_STMT); + assign_stmt = gimple_build_assign (cond_var, t2); + gsi_insert_before (&gsi, assign_stmt, GSI_SAME_STMT); + } + if (!gimple_omp_for_combined_p (fd->for_stmt)) { if (POINTER_TYPE_P (type)) @@ -3270,25 +3289,6 @@ expand_omp_for_generic (struct omp_regio assign_stmt = gimple_build_assign (vback, t); gsi_insert_before (&gsi, assign_stmt, GSI_SAME_STMT); - if (cond_var) - { - tree itype = TREE_TYPE (cond_var); - tree t2; - if ((fd->ordered && fd->collapse == 1) - || bias - || POINTER_TYPE_P (type) - || TREE_CODE (fd->loop.n1) != INTEGER_CST - || fd->loop.cond_code != LT_EXPR) - t2 = build_int_cst (itype, 1); - else - t2 = fold_convert (itype, fd->loop.step); - t2 = fold_build2 (PLUS_EXPR, itype, cond_var, t2); - t2 = force_gimple_operand_gsi (&gsi, t2, false, - NULL_TREE, true, GSI_SAME_STMT); - assign_stmt = gimple_build_assign (cond_var, t2); - gsi_insert_before (&gsi, assign_stmt, GSI_SAME_STMT); - } - if (fd->ordered && counts[fd->collapse - 1] == NULL_TREE) { tree tem; @@ -3962,6 +3962,23 @@ expand_omp_for_static_nochunk (struct om vmain = gimple_omp_continue_control_use (cont_stmt); vback = gimple_omp_continue_control_def (cont_stmt); + if (cond_var) + { + tree itype = TREE_TYPE (cond_var); + tree t2; + if (POINTER_TYPE_P (type) + || TREE_CODE (n1) != INTEGER_CST + || fd->loop.cond_code != LT_EXPR) + t2 = build_int_cst (itype, 1); + else + t2 = fold_convert (itype, step); + t2 = fold_build2 (PLUS_EXPR, itype, cond_var, t2); + t2 = force_gimple_operand_gsi (&gsi, t2, false, + NULL_TREE, true, GSI_SAME_STMT); + assign_stmt = gimple_build_assign (cond_var, t2); + gsi_insert_before (&gsi, assign_stmt, GSI_SAME_STMT); + } + if (!gimple_omp_for_combined_p (fd->for_stmt)) { if (POINTER_TYPE_P (type)) @@ -3975,23 +3992,6 @@ expand_omp_for_static_nochunk (struct om assign_stmt = gimple_build_assign (vback, t); gsi_insert_before (&gsi, assign_stmt, GSI_SAME_STMT); - if (cond_var) - { - tree itype = TREE_TYPE (cond_var); - tree t2; - if (POINTER_TYPE_P (type) - || TREE_CODE (n1) != INTEGER_CST - || fd->loop.cond_code != LT_EXPR) - t2 = build_int_cst (itype, 1); - else - t2 = fold_convert (itype, step); - t2 = fold_build2 (PLUS_EXPR, itype, cond_var, t2); - t2 = force_gimple_operand_gsi (&gsi, t2, false, - NULL_TREE, true, GSI_SAME_STMT); - assign_stmt = gimple_build_assign (cond_var, t2); - gsi_insert_before (&gsi, assign_stmt, GSI_SAME_STMT); - } - t = build2 (fd->loop.cond_code, boolean_type_node, DECL_P (vback) && TREE_ADDRESSABLE (vback) ? t : vback, e); @@ -4607,6 +4607,23 @@ expand_omp_for_static_chunk (struct omp_ vmain = gimple_omp_continue_control_use (cont_stmt); vback = gimple_omp_continue_control_def (cont_stmt); + if (cond_var) + { + tree itype = TREE_TYPE (cond_var); + tree t2; + if (POINTER_TYPE_P (type) + || TREE_CODE (n1) != INTEGER_CST + || fd->loop.cond_code != LT_EXPR) + t2 = build_int_cst (itype, 1); + else + t2 = fold_convert (itype, step); + t2 = fold_build2 (PLUS_EXPR, itype, cond_var, t2); + t2 = force_gimple_operand_gsi (&gsi, t2, false, + NULL_TREE, true, GSI_SAME_STMT); + assign_stmt = gimple_build_assign (cond_var, t2); + gsi_insert_before (&gsi, assign_stmt, GSI_SAME_STMT); + } + if (!gimple_omp_for_combined_p (fd->for_stmt)) { if (POINTER_TYPE_P (type)) --- gcc/cp/cp-tree.h.jj 2019-05-31 23:35:38.461038702 +0200 +++ gcc/cp/cp-tree.h 2019-06-03 12:39:21.453395398 +0200 @@ -4924,7 +4924,7 @@ more_aggr_init_expr_args_p (const aggr_i See semantics.c for details. */ #define CP_OMP_CLAUSE_INFO(NODE) \ TREE_TYPE (OMP_CLAUSE_RANGE_CHECK (NODE, OMP_CLAUSE_PRIVATE, \ - OMP_CLAUSE_LINEAR)) + OMP_CLAUSE__CONDTEMP_)) /* Nonzero if this transaction expression's body contains statements. */ #define TRANSACTION_EXPR_IS_STMT(NODE) \ --- gcc/testsuite/c-c++-common/gomp/lastprivate-conditional-2.c.jj 2019-05-31 23:37:51.071938754 +0200 +++ gcc/testsuite/c-c++-common/gomp/lastprivate-conditional-2.c 2019-06-03 12:25:31.233599215 +0200 @@ -13,7 +13,7 @@ foo (int *p) if (p[i]) b = i; #pragma omp parallel - #pragma omp for simd lastprivate (conditional: c) /* { dg-message "not supported yet" } */ + #pragma omp for simd lastprivate (conditional: c) for (i = 0; i < 32; i++) if (p[i]) c = i; @@ -21,7 +21,7 @@ foo (int *p) for (i = 0; i < 32; i++) if (p[i]) d = i; - #pragma omp parallel for simd lastprivate (conditional: e) /* { dg-message "not supported yet" } */ + #pragma omp parallel for simd lastprivate (conditional: e) for (i = 0; i < 32; i++) if (p[i]) e = i; --- libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-7.c.jj 2019-06-03 12:30:01.087307199 +0200 +++ libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-7.c 2019-06-03 12:57:18.597254143 +0200 @@ -0,0 +1,63 @@ +/* { dg-do run } */ +/* { dg-additional-options "-O2 -fdump-tree-vect-details" } */ +/* { dg-additional-options "-mavx" { target avx_runtime } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 3 "vect" { target avx_runtime } } } */ + +int v, x; + +__attribute__((noipa)) void +foo (int *a) +{ + #pragma omp for simd lastprivate (conditional: x) schedule(simd: static) + for (int i = 0; i < 128; i++) + if (a[i]) + x = a[i]; +} + +__attribute__((noipa)) void +bar (int *a, int *b) +{ + #pragma omp for simd lastprivate (conditional: x, v) schedule(static, 16) + for (int i = 16; i < 128; ++i) + { + if (a[i]) + x = a[i]; + if (b[i]) + v = b[i] + 10; + } +} + +__attribute__((noipa)) void +baz (int *a) +{ + #pragma omp for simd lastprivate (conditional: x) schedule(simd: dynamic, 16) + for (int i = 0; i < 128; i++) + if (a[i]) + x = a[i] + 5; +} + +int +main () +{ + int a[128], b[128], i; + for (i = 0; i < 128; i++) + { + a[i] = ((i % 11) == 2) ? i + 10 : 0; + asm volatile ("" : "+g" (i)); + b[i] = ((i % 13) == 5) ? i * 2 : 0; + } + #pragma omp parallel + foo (a); + if (x != 133) + __builtin_abort (); + x = -3; + #pragma omp parallel + bar (b, a); + if (x != 244 || v != 143) + __builtin_abort (); + #pragma omp parallel + baz (b); + if (x != 249) + __builtin_abort (); + return 0; +} --- libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-8.c.jj 2019-06-03 13:01:22.102373429 +0200 +++ libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-8.c 2019-06-03 13:02:38.295159149 +0200 @@ -0,0 +1,60 @@ +/* { dg-do run } */ +/* { dg-additional-options "-O2 -fdump-tree-vect-details" } */ +/* { dg-additional-options "-mavx" { target avx_runtime } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 3 "vect" { target avx_runtime } } } */ + +int v, x; + +__attribute__((noipa)) int +foo (int *a) +{ + #pragma omp parallel for simd lastprivate (conditional: x) schedule(simd: static) + for (int i = 0; i < 128; i++) + if (a[i]) + x = a[i]; + return x; +} + +__attribute__((noipa)) int +bar (int *a, int *b) +{ + #pragma omp parallel + #pragma omp for simd lastprivate (conditional: x, v) schedule(static, 16) + for (int i = 16; i < 128; ++i) + { + if (a[i]) + x = a[i]; + if (b[i]) + v = b[i] + 10; + } + return x; +} + +__attribute__((noipa)) int +baz (int *a) +{ + #pragma omp parallel for simd lastprivate (conditional: x) schedule(simd: dynamic, 16) + for (int i = 0; i < 128; i++) + if (a[i]) + x = a[i] + 5; + return x; +} + +int +main () +{ + int a[128], b[128], i; + for (i = 0; i < 128; i++) + { + a[i] = ((i % 11) == 2) ? i + 10 : 0; + asm volatile ("" : "+g" (i)); + b[i] = ((i % 13) == 5) ? i * 2 : 0; + } + if (foo (a) != 133) + __builtin_abort (); + if (bar (b, a) != 244 || v != 143) + __builtin_abort (); + if (baz (b) != 249) + __builtin_abort (); + return 0; +} --- libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-9.c.jj 2019-06-03 13:10:44.860421306 +0200 +++ libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-9.c 2019-06-03 13:11:32.053675094 +0200 @@ -0,0 +1,60 @@ +/* { dg-do run } */ + +int v, x; + +__attribute__((noipa)) void +foo (int *a) +{ + #pragma omp for simd lastprivate (conditional: x) schedule(simd: static) if (simd: 0) + for (int i = 0; i < 128; i++) + if (a[i]) + x = a[i]; +} + +__attribute__((noipa)) void +bar (int *a, int *b) +{ + #pragma omp for simd lastprivate (conditional: x, v) schedule(static, 16) simdlen(1) + for (int i = 16; i < 128; ++i) + { + if (a[i]) + x = a[i]; + if (b[i]) + v = b[i] + 10; + } +} + +__attribute__((noipa)) void +baz (int *a) +{ + #pragma omp for simd lastprivate (conditional: x) schedule(simd: dynamic, 16) if (0) + for (int i = 0; i < 128; i++) + if (a[i]) + x = a[i] + 5; +} + +int +main () +{ + int a[128], b[128], i; + for (i = 0; i < 128; i++) + { + a[i] = ((i % 11) == 2) ? i + 10 : 0; + asm volatile ("" : "+g" (i)); + b[i] = ((i % 13) == 5) ? i * 2 : 0; + } + #pragma omp parallel + foo (a); + if (x != 133) + __builtin_abort (); + x = -3; + #pragma omp parallel + bar (b, a); + if (x != 244 || v != 143) + __builtin_abort (); + #pragma omp parallel + baz (b); + if (x != 249) + __builtin_abort (); + return 0; +} --- libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-10.c.jj 2019-06-03 15:17:33.368060408 +0200 +++ libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-10.c 2019-06-03 15:19:11.717504728 +0200 @@ -0,0 +1,57 @@ +/* { dg-do run } */ + +int v, x; + +__attribute__((noipa)) int +foo (int *a) +{ + #pragma omp parallel for simd lastprivate (conditional: x) schedule(simd: static) if (simd: 0) + for (int i = 0; i < 128; i++) + if (a[i]) + x = a[i]; + return x; +} + +__attribute__((noipa)) int +bar (int *a, int *b) +{ + #pragma omp parallel + #pragma omp for simd lastprivate (conditional: x, v) schedule(static, 16) simdlen (1) + for (int i = 16; i < 128; ++i) + { + if (a[i]) + x = a[i]; + if (b[i]) + v = b[i] + 10; + } + return x; +} + +__attribute__((noipa)) int +baz (int *a) +{ + #pragma omp parallel for simd if (simd: 0) lastprivate (conditional: x) schedule(simd: dynamic, 16) + for (int i = 0; i < 128; i++) + if (a[i]) + x = a[i] + 5; + return x; +} + +int +main () +{ + int a[128], b[128], i; + for (i = 0; i < 128; i++) + { + a[i] = ((i % 11) == 2) ? i + 10 : 0; + asm volatile ("" : "+g" (i)); + b[i] = ((i % 13) == 5) ? i * 2 : 0; + } + if (foo (a) != 133) + __builtin_abort (); + if (bar (b, a) != 244 || v != 143) + __builtin_abort (); + if (baz (b) != 249) + __builtin_abort (); + return 0; +}