Bug 20432 - complex reciprocal has too many operations
Summary: complex reciprocal has too many operations
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.1.0
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: missed-optimization
Depends on:
Blocks:
 
Reported: 2005-03-11 21:17 UTC by Thomas Koenig
Modified: 2008-12-11 21:22 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2008-12-11 21:22:46


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Koenig 2005-03-11 21:17:24 UTC
#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
Comment 1 Andrew Pinski 2005-03-11 21:25:06 UTC
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.
Comment 2 Thomas Koenig 2005-03-11 21:36:39 UTC
(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.
Comment 3 Andrew Pinski 2005-03-12 17:35:06 UTC
I cannot remember the rules but -0.0 * 0.0 could be -0.0 (and not 0.0), someone needs to help me 
here.
Comment 4 Thomas Koenig 2005-03-17 13:41:17 UTC
(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?
Comment 5 Thomas Koenig 2008-12-11 21:22:45 UTC
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 :-)