comp.lang.ada
 help / color / mirror / Atom feed
* gnat 4.4.5 generates surprising code when enabling FP checks
@ 2011-04-07 15:48 Markus Schöpflin
  2011-04-07 17:10 ` Georg Bauhaus
  0 siblings, 1 reply; 3+ messages in thread
From: Markus Schöpflin @ 2011-04-07 15:48 UTC (permalink / raw)


The behaviour described below has been observed for gcc 4.3.5, 4.4.5, and 
gnatpro 6.3.2, maybe someone here has any insight on this.

Given the following short code snippet:

procedure FLOAT_CHECKS is
    F1, F2, F3 : SHORT_FLOAT;
begin
    for I in 1..100_000 loop
       for J in 1..10_000 loop
          F1 := SHORT_FLOAT(I);  -- *
          F2 := SHORT_FLOAT(J);  -- *
          F3 := F1 * F2;         -- *
       end loop;
    end loop;
end FLOAT_CHECKS;

Compiling with gnatmake -O3 -gnatDG -gnatVa float_checks.adb gives the 
following intermediate code for the lines marked with '*':

          f1 := short_float({i});
          f2 := short_float({j});
          [constraint_error when
            not boolean!($system__fat_sflt__attr_short_float.
              system__fat_sflt__attr_short_float__valid (f1'
              unrestricted_access, xF => 0))
            "invalid data"]
          [constraint_error when
            not boolean!($system__fat_sflt__attr_short_float.
              system__fat_sflt__attr_short_float__valid (f2'
              unrestricted_access, xF => 0))
            "invalid data"]
          [constraint_error when
            not boolean!($system__fat_sflt__attr_short_float.
              system__fat_sflt__attr_short_float__valid (f1 * f2'
              unrestricted_access, xF => 0))
            "invalid data"]
          f3 := f1 * f2;

So far so good. What really surprises me is that in the resulting assembler 
code the last multiplication is actually performed twice, the disassembled 
object code looks like this (for the last check and multiplication only):

  8048ed6:       d9 45 e4                flds   -0x1c(%ebp)
  8048ed9:       d8 4d e0                fmuls  -0x20(%ebp)
  8048edc:       c7 44 24 04 00 00 00    movl   $0x0,0x4(%esp)
  8048ee3:       00
  8048ee4:       89 3c 24                mov    %edi,(%esp)
  8048ee7:       d9 5d dc                fstps  -0x24(%ebp)
  8048eea:       e8 61 fc ff ff          call   8048b50 
<system__fat_sflt__attr_short_float__valid@plt>
  8048eef:       84 c0                   test   %al,%al
  8048ef1:       74 2c                   je     8048f1f 
<_ada_float_checks+0xaf>
  8048ef3:       83 c3 01                add    $0x1,%ebx
  8048ef6:       d9 45 e4                flds   -0x1c(%ebp)
  8048ef9:       81 fb 11 27 00 00       cmp    $0x2711,%ebx
  8048eff:       d8 4d e0                fmuls  -0x20(%ebp)
  8048f02:       dd d8                   fstp   %st(0)

Is the second multiplication to be expected? Does anybody know if there is 
an optimizer option which would eliminate the second multiplication?

Regards,
Markus



^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: gnat 4.4.5 generates surprising code when enabling FP checks
  2011-04-07 15:48 gnat 4.4.5 generates surprising code when enabling FP checks Markus Schöpflin
@ 2011-04-07 17:10 ` Georg Bauhaus
  2011-04-08 10:43   ` Markus Schöpflin
  0 siblings, 1 reply; 3+ messages in thread
From: Georg Bauhaus @ 2011-04-07 17:10 UTC (permalink / raw)


On 07.04.11 17:48, Markus Schï¿œpflin wrote:
> What really surprises me is that in the resulting assembler
> code the last multiplication is actually performed twice, the disassembled
> object code looks like this (for the last check and multiplication only):

(I noticed that a big portion of the code is for performing
the validity checks requested via -gnatVa; lots of detail
documented in function Valid's body in System.Fat_Gen
(that I do not fully understand).  system__fat_sflt__attr_short_float__valid
refers to an instance of Fat_Gen (Short_Float), a package that
implements floating point attribute functions, IIUC.

(I also noticed that there is a conditional jump after
the call on system__fat_sflt__attr_short_float__valid
to after the second multiplication.)

>  8048ed6:       d9 45 e4                flds   -0x1c(%ebp)
>  8048ed9:       d8 4d e0                fmuls  -0x20(%ebp)
>  8048edc:       c7 44 24 04 00 00 00    movl   $0x0,0x4(%esp)
>  8048ee3:       00
>  8048ee4:       89 3c 24                mov    %edi,(%esp)
>  8048ee7:       d9 5d dc                fstps  -0x24(%ebp)
>  8048eea:       e8 61 fc ff ff          call   8048b50
> <system__fat_sflt__attr_short_float__valid@plt>
>  8048eef:       84 c0                   test   %al,%al
>  8048ef1:       74 2c                   je     8048f1f <_ada_float_checks+0xaf>
>  8048ef3:       83 c3 01                add    $0x1,%ebx
>  8048ef6:       d9 45 e4                flds   -0x1c(%ebp)
>  8048ef9:       81 fb 11 27 00 00       cmp    $0x2711,%ebx
>  8048eff:       d8 4d e0                fmuls  -0x20(%ebp)
>  8048f02:       dd d8                   fstp   %st(0)
> 
> Is the second multiplication to be expected? Does anybody know if there is an
> optimizer option which would eliminate the second multiplication?

Since much of the generated code is a consequence of -gnatVA
(which implies -gnatVf), shouldn't a smaller selection validity
checking do the trick, i.e. if you exclude -gnatVf?

Of course this doesn't answer the question if -gnatVa must be used.
HTH



^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: gnat 4.4.5 generates surprising code when enabling FP checks
  2011-04-07 17:10 ` Georg Bauhaus
@ 2011-04-08 10:43   ` Markus Schöpflin
  0 siblings, 0 replies; 3+ messages in thread
From: Markus Schöpflin @ 2011-04-08 10:43 UTC (permalink / raw)


Am 07.04.2011 19:10, schrieb Georg Bauhaus:

> Since much of the generated code is a consequence of -gnatVA
> (which implies -gnatVf), shouldn't a smaller selection validity
> checking do the trick, i.e. if you exclude -gnatVf?

The point was to have floating point validity checks on, so using -gnatVaF 
unfortunately is not an option.

The project in question used gcc 3.4 and was migrated to a newer gnat 
version, resulting in a serious performance degradation which I'm currently 
investigating.

I think I found the option which is responsible for the degradation (it's 
-gnatVc which is implied by -gnatVa and whose behaviour seems to have 
changed significantly for gcc 4.x).

The thing that surprised me was that the multiplication is actually 
performed twice, I was kind of expecting it to be only done once.

Currently I'm thinking of taking a step backwards and check what the 
project really needs in terms of validity checks in order to catch invalid 
floats (INFs and NAN) as soon as possible.

It looks like using 'type FLOAT_T is new FLOAT range FLOAT'Range' instead 
of unchecked IEEE floats with -gnatVa generates significantly better 
assembler code, so we might be able to just use -gnatVfpr instead.

Regards,
Markus



^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2011-04-08 10:43 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-04-07 15:48 gnat 4.4.5 generates surprising code when enabling FP checks Markus Schöpflin
2011-04-07 17:10 ` Georg Bauhaus
2011-04-08 10:43   ` Markus Schöpflin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox