* Possible optimization bug in GNAT GPL 2009 ?
@ 2009-10-17 20:34 Damien Carbonne
2009-10-18 3:31 ` Gautier write-only
0 siblings, 1 reply; 3+ messages in thread
From: Damien Carbonne @ 2009-10-17 20:34 UTC (permalink / raw)
Hi,
I have a program that behaves differently depending on optimization
level. I managed to reduce it to a relatively small program.
I think there is a bug in GNAT, but before sending a report to AdaCore,
I would prefer to have other's opinion.
Best regards,
Damien Carbonne
Here are the files:
------------------------------------------------------------------------
-- pack07.ads
package Pack07 is
pragma Pure;
subtype Real is Long_Float;
type Min_Max is (Min, Max);
type Index3 is range 0 .. 2;
type Tuple3 is array (Index3) of Real;
type Point3 is new Tuple3;
-- subtype Point3 is Tuple3; -- OK when Point3 is a subtype, not a
new type
type Vector3 is new Tuple3;
-- subtype Vector3 is Tuple3; -- OK when Vector3 is a subtype, not a
new type
type Plane3 is record
N : Vector3;
D : Real;
end record;
type Side_Id is (Left, Right, Bottom, Top, Far, Near);
type Plane_Array is array (Side_Id) of Plane3;
type Frustum3 is record
Planes : Plane_Array;
end record;
type Corner_Array is array (Min_Max) of Point3;
type AABox3 is record
Corners : Corner_Array;
end record;
type Culling_State is (Outside, Intersect, Inside);
function Culling (Frustum : Frustum3; Box : AABox3) return
Culling_State;
end Pack07;
------------------------------------------------------------------------
-- pack07.adb
package body Pack07 is
function Dot (Left : Vector3; Right : Vector3) return Real;
---------
-- Dot --
---------
function Dot (Left : Vector3; Right : Vector3) return Real is
begin
return Left (0) * Right (0) +
Left (1) * Right (1) +
Left (2) * Right (2);
end Dot;
-------------
-- Culling --
-------------
function Culling (Frustum : Frustum3; Box : AABox3) return
Culling_State is
PMin : Point3;
PMax : Point3;
Result : Culling_State := Inside;
begin
for Side in Side_Id loop
for Index in Index3 loop
if Frustum.Planes (Side).N (Index) >= 0.0 then
PMin (Index) := Box.Corners(Min)(Index);
PMax (Index) := Box.Corners(Max)(Index);
else
PMin (Index) := Box.Corners(Max)(Index);
PMax (Index) := Box.Corners(Min)(Index);
end if;
end loop;
if Dot (Frustum.Planes (Side).N, Vector3 (PMax))
+ Frustum.Planes (Side).D < 0.0
then
return Outside;
elsif Dot (Frustum.Planes (Side).N, Vector3 (PMin))
+ Frustum.Planes (Side).D <= 0.0
then
Result := Intersect;
end if;
end loop;
return Result;
end Culling;
end Pack07;
------------------------------------------------------------------------
-- main07.adb
with Ada.Text_IO;
with Pack07; use Pack07;
procedure Main07 is
Frustum : Frustum3;
K1 : constant := 7.07106781186547E-01;
K2 : constant := 1.76776695296637E+00;
Num_X : constant := 2;
Step : constant := 2.0;
Size : constant := Step / 4.0;
X1, X2 : Real;
Boxes : array (-Num_X .. Num_X) of AABox3;
States : array (-Num_X .. Num_X) of Culling_State;
Expected_States : constant array (-Num_X .. Num_X) of Culling_State :=
(Outside, Intersect, Inside, Intersect, Outside);
begin
Frustum.Planes (Left) := (( K1, 0.0, -K1), K2);
Frustum.Planes (Right) := ((-K1, 0.0, -K1), K2);
Frustum.Planes (Bottom) := ((0.0, K1, -K1), K2);
Frustum.Planes (Top) := ((0.0, -K1, -K1), K2);
Frustum.Planes (Far) := ((0.0, 0.0, 1.0), 7.5);
Frustum.Planes (Near) := ((0.0, 0.0, -1.0), 1.5);
for X in -Num_X .. Num_X loop
X1 := Real (X) * Step - Size;
X2 := Real (X) * Step + Size;
Boxes (X) := (Corners => (Point3'(X1, -Size, -Size),
Point3'(X2, Size, Size)));
States (X) := Culling (Frustum, Boxes (X));
end loop;
Ada.Text_IO.Put_Line ("OK/KO: Expected Found");
for X in Boxes'Range (1) loop
if Culling_State'Image (Expected_States (X))
/= Culling_State'Image (States (X))
then
Ada.Text_IO.Put ("KO : ");
else
Ada.Text_IO.Put ("OK : ");
end if;
Ada.Text_IO.Put (Culling_State'Image (Expected_States (X)));
Ada.Text_IO.Set_Col (20);
Ada.Text_IO.Put (Culling_State'Image (States (X)));
Ada.Text_IO.New_Line;
end loop;
end Main07;
-- This program compiles and links correctly on Linux box, with GNAT GPL
2009.
-- However, its execution differs depending on compilation options.
-- 1) When compiled with BUILD = debug ("-O0"),
-- the output is:
-- OK/KO: Expected Found
-- OK : OUTSIDE OUTSIDE
-- OK : INTERSECT INTERSECT
-- OK : INSIDE INSIDE
-- OK : INTERSECT INTERSECT
-- OK : OUTSIDE OUTSIDE
--
-- 2) When compiled with BUILD = release ("-gnatn", "-funroll-loops",
"-O2"),
-- the output is:
-- OK/KO: Expected Found
-- KO : OUTSIDE INTERSECT
-- KO : INTERSECT OUTSIDE
-- KO : INSIDE OUTSIDE
-- KO : INTERSECT OUTSIDE
-- OK : OUTSIDE OUTSIDE
--
-- By changing certain declarations in Pack07, everything works as
expected in
-- release mode.
-- The change may be:
-- "type Point3 is new Tuple3" -> "subtype Point3 is Tuple3"
-- or:
-- "type Vector3 is new Tuple3" -> "subtype Vector3 is Tuple3"
--
-- Other modifications are possible to obtain the expected result.
--
-- This looks like a compiler bug to me. But I may be wrong.
------------------------------------------------------------------------
-- bug07.gpr
project Bug07 is
type Build_Type is ("debug", "release");
Build : Build_Type := External ("BUILD", "debug");
for Source_Dirs use ("src");
for Object_Dir use "obj/" & Build;
for Main use ("main07.adb");
package Compiler is
case Build is
when "release" =>
for Default_Switches ("ada") use
(
"-gnatn",
"-funroll-loops",
"-O2"
);
when "debug" =>
for Default_Switches ("ada") use
(
"-O0"
);
end case;
end Compiler;
end Bug07;
------------------------------------------------------------------------
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Possible optimization bug in GNAT GPL 2009 ?
2009-10-17 20:34 Possible optimization bug in GNAT GPL 2009 ? Damien Carbonne
@ 2009-10-18 3:31 ` Gautier write-only
2009-10-19 22:00 ` Damien Carbonne
0 siblings, 1 reply; 3+ messages in thread
From: Gautier write-only @ 2009-10-18 3:31 UTC (permalink / raw)
Hello, with GNAT GPL 2008 for Windows I get all OK with both build
modes with your project file.
I've also had the same with ObjectAda 7.2.2, to have a "second
opinion".
Uh uh, frustum culling - sounds interesting...
_________________________________________________________
Gautier's Ada programming -- http://sf.net/users/gdemont/
NB: For a direct answer, e-mail address on the Web site!
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Possible optimization bug in GNAT GPL 2009 ?
2009-10-18 3:31 ` Gautier write-only
@ 2009-10-19 22:00 ` Damien Carbonne
0 siblings, 0 replies; 3+ messages in thread
From: Damien Carbonne @ 2009-10-19 22:00 UTC (permalink / raw)
Gautier write-only a �crit :
> Hello, with GNAT GPL 2008 for Windows I get all OK with both build
> modes with your project file.
> I've also had the same with ObjectAda 7.2.2, to have a "second
> opinion".
Thanks for doing this. I also checked the program with GNAT GPL 2009 on
Windows (it also fails), and GNAT GPL 2008 on Linux (it works).
I sent a report to AdaCore.
Damien
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2009-10-19 22:00 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-10-17 20:34 Possible optimization bug in GNAT GPL 2009 ? Damien Carbonne
2009-10-18 3:31 ` Gautier write-only
2009-10-19 22:00 ` Damien Carbonne
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox