From 554fd8c5195424bdbcabf5de30fdc183aba391bd Mon Sep 17 00:00:00 2001 From: upstream source tree Date: Sun, 15 Mar 2015 20:14:05 -0400 Subject: obtained gcc-4.6.4.tar.bz2 from upstream website; verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository. --- gcc/testsuite/gfortran.dg/vect/O3-pr36119.f90 | 28 +++++++ gcc/testsuite/gfortran.dg/vect/O3-pr39595.f | 17 ++++ .../gfortran.dg/vect/cost-model-pr34445.f | 9 +++ .../gfortran.dg/vect/cost-model-pr34445a.f | 29 +++++++ .../gfortran.dg/vect/fast-math-mgrid-resid.f | 46 +++++++++++ .../gfortran.dg/vect/fast-math-pr33299.f90 | 17 ++++ .../gfortran.dg/vect/fast-math-pr38968.f90 | 28 +++++++ .../gfortran.dg/vect/fast-math-real8-pr40801.f90 | 38 +++++++++ .../gfortran.dg/vect/fast-math-vect-8.f90 | 94 ++++++++++++++++++++++ gcc/testsuite/gfortran.dg/vect/no-vfa-pr32377.f90 | 16 ++++ gcc/testsuite/gfortran.dg/vect/no-vfa-pr32457.f90 | 15 ++++ gcc/testsuite/gfortran.dg/vect/pr19049.f90 | 24 ++++++ gcc/testsuite/gfortran.dg/vect/pr32377.f90 | 15 ++++ gcc/testsuite/gfortran.dg/vect/pr33301.f | 14 ++++ gcc/testsuite/gfortran.dg/vect/pr39318.f90 | 21 +++++ gcc/testsuite/gfortran.dg/vect/pr45714-a.f | 27 +++++++ gcc/testsuite/gfortran.dg/vect/pr45714-b.f | 27 +++++++ gcc/testsuite/gfortran.dg/vect/pr46213.f90 | 25 ++++++ gcc/testsuite/gfortran.dg/vect/pr50178.f90 | 29 +++++++ gcc/testsuite/gfortran.dg/vect/pr50412.f90 | 12 +++ gcc/testsuite/gfortran.dg/vect/vect-1.f90 | 11 +++ gcc/testsuite/gfortran.dg/vect/vect-2.f90 | 22 +++++ gcc/testsuite/gfortran.dg/vect/vect-3.f90 | 15 ++++ gcc/testsuite/gfortran.dg/vect/vect-4.f90 | 17 ++++ gcc/testsuite/gfortran.dg/vect/vect-5.f90 | 43 ++++++++++ gcc/testsuite/gfortran.dg/vect/vect-6.f | 25 ++++++ gcc/testsuite/gfortran.dg/vect/vect-7.f90 | 16 ++++ gcc/testsuite/gfortran.dg/vect/vect-gems.f90 | 58 +++++++++++++ gcc/testsuite/gfortran.dg/vect/vect.exp | 91 +++++++++++++++++++++ 29 files changed, 829 insertions(+) create mode 100644 gcc/testsuite/gfortran.dg/vect/O3-pr36119.f90 create mode 100644 gcc/testsuite/gfortran.dg/vect/O3-pr39595.f create mode 100644 gcc/testsuite/gfortran.dg/vect/cost-model-pr34445.f create mode 100644 gcc/testsuite/gfortran.dg/vect/cost-model-pr34445a.f create mode 100644 gcc/testsuite/gfortran.dg/vect/fast-math-mgrid-resid.f create mode 100644 gcc/testsuite/gfortran.dg/vect/fast-math-pr33299.f90 create mode 100644 gcc/testsuite/gfortran.dg/vect/fast-math-pr38968.f90 create mode 100644 gcc/testsuite/gfortran.dg/vect/fast-math-real8-pr40801.f90 create mode 100644 gcc/testsuite/gfortran.dg/vect/fast-math-vect-8.f90 create mode 100644 gcc/testsuite/gfortran.dg/vect/no-vfa-pr32377.f90 create mode 100644 gcc/testsuite/gfortran.dg/vect/no-vfa-pr32457.f90 create mode 100644 gcc/testsuite/gfortran.dg/vect/pr19049.f90 create mode 100644 gcc/testsuite/gfortran.dg/vect/pr32377.f90 create mode 100644 gcc/testsuite/gfortran.dg/vect/pr33301.f create mode 100644 gcc/testsuite/gfortran.dg/vect/pr39318.f90 create mode 100644 gcc/testsuite/gfortran.dg/vect/pr45714-a.f create mode 100644 gcc/testsuite/gfortran.dg/vect/pr45714-b.f create mode 100644 gcc/testsuite/gfortran.dg/vect/pr46213.f90 create mode 100644 gcc/testsuite/gfortran.dg/vect/pr50178.f90 create mode 100644 gcc/testsuite/gfortran.dg/vect/pr50412.f90 create mode 100644 gcc/testsuite/gfortran.dg/vect/vect-1.f90 create mode 100644 gcc/testsuite/gfortran.dg/vect/vect-2.f90 create mode 100644 gcc/testsuite/gfortran.dg/vect/vect-3.f90 create mode 100644 gcc/testsuite/gfortran.dg/vect/vect-4.f90 create mode 100644 gcc/testsuite/gfortran.dg/vect/vect-5.f90 create mode 100644 gcc/testsuite/gfortran.dg/vect/vect-6.f create mode 100644 gcc/testsuite/gfortran.dg/vect/vect-7.f90 create mode 100644 gcc/testsuite/gfortran.dg/vect/vect-gems.f90 create mode 100644 gcc/testsuite/gfortran.dg/vect/vect.exp (limited to 'gcc/testsuite/gfortran.dg/vect') diff --git a/gcc/testsuite/gfortran.dg/vect/O3-pr36119.f90 b/gcc/testsuite/gfortran.dg/vect/O3-pr36119.f90 new file mode 100644 index 000000000..432e8485a --- /dev/null +++ b/gcc/testsuite/gfortran.dg/vect/O3-pr36119.f90 @@ -0,0 +1,28 @@ +! { dg-do compile } + +SUBROUTINE check_dnucint_ana (dcore) + IMPLICIT NONE + INTEGER, PARAMETER :: dp=8 + REAL(dp), DIMENSION(10, 2), INTENT(IN),& + OPTIONAL :: dcore + INTEGER :: i, j + REAL(dp) :: delta, nssss, od, rn, ssssm, & + ssssp + REAL(dp), DIMENSION(10, 2) :: corem, corep, ncore + LOGICAL :: check_value + + delta = 1.0E-8_dp + od = 0.5_dp/delta + ncore = od * (corep - corem) + nssss = od * (ssssp - ssssm) + IF (PRESENT(dcore)) THEN + DO i = 1, 2 + DO j = 1, 10 + IF (.NOT.check_value(ncore(j,i), dcore(j,i), delta, 0.1_dp)) THEN + END IF + END DO + END DO + END IF +END SUBROUTINE check_dnucint_ana + +! { dg-final { cleanup-tree-dump "vect" } } diff --git a/gcc/testsuite/gfortran.dg/vect/O3-pr39595.f b/gcc/testsuite/gfortran.dg/vect/O3-pr39595.f new file mode 100644 index 000000000..021d35b90 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/vect/O3-pr39595.f @@ -0,0 +1,17 @@ +! { dg-do compile } + subroutine foo(a,c,i,m) + real a(4,*),b(3,64),c(3,200),d(64) + integer*8 i,j,k,l,m + do j=1,m,64 + do k=1,m-j+1 + d(k)=a(4,j-1+k) + do l=1,3 + b(l,k)=c(l,i)+a(l,j-1+k) + end do + end do + call bar(b,d,i) + end do + end + +! { dg-final { cleanup-tree-dump "vect" } } + diff --git a/gcc/testsuite/gfortran.dg/vect/cost-model-pr34445.f b/gcc/testsuite/gfortran.dg/vect/cost-model-pr34445.f new file mode 100644 index 000000000..6e4a26248 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/vect/cost-model-pr34445.f @@ -0,0 +1,9 @@ +c { dg-do compile } + Subroutine FndSph(Alpha,Rad) + Dimension Rad(100),RadInp(100) + Do I = 1, NSphInp + Rad(I) = RadInp(I) + Alpha = 1.2 + End Do + End +c { dg-final { cleanup-tree-dump "vect" } } diff --git a/gcc/testsuite/gfortran.dg/vect/cost-model-pr34445a.f b/gcc/testsuite/gfortran.dg/vect/cost-model-pr34445a.f new file mode 100644 index 000000000..aca68bb20 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/vect/cost-model-pr34445a.f @@ -0,0 +1,29 @@ +c { dg-do compile } + subroutine derv (xx,b,bv,det,r,s,t,ndopt,cosxy,thick,edis, + 1 vni,vnt) + implicit real*8 (a-h,o-z) + save +c + common /shell1/ disd(9),ield,ielp,npt,idw,ndrot + common /shell4/xji(3,3),p(3,32),h(32) +c + dimension xx(3,*),ndopt(*),bv(*),vni(*),cosxy(6,*),vnt(*), + 1 edis(*),thick(*),b(*) +c + kk=0 + k2=0 + do 130 k=1,ield + k2=k2 + 3 + if (ndopt(k)) 127,127,130 + 127 kk=kk + 1 + do 125 i=1,3 + b(k2+i)=b(k2+i) + (xji(i,1)*p(1,k) + xji(i,2)*p(2,k))*t + 1 + xji(i,3)*h(k) + th=0.5*thick(kk) + b(k2+i+3)=b(k2+i+3) - th*cosxy(i+3,kk) + 125 b(k2+i+6)=b(k2+i+6) + th*cosxy(i,kk) + k2=k2 + 9 + 130 continue + return + end +c { dg-final { cleanup-tree-dump "vect" } } diff --git a/gcc/testsuite/gfortran.dg/vect/fast-math-mgrid-resid.f b/gcc/testsuite/gfortran.dg/vect/fast-math-mgrid-resid.f new file mode 100644 index 000000000..8f196a69a --- /dev/null +++ b/gcc/testsuite/gfortran.dg/vect/fast-math-mgrid-resid.f @@ -0,0 +1,46 @@ +! { dg-do compile { target i?86-*-* x86_64-*-* } } +! { dg-require-effective-target vect_double } +! { dg-require-effective-target sse2 } +! { dg-options "-O3 -ffast-math -msse2 -fpredictive-commoning -ftree-vectorize -fdump-tree-optimized" } + + +******* RESID COMPUTES THE RESIDUAL: R = V - AU +* +* THIS SIMPLE IMPLEMENTATION COSTS 27A + 4M PER RESULT, WHERE +* A AND M DENOTE THE COSTS OF ADDITION (OR SUBTRACTION) AND +* MULTIPLICATION, RESPECTIVELY. BY USING SEVERAL TWO-DIMENSIONAL +* BUFFERS ONE CAN REDUCE THIS COST TO 13A + 4M IN THE GENERAL +* CASE, OR 10A + 3M WHEN THE COEFFICIENT A(1) IS ZERO. +* + SUBROUTINE RESID(U,V,R,N,A) + INTEGER N + REAL*8 U(N,N,N),V(N,N,N),R(N,N,N),A(0:3) + INTEGER I3, I2, I1 +C + DO 600 I3=2,N-1 + DO 600 I2=2,N-1 + DO 600 I1=2,N-1 + 600 R(I1,I2,I3)=V(I1,I2,I3) + > -A(0)*( U(I1, I2, I3 ) ) + > -A(1)*( U(I1-1,I2, I3 ) + U(I1+1,I2, I3 ) + > + U(I1, I2-1,I3 ) + U(I1, I2+1,I3 ) + > + U(I1, I2, I3-1) + U(I1, I2, I3+1) ) + > -A(2)*( U(I1-1,I2-1,I3 ) + U(I1+1,I2-1,I3 ) + > + U(I1-1,I2+1,I3 ) + U(I1+1,I2+1,I3 ) + > + U(I1, I2-1,I3-1) + U(I1, I2+1,I3-1) + > + U(I1, I2-1,I3+1) + U(I1, I2+1,I3+1) + > + U(I1-1,I2, I3-1) + U(I1-1,I2, I3+1) + > + U(I1+1,I2, I3-1) + U(I1+1,I2, I3+1) ) + > -A(3)*( U(I1-1,I2-1,I3-1) + U(I1+1,I2-1,I3-1) + > + U(I1-1,I2+1,I3-1) + U(I1+1,I2+1,I3-1) + > + U(I1-1,I2-1,I3+1) + U(I1+1,I2-1,I3+1) + > + U(I1-1,I2+1,I3+1) + U(I1+1,I2+1,I3+1) ) +C + RETURN + END +! we want to check that predictive commoning did something on the +! vectorized loop, which means we have to have exactly 13 vector +! additions. +! { dg-final { scan-tree-dump-times "vect_var\[^\\n\]*\\+ " 13 "optimized" } } +! { dg-final { cleanup-tree-dump "vect" } } +! { dg-final { cleanup-tree-dump "optimized" } } diff --git a/gcc/testsuite/gfortran.dg/vect/fast-math-pr33299.f90 b/gcc/testsuite/gfortran.dg/vect/fast-math-pr33299.f90 new file mode 100644 index 000000000..1de184dba --- /dev/null +++ b/gcc/testsuite/gfortran.dg/vect/fast-math-pr33299.f90 @@ -0,0 +1,17 @@ +! { dg-require-effective-target vect_double } + +PROGRAM test + REAL(8) :: f,dist(2) + dist = [1.0_8, 0.5_8] + if( f(1.0_8, dist) /= MINVAL(dist)) then + call abort () + endif +END PROGRAM test + +FUNCTION f( x, dist ) RESULT(s) + REAL(8) :: dist(2), x, s + s = MINVAL(dist) + IF( x < 0 ) s = -s +END FUNCTION f + +! { dg-final { cleanup-tree-dump "vect" } } diff --git a/gcc/testsuite/gfortran.dg/vect/fast-math-pr38968.f90 b/gcc/testsuite/gfortran.dg/vect/fast-math-pr38968.f90 new file mode 100644 index 000000000..bfad470f1 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/vect/fast-math-pr38968.f90 @@ -0,0 +1,28 @@ +! Skip this on platforms that don't have the vectorization instructions +! to handle complex types. This test is very slow on these platforms so +! skipping is better then running it unvectorized. +! { dg-skip-if "" { ia64-*-* sparc*-*-* } { "*" } { "" } } +! It can be slow on some x86 CPUs. +! { dg-timeout-factor 2 } +program mymatmul + implicit none + integer, parameter :: kp = 4 + integer, parameter :: n = 2000 + real(kp), dimension(n,n) :: rr, ri + complex(kp), dimension(n,n) :: a,b,c + real :: t1, t2 + integer :: i, j, k + common // a,b,c + + do j = 1, n + do k = 1, n + do i = 1, n + c(i,j) = c(i,j) + a(i,k) * b(k,j) + end do + end do + end do + +end program mymatmul + +! { dg-final { scan-tree-dump "vectorized 1 loops" "vect" } } +! { dg-final { cleanup-tree-dump "vect" } } diff --git a/gcc/testsuite/gfortran.dg/vect/fast-math-real8-pr40801.f90 b/gcc/testsuite/gfortran.dg/vect/fast-math-real8-pr40801.f90 new file mode 100644 index 000000000..2d4018049 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/vect/fast-math-real8-pr40801.f90 @@ -0,0 +1,38 @@ +! { dg-do compile } + +MODULE YOMPHY0 +REAL :: ECMNP +REAL :: SCO +REAL :: USDMLT +END MODULE YOMPHY0 +SUBROUTINE ACCONV ( KIDIA,KFDIA,KLON,KTDIA,KLEV,& + &CDLOCK) +USE YOMPHY0 , ONLY : ECMNP ,SCO ,USDMLT +REAL :: PAPHIF(KLON,KLEV),PCVGQ(KLON,KLEV)& + &,PFPLCL(KLON,0:KLEV),PFPLCN(KLON,0:KLEV),PSTRCU(KLON,0:KLEV)& + &,PSTRCV(KLON,0:KLEV) +INTEGER :: KNLAB(KLON,KLEV),KNND(KLON) +REAL :: ZCP(KLON,KLEV),ZLHE(KLON,KLEV),ZDSE(KLON,KLEV)& + &,ZPOII(KLON),ZALF(KLON),ZLN(KLON),ZUN(KLON),ZVN(KLON)& + &,ZPOIL(KLON) +DO JLEV=KLEV-1,KTDIA,-1 + DO JIT=1,NBITER + ZLN(JLON)=MAX(0.,ZLN(JLON)& + &-(ZQW(JLON,JLEV)-ZQN(JLON)& + &*(PQ(JLON,JLEV+1)-ZQN(JLON))))*KNLAB(JLON,JLEV) + ENDDO +ENDDO +IF (ITOP < KLEV+1) THEN + DO JLON=KIDIA,KFDIA + ZZVAL=PFPLCL(JLON,KLEV)+PFPLCN(JLON,KLEV)-SCO + KNND(JLON)=KNND(JLON)*MAX(0.,-SIGN(1.,0.-ZZVAL)) + ENDDO + DO JLEV=ITOP,KLEV + DO JLON=KIDIA,KFDIA + ENDDO + ENDDO +ENDIF +END SUBROUTINE ACCONV + +! { dg-final { cleanup-tree-dump "vect" } } +! { dg-final { cleanup-modules "yomphy0" } } diff --git a/gcc/testsuite/gfortran.dg/vect/fast-math-vect-8.f90 b/gcc/testsuite/gfortran.dg/vect/fast-math-vect-8.f90 new file mode 100644 index 000000000..26d850de9 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/vect/fast-math-vect-8.f90 @@ -0,0 +1,94 @@ +! { dg-do compile } +! { dg-require-effective-target vect_float } + +module solv_cap + + implicit none + + public :: init_solve + + integer, parameter, public :: dp = 4 + + real(kind=dp), private :: Pi, Mu0, c0, eps0 + logical, private :: UseFFT, UsePreco + real(kind=dp), private :: D1, D2 + integer, private, save :: Ng1=0, Ng2=0 + integer, private, pointer, dimension(:,:) :: Grid + real(kind=dp), private, allocatable, dimension(:,:) :: G + +contains + + subroutine init_solve(Grid_in, GrSize1, GrSize2, UseFFT_in, UsePreco_in) + integer, intent(in), target, dimension(:,:) :: Grid_in + real(kind=dp), intent(in) :: GrSize1, GrSize2 + logical, intent(in) :: UseFFT_in, UsePreco_in + integer :: i, j + + Pi = acos(-1.0_dp) + Mu0 = 4e-7_dp * Pi + c0 = 299792458 + eps0 = 1 / (Mu0 * c0**2) + + UseFFT = UseFFT_in + UsePreco = UsePreco_in + + if(Ng1 /= 0 .and. allocated(G) ) then + deallocate( G ) + end if + + Grid => Grid_in + Ng1 = size(Grid, 1) + Ng2 = size(Grid, 2) + D1 = GrSize1/Ng1 + D2 = GrSize2/Ng2 + + allocate( G(0:Ng1,0:Ng2) ) + + write(unit=*, fmt=*) "Calculating G" + do i=0,Ng1 + do j=0,Ng2 + G(j,i) = Ginteg( -D1/2,-D2/2, D1/2,D2/2, i*D1,j*D2 ) + end do + end do + + if(UseFFT) then + write(unit=*, fmt=*) "Transforming G" + call FourirG(G,1) + end if + + return + + + contains + function Ginteg(xq1,yq1, xq2,yq2, xp,yp) result(G) + real(kind=dp), intent(in) :: xq1,yq1, xq2,yq2, xp,yp + real(kind=dp) :: G + real(kind=dp) :: x1,x2,y1,y2,t + x1 = xq1-xp + x2 = xq2-xp + y1 = yq1-yp + y2 = yq2-yp + + if (x1+x2 < 0) then + t = -x1 + x1 = -x2 + x2 = t + end if + if (y1+y2 < 0) then + t = -y1 + y1 = -y2 + y2 = t + end if + + G = (x2*y2)-(x1*y2)-(x2*y1)+(x1*y1) + + return + end function Ginteg + + end subroutine init_solve + +end module solv_cap + + +! { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_intfloat_cvt } } } +! { dg-final { cleanup-tree-dump "vect" } } diff --git a/gcc/testsuite/gfortran.dg/vect/no-vfa-pr32377.f90 b/gcc/testsuite/gfortran.dg/vect/no-vfa-pr32377.f90 new file mode 100644 index 000000000..ce4a47afd --- /dev/null +++ b/gcc/testsuite/gfortran.dg/vect/no-vfa-pr32377.f90 @@ -0,0 +1,16 @@ +! { dg-do compile } +! { dg-require-effective-target vect_float } + +subroutine s243(ntimes,ld,n,ctime,dtime,a,b,c,d,e,aa,bb,cc) + +integer ntimes,ld,n,i,nl +real a(n),b(n),c(n),d(n),e(n),aa(ld,n),bb(ld,n),cc(ld,n) +real t1,t2,chksum,ctime,dtime,cs1d + b(:n-1)= b(:n-1)+(c(:n-1)+e(:n-1))*d(:n-1) + a(:n-1)= b(:n-1)+a(2:n)*d(:n-1) + return +end + +! { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" } } +! { dg-final { cleanup-tree-dump "vect" } } + diff --git a/gcc/testsuite/gfortran.dg/vect/no-vfa-pr32457.f90 b/gcc/testsuite/gfortran.dg/vect/no-vfa-pr32457.f90 new file mode 100644 index 000000000..07a2b6056 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/vect/no-vfa-pr32457.f90 @@ -0,0 +1,15 @@ +! { dg-do compile } +! { dg-require-effective-target vect_float } + +SUBROUTINE KEEL(RBOUND) + REAL, DIMENSION(0:100) :: RBOUND + DO N = 1, NP1 + RBOUND(N) = RBOUND(N-1) + 1 + END DO + DO N = 1, NS + WRITE (16,'(I5)') SRAD(N) + END DO +END SUBROUTINE KEEL + +! { dg-final { scan-tree-dump-times "vectorized 0 loops" 1 "vect" } } +! { dg-final { cleanup-tree-dump "vect" } } diff --git a/gcc/testsuite/gfortran.dg/vect/pr19049.f90 b/gcc/testsuite/gfortran.dg/vect/pr19049.f90 new file mode 100644 index 000000000..6c8030cce --- /dev/null +++ b/gcc/testsuite/gfortran.dg/vect/pr19049.f90 @@ -0,0 +1,24 @@ +! { dg-do compile } +! { dg-require-effective-target vect_float } + +subroutine s111 (ntimes,ld,n,ctime,dtime,a,b,c,d,e,aa,bb,cc) +! linear dependence testing +! no dependence - vectorizable +! but not consecutive access + + integer ntimes, ld, n, i, nl + real a(n), b(n), c(n), d(n), e(n), aa(ld,n), bb(ld,n), cc(ld,n) + real t1, t2, second, chksum, ctime, dtime, cs1d + do 1 nl = 1,2*ntimes + do 10 i = 2,n,2 + a(i) = a(i-1) + b(i) + 10 continue + call dummy(ld,n,a,b,c,d,e,aa,bb,cc,1.) + 1 continue + return + end + +! { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" } } +! { dg-final { scan-tree-dump-times "complicated access pattern" 1 "vect" } } +! { dg-final { cleanup-tree-dump "vect" } } + diff --git a/gcc/testsuite/gfortran.dg/vect/pr32377.f90 b/gcc/testsuite/gfortran.dg/vect/pr32377.f90 new file mode 100644 index 000000000..624a9ae7e --- /dev/null +++ b/gcc/testsuite/gfortran.dg/vect/pr32377.f90 @@ -0,0 +1,15 @@ +! { dg-do compile } +! { dg-require-effective-target vect_float } + +subroutine s243(ntimes,ld,n,ctime,dtime,a,b,c,d,e,aa,bb,cc) + + integer ntimes,ld,n,i,nl + real a(n),b(n),c(n),d(n),e(n),aa(ld,n),bb(ld,n),cc(ld,n) + real t1,t2,chksum,ctime,dtime,cs1d + b(:n-1)= b(:n-1)+(c(:n-1)+e(:n-1))*d(:n-1) + a(:n-1)= b(:n-1)+a(2:n)*d(:n-1) + return +end subroutine s243 + +! { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" } } +! { dg-final { cleanup-tree-dump "vect" } } diff --git a/gcc/testsuite/gfortran.dg/vect/pr33301.f b/gcc/testsuite/gfortran.dg/vect/pr33301.f new file mode 100644 index 000000000..0713f3e75 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/vect/pr33301.f @@ -0,0 +1,14 @@ +c { dg-do compile } +C Derived from lapack + SUBROUTINE ZGELSX( M, N, NRHS, A, LDA, B, LDB, JPVT, RCOND, RANK, + $ WORK, RWORK, INFO ) + COMPLEX(kind=8) WORK( * ) +c Following declaration added on transfer to gfortran testsuite. +c It is present in original lapack source + integer rank + DO 20 I = 1, RANK + WORK( ISMAX+I-1 ) = S2*WORK( ISMAX+I-1 ) + 20 CONTINUE + END + +c { dg-final { cleanup-tree-dump "vect" } } diff --git a/gcc/testsuite/gfortran.dg/vect/pr39318.f90 b/gcc/testsuite/gfortran.dg/vect/pr39318.f90 new file mode 100644 index 000000000..c22e558e2 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/vect/pr39318.f90 @@ -0,0 +1,21 @@ +! { dg-do compile { target fopenmp } } +! { dg-options "-c -fopenmp -fexceptions -O2 -ftree-vectorize" } + + subroutine adw_trajsp (F_u,i0,in,j0,jn) + implicit none + real F_u(*) + integer i0,in,j0,jn + integer n,i,j + real*8 xsin(i0:in,j0:jn) +!$omp parallel do private(xsin) + do j=j0,jn + do i=i0,in + xsin(i,j) = sqrt(F_u(n)) + end do + end do +!$omp end parallel do + return + end + +! { dg-final { cleanup-tree-dump "vect" } } + diff --git a/gcc/testsuite/gfortran.dg/vect/pr45714-a.f b/gcc/testsuite/gfortran.dg/vect/pr45714-a.f new file mode 100644 index 000000000..dd99d1fe5 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/vect/pr45714-a.f @@ -0,0 +1,27 @@ +! { dg-do compile { target x86_64-*-* } } +! { dg-options "-O3 -march=core2 -mavx -ffast-math -mveclibabi=svml" } + + integer index(18),i,j,k,l,ipiv(18),info,ichange,neq,lda,ldb, + & nrhs,iplas + real*8 ep0(6),al10(18),al20(18),dg0(18),ep(6),al1(18), + & al2(18),dg(18),ddg(18),xm(6,18),h(18,18),ck(18),cn(18), + & c(18),d(18),phi(18),delta(18),r0(18),q(18),b(18),cphi(18), + & q1(18),q2(18),stri(6),htri(18),sg(18),r(42),xmc(6,18),aux(18), + & t(42),gl(18,18),gr(18,18),ee(6),c1111,c1122,c1212,dd, + & skl(3,3),xmtran(3,3),ddsdde(6,6),xx(6,18) + do + do i=1,18 + htri(i)=dabs(sg(i))-r0(i)-ck(i)*(dg(i)/dtime)**(1.d0/cn(i)) + do j=1,18 + enddo + enddo + do + if(i.ne.j) then + gr(index(i),1)=htri(i) + endif + call dgesv(neq,nrhs,gl,lda,ipiv,gr,ldb,info) + enddo + enddo + end + +! { dg-final { cleanup-tree-dump "vect" } } diff --git a/gcc/testsuite/gfortran.dg/vect/pr45714-b.f b/gcc/testsuite/gfortran.dg/vect/pr45714-b.f new file mode 100644 index 000000000..a536e1f59 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/vect/pr45714-b.f @@ -0,0 +1,27 @@ +! { dg-do compile { target powerpc*-*-* } } +! { dg-options "-O3 -mcpu=power7 -ffast-math -mveclibabi=mass" } + + integer index(18),i,j,k,l,ipiv(18),info,ichange,neq,lda,ldb, + & nrhs,iplas + real*8 ep0(6),al10(18),al20(18),dg0(18),ep(6),al1(18), + & al2(18),dg(18),ddg(18),xm(6,18),h(18,18),ck(18),cn(18), + & c(18),d(18),phi(18),delta(18),r0(18),q(18),b(18),cphi(18), + & q1(18),q2(18),stri(6),htri(18),sg(18),r(42),xmc(6,18),aux(18), + & t(42),gl(18,18),gr(18,18),ee(6),c1111,c1122,c1212,dd, + & skl(3,3),xmtran(3,3),ddsdde(6,6),xx(6,18) + do + do i=1,18 + htri(i)=dabs(sg(i))-r0(i)-ck(i)*(dg(i)/dtime)**(1.d0/cn(i)) + do j=1,18 + enddo + enddo + do + if(i.ne.j) then + gr(index(i),1)=htri(i) + endif + call dgesv(neq,nrhs,gl,lda,ipiv,gr,ldb,info) + enddo + enddo + end + +! { dg-final { cleanup-tree-dump "vect" } } diff --git a/gcc/testsuite/gfortran.dg/vect/pr46213.f90 b/gcc/testsuite/gfortran.dg/vect/pr46213.f90 new file mode 100644 index 000000000..504d1a3cf --- /dev/null +++ b/gcc/testsuite/gfortran.dg/vect/pr46213.f90 @@ -0,0 +1,25 @@ +! { dg-do compile } +! { dg-options "-O -fno-tree-loop-ivcanon -ftree-vectorize -fno-tree-ccp -fno-tree-ch -finline-small-functions" } + +module foo + INTEGER, PARAMETER :: ONE = 1 +end module foo +program test + use foo + integer :: a(ONE), b(ONE), c(ONE), d(ONE) + interface + function h_ext() + end function h_ext + end interface + c = j() + if (any (c .ne. check)) call myabort (7) +contains + function j() + integer :: j(ONE), cc(ONE) + j = cc - j + end function j + function get_d() + end function get_d +end program test + +! { dg-final { cleanup-tree-dump "vect" } } diff --git a/gcc/testsuite/gfortran.dg/vect/pr50178.f90 b/gcc/testsuite/gfortran.dg/vect/pr50178.f90 new file mode 100644 index 000000000..e24ce5b15 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/vect/pr50178.f90 @@ -0,0 +1,29 @@ +! { dg-do compile } + +module yemdyn + implicit none + integer, parameter :: jpim = selected_int_kind(9) + integer, parameter :: jprb = selected_real_kind(13,300) + real(kind=jprb) :: elx + real(kind=jprb), allocatable :: xkcoef(:) + integer(kind=jpim),allocatable :: ncpln(:), npne(:) +end module yemdyn + +subroutine suedyn + + use yemdyn + + implicit none + + integer(kind=jpim) :: jm, jn + real(kind=jprb) :: zjm, zjn, zxxx + + jn=0 + do jm=0,ncpln(jn) + zjm=real(jm,jprb) / elx + xkcoef(npne(jn)+jm) = - zxxx*(zjm**2)**0.5_jprb + end do + +end subroutine suedyn + +! { dg-final { cleanup-tree-dump "vect" } } diff --git a/gcc/testsuite/gfortran.dg/vect/pr50412.f90 b/gcc/testsuite/gfortran.dg/vect/pr50412.f90 new file mode 100644 index 000000000..4f95741f7 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/vect/pr50412.f90 @@ -0,0 +1,12 @@ +! { dg-do compile } + + DOUBLE PRECISION AK,AI,AAE + COMMON/com/AK(36),AI(4,4),AAE(8,4),ii,jj + DO 20 II=1,4 + DO 21 JJ=1,4 + AK(n)=AK(n)-AAE(I,II)*AI(II,JJ) + 21 CONTINUE + 20 CONTINUE + END + +! { dg-final { cleanup-tree-dump "vect" } } diff --git a/gcc/testsuite/gfortran.dg/vect/vect-1.f90 b/gcc/testsuite/gfortran.dg/vect/vect-1.f90 new file mode 100644 index 000000000..cafcec7d0 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/vect/vect-1.f90 @@ -0,0 +1,11 @@ +! { dg-do compile } +! { dg-require-effective-target vect_float } + +DIMENSION A(1000000), B(1000000), C(1000000) +READ*, X, Y +A = LOG(X); B = LOG(Y); C = A + B +PRINT*, C(500000) +END + +! { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" } } +! { dg-final { cleanup-tree-dump "vect" } } diff --git a/gcc/testsuite/gfortran.dg/vect/vect-2.f90 b/gcc/testsuite/gfortran.dg/vect/vect-2.f90 new file mode 100644 index 000000000..0f45a70c5 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/vect/vect-2.f90 @@ -0,0 +1,22 @@ +! { dg-do compile } +! { dg-require-effective-target vect_float } + +SUBROUTINE FOO(A, B, C) +DIMENSION A(1000000), B(1000000), C(1000000) +READ*, X, Y +A = LOG(X); B = LOG(Y); C = A + B +PRINT*, C(500000) +END + +! First loop (A=LOG(X)) is vectorized using peeling to align the store. +! Same for the second loop (B=LOG(Y)). +! Third loop (C = A + B) is vectorized using versioning (for targets that don't +! support unaligned loads) or using peeling to align the store (on targets that +! support unaligned loads). + +! { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" } } +! { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 3 "vect" { xfail { vect_no_align || { ! vector_alignment_reachable } } } } } +! { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" { target { vect_no_align && { ! vector_alignment_reachable } } } } } +! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail { vect_no_align } } } } +! { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 3 "vect" {target { vect_no_align || { { ! vector_alignment_reachable } && { ! vect_hw_misalign } } } } } } +! { dg-final { cleanup-tree-dump "vect" } } diff --git a/gcc/testsuite/gfortran.dg/vect/vect-3.f90 b/gcc/testsuite/gfortran.dg/vect/vect-3.f90 new file mode 100644 index 000000000..5fc4fbf49 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/vect/vect-3.f90 @@ -0,0 +1,15 @@ +! { dg-do compile } +! { dg-require-effective-target vect_float } + +SUBROUTINE SAXPY(X, Y, A, N) +DIMENSION X(N), Y(N) +Y = Y + A * X +END + +! { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 3 "vect" { target vect_no_align } } } +! { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" { target { {! vect_no_align} && { {! vector_alignment_reachable} && {! vect_hw_misalign} } } } } } +! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { target { {! vect_no_align} && { {! vector_alignment_reachable} && {! vect_hw_misalign} } } } } } +! { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { vect_no_align || {! vector_alignment_reachable}} } } } +! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { { vect_no_align } || { ! vector_alignment_reachable} } } } } + +! { dg-final { cleanup-tree-dump "vect" } } diff --git a/gcc/testsuite/gfortran.dg/vect/vect-4.f90 b/gcc/testsuite/gfortran.dg/vect/vect-4.f90 new file mode 100644 index 000000000..592282fb0 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/vect/vect-4.f90 @@ -0,0 +1,17 @@ +! { dg-do compile } +! { dg-require-effective-target vect_float } + +! Peeling to align the store to Y will also align the load from Y. +! The load from X may still be misaligned. + +SUBROUTINE SAXPY(X, Y, A) +DIMENSION X(64), Y(64) +Y = Y + A * X +END + +! { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } +! { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { { vect_no_align } || {! vector_alignment_reachable} } } } } +! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { { vect_no_align } || {! vector_alignment_reachable} } } } } +! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { target { {! vector_alignment_reachable} && {! vect_hw_misalign} } } } } +! { dg-final { scan-tree-dump-times "accesses have the same alignment." 1 "vect" } } +! { dg-final { cleanup-tree-dump "vect" } } diff --git a/gcc/testsuite/gfortran.dg/vect/vect-5.f90 b/gcc/testsuite/gfortran.dg/vect/vect-5.f90 new file mode 100644 index 000000000..72776a6fb --- /dev/null +++ b/gcc/testsuite/gfortran.dg/vect/vect-5.f90 @@ -0,0 +1,43 @@ +! { dg-require-effective-target vect_int } + + Subroutine foo (N, M) + Integer N + Integer M + integer A(8,16) + integer B(8) + + B = (/ 2, 3, 5, 7, 11, 13, 17, 23 /) + + ! Unknown loop bound. J depends on I. + + do I = 1, N + do J = I, M + A(J,2) = B(J) + end do + end do + + do I = 1, N + do J = I, M + if (A(J,2) /= B(J)) then + call abort () + endif + end do + end do + + Return + end + + + program main + + Call foo (16, 8) + + stop + end + +! { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } +! { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { vect_no_align || {! vector_alignment_reachable} } } } } +! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { vect_no_align } } } } +! { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 2 "vect" { target { vect_no_align } } } } +! { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 1 "vect" { target { {! vector_alignment_reachable} && {! vect_hw_misalign} } } } } +! { dg-final { cleanup-tree-dump "vect" } } diff --git a/gcc/testsuite/gfortran.dg/vect/vect-6.f b/gcc/testsuite/gfortran.dg/vect/vect-6.f new file mode 100644 index 000000000..f232dcb82 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/vect/vect-6.f @@ -0,0 +1,25 @@ +! { dg-do compile } + + SUBROUTINE PROPAGATE(ICI1,ICI2,I,J,J1,ELEM,NHSO,HSO + * ,MULST,IROOTS) + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + COMPLEX*16 HSO,ELEM + DIMENSION HSO(NHSO,NHSO),MULST(*),IROOTS(*) + ISHIFT=MULST(ICI1)*(I-1)+1 + JSHIFT=MULST(ICI2)*(J-1)+1 + DO 200 ICI=1,ICI1-1 + ISHIFT=ISHIFT+MULST(ICI)*IROOTS(ICI) + 200 CONTINUE + DO 220 ICI=1,ICI2-1 + JSHIFT=JSHIFT+MULST(ICI)*IROOTS(ICI) + 220 CONTINUE + DO 150 MSS=MS,-MS,-2 + IND1=ISHIFT+K + IND2=JSHIFT+K + HSO(IND1,IND2)=ELEM + HSO(IND2,IND1)=DCONJG(ELEM) + 150 CONTINUE + END + +! { dg-final { cleanup-tree-dump "vect" } } + diff --git a/gcc/testsuite/gfortran.dg/vect/vect-7.f90 b/gcc/testsuite/gfortran.dg/vect/vect-7.f90 new file mode 100644 index 000000000..b82bb95e8 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/vect/vect-7.f90 @@ -0,0 +1,16 @@ +! { dg-do compile } +! { dg-require-effective-target vect_double } + +subroutine foo (x,nnd) + dimension x(nnd) + integer i + + do i=1,nnd + x(i) = 1.d0 + (1.d0*i)/nnd + end do + +end subroutine foo + +! { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_unpack && vect_intfloat_cvt } } } } +! { dg-final { cleanup-tree-dump "vect" } } + diff --git a/gcc/testsuite/gfortran.dg/vect/vect-gems.f90 b/gcc/testsuite/gfortran.dg/vect/vect-gems.f90 new file mode 100644 index 000000000..66e878d3d --- /dev/null +++ b/gcc/testsuite/gfortran.dg/vect/vect-gems.f90 @@ -0,0 +1,58 @@ +! { dg-do compile } +! { dg-require-effective-target vect_double } + +MODULE UPML_mod + +IMPLICIT NONE + +PUBLIC UPMLupdateE + +PRIVATE + +real(kind=8), dimension(:,:,:), allocatable :: Dx_ilow + +real(kind=8), dimension(:), allocatable :: aye, aze +real(kind=8), dimension(:), allocatable :: bye, bze +real(kind=8), dimension(:), allocatable :: fxh, cxh + +real(kind=8) :: epsinv +real(kind=8) :: dxinv, dyinv, dzinv + +integer :: xstart, ystart, zstart, xstop, ystop, zstop + +CONTAINS + +SUBROUTINE UPMLupdateE(nx,ny,nz,Hx,Hy,Hz,Ex,Ey,Ez) + +integer, intent(in) :: nx, ny, nz +real(kind=8), intent(inout), & + dimension(xstart:xstop+1,ystart:ystop+1,zstart:zstop+1) :: Ex, Ey, Ez +real(kind=8), intent(inout), & + allocatable :: Hx(:,:,:), Hy(:,:,:), Hz(:,:,:) + +integer :: i, j, k +real(kind=8) :: Dxold, Dyold, Dzold + +do k=zstart+1,zstop + do j=ystart+1,ystop + do i=xstart+1,0 + + Dxold = Dx_ilow(i,j,k) + + Dx_ilow(i,j,k) = aye(j) * Dx_ilow(i,j,k) + & + bye(j) * ((Hz(i,j,k )-Hz(i,j-1,k))*dyinv + & + (Hy(i,j,k-1)-Hy(i,j,k ))*dzinv) + + Ex(i,j,k) = aze(k) * Ex(i,j,k) + & + bze(k) * (cxh(i)*Dx_ilow(i,j,k) - fxh(i)*Dxold) * epsinv + end do + end do +end do + +END SUBROUTINE UPMLupdateE + +END MODULE UPML_mod + +! { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } +! { dg-final { cleanup-tree-dump "vect" } } +! { dg-final { cleanup-modules "upml_mod" } } diff --git a/gcc/testsuite/gfortran.dg/vect/vect.exp b/gcc/testsuite/gfortran.dg/vect/vect.exp new file mode 100644 index 000000000..11bcecd7c --- /dev/null +++ b/gcc/testsuite/gfortran.dg/vect/vect.exp @@ -0,0 +1,91 @@ +# Copyright (C) 1997, 2004, 2007, 2008, 2010 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# . + +# GCC testsuite that uses the `dg.exp' driver. + +# Load support procs. +load_lib gfortran-dg.exp +load_lib target-supports.exp + +# Set up flags used for tests that don't specify options. +global DEFAULT_VECTCFLAGS +set DEFAULT_VECTCFLAGS "" + +# These flags are used for all targets. +lappend DEFAULT_VECTCFLAGS "-O2" "-ftree-vectorize" "-fno-vect-cost-model" \ + "-ftree-vectorizer-verbose=4" "-fdump-tree-vect-stats" + +# If the target system supports vector instructions, the default action +# for a test is 'run', otherwise it's 'compile'. Save current default. +# Executing vector instructions on a system without hardware vector support +# is also disabled by a call to check_vect, but disabling execution here is +# more efficient. +global dg-do-what-default +set save-dg-do-what-default ${dg-do-what-default} + +# Skip these tests for targets that do not support generating vector +# code. Set additional target-dependent vector flags, which can be +# overridden by using dg-options in individual tests. +if ![check_vect_support_and_set_flags] { + return +} + +# Initialize `dg'. +dg-init + +# Main loop. +gfortran-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/vect-*.\[fF\]{,90,95,03,08} ]] $DEFAULT_VECTCFLAGS +gfortran-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/pr*.\[fF\]{,90,95,03,08} ]] $DEFAULT_VECTCFLAGS + +#### Tests with special options +global SAVED_DEFAULT_VECTCFLAGS +set SAVED_DEFAULT_VECTCFLAGS $DEFAULT_VECTCFLAGS + +# -ffast-math tests +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-ffast-math" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/fast-math-*.\[fF\]{,90,95,03,08} ]] \ + "" $DEFAULT_VECTCFLAGS + +# -ffast-math tests +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-ffast-math" "-fdefault-real-8" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/fast-math-real8*.\[fF\]{,90,95,03,08} ]] \ + "" $DEFAULT_VECTCFLAGS + +# -fvect-cost-model tests +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-fvect-cost-model" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/cost-model-*.\[fF\]{,90,95,03,08} ]] \ + "" $DEFAULT_VECTCFLAGS + +# --param vect-max-version-for-alias-checks=0 tests +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "--param" "vect-max-version-for-alias-checks=0" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/no-vfa-*.\[fF\]{,90,95,03,08} ]] \ + "" $DEFAULT_VECTCFLAGS + +# With -O3 +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-O3" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/O3-*.\[fF\]{,90,95,03,08} ]] \ + "" $DEFAULT_VECTCFLAGS + +# Clean up. +set dg-do-what-default ${save-dg-do-what-default} + +# All done. +dg-finish -- cgit v1.2.3