The following fixes a cut&paste error in disambiguating using restrict info. Instead of using the for this purpose computed rbase1/rbase2 which preserve MEM_REF bases even when they are based on a decl the code performs the check on the bases that drop info for those ...
Bootstrapped and tested on x86_64-unknown-linux-gnu. The patch helps addressing regressions in SPEC so I am planning to push it even though the bug itself is not a regression on the specific testcase (a testcase which would "regress" in inlining behavior could be viewed as regression though). I am also considering to push for GCC 11.3 but likely not further. Richard. 2022-02-10 Richard Biener <rguent...@suse.de> PR tree-optimization/104466 * tree-ssa-alias.cc (refs_may_alias_p_2): Use rbase1/rbase2 for the MR_DEPENDENCE checks as intended. * gfortran.dg/pr104466.f90: New testcase. --- gcc/testsuite/gfortran.dg/pr104466.f90 | 116 +++++++++++++++++++++++++ gcc/tree-ssa-alias.cc | 8 +- 2 files changed, 120 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/pr104466.f90 diff --git a/gcc/testsuite/gfortran.dg/pr104466.f90 b/gcc/testsuite/gfortran.dg/pr104466.f90 new file mode 100644 index 00000000000..ec0e45866be --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr104466.f90 @@ -0,0 +1,116 @@ +! { dg-do compile } +! { dg-options "-std=legacy -O2 --param max-inline-insns-auto=0 --param max-inline-insns-single=0 -fdump-tree-lim2-details" } + + MODULE mod_param + integer, parameter :: Ngrids = 1 + integer, dimension(Ngrids) :: N + END + MODULE mod_forces + TYPE T_FORCES + real, pointer :: sustr(:,:) + real, pointer :: svstr(:,:) + real, pointer :: bustr(:,:) + real, pointer :: bvstr(:,:) + real, pointer :: srflx(:,:) + real, pointer :: stflx(:,:,:) + END TYPE + TYPE (T_FORCES), allocatable :: FORCES(:) + END + MODULE mod_grid + TYPE T_GRID + real, pointer :: f(:,:) + real, pointer :: Hz(:,:,:) + real, pointer :: z_r(:,:,:) + real, pointer :: z_w(:,:,:) + END TYPE + TYPE (T_GRID), allocatable :: GRID(:) + END + MODULE mod_scalars + USE mod_param + END + MODULE mod_mixing + TYPE T_MIXING + integer, pointer :: ksbl(:,:) + real, pointer :: Akv(:,:,:) + real, pointer :: Akt(:,:,:,:) + real, pointer :: alpha(:,:) + real, pointer :: beta(:,:) + real, pointer :: bvf(:,:,:) + real, pointer :: hsbl(:,:) + real, pointer :: ghats(:,:,:,:) + END TYPE + TYPE (T_MIXING), allocatable :: MIXING(:) + END + MODULE mod_ocean + TYPE T_OCEAN + real, pointer :: pden(:,:,:) + real, pointer :: u(:,:,:,:) + real, pointer :: v(:,:,:,:) + END TYPE + TYPE (T_OCEAN), allocatable :: OCEAN(:) + END + MODULE lmd_skpp_mod + PRIVATE + PUBLIC lmd_skpp + CONTAINS + SUBROUTINE lmd_skpp + USE mod_forces + USE mod_grid + USE mod_mixing + USE mod_ocean + integer tile + integer UBi, UBj + CALL lmd_skpp_tile (ng, tile, LBi, UBi, LBj, UBj, & + IminS, ImaxS, JminS, JmaxS, nstp0, & + GRID(ng) % f, GRID(ng) % Hz, & + GRID(ng) % z_r, GRID(ng) % z_w, & + OCEAN(ng) % u, OCEAN(ng) % v, & + OCEAN(ng) % pden, FORCES(ng) % srflx, & + FORCES(ng) % stflx, FORCES(ng) % bustr, & + FORCES(ng) % bvstr, FORCES(ng) % sustr, & + FORCES(ng) % svstr, MIXING(ng) % alpha, & + MIXING(ng) % beta, MIXING(ng) % bvf, & + MIXING(ng) % ghats, MIXING(ng) % Akt, & + MIXING(ng) % Akv, MIXING(ng) % hsbl, MIXING(ng) % ksbl) + END + SUBROUTINE lmd_skpp_tile (ng, tile, LBi, UBi, LBj, UBj, & + IminS, ImaxS, JminS, JmaxS, nstp, f, Hz, z_r, z_w, & + u, v, pden, srflx, stflx, bustr, bvstr, sustr, svstr, & + alpha, beta, bvf, & + ghats, Akt, Akv, hsbl, ksbl) + USE mod_scalars + integer tile + integer UBi, UBj + real f(:,:) + real Hz(:,:,:) + real z_r(:,:,:) + real z_w(:,:,:) + real u(:,:,:,:) + real v(:,:,:,:) + real pden(:,:,:) + real srflx(:,:) + real stflx(:,:,:) + real alpha(:,:) + real beta(:,:) + real bustr(:,:) + real bvstr(:,:) + real sustr(:,:) + real svstr(:,:) + real bvf(:,:,:) + real Akt(:,:,:,:) + real Akv(:,:,:) + real hsbl(:,:) + integer ksbl(:,:) + real ghats(:,:,:,:) + DO j=Jstr,Jend + DO iik=IstrIstr,z_w(i,j,N(ng)) + IF (hsbl0.gt.z_w0) THEN + ksbl=zbl + END IF + END DO + END DO + END + END + +! { dg-final { scan-tree-dump-not ": dependent" "lim2" } } +! { dg-final { scan-tree-dump "Moving statement\[\n\r\]_\[0-9\]+ = n" "lim2" } } diff --git a/gcc/tree-ssa-alias.cc b/gcc/tree-ssa-alias.cc index d434446a997..3e8d2455ba5 100644 --- a/gcc/tree-ssa-alias.cc +++ b/gcc/tree-ssa-alias.cc @@ -2420,12 +2420,12 @@ refs_may_alias_p_2 (ao_ref *ref1, ao_ref *ref2, bool tbaa_p) rbase2 = TREE_OPERAND (rbase2, 0); } if (rbase1 && rbase2 - && (TREE_CODE (base1) == MEM_REF || TREE_CODE (base1) == TARGET_MEM_REF) - && (TREE_CODE (base2) == MEM_REF || TREE_CODE (base2) == TARGET_MEM_REF) + && (TREE_CODE (rbase1) == MEM_REF || TREE_CODE (rbase1) == TARGET_MEM_REF) + && (TREE_CODE (rbase2) == MEM_REF || TREE_CODE (rbase2) == TARGET_MEM_REF) /* If the accesses are in the same restrict clique... */ - && MR_DEPENDENCE_CLIQUE (base1) == MR_DEPENDENCE_CLIQUE (base2) + && MR_DEPENDENCE_CLIQUE (rbase1) == MR_DEPENDENCE_CLIQUE (rbase2) /* But based on different pointers they do not alias. */ - && MR_DEPENDENCE_BASE (base1) != MR_DEPENDENCE_BASE (base2)) + && MR_DEPENDENCE_BASE (rbase1) != MR_DEPENDENCE_BASE (rbase2)) return false; ind1_p = (TREE_CODE (base1) == MEM_REF -- 2.34.1