Open llvmbot opened 4 years ago
You are right, looks like this is the problem. The calling convention for AMD64 says so, too:
https://en.wikipedia.org/wiki/X86_calling_conventions#System_V_AMD64_ABI
I tested it with this program:
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
union N {
double d;
uint64_t u;
};
int main(int argc, char*argv[])
{
union N x;
union N y;
union N z;
x.d = 2.0;
y.d = 3.0;
z.d = x.d * y.d;
printf("%"PRId64"\n", z.u);
printf("%f\n", z.d);
return 0;
}
and it prints this:
4618441417868443648
0.000000
I verified that the first number is the representation for the double float value 6, so it does at least the calculation.
I think this is a bug in CLANG, because when compiling it without the "-mno-sse", it places it in the XMM0 value, so CLANG knows that it has to place it in this register. If I specify that not XMM registers should be used, then it should abort with an error, because it can't place the value in this register anymore.
But I also noticed that it still generates fmul. Is this right? I thought with "-msoft-float" it shouldn't use the FPU instructions. This is the full main function, disassembled with "objdump -d":
0000000000401130 <main>:
401130: 55 push %rbp
401131: 48 89 e5 mov %rsp,%rbp
401134: 48 83 ec 30 sub $0x30,%rsp
401138: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%rbp)
40113f: 89 7d f8 mov %edi,-0x8(%rbp)
401142: 48 89 75 f0 mov %rsi,-0x10(%rbp)
401146: 48 be 00 00 00 00 00 movabs $0x4000000000000000,%rsi
40114d: 00 00 40
401150: 48 89 75 e8 mov %rsi,-0x18(%rbp)
401154: 48 be 00 00 00 00 00 movabs $0x4008000000000000,%rsi
40115b: 00 08 40
40115e: 48 89 75 e0 mov %rsi,-0x20(%rbp)
401162: dd 45 e8 fldl -0x18(%rbp)
401165: dd 45 e0 fldl -0x20(%rbp)
401168: de c9 fmulp %st,%st(1)
40116a: 48 89 e6 mov %rsp,%rsi
40116d: dd 1e fstpl (%rsi)
40116f: bf 04 20 40 00 mov $0x402004,%edi
401174: 31 c0 xor %eax,%eax
401176: 88 c1 mov %al,%cl
401178: 88 c8 mov %cl,%al
40117a: e8 b1 fe ff ff callq 401030 <printf@plt>
40117f: 31 d2 xor %edx,%edx
401181: 89 45 dc mov %eax,-0x24(%rbp)
401184: 89 d0 mov %edx,%eax
401186: 48 83 c4 30 add $0x30,%rsp
40118a: 5d pop %rbp
40118b: c3 retq
40118c: 0f 1f 40 00 nopl 0x0(%rax)
I think the problem is that printf doesn’t know about the soft float switch since it’s in a precompiled library. It expects to receive floating point data in an xmm register. But the soft float setting prevents the compiler from generating any code that uses an xmm register.
@llvm/issue-subscribers-backend-x86
Author: None (llvmbot)
Extended Description
When I compile this program:
with "clang -msoft-float -mno-sse -O0 test.c", it prints 0 instead of 6.
Output of clang --version:
clang --version clang version 7.0.1-8 (tags/RELEASE_701/final) Target: x86_64-pc-linux-gnu Thread model: posix InstalledDir: /usr/bin
I'm trying to use soft-float without any FPU or XMM registers, as it is e.g. possible on ARM.