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

Compiler Bug: unexpected behavior of ifx with -O2 flag on CONQUEST

Jingbo_SHAN
Beginner
652 Views

I am trying to compile the Conquest project with Intel Fortran Compiler (ifx) 2024.0.2 and Intel oneApi MPI (mpiifx), but encounter an unexpected behavior.

When I add the -O2 flag (same for -O3), the program failed during initialization. I also tried other compilers (like ifort, gfortan, flang). They all work fine.

Here's a piece of code modified from the original Hilbert3D.f90 that reproduces the problem: (also in the attached tar.gz file)

! Hilbert3D.f90
module Hilbert3D
   implicit none
   public :: Hilbert3D_IntToCoords
contains
   subroutine Hilbert3D_IntToCoords(N, a, b)
      integer, intent(in) :: N
      integer, dimension(:), intent(in) :: a
      integer, dimension(:), intent(out) :: b
      integer :: c_start, c_end, start, end, ii, c_ind
      start = 0
      end = 1
      do ii = 1, N
         c_ind = a(ii)
         ! if(ii.eq.2)write(*,*)"GET",start,end,c_ind
         b(ii) = GrayEncodeTravel(start, end, c_ind)
         call ChildStartEnd(start, end, c_ind, c_start, c_end)
         start = c_start
         end = c_end
      end do
   end subroutine Hilbert3D_IntToCoords

   subroutine ChildStartEnd(parentStart, parentEnd, parentInd, childStart, childEnd)
      integer, intent(in) :: parentStart, parentEnd, parentInd
      integer, intent(out) :: childStart, childEnd
      integer :: start_ind, end_ind
      ! next lower even number or 0
      start_ind = max(0, iand((parentInd - 1), not(1)))
      ! next higher odd number or maximum
      end_ind = min(7, ior((parentInd + 1), 1))
      childStart = GrayEncodeTravel(parentStart, parentEnd, start_ind)
      childEnd = GrayEncodeTravel(parentStart, parentEnd, end_ind)
   end subroutine ChildStartEnd
 
   function GrayEncodeTravel(start, end, ind)
      integer, intent(in) :: start, end, ind
      integer :: GrayEncodeTravel, travel, gn, rotated_gn
      travel = ieor(start, end)
      gn = ieor(ind, ishft(ind,-1)) * ishft(travel, 1)
      rotated_gn = iand(ior(gn, ishft(gn, -3)), 7)
      GrayEncodeTravel = ieor(rotated_gn, start)
   end function GrayEncodeTravel
end module Hilbert3D
! main.f90
program main
   use Hilbert3D
   implicit none
   integer, parameter :: N = 2
   integer, dimension(2):: a, b

   a = [0, 0]
   call Hilbert3D_IntToCoords(N, a, b)
   write(*,*) 'b:',b
end program  main

This program should output `b: 0 0`,but it gives `b: 0 2` when compiled with ifx -O2.

I examine the assembly code and find the main problem ifx has done unexpectedly is that in subroutine Hilbert3D_IntToCoords, the call to ChildStartEnd is inlined and `max(0, )` was optimized out. So when parentInd (i.e. c_ind) = 0, start_ind is unexpectedly assigned a negative value.

Labels (1)
1 Solution
Ron_Green
Moderator
619 Views

I confirmed the bug you see in 2024.0.x.  
I tested with an early build of 2024.1.0, due out in April.  It gives the correct result

ifx -O2 -xhost -c hilb.f90 ; ifx -O2 -xhost prog.f90 hilb.o

rwgreen@orcsle153:~/quad/friday$ ./a.out

b:           0           0

 

View solution in original post

1 Reply
Ron_Green
Moderator
620 Views

I confirmed the bug you see in 2024.0.x.  
I tested with an early build of 2024.1.0, due out in April.  It gives the correct result

ifx -O2 -xhost -c hilb.f90 ; ifx -O2 -xhost prog.f90 hilb.o

rwgreen@orcsle153:~/quad/friday$ ./a.out

b:           0           0

 

Reply