From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 128983 invoked by alias); 7 Jan 2016 21:49:34 -0000 Mailing-List: contact fortran-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: fortran-owner@gcc.gnu.org Received: (qmail 128956 invoked by uid 89); 7 Jan 2016 21:49:33 -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 spammy=UD:code, nest, Assignment, sum X-Spam-User: qpsmtpd, 2 recipients 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, 07 Jan 2016 21:49:32 +0000 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id D3ECE92A42; Thu, 7 Jan 2016 21:49:30 +0000 (UTC) Received: from tucnak.zalov.cz ([10.3.113.3]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u07LnTWR009286 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Thu, 7 Jan 2016 16:49:30 -0500 Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.15.2/8.15.2) with ESMTP id u07LnRFi025673; Thu, 7 Jan 2016 22:49:28 +0100 Received: (from jakub@localhost) by tucnak.zalov.cz (8.15.2/8.15.2/Submit) id u07LnQBu025672; Thu, 7 Jan 2016 22:49:26 +0100 Date: Thu, 07 Jan 2016 21:49:00 -0000 From: Jakub Jelinek To: gcc-patches@gcc.gnu.org, fortran@gcc.gnu.org Subject: [PATCH] Fix !$omp workshare (PR fortran/69128) Message-ID: <20160107214926.GR18720@tucnak.redhat.com> Reply-To: Jakub Jelinek MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) X-SW-Source: 2016-01/txt/msg00025.txt.bz2 Hi! As the testcase shows, gfc_trans_scalarized_loop_end can be called multiple times (and not just for different dimensions of the same loop) on a single assignment, and we could in that case when inside of !$omp workshare generate nested !$omp do, which is obviously incorrect. Fixed by making sure we do it only in the toplevel loop nest generated from the statement. Bootstrapped/regtested on x86_64-linux and i686-linux, will commit tomorrow. 2016-01-07 Jakub Jelinek PR fortran/69128 * trans.h (OMPWS_SCALARIZER_BODY): Define. (OMPWS_NOWAIT): Renumber. * trans-stmt.c (gfc_trans_where_3): Only set OMPWS_SCALARIZER_WS if OMPWS_SCALARIZER_BODY is not set already, and set also OMPWS_SCALARIZER_BODY until the final loop creation. * trans-expr.c (gfc_trans_assignment_1): Likewise. * trans-openmp.c (gfc_trans_omp_workshare): Also clear OMPWS_SCALARIZER_BODY. * trans-array.c (gfc_trans_scalarized_loop_end): Don't create OMP_FOR if OMPWS_SCALARIZER_BODY is set. * gfortran.dg/gomp/pr69128.f90: New test. --- gcc/fortran/trans.h.jj 2016-01-07 18:38:20.274008188 +0100 +++ gcc/fortran/trans.h 2016-01-07 18:42:25.187630832 +0100 @@ -1039,7 +1039,9 @@ extern const char gfc_msg_wrong_return[] construct is not workshared. */ #define OMPWS_SCALARIZER_WS 4 /* Set if scalarizer should attempt to create parallel loops. */ -#define OMPWS_NOWAIT 8 /* Use NOWAIT on OMP_FOR. */ +#define OMPWS_SCALARIZER_BODY 8 /* Set if handling body of potential + parallel loop. */ +#define OMPWS_NOWAIT 16 /* Use NOWAIT on OMP_FOR. */ extern int ompws_flags; #endif /* GFC_TRANS_H */ --- gcc/fortran/trans-stmt.c.jj 2016-01-07 18:38:20.269008257 +0100 +++ gcc/fortran/trans-stmt.c 2016-01-07 18:42:25.186630846 +0100 @@ -5057,10 +5057,15 @@ gfc_trans_where_3 (gfc_code * cblock, gf gfc_loopinfo loop; gfc_ss *edss = 0; gfc_ss *esss = 0; + bool maybe_workshare = false; /* Allow the scalarizer to workshare simple where loops. */ - if (ompws_flags & OMPWS_WORKSHARE_FLAG) - ompws_flags |= OMPWS_SCALARIZER_WS; + if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_BODY)) + == OMPWS_WORKSHARE_FLAG) + { + maybe_workshare = true; + ompws_flags |= OMPWS_SCALARIZER_WS | OMPWS_SCALARIZER_BODY; + } cond = cblock->expr1; tdst = cblock->next->expr1; @@ -5160,6 +5165,8 @@ gfc_trans_where_3 (gfc_code * cblock, gf gfc_add_expr_to_block (&body, tmp); gfc_add_block_to_block (&body, &cse.post); + if (maybe_workshare) + ompws_flags &= ~OMPWS_SCALARIZER_BODY; gfc_trans_scalarizing_loops (&loop, &body); gfc_add_block_to_block (&block, &loop.pre); gfc_add_block_to_block (&block, &loop.post); --- gcc/fortran/trans-openmp.c.jj 2016-01-07 18:38:20.279008119 +0100 +++ gcc/fortran/trans-openmp.c 2016-01-07 18:42:25.188630818 +0100 @@ -4297,7 +4297,7 @@ gfc_trans_omp_workshare (gfc_code *code, /* By default, every gfc_code is a single unit of work. */ ompws_flags |= OMPWS_CURR_SINGLEUNIT; - ompws_flags &= ~OMPWS_SCALARIZER_WS; + ompws_flags &= ~(OMPWS_SCALARIZER_WS | OMPWS_SCALARIZER_BODY); switch (code->op) { --- gcc/fortran/trans-array.c.jj 2016-01-07 18:38:20.284008050 +0100 +++ gcc/fortran/trans-array.c 2016-01-07 18:42:25.191630777 +0100 @@ -3601,7 +3601,8 @@ gfc_trans_scalarized_loop_end (gfc_loopi tree init; tree incr; - if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_WS)) + if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_WS + | OMPWS_SCALARIZER_BODY)) == (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_WS) && n == loop->dimen - 1) { --- gcc/fortran/trans-expr.c.jj 2016-01-07 18:38:20.289007981 +0100 +++ gcc/fortran/trans-expr.c 2016-01-07 18:42:25.193630749 +0100 @@ -9160,6 +9160,7 @@ gfc_trans_assignment_1 (gfc_expr * expr1 bool scalar_to_array; tree string_length; int n; + bool maybe_workshare = false; /* Assignment of the form lhs = rhs. */ gfc_start_block (&block); @@ -9234,8 +9235,13 @@ gfc_trans_assignment_1 (gfc_expr * expr1 } /* Allow the scalarizer to workshare array assignments. */ - if ((ompws_flags & OMPWS_WORKSHARE_FLAG) && loop.temp_ss == NULL) - ompws_flags |= OMPWS_SCALARIZER_WS; + if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_BODY)) + == OMPWS_WORKSHARE_FLAG + && loop.temp_ss == NULL) + { + maybe_workshare = true; + ompws_flags |= OMPWS_SCALARIZER_WS | OMPWS_SCALARIZER_BODY; + } /* Start the scalarized loop body. */ gfc_start_scalarized_body (&loop, &body); @@ -9384,6 +9390,9 @@ gfc_trans_assignment_1 (gfc_expr * expr1 gfc_add_expr_to_block (&loop.code[expr1->rank - 1], tmp); } + if (maybe_workshare) + ompws_flags &= ~OMPWS_SCALARIZER_BODY; + /* Generate the copying loops. */ gfc_trans_scalarizing_loops (&loop, &body); --- gcc/testsuite/gfortran.dg/gomp/pr69128.f90.jj 2016-01-07 18:58:59.044893885 +0100 +++ gcc/testsuite/gfortran.dg/gomp/pr69128.f90 2016-01-07 18:58:51.000000000 +0100 @@ -0,0 +1,23 @@ +! PR fortran/69128 +! { dg-do compile } + +program test + implicit none + interface + subroutine use(b, c) + real, allocatable :: b(:), c(:) + end subroutine + end interface + real, allocatable :: a(:,:), b(:), c(:) + integer :: dim1, dim2, i,j + dim1=10000 + dim2=500 + allocate(a(dim1,dim2),b(dim1),c(dim1)) + call random_number(a) + +!$omp parallel workshare + b(:) = maxval(a(:,:), dim=2) + c(:) = sum(a(:,:), dim=2) +!$omp end parallel workshare + call use(b, c) +end program Jakub