Bugzilla – Bug 879
[X86] No support for fp stack in inline asm
Last modified: 2008-03-11 14:50:35
You need to log in before you can comment on or make changes to this bug.
Hi there, I was compiling lame-3.95.1 with the new tar file llvm-1.8a.tar.gz and llvm-gcc4-1.8-source on Fedora Core 5. I wanted to check some timings for .wav to .mp3 encoding. The lame package compiles fine using llvm-gcc and -O0 but it dies using -O3 (which is the default opt level in the makefile). Gcc 4.0.3 works fine with all opt levels. Llvm-gcc dies on all opt levels, except -0O. The compilation goes through the mpglib subdirectory fine but it dies in the libmp3lame subdirectory with the following: snip.... llvm-gcc -DHAVE_CONFIG_H -I. -I. -I.. -I../include -I. -I../mpglib/ -I.. -Wall -pipe -O3 -MT VbrTag.lo -MD -MP -MF .deps/VbrTag.Tpo -c VbrTag.c -fPIC -DPIC -o .libs/VbrTag.o VbrTag.c: In function 'PutLameVBR': VbrTag.c:772: warning: pointer targets in passing argument 1 of '__builtin_strncpy' differ in signedness VbrTag.c: In function 'PutVbrTag': VbrTag.c:1000: warning: pointer targets in passing argument 2 of 'CRC_writeheader' differ in signedness cc1: SelectionDAGISel.cpp:2142: void llvm::SelectionDAGLowering::visitInlineAsm(llvm::CallInst&): Assertion `!Regs.Regs.empty() && "Couldn't allocate output reg!"' failed. VbrTag.c: At top level: VbrTag.c:1030: internal compiler error: Aborted snip... I don't know enough about llvm at present, to offer an intelligent guess as to why this is happening. Sorry ;) Lame source can be downloaded here: http://prdownloads.sourceforge.net/lame/lame-3.95.1.tar.gz Thanks, Kelly
Can you please attach a ".i" file, generated according to these instructions: http://llvm.org/docs/HowToSubmitABug.html#front-end Thanks, -Chris
Created an attachment (id=380) [details] Crashes llvm-gcc A .i file of the offending VbrTag.c file.
Here is a reduced testcase: double floor(double __x) { register long double __value; __volatile unsigned short int __cw; __volatile unsigned short int __cwtmp; __asm __volatile("fnstcw %0":"=m"(__cw)); __cwtmp = (__cw & 0xf3ff) | 0x0400; __asm __volatile("fldcw %0"::"m"(__cwtmp)); __asm __volatile("frndint":"=t"(__value):"0"(__x)); __asm __volatile("fldcw %0"::"m"(__cw)); return __value; } Basically this boils down to the fact that we don't support "t" constraints (fp stack) in inline asms. Unfortunately, I don't plan to implement this support in the near future, however, as a work-around, most linux distros allow you to compile with -D__NO_MATH_INLINES, which disables these. -Chris
Here's a testcase from redhat FC5 headers: double %intcoord(double %X) { %tmp85 = call double asm sideeffect "frndint", "={st},0,~{dirflag},~{fpsr},~{flags}"( double %X) ret double %tmp85 } It would be good to support the simple case of this at least. -Chris
This patch: http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20060821/037043.html was applied to work around this problem on x86/Linux. It needs to be undone once this bug is resolved.
*** Bug 871 has been marked as a duplicate of this bug. ***
*** Bug 921 has been marked as a duplicate of this bug. ***
*** Bug 937 has been marked as a duplicate of this bug. ***
Another simple testcase from Qt: inline double qCos_x86(double a) { double r; __asm__ ( "fcos" : "=t" (r) : "0" (a)); return r; }
Here are some testcases: double floor(double __x) { double __value; __asm ("frndint":"=t"(__value):"0"(__x)); return __value; } // This has two inputs and pops one. int test(double x, double y) { register char __result; __asm__ ("fucomip %%st(1), %%st; seta %%al" : "=a" (__result) : "u" (y), "t" (x) : "cc", "st"); return __result; } double test2(double __x) { double __value; __asm __volatile__("fscale" : "=t" (__value) : "0" (1.0), "u" (__x)); return __value; } Unfortunately, this won't happen for 1.9. -Chris
*** Bug 1051 has been marked as a duplicate of this bug. ***
*** Bug 1211 has been marked as a duplicate of this bug. ***
*** Bug 1272 has been marked as a duplicate of this bug. ***
akor, could you try adding something like this to i386.h: builtin_assert("__NO_MATH_INLINES"); Somewhere in TARGET_CPU_CPP_BUILTINS. This should eliminate the worst part of this problem until we can fix it right.
s/builtin_assert/builtin_define, sorry.
Ok. Will try.
I'm ok with the following patch: diff -r 4fe28e061ca4 gcc/config/i386/i386.h --- a/gcc/config/i386/i386.h Sun Mar 25 09:02:33 2007 +0000 +++ b/gcc/config/i386/i386.h Tue Mar 27 21:01:00 2007 +0400 @@ -746,8 +746,11 @@ extern int x86_prefetch_sse; { \ builtin_define ("__nocona"); \ builtin_define ("__nocona__"); \ - } \ - } \ + } \ + /*APPLE LOCAL begin LLVM PR879 workaround */ \ + builtin_define("__NO_MATH_INLINES"); \ + /*APPLE LOCAL end LLVM PR879 workaround */ \ + } \ while (0) #define TARGET_CPU_DEFAULT_i386 0 Btw, is it ok, that apple-related parts uses tabs for indentation?
Thanks Anton, applied: http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20070326/046493.html I think this should significantly reduce the pain of this bug for linux users.
Simple asms like that in Comment #9 now work: _qCos_x86: fldl 4(%esp) # InlineAsm Start fcos # InlineAsm End #FP_REG_KILL ret
(In reply to comment #19) > Simple asms like that in Comment #9 now work: Nice!
There are a bunch more examples here: http://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Extended-Asm
'f' now works. 'u' doesn't. 't' does, but probably not in combination with 'f' yet. Slow progress.