https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64540

            Bug ID: 64540
           Summary: [4.9 regression] Casting to/from long double emits
                    ambiguous fild/fisttp instruction
           Product: gcc
           Version: 4.9.2
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: driver
          Assignee: unassigned at gcc dot gnu.org
          Reporter: zanpeeters at gmail dot com

Created attachment 34401
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=34401&action=edit
Minimal code example

GCC 4.9.2 emits a fild instruction for a cast of signed char, unsigned char, or
signed short (but not unsigned short) to long double. For the reverse cast a
fisttp instruction is emitted.

Minimal code example:

int main()
{
  unsigned char a = 0;
  long double d = 0.0;

  d = (long double)a;

  return 0;
}

On a Mac, compiling this minimal code with -Wa,-q (send -q to the assembler,
which then uses the clang built in assembler rather than as) generates the
following error:

> gcc -Wa,-q minexmpl.c
/var/folders/Dc/DcfDPTBiHROi8AvxZY9-HE+++TI/-Tmp-//cc7UuOqP.s:16:2: error:
ambiguous instructions require an explicit suffix (could be 'filds', or
'fildl')
        fild    -34(%rbp)

GCC 4.8.3 emits filds/fisttps instructions for the same code and does not
generate an error when send to the clang assembler. Since GCC 4.8.3 emitted the
correct instructions this seems a regression to me. Any particular reason this
change was made?

Attached is a complete minimal code example with all casting combinations that
lead to errors. On any OS (also non-Mac):

> gcc-4.9 -S -o out49.s fild_fisttp.c
> gcc-4.8 -S -o out48.s fild_fisttp.c
> diff -u out48.s out49.s
--- out48.s
+++ out49.s
@@ -14,25 +14,25 @@
    fstpt       -32(%rbp)
-   filds       -4(%rbp)
+   fild        -4(%rbp)
    fstpt       -32(%rbp)
    fldt        -32(%rbp)
-   fisttps     -34(%rbp)
+   fisttp      -34(%rbp)
    movzwl      -34(%rbp), %eax
(truncated for brevity, full diff below)

Note 1:
Not accepting fild, fisttp, and others is a design choice by LLVM, see
http://clang.llvm.org/compatibility.html#inline-asm  I have tested the above
minimal code example with Apple clang 3.0/XCode 4.2, Macports clang 3.3, and
Macports clang 3.5 and all give the same result.

Note 2:
The reason for using the clang assembler is that the as assembler on Mac is
very old and does not accept AVX or newer instructions, as explained here:
https://stackoverflow.com/questions/9840207/how-to-use-avx-pclmulqdq-on-mac-os-x-lion

=====================

Other information:

System: Mac OS X 10.6.8

gcc version 4.9.2 (MacPorts gcc49 4.9.2_1)
Using built-in specs.
COLLECT_GCC=gcc-mp-4.9
COLLECT_LTO_WRAPPER=/opt/local/libexec/gcc/x86_64-apple-darwin10/4.9.2/lto-wrapper
Target: x86_64-apple-darwin10
Configured with:
/opt/local/var/macports/build/_Users_zan_Library_Macports_lang_gcc49/gcc49/work/gcc-4.9.2/configure
--prefix=/opt/local --disable-silent-rules --build=x86_64-apple-darwin10
--enable-languages=c,c++,objc,obj-c++,lto,fortran,java
--libdir=/opt/local/lib/gcc49 --includedir=/opt/local/include/gcc49
--infodir=/opt/local/share/info --mandir=/opt/local/share/man
--datarootdir=/opt/local/share/gcc-4.9 --with-local-prefix=/opt/local
--with-system-zlib --disable-nls --program-suffix=-mp-4.9
--with-gxx-include-dir=/opt/local/include/gcc49/c++/ --with-gmp=/opt/local
--with-mpfr=/opt/local --with-mpc=/opt/local --with-isl=/opt/local
--disable-isl-version-check --with-cloog=/opt/local
--disable-cloog-version-check --enable-stage1-checking --disable-multilib
--enable-lto --enable-libstdcxx-time --with-as=/opt/local/bin/as
--with-ld=/opt/local/bin/ld --with-ar=/opt/local/bin/ar
--with-bugurl=https://trac.macports.org/newticket --with-pkgversion='MacPorts
gcc49 4.9.2_1'
Thread model: posix

gcc version 4.8.3 (MacPorts gcc48 4.8.3_2)
COLLECT_GCC=gcc-mp-4.8
COLLECT_LTO_WRAPPER=/opt/local/libexec/gcc/x86_64-apple-darwin10/4.8.3/lto-wrapper
Target: x86_64-apple-darwin10
Configured with:
/opt/local/var/macports/build/_Users_zan_Library_Macports_lang_gcc48/gcc48/work/gcc-4.8.3/configure
--prefix=/opt/local --disable-silent-rules --build=x86_64-apple-darwin10
--enable-languages=c,c++,objc,obj-c++,lto,fortran,java
--libdir=/opt/local/lib/gcc48 --includedir=/opt/local/include/gcc48
--infodir=/opt/local/share/info --mandir=/opt/local/share/man
--datarootdir=/opt/local/share/gcc-4.8 --with-local-prefix=/opt/local
--with-system-zlib --disable-nls --program-suffix=-mp-4.8
--with-gxx-include-dir=/opt/local/include/gcc48/c++/ --with-gmp=/opt/local
--with-mpfr=/opt/local --with-mpc=/opt/local --with-cloog=/opt/local
--enable-cloog-backend=isl --disable-cloog-version-check
--disable-isl-version-check --enable-stage1-checking --disable-multilib
--enable-lto --enable-libstdcxx-time --with-as=/opt/local/bin/as
--with-ld=/opt/local/bin/ld --with-ar=/opt/local/bin/ar
--with-bugurl=https://trac.macports.org/newticket --with-pkgversion='MacPorts
gcc48 4.8.3_2'
Thread model: posix

==========================
Diff output

--- fild_fisttp48.s    2015-01-08 19:21:11.000000000 +0000
+++ fild_fisttp49.s    2015-01-08 19:20:50.000000000 +0000
@@ -14,25 +14,25 @@
     movq    %rax, -32(%rbp)
     movl    %edx, -24(%rbp)
     movzbl    -1(%rbp), %eax
-    movw    %ax, -34(%rbp)
-    filds    -34(%rbp)
+    movw    %ax, -36(%rbp)
+    fild    -36(%rbp)
     fstpt    -32(%rbp)
     movsbw    -2(%rbp), %ax
-    movw    %ax, -34(%rbp)
-    filds    -34(%rbp)
+    movw    %ax, -36(%rbp)
+    fild    -36(%rbp)
     fstpt    -32(%rbp)
-    filds    -4(%rbp)
+    fild    -4(%rbp)
     fstpt    -32(%rbp)
     fldt    -32(%rbp)
-    fisttps    -34(%rbp)
+    fisttp    -34(%rbp)
     movzwl    -34(%rbp), %eax
     movb    %al, -1(%rbp)
     fldt    -32(%rbp)
-    fisttps    -34(%rbp)
+    fisttp    -34(%rbp)
     movzwl    -34(%rbp), %eax
     movb    %al, -2(%rbp)
     fldt    -32(%rbp)
-    fisttps    -4(%rbp)
+    fisttp    -4(%rbp)
     movl    $0, %eax
     popq    %rbp
 LCFI2:

Reply via email to