[Bug c/43782] Erroneous expansion of __asm__() directive

2010-04-29 Thread beebe at math dot utah dot edu


--- 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:: ATT Syntax versus Intel Syntax

that gcc uses the ATT 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::   ATT 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 ATT 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. BeebeTel: +1 801 581 5254  -
- University of UtahFAX: +1 801 581 4148  -
- Department of Mathematics, 110 LCBInternet e-mail: be...@math.utah.edu  -
- 155 S 1400 E RM 233   be...@acm.org  be...@computer.org -
- Salt Lake City, UT 84112-0090, USAURL: http://www.math.utah.edu/~beebe/ -
---


-- 


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



[Bug c/43782] Erroneous expansion of __asm__() directive

2010-04-19 Thread beebe at math dot utah dot edu


--- 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. BeebeTel: +1 801 581 5254  -
- University of UtahFAX: +1 801 581 4148  -
- Department of Mathematics, 110 LCBInternet e-mail: be...@math.utah.edu  -
- 155 S 1400 E RM 233   be...@acm.org  be...@computer.org -
- Salt Lake City, UT 84112-0090, USAURL: http://www.math.utah.edu/~beebe/ -
---


-- 


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



[Bug c/43782] Erroneous expansion of __asm__() directive

2010-04-19 Thread beebe at math dot utah dot edu


--- 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 ATT 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. BeebeTel: +1 801 581 5254  -
- University of UtahFAX: +1 801 581 4148  -
- Department of Mathematics, 110 LCBInternet e-mail: be...@math.utah.edu  -
- 155 S 1400 E RM 233   be...@acm.org  be...@computer.org -
- Salt Lake City, UT 84112-0090, USAURL: http://www.math.utah.edu/~beebe/ -
---


-- 


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



[Bug c/43782] New: Erroneous expansion of __asm__() directive

2010-04-17 Thread beebe at math dot utah dot edu
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



[Bug c/43730] New: internal compiler error: in expand_builtin_interclass_mathfn, at builtins.c:2313

2010-04-12 Thread beebe at math dot utah dot edu
Compilation of this test file with versions of gcc-4.5 dated 20090528 to
20100107 produce a fatal internal compiler error; comparable versions of
gcc-4.3 and gcc-4.4 do not have this problem:

% cat bug003.c
extern int (isinfl)(long double);

int
bugfun(long double x, long double y)
{
int result;

if (isinfl(x))
result = isinfl(y);
else
{
int kx, ky;
kx = ky = 1;
result = (kx == ky);
}
return (result);
}

% gcc-4.5-20100107  -g -c bug003.c
bug003.c: In function 'bugfun':
bug003.c:9:9: internal compiler error: in expand_builtin_interclass_mathfn, at
builtins.c:2313
Please submit a full bug report,
with preprocessed source if appropriate.
See http://gcc.gnu.org/bugs.html for instructions.

A test with gcc-4.5-20090528 on IA-32 (triplets i686-pc-linux-gnu)
produces a similar report:
% gcc-4.5-20090528 -g -c bug003.c
bug003.c: In function 'bugfun':
bug003.c:9: internal compiler error: in expand_builtin_interclass_mathfn, at
builtins.c:2297


-- 
   Summary: internal compiler error: in
expand_builtin_interclass_mathfn, at builtins.c:2313
   Product: gcc
   Version: 4.5.0
Status: UNCONFIRMED
  Severity: normal
  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=43730



[Bug c/31385] New: gcc fails to find spill register for decimal arithmetic

2007-03-28 Thread beebe at math dot utah dot edu
In compilation of a large library of code for decimal floating-point
arithmetic, I found that compilations with -g would succeed, but most
would fail with -O1, -O2, or -O3 on IA-32.  I've taken a single example
and chopped away extraneous code to produce a standalone file
that exhibits the compiler error:

% cat bug002.c
typedef _Decimal32 fp_t;

extern fp_t g(fp_t);

fp_t
bug(fp_t x)
{
fp_t result;
int n;
fp_t f, f3, y, z;

n = 0;
y = 1.DF;
f = g(x);

if (f  0.DF)
f = -f;

f3 = 2.DF;

z = (y + y + f / (y * y));
y = (z + z) / (9.DF) + f3 / (z * z);

result = y;

return (result);
}

% gcc --version
gcc (GCC) 4.3.0 20070316 (experimental)

% gcc -c -O1 bug002.c
bug002.c: In function 'bug':
bug002.c:27: error: unable to find a register to spill in class 'GENERAL_REGS'
bug002.c:27: error: this is the insn:
(insn 25 24 26 3 (set (subreg:SI (reg/v:SD 59 [ f ]) 0)
(plus:SI (subreg:SI (reg/v:SD 59 [ f ]) 0)
(const_int -2147483648 [0x8000]))) 144 {*lea_1} (nil)
(nil))
bug002.c:27: internal compiler error: in spill_failure, at reload1.c:1944


-- 
   Summary: gcc fails to find spill register for decimal arithmetic
   Product: gcc
   Version: 4.3.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: beebe at math dot utah dot edu
 GCC build triplet: i686-pc-linux-gnu
  GCC host triplet: i686-pc-linux-gnu
GCC target triplet: i686-pc-linux-gnu


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



[Bug c/31321] New: gcc fails to compile simple long double initializers

2007-03-22 Thread beebe at math dot utah dot edu
gcc-4.3-20070316 and gcc-4.2-20070307 both fail to compile this
one-line file on Mac OS X 10.4.9 (up to current Apple patch levels):

% cat foo.c
static const long double X = (27.0L) / (35.0L);

% gcc-4.3-20070316 -c foo.c
foo.c:1: error: initializer element is not constant

If the divisor is changed to 32.0L, it compiles, as does any similar
statement where the right-hand side can be evaluated exactly.

The compilers were built like this:

  nice time env LDFLAGS=-L/usr/local/lib \
../gcc-4.3-20070316/configure \
--enable-decimal-float \
--enable-languages=c,c++ \
--with-gmp=/usr/local \
--with-mpfr=/usr/local

nice time make bootstrap

Similar code with float and double initializers compiles without problems.


-- 
   Summary: gcc fails to compile simple long double initializers
   Product: gcc
   Version: 4.3.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: beebe at math dot utah dot edu
 GCC build triplet: powerpc-apple-darwin8.9.0
  GCC host triplet: powerpc-apple-darwin8.9.0
GCC target triplet: powerpc-apple-darwin8.9.0


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



[Bug c/30992] New: Scaling error in decimal floating-point arithmetic blows conversions to integers

2007-02-27 Thread beebe at math dot utah dot edu
The function DFP_TO_INT() in gcc/config/dfp-bit.c has the job of converting
decimal floating point values to integers.  It does this by calling the
decNumberFromString() function from the IBM decnumber library, but with an
incorrect argument.  Fortunately, the patch is just one character:

% diff -c gcc-4.3-20070209/gcc/config/dfp-bit.c
/local/build/gcc/gcc-4.3-20070209/gcc/config
*** gcc-4.3-20070209/gcc/config/dfp-bit.c   Mon Jan 29 16:01:35 2007
--- /local/build/gcc/gcc-4.3-20070209/gcc/config/dfp-bit.c  Thu Feb 15
12:41:12 2007
***
*** 450,456 
/* Rescale if the exponent is less than zero.  */
decNumberToIntegralValue (n2, n1, context);
/* Get a value to use for the quantize call.  */
!   decNumberFromString (qval, (char *) 1.0, context);
/* Force the exponent to zero.  */
decNumberQuantize (n1, n2, qval, context);
/* Get a string, which at this point will not include an exponent.  */
--- 450,456 
/* Rescale if the exponent is less than zero.  */
decNumberToIntegralValue (n2, n1, context);
/* Get a value to use for the quantize call.  */
!   decNumberFromString (qval, (char *) 1., context);
/* Force the exponent to zero.  */
decNumberQuantize (n1, n2, qval, context);
/* Get a string, which at this point will not include an exponent.  */

Without this patch, the range of numbers that can be correctly converted
to integers is sharply reduced: most conversions of large values are
wrong.  For example, the value x = 1048576.0DF is exactly representable
as a _Decimal32 value and as a 32-bit int, but the bad code converts it 
to an int value of 2147483647, and a long int value of 9223372036854775807. 
With the patch, integer conversions are now correct for all floating-point
values for which exact integer counterparts exist.

The bug exists in all versions of dfp-bit.c in gcc-4.2 and gcc-4.3
distributions.

As an aside, I now have a complete C99 library for decimal arithmetic
working under gcc-4.2 and gcc-4.3 on AMD64, thanks to the prototype
support for decimal arithmetic in gcc.  I look forward to the decimal
support working on other platforms.


-- 
   Summary: Scaling error in decimal floating-point arithmetic blows
conversions to integers
   Product: gcc
   Version: 4.3.0
Status: UNCONFIRMED
  Severity: normal
  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=30992



[Bug c/30013] New: Multiple flaws in decimal floating-point arithmetic conversions fixed

2006-11-28 Thread beebe at math dot utah dot edu
)(_Decimal128)(%.21Lg) = %.21Lg = %La\n, x,
(long double)y, (long double)y);

(void)printf(\n);

y = (long double)(float)(_Decimal32)x;
(void)printf( (long double)(float)(_Decimal32)(%.21Lg) = %.21Lg = %La\n,
x, y, y);

y = (long double)(float)(_Decimal64)x;
(void)printf( (long double)(float)(_Decimal64)(%.21Lg) = %.21Lg = %La\n,
x, y, y);

y = (long double)(float)(_Decimal128)x;
(void)printf((long double)(float)(_Decimal128)(%.21Lg) = %.21Lg = %La\n,
x, y, y);

(void)printf(\n);

y = (long double)(double)(_Decimal32)x;
(void)printf( (long double)(double)(_Decimal32)(%.21Lg) = %.21Lg = %La\n,
x, y, y);

y = (long double)(double)(_Decimal64)x;
(void)printf( (long double)(double)(_Decimal64)(%.21Lg) = %.21Lg = %La\n,
x, y, y);

y = (long double)(double)(_Decimal128)x;
(void)printf((long double)(double)(_Decimal128)(%.21Lg) = %.21Lg = %La\n,
x, y, y);

(void)printf(\n);

y = (long double)(_Decimal32)x;
(void)printf( (long double)(_Decimal32)(%.21Lg) = %.21Lg = %La\n, x, y,
y);

y = (long double)(_Decimal64)x;
(void)printf( (long double)(_Decimal64)(%.21Lg) = %.21Lg = %La\n, x, y,
y);

y = (long double)(_Decimal128)x;
(void)printf((long double)(_Decimal128)(%.21Lg) = %.21Lg = %La\n, x, y,
y);
}

int
main(int argc, char* argv[])
{
test(3.141592653589793238462643383279502884L);

return (EXIT_SUCCESS);
}


-- 
   Summary: Multiple flaws in decimal floating-point arithmetic
conversions fixed
   Product: gcc
   Version: 4.3.0
Status: UNCONFIRMED
  Severity: normal
  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=30013