Bug 55145 - Different bits for long double constant depending on long int size
Summary: Different bits for long double constant depending on long int size
Status: RESOLVED DUPLICATE of bug 21718
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.8.0
: P3 normal
Target Milestone: 4.8.3
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on: 21718
Blocks:
  Show dependency treegraph
 
Reported: 2012-10-31 05:39 UTC by H.J. Lu
Modified: 2013-11-20 14:41 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2012-11-01 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description H.J. Lu 2012-10-31 05:39:02 UTC
After fixing PR 55142, GCC 4.8 revision 193001 miscompiles
glibc trunk for x32 with -maddress-mode=long.  Most glibc
tests failed with "Segmentation fault".  It is independent
of LRA and may have something to do with recent subreg
changes.
Comment 1 Uroš Bizjak 2012-11-01 10:08:50 UTC
So is this PR a manifestation of presumably wrong fix for PR 55142 or an independent bug?
Comment 2 H.J. Lu 2012-11-01 22:29:22 UTC
I don't know if there are other bugs in addition to PR 55142.
I will leave it open until I can compile glibc to verify.
Comment 3 H.J. Lu 2012-11-04 08:11:01 UTC
GCC i386 and GCC x86-64 generate different bits long double constant
depending ptr_mode:

[hjl@gnu-tools-1 tmp]$ cat y.c
const long double
 pio2_hi = 1.5707963267948966192021943710788178805159986950457096099853515625L;
[hjl@gnu-tools-1 tmp]$ /usr/gcc-4.7.3-32bit/bin/gcc -S y.c -o 32.s
[hjl@gnu-tools-1 tmp]$ gcc -S y.c -o 64.s
[hjl@gnu-tools-1 tmp]$ diff -up 64.s 32.s
--- 64.s	2012-11-04 01:06:52.492398183 -0700
+++ 32.s	2012-11-04 01:06:47.685344002 -0700
@@ -3,11 +3,10 @@
 	.section	.rodata
 	.align 16
 	.type	pio2_hi, @object
-	.size	pio2_hi, 16
+	.size	pio2_hi, 12
 pio2_hi:
-	.long	560513588
-	.long	3373259426
+	.long	560513589
+	.long	-921707870
 	.long	16383
-	.long	0
-	.ident	"GCC: (GNU) 4.7.2 20120921 (Red Hat 4.7.2-2)"
+	.ident	"GCC: (GNU) 4.7.3 20121024 (prerelease)"
 	.section	.note.GNU-stack,"",@progbits
[hjl@gnu-tools-1 tmp]$ gcc -c 32.s 64.s
[hjl@gnu-tools-1 tmp]$ objdump -s -j .rodata 32.o > 32
[hjl@gnu-tools-1 tmp]$ objdump -s -j .rodata 64.o > 64
[hjl@gnu-tools-1 tmp]$ diff -up 32 64
--- 32	2012-11-04 01:07:37.341913094 -0700
+++ 64	2012-11-04 01:07:42.192979572 -0700
@@ -1,5 +1,5 @@
 
-32.o:     file format elf64-x86-64
+64.o:     file format elf64-x86-64
 
 Contents of section .rodata:
- 0000 35c26821 a2da0fc9 ff3f0000           5.h!.....?..    
+ 0000 34c26821 a2da0fc9 ff3f0000 00000000  4.h!.....?......
[hjl@gnu-tools-1 tmp]$ 

Ignore padding, i386 GCC generates 35c26821 and
x86-64 generates 34c26821.
Comment 4 H.J. Lu 2012-11-04 10:14:07 UTC
It is due to long int usage in real.h. Depending on
size of long int, real.c gives slightly different
results.
Comment 5 Andreas Schwab 2012-11-04 11:04:03 UTC
This cannot explain the crashes you see since the difference is just one ULP.
Comment 6 H.J. Lu 2012-11-04 11:09:12 UTC
(In reply to comment #5)
> This cannot explain the crashes you see since the difference is just one ULP.

The glibc crash is fixed by

http://gcc.gnu.org/ml/gcc-patches/2012-11/msg00248.html
Comment 7 H.J. Lu 2012-11-04 22:51:46 UTC
Here are different internal values from the same input:

32-bit long: 1.57079632679489661925640447970309310221637133509
Input:       1.5707963267948966192021943710788178805159986950457096099853515625
64-bit long: 1.57079632679489661914798426245454265881562605500221252441

Input value is extremely close to a half-way value between 32-bit
and 64-bit longs.
Comment 8 Vincent Lefèvre 2012-11-04 23:43:44 UTC
(In reply to comment #7)
> Here are different internal values from the same input:
> 
> 32-bit long: 1.57079632679489661925640447970309310221637133509
> Input:       1.5707963267948966192021943710788178805159986950457096099853515625
> 64-bit long: 1.57079632679489661914798426245454265881562605500221252441
> 
> Input value is extremely close to a half-way value between 32-bit
> and 64-bit longs.

1.5707963267948966192021943710788178805159986950457096099853515625 is *exactly* the 65-bit binary number 1.1001001000011111101101010100010001000010110100011000010001101001, thus exactly a halfway value between two consecutive long double numbers (for 64-bit precision):
  1.100100100001111110110101010001000100001011010001100001000110100
and
  1.100100100001111110110101010001000100001011010001100001000110101

I suppose that the difference is due to the fact that the algorithm used in GCC has not been written to round correctly, and if this algorithm uses variables of type "long" internally, it is not surprising to get different results on different architectures (32-bit long and 64-bit long).
Comment 9 Jakub Jelinek 2013-03-22 14:44:28 UTC
GCC 4.8.0 is being released, adjusting target milestone.
Comment 10 Jakub Jelinek 2013-05-31 10:58:36 UTC
GCC 4.8.1 has been released.
Comment 11 Jakub Jelinek 2013-10-16 09:49:17 UTC
GCC 4.8.2 has been released.
Comment 12 Joseph S. Myers 2013-11-20 14:41:05 UTC
Just another instance of bug 21718.

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