1. 12

  2. 1

    The assembly in ARC is actually pretty simple: it’s a no-op at the right point to tell the runtime that it can use the fast paths for returns. I think you can just strip this out and everything will work, just slower. In practice, you probably want to replace the instruction.

    That said, there are a lot more subtle issues in this kind of thing. LLVM IR leaks some details of the calling convention. If you go beyond a handful of integer / pointer arguments, the lowering of a complex [Objective-]C[++] call will be different between AArch64 and x86-64. If you compile both the caller and callees to bitcode for one and then to binary for the other, everything will work fine (though it won’t respect the language ABIs), but if the caller is compiled via this indirect path and the callee is compiled directly (e.g. as a system framework), then you’ll get mismatch.

    You’ll also see some more subtle differences where Apple used the fact that there were no legacy iOS binaries and so took the opportunity (as they did with PowerPC64, x86-32, and x86-64) to clean up legacy compatibility fields in a few structures. LLVM IR doesn’t know anything about these. The core problem here is nothing to do with LLVM and is really a C issue: once C code has run through the preprocessor, it is no longer architecture or platform agnostic. Headers are full of things like #ifdef __LP64__ or #ifdef __arm__ that will generate different sequences of tokens for the C compiler to consume.

    This kind of thing is trivial to get working for simple cases, but rapidly hits problems and has a very long tail of corner cases that are incredibly hard to get right.