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 <stdio.h> #include <stdlib.h> 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