You could have separate memory blocks for integers and reals. That would be legal, but it does increase the amount of book-keeping.
I think that’s only one impediment. Compilers generally are able to multi-version for array contiguity, at least for simple cases, but the choice when to multi-version depends on flags and internal heuristics. The more serious impediment is the aliasing of pointer targets, although this should be easier to resolve in Fortran, as the target
attribute is required for pointer association. I think one more factor is the scope in which the pointer is used. In a local scope it may be simple to prove that a pointer array does not alias. But it is easy to create a context where proving it may not be possible:
module a_mod
real, pointer :: a(:)
end module
module b_mod
real, pointer :: b(:)
end module
program aliasing
use a_mod
use b_mod
real, allocatable :: c(:)
external :: initialization
allocate(c(1000))
call initialization(1000) ! maybe a => b, or b => a, no way of knowing...
c = a + b
print *, maxval(c)
end program
One way to resolve such issues of sub-optimal auto-vectorization is to exploit the basic rule of dummy argument analysing and perform the work in a subroutine. This has been discussed here before: Fortran pointers, and aliasing - #9 by lkedward. So in the snippet above, we could pack the sum into a subprogram:
call initialization(1000) ! maybe a => b, or b => a, no way of knowing...
call do_sum(a,b,c) ! we guarantee that a and b aren't associated
print *, maxval(c)
contains
subroutine do_sum(a,b,c)
real, intent(in) :: a(:), b(:) ! adding contiguous here can help
real, intent(out) :: c(:)
c = a + b
end subroutine
end program