#include <math.h> #include <complex.h> int main() { float complex c,d; foo(&c); d=1.0/c; return creal(d)+cimag(d)<0; } $ gcc -S -O -fdump-tree-optimized recip.c $ tail -25 recip.c.t66.optimized <bb 0>: foo (&c); SR.24 = (double) REALPART_EXPR <c>; SR.23 = (double) IMAGPART_EXPR <c>; if (ABS_EXPR <SR.24> < ABS_EXPR <SR.23>) goto <L1>; else goto <L2>; <L1>:; D.2387 = SR.24 / SR.23; D.2389 = SR.23 + SR.24 * D.2387; SR.25 = (D.2387 + 0.0) / D.2389; SR.26 = (D.2387 * 0.0 - 1.0e+0) / D.2389; goto <bb 3>; <L2>:; D.2395 = SR.23 / SR.24; D.2397 = SR.24 + SR.23 * D.2395; SR.25 = (D.2395 * 0.0 + 1.0e+0) / D.2397; SR.26 = (0.0 - D.2395) / D.2397; <bb 3>: return (double) (float) SR.25 + (double) (float) SR.26 < 0.0; } $ gcc -v Using built-in specs. Target: i686-pc-linux-gnu Configured with: ../gcc-4.1/configure --prefix=/home/ig25 --enable-languages=c,f95 Thread model: posix gcc version 4.1.0 20050311 (experimental) I can't see a reason why the +0 and *0 operations should be necessary. Thomas
D.2395 * 0.0 Can trap if D.2395 is a non quiet NAN. Likewise for "D.2387 + 0.0" Though in this case it does not matter because we are going to trap later on.
(In reply to comment #1) > D.2395 * 0.0 > Can trap if D.2395 is a non quiet NAN. D.2395 gets its value from D.2395 = SR.23 / SR.24; two lines earlier. Is there anything that would generate a signaling NaN for this case and not trap immediately? > Likewise for "D.2387 + 0.0" Same argument. > Though in this case it does not matter because we are going to trap later on. .. which is true, and which is why I think this is missed-optimization.
I cannot remember the rules but -0.0 * 0.0 could be -0.0 (and not 0.0), someone needs to help me here.
(In reply to comment #3) > I cannot remember the rules but -0.0 * 0.0 could be -0.0 (and not 0.0), someone needs to help me > here. I'm trying to see what input could apply to, but I can't think of one. What were you referring to?
This is still active with gcc -cx-complex-rules: <bb 2>: foo (&c); D.2256 = (double) REALPART_EXPR <c>; D.2258 = (double) IMAGPART_EXPR <c>; if (ABS_EXPR <D.2256> < ABS_EXPR <D.2258> != 0) goto <bb 3>; else goto <bb 4>; <bb 3>: Invalid sum of outgoing probabilities 0.0% Invalid sum of incoming frequencies 10000, should be 0 D.2292 = D.2256 / D.2258; D.2294 = D.2258 + D.2256 * D.2292; CR.13 = D.2292 + 0.0 / D.2294; CI.14 = D.2292 * 0.0 - 1.0e+0 / D.2294; goto <bb 5>; <bb 4>: Invalid sum of outgoing probabilities 0.0% D.2300 = D.2258 / D.2256; D.2302 = D.2256 + D.2258 * D.2300; CR.13 = D.2300 * 0.0 + 1.0e+0 / D.2302; CI.14 = 0.0 - D.2300 / D.2302; Maybe time to confirm this bug after more than three years :-)
Still an issue: #include <math.h> #include <complex.h> int main() { float complex c,d; foo(&c); d=1.0f/c; return creal(d)+cimag(d)<0; } Using -fcx-fortran-rules yields (from the optimized dump) _13 = REALPART_EXPR <c>; _14 = IMAGPART_EXPR <c>; _15 = ABS_EXPR <_13>; _16 = ABS_EXPR <_14>; if (_15 < _16) goto <bb 3>; else goto <bb 4>; <bb 3>: _18 = _13 / _14; _19 = _13 * _18; _20 = _14 + _19; _21 = _18 + 0.0; _22 = _18 * 0.0; _23 = _22 - 1.0e+0; _24 = _21 / _20; _25 = _23 / _20; goto <bb 5>; <bb 4>: _26 = _14 / _13; _27 = _14 * _26; _28 = _13 + _27; _29 = _26 * 0.0; _30 = _29 + 1.0e+0; _31 = 0.0 - _26; _32 = _30 / _28; _33 = _31 / _28; I do not think it is possible to create a NaN/Inf situation here where just ignoring the imaginary zero is wrong.