From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 2320 invoked by alias); 4 Jan 2003 21:26:01 -0000 Mailing-List: contact gcc-prs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-prs-owner@gcc.gnu.org Received: (qmail 2300 invoked by uid 71); 4 Jan 2003 21:26:00 -0000 Resent-Date: 4 Jan 2003 21:26:00 -0000 Resent-Message-ID: <20030104212600.2299.qmail@sources.redhat.com> Resent-From: gcc-gnats@gcc.gnu.org (GNATS Filer) Resent-Cc: gcc-prs@gcc.gnu.org, gcc-bugs@gcc.gnu.org Resent-Reply-To: gcc-gnats@gcc.gnu.org, Kevin Ryde Received: (qmail 1457 invoked from network); 4 Jan 2003 21:20:13 -0000 Received: from unknown (HELO sunny.pacific.net.au) (203.25.148.40) by 209.249.29.67 with SMTP; 4 Jan 2003 21:20:13 -0000 Received: from wisma.pacific.net.au (wisma.pacific.net.au [210.23.129.72]) by sunny.pacific.net.au with ESMTP id h04LK0KR022113; Sun, 5 Jan 2003 08:20:00 +1100 (EST) Received: from localhost (ppp121.dyn228.pacific.net.au [203.143.228.121]) by wisma.pacific.net.au with ESMTP id IAA10051; Sun, 5 Jan 2003 08:19:58 +1100 (EST) Received: from gg by localhost with local (Exim 3.35 #1 (Debian)) id 18Uvhb-0004AN-00; Sun, 05 Jan 2003 07:19:31 +1000 Message-Id: <87znqg4nq6.fsf@zip.com.au> Date: Sat, 04 Jan 2003 21:26:00 -0000 From: Kevin Ryde To: gcc-gnats@gcc.gnu.org Cc: =?iso-8859-1?q?Torbj=F6rn?= Granlund Subject: optimization/9174: pentium4 double raw through union X-SW-Source: 2003-01/txt/msg00296.txt.bz2 List-Id: >Number: 9174 >Category: optimization >Synopsis: pentium4 double raw through union >Confidential: no >Severity: serious >Priority: medium >Responsible: unassigned >State: open >Class: wrong-code >Submitter-Id: net >Arrival-Date: Sat Jan 04 13:26:00 PST 2003 >Closed-Date: >Last-Modified: >Originator: >Release: 3.2.1 >Organization: >Environment: System: FreeBSD binxxxxx.swox.se 4.6-STABLE FreeBSD 4.6-STABLE #1: Sun Sep 15 20:28:51 CEST 2002 tege@king.swox.se:/media/u/FreeBSD/RELENG_4/src/sys/compile/CLIENT i386 host: i386-unknown-freebsd4.6 build: i386-unknown-freebsd4.6 target: i386-unknown-freebsd4.6 configured with: /u/gcc/gcc-3.2.1/configure --enable-languages=c,c++ >Description: Using a union to access the raw bytes of a double returns an incorrect part of the double when compiled with -O and -march=pentium4. >How-To-Repeat: The file foo.c below, compiled and run gcc -O -march=pentium4 foo.c ./a.out produces want 419D6F34 got 54000000 Whereas I believe the "want" value is correct and the "got" ought to be the same, which it is if compiled either without -O or without -march=pentium4. The program attempts to do a raw read of the high 32-bits of a double using an array of two "unsigned"s. The code seems to come out as fstpl -8(%ebp) movsd -8(%ebp), %xmm1 movd %xmm1, %eax I think movd here is incorrect. It ignores the "[1]" index on the u.s access, and instead returns the low half of the double. For what it's worth, this seems to occur the same when using a bitfield to access part of the double, which is how I struck it in some code that's part of the GMP MPFR library. Also for what it's worth, the test "d != 0" seems necessary to induce gcc to load the double onto the x87 stack then send it to an integer register. Incidentally, movsd+movd is not efficient, no doubt a plain movl could load from memory straight to eax. And the fstpl is unnecessary too, since the value in question is still in the parameters on the stack, and could be read direct from there into eax. Though perhaps it's a bit tricky to "see through" a union back to the original operand for a raw access. --=-=-= Content-Type: text/x-csrc Content-Disposition: attachment; filename=foo.c union dbl { double d; unsigned s[2]; }; unsigned foo (double d) { union dbl u; if (d != 0) { u.d = d; return u.s[1]; } else return 0; } int main (void) { double d = 123456789.0; union dbl u; u.d = d; printf ("want %X\n", u.s[1]); printf ("got %X\n", foo (d)); return 0; } --=-=-=-- >Fix: >Release-Note: >Audit-Trail: >Unformatted: --=-=-=