[Bug ada/59772] New: Floating point constants are not correctly encoded on AVR target
j-etienne at users dot sourceforge.net
gcc-bugzilla@gcc.gnu.org
Sat Jan 11 22:47:00 GMT 2014
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59772
Bug ID: 59772
Summary: Floating point constants are not correctly encoded on
AVR target
Product: gcc
Version: unknown
Status: UNCONFIRMED
Severity: critical
Priority: P3
Component: ada
Assignee: unassigned at gcc dot gnu.org
Reporter: j-etienne at users dot sourceforge.net
In code compiled for AVR target, the floating point constants are not correct
in the generated code.
Sample code (specification first, then body) :
-------------
package Float_Test is
function Div_Test (Value : Float) return Float;
function Perimeter_Test (Value : Float) return Float;
end Float_Test;
package body Float_Test is
K_Denominator : constant Float := Float (4096);
K_Pi : constant Float := 3.1415927;
function Div_Test (Value : Float) return Float
is
begin
return (Value / K_Denominator);
end Div_Test;
function Perimeter_Test (Value : Float) return Float
is
begin
return (Value * K_Pi);
end Perimeter_Test;
end Float_Test;
-------------
When I commpile this sample code, with the following command :
avr-gcc -Wall -Wextra -fno-strict-aliasing -fwrapv
-fno-aggressive-loop-optimizations -mmcu=at90usb1287 -Os -S -gnatp -I
~/Programmation/Unix/gcc-4.8.2/gcc/ada float_test.adb -fdump-tree-original
-gnatD
It generates wrong values for both floating point constants :
-------------
.file "float_test.adb"
__SP_H__ = 0x3e
__SP_L__ = 0x3d
__SREG__ = 0x3f
__RAMPZ__ = 0x3b
__tmp_reg__ = 0
__zero_reg__ = 1
.global __divsf3
.text
.global float_test__div_test
.type float_test__div_test, @function
float_test__div_test:
/* prologue: function */
/* frame size = 0 */
/* stack size = 0 */
.L__stack_usage = 0
ldi r18,0
ldi r19,0
movw r20,r18
call __divsf3
ret
.size float_test__div_test, .-float_test__div_test
.global __mulsf3
.global float_test__perimeter_test
.type float_test__perimeter_test, @function
float_test__perimeter_test:
/* prologue: function */
/* frame size = 0 */
/* stack size = 0 */
.L__stack_usage = 0
ldi r18,0
ldi r19,lo8(-80)
ldi r20,lo8(125)
ldi r21,lo8(58)
call __mulsf3
ret
.size float_test__perimeter_test, .-float_test__perimeter_test
.global float_test_E
.data
.type float_test_E, @object
.size float_test_E, 2
float_test_E:
.zero 2
.ident "GCC: (GNU) 4.8.2"
.global __do_copy_data
-------------
The denominator provided as argument to divsf3 is 0.0 instead of 4096, and the
constant term provided as argument to mulsf3 is 0.000967741 instead of
3.12415927
I'm using a cross GCC for AVR target hosted on MacOSX 10.9. avr-gcc -v gives :
Using built-in specs.
COLLECT_GCC=avr-gcc
COLLECT_LTO_WRAPPER=/opt/avr-ada-test/libexec/gcc/avr/4.8.2/lto-wrapper
Target: avr
Configured with: ../gcc-4.8.2/configure --prefix=/opt/avr-ada-test --target=avr
--program-prefix=avr- --disable-shared --disable-nls --disable-libssp
--with-system-zlib --disable-libada --enable-languages=ada,c --enable-cpp
--with-dwarf2 --enable-version-specific-runtime-libs --with-gmp=/opt/local
--with-mpfr=/opt/local --with-mpc=/opt/local
Thread model: single
gcc version 4.8.2 (GCC)
Please note that I reproduced the same behaviour on a x86-linux host.
I first stumbled upon this bug when migrating my application to AVR GCC 4.7.2
using the RTS from AVR-Ada.
With GCC 4.8.2, I tried several "system.ads" locations : the one from the AVR
Ada RTS, from the native compiler, from the GCC source tree, and always got the
same result.
I noticed that in the GNAT debug file "float_test.adb.dg" , the constants are
correct :
-------------
float_test__k_denominator : constant float := [8388608.0*2**(-11)];
float_test__k_pi : constant float := [13176795.0*2**(-22)];
function float_test__div_test (value : float) return float is
begin
return (value / float_test__k_denominator);
end float_test__div_test;
function float_test__perimeter_test (value : float) return float is
begin
return (value * float_test__k_pi);
end float_test__perimeter_test;
-------------
While in the "original" tree dump "float_test.adb.003t.original", they are not
(and have the values that are eventually found in the machine code) :
-------------
Float_Test.Div_Test (const float value)
{
return (float) value / 0.0;
Float_Test.Perimeter_Test (const float value)
{
return (float) value * 9.677410125732421875e-4;
-------------
The encoding was correct with GCC 4.5
More information about the Gcc-bugs
mailing list