This is an archive of the discontinued LLVM Phabricator instance.

[compiler-rt][builtins] XFAIL tests involving complex divide for ARM hard float targets
AbandonedPublic

Authored by peter.smith on Jul 3 2017, 8:29 AM.

Details

Summary

The check-builtins is failing 3 tests on a v7 armhf target:

  • divtc3_test.c
  • divdc3_test.c
  • divxc3_test.c
  • mulsc3_test.c (already marked UNSUPPORTED, but for the same underlying cause)

Clang is always using the soft float calling convention for implicit calls to the complex divide functions, such as in the expression used to detect whether test results are within a reasonable tolerance:

if (cabsl((r - z)/r) > 1.e-6) ...

This gives an incorrect result for the hard float calling convention as the builtin function in compiler-rt (or libgcc) is expecting hard float. I think that this is clang/llvm https://bugs.llvm.org/show_bug.cgi?id=28164 . Given that the compiler-rt builtin is working correctly and the problem is in clang/llvm, I think the tests should be marked as XFAIL.

A possible alternative is to not use the divide operator in (r-z)/r and instead call out to a function that evaluates the division without calling a complex divide builtin. I've prototyped this and the tests all pass, but such an implementation wouldn't have caught the problem in 28164.

As an aside the divsc3_test doesn't use the expression above to check the result of __divsc3, instead it uses if (r != z), which I guess is a bit inconsistent with the other complex divide routines but doesn't seem to be causing any problems right now.

Diff Detail

Event Timeline

peter.smith created this revision.Jul 3 2017, 8:29 AM
compnerd edited edge metadata.Jul 4 2017, 11:32 AM

The generation of the soft float calls to the GNU division routines is for compatibility. GCC will generate soft float calls unless the target is marked as hf. So, we should adjust the triple that we use (-target armv7-unknown-none-eabihf -meabi=gnu should do the trick I believe). GCC's handling of the ABI here is really rather annoying since -target armv7-unknown-none-eabi -meabi=gnu -mfloat-abi=hard will generate soft float calls to the routines, but -target armv7-unknown-none-eabihf -meabi=gnu -mfloat-abi=soft will generate hard float calls. However, we need to emulate the silly behaviour for compatibility.

Thanks very much for the comment, I'm not sure that I've understood it correctly though as I'm not sure whether the command line options in the comment are clang or gcc options. I think that they are clang?

I think that this particular case is deeper than compatibility with gcc. There is no set of non-darwin command line options to get clang/llvm to use hard-float calls to the complex helper functions. Clang marks these calls as explicitly aapcs so they will always be called using a soft-float calling convention (http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20141201/119292.html). GCC will use a hard-float calling convention with a hard-float target such as arm-linux-gnueabihf. Or arm-none-eabi-gcc with something like -mfloat-abi=hard -mcpu=cortex-m4. As it stands at the moment I think clang can't be used with _Complex and a hard float compiled compiler-rt or libgcc

I'm intending to post a patch for clang to match the gcc behaviour, if this is accepted then there won't be any need to xfail these tests.

Please let me know if I've misunderstood?

peter.smith abandoned this revision.Jul 28 2017, 3:18 AM

Abandoning this change as D35538 makes this unnecessary.