Bug 39986 - decimal float constant is incorrect when cc1 is a 64-bit binary
Summary: decimal float constant is incorrect when cc1 is a 64-bit binary
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.5.0
: P3 normal
Target Milestone: ---
Assignee: Janis Johnson
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2009-04-30 23:59 UTC by Janis Johnson
Modified: 2009-05-13 20:46 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2009-05-01 18:57:58


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Janis Johnson 2009-04-30 23:59:14 UTC
When cc1 for powerpc64-linux is a 32-bit binary, compiling

  _Decimal32 x = 1.2df;

with "-m64 -S" results in:

        .file   "df.c"
        .section        ".toc","aw"
        .section        ".text"
        .globl x
        .section        ".data"
        .align 2
        .type   x, @object
        .size   x, 4
x:
        .long   574619666
        .ident  "GCC: (GNU) 4.5.0 20090430 (experimental) [trunk revision 147009]"

When the same compiler is built to be a 64-bit binary then the result is the same except for

        .size   x, 4
x:
        .long   2467972673108443136

I normally configure GCC using --with-cpu=default32 and haven't yet checked to see long the bug has existed; perhaps as long as GCC has supported decimal float arithmetic.

If check_effective_target_dfprt_nocache fails then the tests in gcc.dg/dfp are treated as compile-only and the struct-layout-1 tests do not support decimal float types, and currently there is no test for the correct constant value so the bug was not detected by running the testsuite.
Comment 1 Janis Johnson 2009-05-01 18:57:58 UTC
The problem is that in dfp.c, functions encode_decimal* and decode_decimal* use memcpy from a 32-bit int to a long for 32 bits.  This works fine with -32 where long is 32 bits, but not for -m64 where long is 32 bits.  I assume that it magically works fine on little-endian systems like x86_64.

This is not a regression, just a horrible wrong-code bug.

I'm testing a patch.
Comment 2 Janis Johnson 2009-05-01 19:03:57 UTC
D'oh, I of course meant that long is 32-bits when GCC is build with default -m32 and that long is 64-bits when GCC is built with default -m64; the host size of long, not the target size.
Comment 3 Janis Johnson 2009-05-04 21:24:18 UTC
On x86_64 with a 64-bit compiler, positive decimal float constants are OK, negative decimal float constants are wrong for both -m64 (the default) and -m32.
Comment 4 Janis Johnson 2009-05-06 17:01:08 UTC
Subject: Bug 39986

Author: janis
Date: Wed May  6 16:59:53 2009
New Revision: 147188

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=147188
Log:
	PR middle-end/39986
	* dfp.c (encode_decimal32, decode_decimal32, encode_decimal64,
	decode_decimal64, encode_decimal128, decode_decimal128): Avoid
	32-bit memcpy into long.

	* gcc.dg/dfp/pr39986.c: New test.

Added:
    trunk/gcc/testsuite/gcc.dg/dfp/pr39986.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/dfp.c
    trunk/gcc/testsuite/ChangeLog

Comment 5 Janis Johnson 2009-05-06 17:18:28 UTC
This was a regression after all, release branches do not have the bug.  I added the new test case to the 4.4 and 4.3 branches.
Comment 6 H.J. Lu 2009-05-07 13:15:28 UTC
Only the testcase was checked into 4.4 branch:

http://gcc.gnu.org/ml/gcc-cvs/2009-05/msg00163.html

The dfp.c change is missing on 4.4 branch.
Comment 7 H.J. Lu 2009-05-07 13:22:04 UTC
Gcc 4.4.1 revision  147214 gave:

FAIL: gcc.dg/dfp/pr39986.c scan-assembler .long\t(-1572863965|-1308622825)\n
FAIL: gcc.dg/dfp/pr39986.c scan-assembler .long\t(-1572863965|-1308622825)\n
FAIL: gcc.dg/dfp/pr39986.c scan-assembler .long\t(-1574174720|-1319108608)\n
FAIL: gcc.dg/dfp/pr39986.c scan-assembler .long\t(-1574174720|-1319108608)\n
FAIL: gcc.dg/dfp/pr39986.c scan-assembler .long\t(-1576681472|-1339162624)\n
FAIL: gcc.dg/dfp/pr39986.c scan-assembler .long\t(-1576681472|-1339162624)\n

on Linux/Intel64.
Comment 8 Janis Johnson 2009-05-07 21:39:10 UTC
Subject: Bug 39986

Author: janis
Date: Thu May  7 21:38:46 2009
New Revision: 147253

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=147253
Log:
	PR middle-end/39986
	* dfp.c (encode_decimal32, decode_decimal32, encode_decimal64,
	decode_decimal64, encode_decimal128, decode_decimal128): Avoid
	32-bit memcpy into long.

Modified:
    branches/gcc-4_4-branch/gcc/ChangeLog
    branches/gcc-4_4-branch/gcc/dfp.c

Comment 9 Janis Johnson 2009-05-07 21:43:44 UTC
Subject: Bug 39986

Author: janis
Date: Thu May  7 21:43:32 2009
New Revision: 147255

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=147255
Log:
	PR middle-end/39986
	* dfp.c (encode_decimal32, decode_decimal32, encode_decimal64,
	decode_decimal64, encode_decimal128, decode_decimal128): Avoid
	32-bit copy into long.

Modified:
    branches/gcc-4_3-branch/gcc/ChangeLog
    branches/gcc-4_3-branch/gcc/dfp.c

Comment 10 Andrew Pinski 2009-05-13 20:46:17 UTC
Fixed.