Xcode 14.3 compiler bug

Once in a blue moon or two we stumble upon compiler bugs and after carefully ruling out that it’s our error (or maybe just differences between compilers) we confirm we really have one.
One of our tests started failing when we bumped to the HEAD of the develop branch of JUCE and updated to Xcode 14.3

After a lot of debugging I narrowed it down to a difference in result when calling Line<float>::findIntersection with certain inputs.

With even more debugging and messing around with the code I determined that this line was resulting in different results for some inputs than it used (the tests continue to pass on Windows with latest MSVC, btw).

I didn’t examine the produced assembler code (I don’t know any ARM) but I did find that if I split up the calculation then the old behaviour returned (an old trick I’ve used to work around compiler bugs before):

This now produces the old expected results:

      const auto s1 = p1.y - p3.y;
      const auto s2 = p1.x - p3.x;
      const auto m1 = s1 * d2.x;
      const auto m2 = s2 * d2.y;
      const auto s3 = m1 - m2;
      const auto along1 = s3 / divisor;

It would be extremely helpful for us if you would be willing add this work-around for the Xcode (clang?) bug*.
The results would be the same as they used to and it would not hurt anyone. We could even put some compile time checks against the version of the compiler if you would like to check if it’s fixed one day in the future? On request I can supply exact versions of the inputs that demonstrate the issue. Weirdly, it doesn’t happen if I isolate that calculation outside of this function, which strengthens the case that it’s a compiler bug.

  • It might not technically be a bug but some corner of the spec that allows for this difference. I’m no expert on such deep parts of the C++/ieee 754/ARM64 specs.
1 Like

Dumb question here: is this really a compiler bug, or is it more of an “I didn’t know that the compiler would optimize these codepaths differently because I just auto all the things …”

What happens to this code with different “-O” settings? Usually when you discover something like this, you should try different -O’s, to be sure the assumption you made about the scope of variables, auto or otherwise, are correct …

EDIT: do things behave differently if you add " * 1.0F " to the offending line?

1 Like

Oh I know it may it may not be a bug exactly :wink:

99.9% of time we think it might be it isn’t. But I leaned towards bug because the same exact line of code produces a different result (the old one) when I duplicated it in a standalone test. It’s the same in a debug build and O3 so not that. I wish I could isolate it from juce and submit to clang or Apple but haven’t been able to.

Regarding ‘auto’ I changed all instances of that in the juce code to ValueType (for the float types) and it didn’t help. Only breaking up the calculation on that line I linked into mathematically equivalent but separate lines returns the old behaviour.

Well that’s just a feature of floating point computations and compiler optimizations :slight_smile:
Do you “fast-math” or “Relax IEEE Compliance”?

No optimisations, no fast-math, just a new version of Xcode. That’s it.

1 Like

No, same. I’ve got a bit of a cold at the moment but once I recover I’ll try again to make a repo that demos the issue.