Hi LLVM hackers, when switching one of our projects to LLVM we discovered some strange behavior. We tracked the issue down to the following test case: int main() { double v = 0.84711; int r; __asm__("fistl %0": "=m"(r) : "t"(v)); return r; } The (relevant) clang generated asm looks like this: fldt 0.84711 ## InlineAsm Start fistl -4(%ebp) ## InlineAsm End The compiler is loading the constant into the top fpu stack register (as requested by "t" constraint) and then is executing the asm statement. The asm statement doesn't pop the value from the fp stack. Running this statement in a loop will quickly result in a fp stack overflow. As i'm not a real inline asm expert i'm wondering who is supposed to clean up the mess. There is a section in the gcc manual dealing with situations like this: http://gcc.gnu.org/onlinedocs/gcc-4.6.1/gcc/Extended-Asm.html#Extended-Asm (Section 6.41.2 i386 floating point asm operands) According to that page i would assume that it is the job of the compiler to handle the stack usage since the asm doesn't modify the fpu stack and we also didn't mark it as clobbered. Same code compiled with gcc-4.2: fldl 0.84711 fistl -4(%ebp) fstp %st(0) This seems fine and works as expected. Changing the inline asm to __asm__("fistl %0": "=m"(r) : "t"(v) : "st"); // Marking fpu top stack as clobbered Will result in the same output for gcc-4.2 and clang: fldt 0.84711 ## InlineAsm Start fistl -4(%ebp) ## InlineAsm End This code seems fine, of course it doesn't work but is exactly what was requested. The issue can we worked around by using the following asm statement: __asm__("fistpl %0": "=m"(r) : "t"(v) : "st"); which actively pops the value from the stack but i really would like to understand (and fix) the root of the problem and not tamper some band aid over it. I'm happy to file a bug if someone can confirm that my inline asm understanding is right and we're indeed talking about a compile issue here. Thanks a lot for your help! Best, Florian
On Aug 31, 2011, at 12:28 AM, Florian Schirmer wrote:> Hi LLVM hackers, > > when switching one of our projects to LLVM we discovered some strange behavior. We tracked the issue down to the following test case: > > int main() > { > double v = 0.84711; > int r; > > __asm__("fistl %0": "=m"(r) : "t"(v)); > > return r; > } > > The (relevant) clang generated asm looks like this: > > fldt 0.84711 > ## InlineAsm Start > fistl -4(%ebp) > ## InlineAsm EndThis has been fixed in SVN trunk. /jakob
Reasonably Related Threads
- More BeOS woe
- [LLVMdev] Feature request for include llvm-mc in llvm.org/builds
- [LLVMdev] Feature request for include llvm-mc in llvm.org/builds
- [LLVMdev] LLVM-GCC generating too much code from inline assembly
- [LLVMdev] LLVM-GCC generating too much code from inline assembly