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

Crash/zero divide in loop although safeguarded

uha
Novice
1,264 Views

The following code gives "floating divide by zero" with O2:

module MDivZero
  implicit none
  public
  contains

    subroutine test(n, arr, arrOut)
    integer ::i, n
    real(4) :: arr(:), arrOut(:)
    arr = 1.0
    do i = 20, n,20
      arr(i) = 0
    enddo

    arrOut = 1.0
    do i = 1, n
      if(arr(i).gt.1) then
        arrOut(i) = arrOut(i) / arr(i)! Crashes in production code, but works here!
      else
        arrOut(i) = 0.0
      endif
    enddo

    arrOut = 88.0
    where (arr.gt.1)
      arrOut = arrOut / arr ! Crash!
    elsewhere
      arrOut = 0.0
    endwhere
  end subroutine test
endmodule MDivZero

program Console1
  use MDivZero
  implicit none
  integer :: n = 1000
  real(4), allocatable :: arr(:), arrOut(:)
  allocate(arr(n), arrOut(n))

  call test(n, arr, arrOut)
end program Console1

 

This does not happen in debug mode/without optimizations. It also does not happen when the arrays are local to the subroutine instead of being passed in.

 

In my production code this does not only happen in where...elsewhere but also in ordinary do-loops - this I could not reproduce in this small sample.

0 Kudos
9 Replies
Steve_Lionel
Honored Contributor III
1,197 Views

Please provide a complete reproducer.

0 Kudos
uha
Novice
1,192 Views

Hi Steve,

the given code is a complete program that crashes, can you specify what´s missing?

thanks!

0 Kudos
Steve_Lionel
Honored Contributor III
1,069 Views

Sorry, I overlooked the main program.

It does not crash for me. I do note that the way you wrote this, arrOut elements will never get set to anything but zero, since all elements of arr are either zero or 1, so none of the assignments will happen. I modified it to set some elements to 1.5 and got reasonable results.

uha
Novice
1,022 Views

Your "works for me" has been very helpful! I compared my project settings to the default ones and it turns out this only happens when using /fpe:0 (and optimization /O2). Using that it crashes even when initializing arr = 1.0 and no zeros at all and a condition where no division should be executed:

arr = 1.0
arrOut = 1.0
where (arr.gt.10.0)
  arrOut = arrOut / arr
elsewhere
  arrOut = 0.0
endwhere

Only if you change the operator to anything but '/' it works.  Btw. the error does not say "zero division" but "floating invalid".

Steve_Lionel
Honored Contributor III
962 Views

Interesting. I found that I could reduce n to 40 and still get the error, below that not. What I can determine is that the code has vectorized and a vector divide is being done in the where loop with xmm15 loaded with some NaNs. I haven't investigated further, but there is definitely a bug here. I would not expect vector instructions in the where.

0 Kudos
Ron_Green
Moderator
960 Views

I had a chance to dig in a little more, ignore my previous reply, which I deleted.  

 

Check your options to see if you have /fast  or the combination of /Qipo /Qxhost

There seems to be an interplay with these 2.  Steve may be right, there may be a vectorizer bug here with the use of IPO and processor targeting.  Without either there is not fp error. 

 

I will keep digging deeper to see if there is a bug.  Sure is looking like it.

 

ron

 

 

 

 

0 Kudos
Steve_Lionel
Honored Contributor III
928 Views

I didn't use either /Qipo or /Qxhost and got the error. All I needed to add to the default /O2 was /fpe0.

0 Kudos
Ron_Green
Moderator
918 Views

you beat me to it - seeing the same here also.  I was chasing a red herring.  I'll use opt-bisect-limit to find the phase and write it up.  Appears to be a regression in the vectorizer.

 

 

Ron_Green
Moderator
707 Views

It appears I did not post the bug ID.  It is CMPLRLLVM-63857

We hope to have a fix for the 2025.1 release, it is being worked on this week. 

Reply