------- Comment #4 from dominiq at lps dot ens dot fr 2007-10-18 15:23 ------- > while we expand a constant integral power to an optimal (as of the count of > multiplications / additions) series of multiplications and additions.
It seems the difference is coming from something else. I'll bet that with -O3 the powers are computed at compile time with some extra precision. At least it is what I conclude from the following code: integer :: ia(16) = (/ 1, 1, 2, 2, 3, 3, 4, 4, 6, 5, 6, 6, 10, 7, 9, 8 /) real(8) :: a(16), b(16), c(16), d(16) real(16) :: e(16) real(8), parameter :: r=4.51556282882533D0 a(1) = r a(2) = a(1)*a(1) a(3:4) = a(2)*a(1:2) a(5:8) = a(4)*a(1:4) a(9:16) = a(8)*a(1:8) b(1) = r do i = 2, 16 b(i) = b(ia(i))*b(i-ia(i)) end do e(1) = r e(2) = e(1)*e(1) e(3:4) = e(2)*e(1:2) e(5:8) = e(4)*e(1:4) e(9:16) = e(8)*e(1:8) d = real(e,8) do i=1, 16 c(i) = r**i end do do i=1, 16 print *, a(i)/d(i)-1.0d0, b(i)/d(i)-1.0d0, c(i)/d(i)-1.0d0 end do print * print *, sum(abs(a/d-1.0d0)), sum(abs(b/d-1.0d0)), sum(abs(c/d-1.0d0)), epsilon(r) end a stores the powers computed from the usual shift, b those computed from the "optimal" tree (from gcc/builtins.c, c those computed from the power, and d the values rounded from values with higher precision. At -O2 the output is: 0.0000000000000000 0.0000000000000000 0.0000000000000000 0.0000000000000000 0.0000000000000000 0.0000000000000000 0.0000000000000000 0.0000000000000000 0.0000000000000000 2.22044604925031308E-016 2.22044604925031308E-016 2.22044604925031308E-016 2.22044604925031308E-016 2.22044604925031308E-016 2.22044604925031308E-016 2.22044604925031308E-016 0.0000000000000000 2.22044604925031308E-016 2.22044604925031308E-016 2.22044604925031308E-016 2.22044604925031308E-016 4.44089209850062616E-016 4.44089209850062616E-016 4.44089209850062616E-016 2.22044604925031308E-016 0.0000000000000000 2.22044604925031308E-016 4.44089209850062616E-016 2.22044604925031308E-016 4.44089209850062616E-016 4.44089209850062616E-016 2.22044604925031308E-016 4.44089209850062616E-016 4.44089209850062616E-016 0.0000000000000000 4.44089209850062616E-016 4.44089209850062616E-016 4.44089209850062616E-016 4.44089209850062616E-016 4.44089209850062616E-016 2.22044604925031308E-016 4.44089209850062616E-016 6.66133814775093924E-016 0.0000000000000000 6.66133814775093924E-016 6.66133814775093924E-016 6.66133814775093924E-016 6.66133814775093924E-016 5.10702591327572009E-015 2.88657986402540701E-015 5.10702591327572009E-015 2.22044604925031308E-016 a and c are equal, while at -O3 the output is 0.0000000000000000 0.0000000000000000 0.0000000000000000 0.0000000000000000 0.0000000000000000 0.0000000000000000 0.0000000000000000 0.0000000000000000 0.0000000000000000 2.22044604925031308E-016 2.22044604925031308E-016 0.0000000000000000 2.22044604925031308E-016 2.22044604925031308E-016 0.0000000000000000 2.22044604925031308E-016 0.0000000000000000 0.0000000000000000 2.22044604925031308E-016 2.22044604925031308E-016 0.0000000000000000 4.44089209850062616E-016 4.44089209850062616E-016 0.0000000000000000 2.22044604925031308E-016 0.0000000000000000 0.0000000000000000 4.44089209850062616E-016 2.22044604925031308E-016 0.0000000000000000 4.44089209850062616E-016 2.22044604925031308E-016 0.0000000000000000 4.44089209850062616E-016 0.0000000000000000 0.0000000000000000 4.44089209850062616E-016 4.44089209850062616E-016 0.0000000000000000 4.44089209850062616E-016 2.22044604925031308E-016 0.0000000000000000 6.66133814775093924E-016 0.0000000000000000 0.0000000000000000 6.66133814775093924E-016 6.66133814775093924E-016 0.0000000000000000 5.10702591327572009E-015 2.88657986402540701E-015 0.0000000000000000 2.22044604925031308E-016 c and d are equal. If the difference were coming only from the "optimal" tree, c should be equal to b. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33780