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

Crash/zero divide in loop although safeguarded

uha
Novice
528 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
8 Replies
Steve_Lionel
Honored Contributor III
461 Views

Please provide a complete reproducer.

0 Kudos
uha
Novice
456 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
333 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
286 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".

0 Kudos
Steve_Lionel
Honored Contributor III
226 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
224 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
192 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
182 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.

 

 

Reply