<div dir="ltr">Hi,<div><br></div><div>I've run into a compatibility issue with the calling convention of the runtime library (libgcc/compiler-rt) functions on ARM with hard floating point. Clang passes the floating point arguments in integer registers (like with -mfloat-abi=soft), but GCC calls them like other functions with the hard-float ABI. The only reference to this I can find online is <a href="http://lists.llvm.org/pipermail/llvm-dev/2014-October/077898.html">this LLVM development mailing list post</a> discussing why Clang switched to always using soft-float. At least one of the Clang developers thought GCC did this too, but it doesn't seem to currently. Complex arithmetic is implemented with these functions even when hardware floating point is supported, which means complex arithmetic is pretty completely broken on platforms like this when using libgcc.</div><div><br></div><div>I found the code in clang's lib/CodeGen/TargetInfo.cpp which sets BuiltinCC to CallingConv::ARM_AAPCS and the __attribute__((pcs("aapcs"))) in compiler-rt's lib/builtins/int_lib.h which compiles the relevant functions that way. I can't find any evidence of GCC doing either of those.</div><div><br></div><div>In all three copies of libgcc.a I've disassembled (Debian Jessie armhf and both of the ones from gcc-linaro-4.9-2015.05-x86_64_arm-linux-gnueabihf) __divdc3 (for example) definitely uses the hard-float ABI. In clang+llvm-3.8.0-armv7a-linux-gnueabihf/lib/clang/3.8.0/lib/linux/libclang_rt.builtins-armhf.a (downloaded from <a href="http://llvm.org">llvm.org</a>), __divdc3 is definitely using the soft-float ABI.</div><div><br></div><div>I wrote up a simple test program to demonstrate the effects:</div><div><div>$ cat test_complex.c </div><div>#include <complex.h></div><div>#include <stdio.h></div><div><br></div><div>int main(int argc, char **argv) {</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>double complex two = 2.0 + 0.0 * I;</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre"> </span>// Prevent GCC from just optimizing all the math out.</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>if (argv[0] == '\0') {</div><div><span class="Apple-tab-span" style="white-space:pre">               </span>two += 1.0;</div><div><span class="Apple-tab-span" style="white-space:pre">  </span>}</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">   </span>double complex result = two / two;</div><div><span class="Apple-tab-span" style="white-space:pre">   </span>if (creal(result) > 1.5) {</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>printf("broken\n");</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>} else {</div><div><span class="Apple-tab-span" style="white-space:pre">             </span>printf("works\n");</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>}</div><div>}</div></div><div><div>$ gcc -lm test_complex.c -O3 && ./a.out</div><div>works</div></div><div><div>$ clang -lm test_complex.c -O3 && ./a.out</div><div>broken</div></div><div><br></div><div>I've tried with Clang 3.7.1 I cross-compiled for armhf myself and 3.8.0 binaries downloaded from <a href="http://llvm.org">llvm.org</a>.</div><div><br></div><div>I'm pretty sure using clang with libgcc is supposed to work, so this seems like a bug. <span style="line-height:1.5">Is there some solution I'm not seeing?</span></div><div><br></div><div>Thanks in advance,</div><div>Brian Silverman</div></div>