Bug 44098 - -O3 causes quickInvSqrt() to return -inf.
Summary: -O3 causes quickInvSqrt() to return -inf.
Status: RESOLVED DUPLICATE of bug 21920
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 4.5.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
Depends on:
Reported: 2010-05-12 14:45 UTC by Hans-Kristian Arntzen
Modified: 2010-05-12 15:29 UTC (History)
37 users (show)

See Also:
Host: x86_64-unknown-linux-gnu
Target: x86_64-unknown-linux-gnu
Build: x86_64-unknown-linux-gnu
Known to work:
Known to fail:
Last reconfirmed:

The test case. (229 bytes, text/plain)
2010-05-12 14:56 UTC, Hans-Kristian Arntzen
ASM output with -O2 (539 bytes, text/plain)
2010-05-12 15:00 UTC, Hans-Kristian Arntzen
ASM output with -O3 (693 bytes, text/plain)
2010-05-12 15:01 UTC, Hans-Kristian Arntzen

Note You need to log in before you can comment on or make changes to this bug.
Description Hans-Kristian Arntzen 2010-05-12 14:45:49 UTC
I have tested the famous quickInvSqrt() algorithm uses in Quake, and it does not compile correctly when compiling with -O3. It does however work completely fine when compiling for -O0, -O1 and -O2.

The function goes like so:

float quickInvSqrt(float x)
   float xhalf = 0.5f*x;
   int i = *(int*)&x;
   i = 0x5f3759df - (i>>1);
   x = *(float*)&i;
   x = x*(1.5f - xhalf*x*x);
   return x;
Comment 1 Hans-Kristian Arntzen 2010-05-12 14:56:07 UTC
Created attachment 20645 [details]
The test case.

Actually, it's quite absurd, but trying to print out from 1 to 10 rather than 1 to 100 seemed to work, even with -O3.
Comment 2 Hans-Kristian Arntzen 2010-05-12 15:00:36 UTC
Created attachment 20646 [details]
ASM output with -O2

Assembly output using gcc -S -O2 invsqrt.c
Comment 3 Hans-Kristian Arntzen 2010-05-12 15:01:09 UTC
Created attachment 20647 [details]
ASM output with -O3

Assembly output with -O3.
Comment 4 Paolo Carlini 2010-05-12 15:04:41 UTC
First blush, I can see some pretty serious aliasing violations... try -Wall
Comment 5 Paolo Carlini 2010-05-12 15:07:12 UTC
and then try -O3 -fno-strict-aliasing
Comment 6 Hans-Kristian Arntzen 2010-05-12 15:23:36 UTC
That worked (-O3 -fno-strict-aliasing). But why does this work on -O2 and not -O3?
Comment 7 Paolo Carlini 2010-05-12 15:25:02 UTC
You are violating the aliasing rules, anything can happen, at any optimization level...
Comment 8 Paolo Carlini 2010-05-12 15:29:18 UTC

*** This bug has been marked as a duplicate of 21920 ***