diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fd4a6af7720..d4ee2a2754c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2019-02-01 Bin Cheng + + PR tree-optimization/88932 + * tree-predcom.c (try_combine_chains): Get loop bbs in dom order. + 2019-01-31 Jakub Jelinek PR middle-end/89137 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 989f4c5acec..2bf2433529c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-02-01 Bin Cheng + + PR tree-optimization/88932 + * gfortran.dg/pr88932.f90: New test. + 2019-01-31 Marek Polacek PR c++/88983 - ICE with switch in constexpr function. diff --git a/gcc/testsuite/gfortran.dg/pr88932.f90 b/gcc/testsuite/gfortran.dg/pr88932.f90 new file mode 100644 index 00000000000..dc3a51b710a --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr88932.f90 @@ -0,0 +1,143 @@ +! { dg-do compile } +! { dg-options "-O1 -fpredictive-commoning -fno-tree-ch -fno-tree-dominator-opts -fno-tree-fre" } +! +! PR tree-optimization/88932 +! + +implicit none + +interface + subroutine check_value(b, n, val) + integer :: b(..) + integer, value :: n + integer :: val(n) + end subroutine +end interface + +integer, target :: x(2:5,4:7), y(-4:4) +integer, allocatable, target :: z(:,:,:,:) +integer, allocatable :: val(:) +integer :: i + +allocate(z(1:4, -2:5, 4, 10:11)) + +if (rank(x) /= 2) STOP 1 +val = [(2*i+3, i = 1, size(x))] +x = reshape (val, shape(x)) +call foo(x, rank(x), lbound(x), ubound(x), val) +call foo2(x, rank(x), lbound(x), ubound(x), val) +call bar(x,x,.true.) +call bar(x,prsnt=.false.) + +if (rank(y) /= 1) STOP 2 +val = [(2*i+7, i = 1, size(y))] +y = reshape (val, shape(y)) +call foo(y, rank(y), lbound(y), ubound(y), val) +call foo2(y, rank(y), lbound(y), ubound(y), val) +call bar(y,y,.true.) +call bar(y,prsnt=.false.) + +if (rank(z) /= 4) STOP 3 +val = [(2*i+5, i = 1, size(z))] +z(:,:,:,:) = reshape (val, shape(z)) +call foo(z, rank(z), lbound(z), ubound(z), val) +call foo(z, rank(z), lbound(z), ubound(z), val) +call foo2(z, rank(z), lbound(z), ubound(z), val) +call bar(z,z,.true.) +call bar(z,prsnt=.false.) + +contains + subroutine bar(a,b, prsnt) + integer, pointer, optional, intent(in) :: a(..),b(..) + logical, value :: prsnt + if (.not. associated(a)) STOP 4 + if (present(b)) then + ! The following is not valid. + ! Technically, it could be allowed and might be in Fortran 2015: + ! if (.not. associated(a,b)) STOP 5 + else + if (.not. associated(a)) STOP 6 + end if + if (.not. present(a)) STOP 7 + if (prsnt .neqv. present(b)) STOP 8 + end subroutine + + ! POINTER argument - bounds as specified before + subroutine foo(a, rnk, low, high, val) + integer,pointer, intent(in) :: a(..) + integer, value :: rnk + integer, intent(in) :: low(:), high(:), val(:) + integer :: i + + + + if (rank(a) /= rnk) STOP 9 + if (size(low) /= rnk .or. size(high) /= rnk) STOP 10 + if (size(a) /= product (high - low +1)) STOP 11 + + if (rnk > 0) then + if (low(1) /= lbound(a,1)) STOP 12 + if (high(1) /= ubound(a,1)) STOP 13 + if (size (a,1) /= high(1)-low(1)+1) STOP 14 + end if + + do i = 1, rnk + if (low(i) /= lbound(a,i)) STOP 15 + if (high(i) /= ubound(a,i)) STOP 16 + if (size (a,i) /= high(i)-low(i)+1) STOP 17 + end do + call check_value (a, rnk, val) + call foo2(a, rnk, low, high, val) + end subroutine + + ! Non-pointer, non-allocatable bounds. lbound == 1 + subroutine foo2(a, rnk, low, high, val) + integer, intent(in) :: a(..) + integer, value :: rnk + integer, intent(in) :: low(:), high(:), val(:) + integer :: i + + if (rank(a) /= rnk) STOP 18 + if (size(low) /= rnk .or. size(high) /= rnk) STOP 19 + if (size(a) /= product (high - low +1)) STOP 20 + + if (rnk > 0) then + if (1 /= lbound(a,1)) STOP 21 + if (high(1)-low(1)+1 /= ubound(a,1)) STOP 22 + if (size (a,1) /= high(1)-low(1)+1) STOP 23 + end if + + do i = 1, rnk + if (1 /= lbound(a,i)) STOP 24 + if (high(i)-low(i)+1 /= ubound(a,i)) STOP 25 + if (size (a,i) /= high(i)-low(i)+1) STOP 26 + end do + call check_value (a, rnk, val) + end subroutine foo2 + + ! ALLOCATABLE argument - bounds as specified before + subroutine foo3 (a, rnk, low, high, val) + integer, allocatable, intent(in), target :: a(..) + integer, value :: rnk + integer, intent(in) :: low(:), high(:), val(:) + integer :: i + + if (rank(a) /= rnk) STOP 27 + if (size(low) /= rnk .or. size(high) /= rnk) STOP 28 + if (size(a) /= product (high - low +1)) STOP 29 + + if (rnk > 0) then + if (low(1) /= lbound(a,1)) STOP 30 + if (high(1) /= ubound(a,1)) STOP 31 + if (size (a,1) /= high(1)-low(1)+1) STOP 32 + end if + + do i = 1, rnk + if (low(i) /= lbound(a,i)) STOP 33 + if (high(i) /= ubound(a,i)) STOP 34 + if (size (a,i) /= high(i)-low(i)+1) STOP 35 + end do + call check_value (a, rnk, val) + call foo(a, rnk, low, high, val) + end subroutine +end diff --git a/gcc/tree-predcom.c b/gcc/tree-predcom.c index 8c4a6581531..1870645d66d 100644 --- a/gcc/tree-predcom.c +++ b/gcc/tree-predcom.c @@ -2836,7 +2836,7 @@ try_combine_chains (struct loop *loop, vec *chains) return; /* Setup UID for all statements in dominance order. */ - basic_block *bbs = get_loop_body (loop); + basic_block *bbs = get_loop_body_in_dom_order (loop); renumber_gimple_stmt_uids_in_blocks (bbs, loop->num_nodes); free (bbs);