Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Compiler Bug: passing bounds when aliased

Rodrigo_R_
Beginner
295 Views

Hi.

The Fortran Standard specifies in 8.5.8.4 that the bounds of a dummy Deferred-shape array (both pointer or allocatable) are those from its effective argument.

Nonetheless, this behaviour is not respected with Intel Compiler 18 update 2 for windows x64.

The error occurs in the specific case the effective argument of the Deferred-shape array is aliased by an Assumed-shape array dummy argument inside the same procedure. The error stands for both allocatable and pointer arrays. See example code below:

program example
  implicit none
  integer, allocatable :: x(:), y(:)
  integer, pointer :: p(:), q(:)
  allocate(x(-1:1))
  x = 0
  y = x
  call test1(x, y)    ! output: -1, -1
  call test2(x, y, x) ! output:  1, -1 (wrong result)
  call test3(x, y, x) ! output: -1, -1
  call test4(x, y, x) ! output: -1, -1
  call test5(x, y, x) ! output: -1, -1
  call test6(x, y, x) ! output: -1, -1
  allocate(p(-1:1))
  p = 0
  q => p
  call test1b(p, q)    ! output: -1, -1
  call test2b(p, q, p) ! output:  1, -1 (wrong too)

contains
  subroutine test1(aliased, control)
    integer, allocatable :: aliased(:), control(:)
    print*, lbound(aliased), lbound(control)
  end
  subroutine test2(aliased, control, assumed_shape_alias)
    integer, allocatable :: aliased(:), control(:)
    integer :: assumed_shape_alias(:)
    print*, lbound(aliased), lbound(control)
  end
  subroutine test3(aliased, control, explicit_shape_alias)
    integer, allocatable :: aliased(:), control(:)
    integer :: explicit_shape_alias(3)
    print*, lbound(aliased), lbound(control)
  end
  subroutine test4(aliased, control, deferred_shape_alias)
    integer, allocatable :: aliased(:), control(:)
    integer, allocatable :: deferred_shape_alias(:)
    print*, lbound(aliased), lbound(control)
  end
  subroutine test5(aliased, control, assumed_length_alias)
    integer, allocatable :: aliased(:), control(:)
    integer :: assumed_length_alias(*)
    print*, lbound(aliased), lbound(control)
  end
  subroutine test6(aliased, control, assumed_rank_alias)
    integer, allocatable :: aliased(:), control(:)
    integer :: assumed_rank_alias(..)
    print*, lbound(aliased), lbound(control)
  end
  subroutine test1b(aliased, control)
    integer, pointer :: aliased(:), control(:)
    print*, lbound(aliased), lbound(control)
  end
  subroutine test2b(aliased, control, assumed_shape_alias)
    integer, pointer :: aliased(:), control(:)
    integer :: assumed_shape_alias(:)
    print*, lbound(aliased), lbound(control)
  end
end

I am not using any optimization option, but all the checks and warns.

Compiling with gfortran 8.0.0 yields the correct result.

0 Kudos
4 Replies
Steve_Lionel
Honored Contributor III
295 Views

You seem to be referring to the draft of Fortran 2018. The corresponding section in the current standard Fortran 2008  is 5.3.8.4. 

I assume that you know that for assumed-shape dummy arguments (in your example, those that are not ALLOCATABLE or POINTER), the lower bound of the dummy argument is always 1 (unless specified otherwise in the dummy argument declaration). The compiler may be doing something wrong related to this. At first I thought you were violating the standard regarding aliasing, but I now think that's not the case.

Please report the error via https://supporttickets.intel.com/?lang=en-US as otherwise it may be overlooked.

0 Kudos
Rodrigo_R_
Beginner
295 Views

You seem to be referring to the draft of Fortran 2018 (...)

Exactly. Thank you for the standard reference.

I assume that you know that for assumed-shape dummy arguments (...), the lower bound of the dummy argument is always 1

Yes, I am aware of that. I am interested specifically in the case of deferred-shape arrays, that do pass bounds info to the procedures.

At first I thought you were violating the standard regarding aliasing (...)

I also tried to find any violation but I couldn't.

Please report the error (...) as otherwise it may be overlooked.

I just did this. Thank you for the interest.

0 Kudos
CTOptimizer
Beginner
295 Views

Good discussion.

As I also optimize C code and know what "aliasing" is (and its relation to the C99 "restrict" keyword), I decided to pull of the Fortran 2008 standard.  Steve brought up the "[Fortran] standard [rules] regarding aliasing", so I opened up F2008 and searched for "alias" or "aliasing" and found no references.  Given "alias(ing)" seems to be the primary term in our collective vernacular, it would be helpful if the term appeared in the relevant sections of the standard text.

For fun, I did some further digging and found one of Steve's older blog posts on the topic - it may be helpful to those looking for more info:

https://software.intel.com/en-us/blogs/2009/07/10/doctor-fortran-in-ive-come-here-for-an-argument-side-2

Mark

0 Kudos
Steve_Lionel
Honored Contributor III
295 Views

Yes, that old post of mine has the relevant info. As you note, the standard doesn't talk about "aliasing" as it would then have to define that term - rather it explains what you can and cannot do in a standard-conforming program. It boils down to "is the compiler aware of everything in the current procedure that can change the definition or definition status of a variable?" If not, then you're not allowed to invisibly make such changes. There are ways to tell the compiler that aliasing is a possibility, including the TARGET attribute. There's also VOLATILE in F2008 which covers changes that can occur from outside the current procedure. ASYNCHRONOUS is a milder form of this.

0 Kudos
Reply