c++ - Is this GCC optimization incorrect? -



c++ - Is this GCC optimization incorrect? -

i have functor takes value, casts double, takes log , casts value original type. purpose of question, original , output type float. here original c++ code:

return static_cast< toutput >( std::log( static_cast< double >( ) ) )

when compile in debug mode, goes expected , gcc calls underlying log function:

51:/myfile.h **** homecoming static_cast< toutput >( std::log( static_cast< double >( ) ) ); 219133 .loc 112 51 0 219134 0010 488b45f0 movq -16(%rbp), %rax # a, tmp64 219135 0014 f30f1000 movss (%rax), %xmm0 # *a_1(d), d.237346 219136 0018 0f14c0 unpcklps %xmm0, %xmm0 # d.237346, d.237346 219137 001b 0f5ac0 cvtps2pd %xmm0, %xmm0 # d.237346, d.237347 219138 001e e8000000 phone call log # 219138 00 219139 0023 660f14c0 unpcklpd %xmm0, %xmm0 # d.237347 219140 0027 660f5ac0 cvtpd2ps %xmm0, %xmm0 # d.237347, d.237346 219141 002b f30f1145 movss %xmm0, -20(%rbp) # d.237346, %sfp 219141 ec 219142 0030 8b45ec movl -20(%rbp), %eax # %sfp, <retval>

however, when turn optimizations on (-o2 -ggdb3 -dndebug), calls logf (???) function:

51:/myfile.h **** homecoming static_cast< toutput >( std::log( static_cast< double >( ) ) ); 145171 .loc 64 51 0 145172 01a0 f30f1004 movss (%rdx,%rax,4), %xmm0 # mem[(const float &)_84], mem[(const float &)_84] 145172 82 145173 01a5 e8000000 phone call logf #

it gives different output. normal? doing wrong? seems me gcc taking liberal interpretation of code, wouldn't expect in absence of -ffast-math option.

it borderline optimization transform conversion float of application of double-precision log float application of single-precision log, can argued acceptable.

assuming logf correctly rounded , double-precision log correctly rounded or @ to the lowest degree faithfully-rounded, 2 computations differ. can differ (for rare inputs) because of double-rounding (in “double” means “twice” , not refer type). double-rounding statistically less important there additional digits in intermediate type's significand compared final type's significand (and statistical argument rubbish mathematical point of view, “works in practice” functions have not been designed counter-examples). didactic reasons, people (or wikipedia) explain 1 or 2 digits of precision, when have 53 - 24 = 29 binary digits, can expected happen 1 time in 229.

i surprised optimization, , disturbed if had written code myself exhaustive search of double-rounding problems log, considering c++ standard not mandate level of accuracy std::log, possible consider “not bug”.

if, instead of log, had been talking of 1 of basic operations (such *), transformation have been incorrect, compiler claims provide ieee 754 semantics, when introduces visible changes. basic operation, accuracy specified indirectly ieee 754, , specification leaves no room variations.

it happens basic operations, there cannot visible alter when floatop(flx,fly) replaces (float)doubleop((double)flx, (double)fly) (this thesis demonstrates in chapter 6) , there can visible differences when types double , long double. exact bug recently fixed in clang stephen canon.

c++ linux gcc assembly floating-point

Comments

Popular posts from this blog

Delphi change the assembly code of a running process -

json - Hibernate and Jackson (java.lang.IllegalStateException: Cannot call sendError() after the response has been committed) -

C++ 11 "class" keyword -