From patchwork Fri Oct 12 14:35:01 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tobias Burnus X-Patchwork-Id: 983080 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-487459-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=physik.fu-berlin.de 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 42Wr3F5vSRz9s1x for ; Sat, 13 Oct 2018 01:35:20 +1100 (AEDT) Received: (qmail 97639 invoked by alias); 12 Oct 2018 14:35:12 -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 97604 invoked by uid 89); 12 Oct 2018 14:35:11 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-22.3 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, KAM_STOCKGEN autolearn=ham version=3.3.2 spammy=UD:ar, grace, 44, off-by-one X-HELO: outpost19.zedat.fu-berlin.de Received: from outpost19.zedat.fu-berlin.de (HELO outpost19.zedat.fu-berlin.de) (130.133.4.112) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 12 Oct 2018 14:35:07 +0000 Received: from relay1.zedat.fu-berlin.de ([130.133.4.67]) by outpost.zedat.fu-berlin.de (Exim 4.85) with esmtps (TLSv1.2:DHE-RSA-AES256-GCM-SHA384:256) (envelope-from ) id <1gAyWv-0039HB-4T>; Fri, 12 Oct 2018 16:35:05 +0200 Received: from mx.physik.fu-berlin.de ([160.45.64.218]) by relay1.zedat.fu-berlin.de (Exim 4.85) with esmtps (TLSv1.2:DHE-RSA-AES128-SHA:128) (envelope-from ) id <1gAyWv-003x0e-0N>; Fri, 12 Oct 2018 16:35:05 +0200 Received: from login2.physik.fu-berlin.de ([160.45.66.208]) by mx.physik.fu-berlin.de with esmtps (TLS1.2:RSA_AES_128_CBC_SHA1:128) (Exim 4.80) (envelope-from ) id 1gAyWr-0008QB-Mr; Fri, 12 Oct 2018 16:35:01 +0200 Received: from tburnus by login2.physik.fu-berlin.de with local (Exim 4.84_2 #2 (Debian)) id 1gAyWr-0007PO-Lm; Fri, 12 Oct 2018 16:35:01 +0200 Date: Fri, 12 Oct 2018 16:35:01 +0200 From: Tobias Burnus To: gcc-patches@gcc.gnu.org, fortran@gcc.gnu.org Subject: [Patch, Fortran] PR87597 - fix off-by-one issue with inline matmul Message-ID: <20181012143501.GB11980@physik.fu-berlin.de> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) Sender: Tobias Burnus In the front-end optimization for matmul, we call lbound() for each matrix argument to obtain the shift to the 0-based loop variables. If the first argument is a PARAMETER, it appears initially as EXPR_VARIABLE and has associated ref->u.ar for the AR_FULL and ref->u.ar.as contains the bounds. Running gfc_simplify_expr() on the generated lbound() will simplify the array argument to an EXPR_ARRAY, which always has a lower bound of 1. The problem starts as soon as the PARAMETER array has bounds which do not start with 1 but, e.g., with 0 as with the test case: gfortran generates than code which is off by one (reads the wrong element and beyond array bounds). Fixed by explicitly preventing this during gfc_simplify_expr. I hope that's the only place where matters and that it doesn't cause missed optimizations. Build and regtested on x86-64-linux. OK for the trunk and - after a grace time - for GCC 6, 7 and 8? Tobias 2018-10-12 Tobias Burnus PR fortran/87597 * expr.c (gfc_simplify_expr): Avoid simplifying the 'array' argument to lbound/ubound/lcobound/ ucobound. PR fortran/87597 * gfortran.dg/inline_matmul_24.f90: New. diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c index 1cfda5fbfed..ca6f95d9d8e 100644 --- a/gcc/fortran/expr.c +++ b/gcc/fortran/expr.c @@ -1937,7 +1937,20 @@ gfc_simplify_expr (gfc_expr *p, int type) break; case EXPR_FUNCTION: - for (ap = p->value.function.actual; ap; ap = ap->next) + // For array-bound functions, we don't need to optimize + // the 'array' argument. In particular, if the argument + // is a PARAMETER, simplifying might convert an EXPR_VARIABLE + // into an EXPR_ARRAY; the latter has lbound = 1, the former + // can have any lbound. + ap = p->value.function.actual; + if (p->value.function.isym && + (p->value.function.isym->id == GFC_ISYM_LBOUND + || p->value.function.isym->id == GFC_ISYM_UBOUND + || p->value.function.isym->id == GFC_ISYM_LCOBOUND + || p->value.function.isym->id == GFC_ISYM_UCOBOUND)) + ap = ap->next; + + for ( ; ap; ap = ap->next) if (!gfc_simplify_expr (ap->expr, type)) return false; diff --git a/gcc/testsuite/gfortran.dg/inline_matmul_24.f90 b/gcc/testsuite/gfortran.dg/inline_matmul_24.f90 new file mode 100644 index 00000000000..067f6daf200 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/inline_matmul_24.f90 @@ -0,0 +1,42 @@ +! { dg-do run } +! { dg-options "-ffrontend-optimize -fdump-tree-original" } +! +! PR fortran/87597 +! +! Contributed by gallmeister +! +! Before, for the inlined matmul, +! gamma5 was converted to an EXPR_ARRAY with lbound = 1 +! instead of the lbound = 0 as declared; leading to +! an off-by-one problem. +! +program testMATMUL + implicit none + complex, dimension(0:3,0:3), parameter :: gamma5 = reshape((/ 0., 0., 1., 0., & + 0., 0., 0., 1., & + 1., 0., 0., 0., & + 0., 1., 0., 0. /),(/4,4/)) + complex, dimension(0:3,0:3) :: A, B, D + integer :: i + + A = 0.0 + do i=0,3 + A(i,i) = i*1.0 + end do + + B = cmplx(7,-9) + B = matmul(A,gamma5) + + D = reshape([0, 0, 2, 0, & + 0, 0, 0, 3, & + 0, 0, 0, 0, & + 0, 1, 0, 0], [4, 4]) + write(*,*) B(0,:) + write(*,*) B(1,:) + write(*,*) B(2,:) + write(*,*) B(3,:) + if (any(B /= D)) then + call abort() + end if +end program testMATMUL +! { dg-final { scan-tree-dump-times "gamma5\[__var_1_do \\* 4 \\+ __var_2_do\]" 1 "optimized" } }