* double address to long word pointer cast -O2 optimization bug
@ 2010-03-01 18:22 Kevin Yohe
2010-03-01 18:27 ` Brian Budge
0 siblings, 1 reply; 2+ messages in thread
From: Kevin Yohe @ 2010-03-01 18:22 UTC (permalink / raw)
To: gcc-help
I have recently come across what appears to be an optimization bug. I am
using gcc version 4.3.1 configured for a powerpc 750. I am using -O2
optimization. The bug is related to passing a double defined as a local
variable into a trace function which takes 8 32-bit unsigned integers of
auxiliary data. The trace function is using the c++ default arguments (not
varargs). When I want to trace my local double I am performing the
following cast conversions to map the upper and lower data words into 32-bit
aux data parameters.
double myDouble;
...
Trace((unsigned int)(*(long long int*)&myDouble) >> 32),
// aux data word 1 myDouble
upper word
(unsigned int)(*(long long int*)&myDouble) & 0xffffffff) );
// aux data word 2 myDouble
lower word
The trace method logs the data to a buffer in memory. When I dump the data
logged in my buffer, the values are clearly not 64-bit floating point. They
appear to be 32-bit memory addresses that were residual on the stack. This
only seemed to be a problem with some of the double variables that I passed
into the trace function. For example, in the case below,
double myDouble1 = func1();
...
double myDouble2 = func2();
Trace(((unsigned int)(*(long long int*)&myDouble1) >> 32),
(unsigned int)(*(long long int*)&myDouble1) & 0xffffffff),
(((unsigned int)(*(long long int*)&myDouble2) >> 32),
(unsigned int)(*(long long int*)&myDouble2) & 0xffffffff));
The "myDouble1" value looks correct but the "myDouble2" value is incorrect.
I was able to fix the problem 3 different ways. The first was simply to
remove optimization (i.e -O0). The second was to make the bad double
parameters global as in the example below.
double myDouble1 = func1();
...
static double myDouble2 = func2();
Trace(((unsigned int)(*(long long int*)&myDouble1) >> 32),
(unsigned int)(*(long long int*)&myDouble1) & 0xffffffff),
(((unsigned int)(*(long long int*)&myDouble2) >> 32),
(unsigned int)(*(long long int*)&myDouble2) & 0xffffffff));
Another thing I tried was to insert a nop instruction just before the call
to Trace as in the example below.
double myDouble1 = func1();
...
double myDouble2 = func2();
asm("nop");
Trace(((unsigned int)(*(long long int*)&myDouble1) >> 32),
(unsigned int)(*(long long int*)&myDouble1) & 0xffffffff),
(((unsigned int)(*(long long int*)&myDouble2) >> 32),
(unsigned int)(*(long long int*)&myDouble2) & 0xffffffff));
I am not sure why the last example worked. The only thing I can think of is
that the "asm" call prevents the method from being optimized. Let me know
if this is a known issue or if you need more details.
Thanks,
Kevin
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: double address to long word pointer cast -O2 optimization bug
2010-03-01 18:22 double address to long word pointer cast -O2 optimization bug Kevin Yohe
@ 2010-03-01 18:27 ` Brian Budge
0 siblings, 0 replies; 2+ messages in thread
From: Brian Budge @ 2010-03-01 18:27 UTC (permalink / raw)
To: Kevin Yohe; +Cc: gcc-help
Hi Kevin -
This is an example of breaking the strict aliasing rules of C++. You
should use unions to perform these kind of manipulations.
Brian
On Mon, Mar 1, 2010 at 10:22 AM, Kevin Yohe <kevin@ssc-nh.com> wrote:
> I have recently come across what appears to be an optimization bug. I am
> using gcc version 4.3.1 configured for a powerpc 750. I am using -O2
> optimization. The bug is related to passing a double defined as a local
> variable into a trace function which takes 8 32-bit unsigned integers of
> auxiliary data. The trace function is using the c++ default arguments (not
> varargs). When I want to trace my local double I am performing the
> following cast conversions to map the upper and lower data words into 32-bit
> aux data parameters.
>
> double myDouble;
> ...
> Trace((unsigned int)(*(long long int*)&myDouble) >> 32),
> // aux data word 1 myDouble
> upper word
> (unsigned int)(*(long long int*)&myDouble) & 0xffffffff) );
> // aux data word 2 myDouble
> lower word
>
> The trace method logs the data to a buffer in memory. When I dump the data
> logged in my buffer, the values are clearly not 64-bit floating point. They
> appear to be 32-bit memory addresses that were residual on the stack. This
> only seemed to be a problem with some of the double variables that I passed
> into the trace function. For example, in the case below,
>
> double myDouble1 = func1();
> ...
> double myDouble2 = func2();
>
> Trace(((unsigned int)(*(long long int*)&myDouble1) >> 32),
> (unsigned int)(*(long long int*)&myDouble1) & 0xffffffff),
> (((unsigned int)(*(long long int*)&myDouble2) >> 32),
> (unsigned int)(*(long long int*)&myDouble2) & 0xffffffff));
>
>
> The "myDouble1" value looks correct but the "myDouble2" value is incorrect.
> I was able to fix the problem 3 different ways. The first was simply to
> remove optimization (i.e -O0). The second was to make the bad double
> parameters global as in the example below.
>
> double myDouble1 = func1();
> ...
> static double myDouble2 = func2();
>
> Trace(((unsigned int)(*(long long int*)&myDouble1) >> 32),
> (unsigned int)(*(long long int*)&myDouble1) & 0xffffffff),
> (((unsigned int)(*(long long int*)&myDouble2) >> 32),
> (unsigned int)(*(long long int*)&myDouble2) & 0xffffffff));
>
> Another thing I tried was to insert a nop instruction just before the call
> to Trace as in the example below.
>
>
> double myDouble1 = func1();
> ...
> double myDouble2 = func2();
>
> asm("nop");
>
> Trace(((unsigned int)(*(long long int*)&myDouble1) >> 32),
> (unsigned int)(*(long long int*)&myDouble1) & 0xffffffff),
> (((unsigned int)(*(long long int*)&myDouble2) >> 32),
> (unsigned int)(*(long long int*)&myDouble2) & 0xffffffff));
>
> I am not sure why the last example worked. The only thing I can think of is
> that the "asm" call prevents the method from being optimized. Let me know
> if this is a known issue or if you need more details.
>
> Thanks,
>
> Kevin
>
>
>
>
>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2010-03-01 18:27 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-03-01 18:22 double address to long word pointer cast -O2 optimization bug Kevin Yohe
2010-03-01 18:27 ` Brian Budge
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).