C++ compiler optimization: /fp:fast fails to honour cast from single to double in x64 - by PhilAtkin

Status : 

  Fixed<br /><br />
		This item has been fixed in the current or upcoming version of this product.<br /><br />
		A more detailed explanation for the resolution of this particular item may have been provided in the comments section.

Sign in
to vote
ID 719105 Comments
Status Closed Workarounds
Type Bug Repros 0
Opened 1/18/2012 3:52:08 AM
Access Restriction Public


double s;
float *p;


s += (double)(*p) * (double)(*p);

Under some circumstances the multiplication compiles to a _single_ precision operator, MULSS.  This can lead to overflows, the avoidance of which is the objective of the cast.  From my understanding of /fp:fast, this does not fall within the imprecision latitude that's intended.

Assignment to a temporary double solves the problem in this instance.
Sign in to post a comment.
Posted by PhilAtkin on 1/25/2012 at 3:41 AM
I wanted to say that this is the most thoughtful, constructive response I've ever had from Microsoft on any subject - and that's not just because you agreed with me! Thanks,

Phil Atkin
Pixel Analytics
Posted by Microsoft on 1/24/2012 at 1:52 PM
Good news. There is consensus that the generated code violates the intent of /fp:fast. I've implemented a fix to the optimizer for inclusion in the next release of Visual Studio. This issue will be resolved as fixed once this is finalized.

Thanks again for reporting this issue and helping to make VC++ even better. As always please respond with any additional questions or concerns.

ian Bearman
VC++ Code Generation and Optimization Team
Posted by Microsoft on 1/23/2012 at 1:35 PM
First, thanks for reporting this issue. What is happening (as you’ve pointed out) is that the compiler is performing the multiplication at single-precision instead of at double-precision as specified in the source code. This transformation only occurs under /fp:fast as the complier believes that this results in an acceptable loss of precision.

Thus we come to the crux of the problem: is doing the multiply at a lower precision appropriate under /fp:fast? The documentation is fuzzy at best. As Mike Danes helpfully pointed out it does say that typecasts may not occur and it also says that "in some instances the compiler may choose to perform intermediate expressions at a lower precision than specified in the source code".

Regardless of what the documentation says, the fact that we get such an incorrect answer, that is clearly not a rounding error, makes this appears to be outside of at least the spirit of the specification. I'm in the processes of talking this over with a couple of other experts in this area. I'll let you know shortly what we (MSFT) decide regarding this issue.

In the meantime it sounds like you have some acceptable workarounds. I’m keeping an eye on this thread, so if you have any other questions please feel free to post them while I work on this.

ian Bearman
VC++ Code Generation and Optimization Team
Posted by Mike Danes on 1/19/2012 at 2:24 AM
According to the compiler documentation it appears that this is how it's supposed to work:


"Rounding at assignments, typecasts and function-calls may not always occur"
Posted by MS-Moderator10 [Feedback Moderator] on 1/18/2012 at 6:35 PM
Thank you for submitting feedback on Visual Studio 2010 and .NET Framework. Your issue has been routed to the appropriate VS development team for investigation. We will contact you if we require any additional information.
Posted by MS-Moderator01 on 1/18/2012 at 6:27 PM
Thank you for your feedback, we are currently reviewing the issue you have submitted. If this issue is urgent, please contact support directly(http://support.microsoft.com)