https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96807
Bug ID: 96807
Summary: Division by zero produces zero with gcc -O2
Product: gcc
Version: unknown
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: fazedo at gmail dot com
Target Milestone: ---
Hello,
The following code produces 1/0 = 0 with gcc -O2:
#include
#include
int main(int argn, char** argc){
unsigned base = argn>1 ? atoi(argc[1]) : 0;
if (base!=1) printf("%d\n", 1/base); // produces 0 for base=0 with -O2
return 0;
}
The same behavior occurs with clang but not with icc. If 1/base is not guarded
by if or if base is a signed integer, it produces a floating point exception
even with -O2.
As a result, Fortran's intrinsic power operator (**) applied to integers is
producing wrong results when the base is zero and the exponent is negative.
Instead of giving division by zero or infinity, it gives zero.
The code given below shows that base**(-1) yields 0 when base=0.
It is my understanding that gfortran calls functions pow_iX_iY from
libgfortran/generated. These functions are correctly coded but they produce
0**n=0 for n<0 due to optimizations when libgfortran is compiled.
program power
implicit none
integer (kind = 4) :: base = 0
print *, base**(-1) ! produces 0
print *, real(base, 4)**(-1) ! produces infinity
end program
By the way, is there any advantage to using the pow_XX_YY.c functions on
libgfortran/generated instead of __powiXX2 (and its integer version) defined
for __builtin_powi on libgcc2.c?
It seems to me that libgcc2's version reads much better and should be a little
faster because it saves the first multiplication (by pow=1).
The only difference in behaviour I see is that when the exponent is negative
and the base if a floating point type, libgcc2 calculates 1/(x**(-n)) while
libgfortran calculates (1/x)**(-n). The first version being more accurate.
I am using gcc 9.3.0 on x86-64.
Best regards,
Fabio Azevedo