comp.lang.ada
 help / color / mirror / Atom feed
* 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