public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/43782]  New: Erroneous expansion of __asm__() directive
@ 2010-04-18  4:07 beebe at math dot utah dot edu
  2010-04-18  6:44 ` [Bug c/43782] " pinskia at gcc dot gnu dot org
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: beebe at math dot utah dot edu @ 2010-04-18  4:07 UTC (permalink / raw)
  To: gcc-bugs

Between gcc-4.5-20090903 (correct) and gcc-4.5-20091008 (wrong), a
bug was introduced in the expansion of _asm__() directives on AMD64.
The bug has been reproduced also in gcc-4.5-20100107 and yesterday's
first release of gcc-4.6-20100416.  Here is test program, with leading
comments that reflect its test results:

/***********************************************************************
Demonstrate a bug in the handling of __asm__() in recent gcc-4.5 and
gcc-4.6 releases on AMD64:

        gcc-4.1-20070723 mysqrt(4) = 2
        gcc-4.1-20071126 mysqrt(4) = 2
        gcc-4.1-20071231 mysqrt(4) = 2
        gcc-4.1-20080211 mysqrt(4) = 2
        gcc-4.1-20080218 mysqrt(4) = 2
        gcc-4.1-20080407 mysqrt(4) = 2
        gcc-4.1-20080630 mysqrt(4) = 2
        gcc-4.2-20061031 mysqrt(4) = 2
        gcc-4.2-20070124 mysqrt(4) = 2
        gcc-4.2-20070207 mysqrt(4) = 2
        gcc-4.2-20070815 mysqrt(4) = 2
        gcc-4.2-20070905 mysqrt(4) = 2
        gcc-4.2-20071128 mysqrt(4) = 2
        gcc-4.2-20071219 mysqrt(4) = 2
        gcc-4.2-20071226 mysqrt(4) = 2
        gcc-4.2-20080102 mysqrt(4) = 2
        gcc-4.2-20080213 mysqrt(4) = 2
        gcc-4.2-20080220 mysqrt(4) = 2
        gcc-4.2-20080409 mysqrt(4) = 2
        gcc-4.2-20080806 mysqrt(4) = 2
        gcc-4.2-20081015 mysqrt(4) = 2
        gcc-4.2-20081126 mysqrt(4) = 2
        gcc-4.2-20090121 mysqrt(4) = 2
        gcc-4.2-20090325 mysqrt(4) = 2
        gcc-4.3-20061118 mysqrt(4) = 2
        gcc-4.3-20070209 mysqrt(4) = 2
        gcc-4.3-20070511 mysqrt(4) = 2
        gcc-4.3-20070720 mysqrt(4) = 2
        gcc-4.3-20070914 mysqrt(4) = 2
        gcc-4.3-20081016 mysqrt(4) = 2
        gcc-4.3-20081127 mysqrt(4) = 2
        gcc-4.3-20090122 mysqrt(4) = 2
        gcc-4.3-20090524 mysqrt(4) = 2
        gcc-4.3-20090816 mysqrt(4) = 2
        gcc-4.3-20100103 mysqrt(4) = 2
        gcc-4.4-20081017 mysqrt(4) = 2
        gcc-4.4-20081128 mysqrt(4) = 2
        gcc-4.4-20090123 mysqrt(4) = 2
        gcc-4.4-20090526 mysqrt(4) = 2
        gcc-4.4-20090818 mysqrt(4) = 2
        gcc-4.4-20090908 mysqrt(4) = 2
        gcc-4.4-20100105 mysqrt(4) = 2
        gcc-4.4-20100112 mysqrt(4) = 2
        gcc-4.5-20090528 mysqrt(4) = 2
        gcc-4.5-20090820 mysqrt(4) = 2
        gcc-4.5-20090903 mysqrt(4) = 2
        gcc-4.5-20091008 mysqrt(4) = 0
        gcc-4.5-20100107 mysqrt(4) = 0
        gcc-4.6-20100416 mysqrt(4) = 0

***********************************************************************/

#include <stdio.h>
#include <stdlib.h>

double
mysqrt(double x)
{
    double result;
    __asm__ __volatile__("sqrtsd %0, %1" : "=x" (result) : "x" (x)); /* use
AMD64 SSE2 instruction */
    return (result);
}

int
main(void)
{
    double x, y;

    x = 4.0;
    y = mysqrt(x);
    (void)printf("mysqrt(%g) = %.17g\n", x, y);

    return (EXIT_SUCCESS);
}


-- 
           Summary: Erroneous expansion of __asm__() directive
           Product: gcc
           Version: 4.5.0
            Status: UNCONFIRMED
          Severity: major
          Priority: P3
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: beebe at math dot utah dot edu
 GCC build triplet: x86_64-unknown-linux-gnu
  GCC host triplet: x86_64-unknown-linux-gnu
GCC target triplet: x86_64-unknown-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43782


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

* [Bug c/43782] Erroneous expansion of __asm__() directive
  2010-04-18  4:07 [Bug c/43782] New: Erroneous expansion of __asm__() directive beebe at math dot utah dot edu
@ 2010-04-18  6:44 ` pinskia at gcc dot gnu dot org
  2010-04-18  6:45 ` pinskia at gcc dot gnu dot org
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2010-04-18  6:44 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #1 from pinskia at gcc dot gnu dot org  2010-04-18 06:44 -------
You have the wrong inline-asm:
 sqrtsd %0, %1

That is wrong because with AT&T style x86 asm, the src is first and the dest is
second.


-- 

pinskia at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|                            |INVALID


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43782


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

* [Bug c/43782] Erroneous expansion of __asm__() directive
  2010-04-18  4:07 [Bug c/43782] New: Erroneous expansion of __asm__() directive beebe at math dot utah dot edu
  2010-04-18  6:44 ` [Bug c/43782] " pinskia at gcc dot gnu dot org
@ 2010-04-18  6:45 ` pinskia at gcc dot gnu dot org
  2010-04-19 14:35 ` beebe at math dot utah dot edu
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2010-04-18  6:45 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #2 from pinskia at gcc dot gnu dot org  2010-04-18 06:45 -------
Oh I forgot to mention, sqrt will use sqrtsd and will be inlined so you don't
need to use inline-asm yourself.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43782


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

* [Bug c/43782] Erroneous expansion of __asm__() directive
  2010-04-18  4:07 [Bug c/43782] New: Erroneous expansion of __asm__() directive beebe at math dot utah dot edu
  2010-04-18  6:44 ` [Bug c/43782] " pinskia at gcc dot gnu dot org
  2010-04-18  6:45 ` pinskia at gcc dot gnu dot org
@ 2010-04-19 14:35 ` beebe at math dot utah dot edu
  2010-04-19 14:35 ` beebe at math dot utah dot edu
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: beebe at math dot utah dot edu @ 2010-04-19 14:35 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #3 from beebe at math dot utah dot edu  2010-04-19 14:34 -------
Subject: Re:  Erroneous expansion of __asm__() directive

>> Oh I forgot to mention, sqrt will use sqrtsd and will be inlined so you don't
>> need to use inline-asm yourself.

The test code that I sent is an extract of a larger system; its use of
__asm__() is intentional.

-------------------------------------------------------------------------------
- Nelson H. F. Beebe                    Tel: +1 801 581 5254                  -
- University of Utah                    FAX: +1 801 581 4148                  -
- Department of Mathematics, 110 LCB    Internet e-mail: beebe@math.utah.edu  -
- 155 S 1400 E RM 233                       beebe@acm.org  beebe@computer.org -
- Salt Lake City, UT 84112-0090, USA    URL: http://www.math.utah.edu/~beebe/ -
-------------------------------------------------------------------------------


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43782


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

* [Bug c/43782] Erroneous expansion of __asm__() directive
  2010-04-18  4:07 [Bug c/43782] New: Erroneous expansion of __asm__() directive beebe at math dot utah dot edu
                   ` (2 preceding siblings ...)
  2010-04-19 14:35 ` beebe at math dot utah dot edu
@ 2010-04-19 14:35 ` beebe at math dot utah dot edu
  2010-04-19 14:56 ` jakub at gcc dot gnu dot org
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: beebe at math dot utah dot edu @ 2010-04-19 14:35 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #4 from beebe at math dot utah dot edu  2010-04-19 14:35 -------
Subject: Re:  Erroneous expansion of __asm__() directive

>> That is wrong because with AT&T style x86 asm, the src is first and the dest is
>> second.

That cannot be the case: you cannot change the operand order after three 
years of it working one way!

-------------------------------------------------------------------------------
- Nelson H. F. Beebe                    Tel: +1 801 581 5254                  -
- University of Utah                    FAX: +1 801 581 4148                  -
- Department of Mathematics, 110 LCB    Internet e-mail: beebe@math.utah.edu  -
- 155 S 1400 E RM 233                       beebe@acm.org  beebe@computer.org -
- Salt Lake City, UT 84112-0090, USA    URL: http://www.math.utah.edu/~beebe/ -
-------------------------------------------------------------------------------


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43782


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

* [Bug c/43782] Erroneous expansion of __asm__() directive
  2010-04-18  4:07 [Bug c/43782] New: Erroneous expansion of __asm__() directive beebe at math dot utah dot edu
                   ` (3 preceding siblings ...)
  2010-04-19 14:35 ` beebe at math dot utah dot edu
@ 2010-04-19 14:56 ` jakub at gcc dot gnu dot org
  2010-04-19 15:07 ` pinskia at gmail dot com
  2010-04-30  0:23 ` beebe at math dot utah dot edu
  6 siblings, 0 replies; 8+ messages in thread
From: jakub at gcc dot gnu dot org @ 2010-04-19 14:56 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #5 from jakub at gcc dot gnu dot org  2010-04-19 14:56 -------
Nobody changed the order of arguments, in AT&T syntax always the result is the
last, in Intel syntax (not the default on Linux unless -masm=intel) the result
is the first.
Perhaps you were lucky and both the input and output got the same register and
so it didn't matter (say sqrtsd %xmm0, %xmm0).
You can also write the asm using
"sqrtsd {%1, %0|%0, %1}"
and then it will work with both the default AT&T syntax and -masm=intel.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43782


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

* [Bug c/43782] Erroneous expansion of __asm__() directive
  2010-04-18  4:07 [Bug c/43782] New: Erroneous expansion of __asm__() directive beebe at math dot utah dot edu
                   ` (4 preceding siblings ...)
  2010-04-19 14:56 ` jakub at gcc dot gnu dot org
@ 2010-04-19 15:07 ` pinskia at gmail dot com
  2010-04-30  0:23 ` beebe at math dot utah dot edu
  6 siblings, 0 replies; 8+ messages in thread
From: pinskia at gmail dot com @ 2010-04-19 15:07 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #6 from pinskia at gmail dot com  2010-04-19 15:07 -------
Subject: Re:  Erroneous expansion of __asm__() directive



Sent from my iPhone

On Apr 19, 2010, at 7:35 AM, "Nelson H. F. Beebe"  
<beebe@math.utah.edu> wrote:

>>> That is wrong because with AT&T style x86 asm, the src is first  
>>> and the dest is
>>> second.
>
> That cannot be the case: you cannot change the operand order after  
> three
> years of it working one way!

It did not change. Just what happened was gcc is now inlining the  
function. Before it was not inlining the function which allowed the  
inline-asm's two operands to be the same (the argument to the function  
and the return value are done in the same register). Which means you  
were just getting lucky that it worked. In fact AT&T asm has always  
been that way; while intel style asm is the opposite. Gcc outputs AT&T  
by default, though you can change it via an option.


>
> --- 
> --- 
> --- 
> ----------------------------------------------------------------------
> - Nelson H. F. Beebe                    Tel: +1 801 581  
> 5254                  -
> - University of Utah                    FAX: +1 801 581  
> 4148                  -
> - Department of Mathematics, 110 LCB    Internet e-mail: beebe@math.utah.edu 
>   -
> - 155 S 1400 E RM 233                       beebe@acm.org  beebe@computer.org 
>  -
> - Salt Lake City, UT 84112-0090, USA    URL: http://www.math.utah.edu/~beebe/ 
>  -
> --- 
> --- 
> --- 
> ----------------------------------------------------------------------


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43782


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

* [Bug c/43782] Erroneous expansion of __asm__() directive
  2010-04-18  4:07 [Bug c/43782] New: Erroneous expansion of __asm__() directive beebe at math dot utah dot edu
                   ` (5 preceding siblings ...)
  2010-04-19 15:07 ` pinskia at gmail dot com
@ 2010-04-30  0:23 ` beebe at math dot utah dot edu
  6 siblings, 0 replies; 8+ messages in thread
From: beebe at math dot utah dot edu @ 2010-04-30  0:23 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #7 from beebe at math dot utah dot edu  2010-04-30 00:23 -------
Subject: Re:  Erroneous expansion of __asm__() directive

I accept the explanation of the problem with my sample __asm__()
directive, and I think that we can close my bug report at

        http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43782

Since I corrected the test code to put the destination register last,
I have written an extensive test suite to check all of the other uses
of __asm__() directives in my code, and satisfied myself that there
was only one problem instance.

I also verified that after the change, the 49 gcc compiler versions
that I tested now produce the correct answer, as do icc, nvcc, opencc,
pathcc, pgcc, suncc, and upc; they all recognize the __asm__()
directive on x86_64.

However, I strongly recommend some updates in the gcc manual and
possibly also the gas manual.

I went through both in detail, and found that the gcc documentation,
which is where any programmer would expect gcc's __asm__() directive
to be documented, makes NO MENTION WHATSOEVER of the operand order
in ``5.37 Assembler Instructions with C Expression Operands''.

Elsewhere in the gcc manual, there is only this brief description

`-masm=DIALECT'
     Output asm instructions using selected DIALECT.  Supported choices
     are `intel' or `att' (the default one).  Darwin does not support
     `intel'.

but nothing more.

In the gas manual, there is an explanation in the section

* i386-Syntax::                 AT&T Syntax versus Intel Syntax

that gcc uses the AT&T src,dst order on all platforms.  For any
programmer used to reading or writing assembly code (outside of gcc)
for the Intel and AMD processor families over the last 30 years, that
is the opposite of expectation and instruction-set reference manuals.

The gas manual also has a critical section

* i386-Bugs::                   AT&T Syntax bugs

that affects the coding of subtraction instructions.

I believe that the gcc manual's description of the __asm__() directive
should carry a prominent cross reference to those two sections, and a
clear statement that the default operand order is consistent across
platforms, but may differ from vendor instruction-set manuals.

One respondent suggested:

    You can also write the asm using
    "sqrtsd {%1, %0|%0, %1}"
    and then it will work with both the default AT&T syntax and -masm=intel.

However, the vertical-bar syntax is not documented at all in the
__asm__() directive description in the gcc manual.  That too needs
improvement.

-------------------------------------------------------------------------------
- Nelson H. F. Beebe                    Tel: +1 801 581 5254                  -
- University of Utah                    FAX: +1 801 581 4148                  -
- Department of Mathematics, 110 LCB    Internet e-mail: beebe@math.utah.edu  -
- 155 S 1400 E RM 233                       beebe@acm.org  beebe@computer.org -
- Salt Lake City, UT 84112-0090, USA    URL: http://www.math.utah.edu/~beebe/ -
-------------------------------------------------------------------------------


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43782


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

end of thread, other threads:[~2010-04-30  0:23 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-04-18  4:07 [Bug c/43782] New: Erroneous expansion of __asm__() directive beebe at math dot utah dot edu
2010-04-18  6:44 ` [Bug c/43782] " pinskia at gcc dot gnu dot org
2010-04-18  6:45 ` pinskia at gcc dot gnu dot org
2010-04-19 14:35 ` beebe at math dot utah dot edu
2010-04-19 14:35 ` beebe at math dot utah dot edu
2010-04-19 14:56 ` jakub at gcc dot gnu dot org
2010-04-19 15:07 ` pinskia at gmail dot com
2010-04-30  0:23 ` beebe at math dot utah dot edu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).