keithw/mosh — pull request #268 by piannucci (2012-05-11 06:20:36+00:00)
Title: Wrap ARM NEON int8x16_t in a struct to work around bug in clang 3.1.

There is a limitation in the HEAD version of clang that blocks an iOS build. This patch makes a modest change to ocb.cc to work around the issue.

In particular, for ARM cores with the NEON SIMD instruction set extension, ocb.cc defines a block to be an int8x16_t vector type. The ARM Architecture Procedure Call Standard indicates that this containerized vector type should be returned by placing it in the vector co-processor's lowest-numbered registers, which is much more efficient than copying the vector over to the general-purpose registers when returning from a function, and then copying it back to the vector co-processor. Clang hits an assertion when trying to compile ocb.cc for iOS (which targets a thumbv7 ARM with NEON); it seems to expect returned vectors to be either a pair of doubles or else to fit in one register. This particular type fits in four registers. The assertion is in llvm/lib/Target/ARM/ARMFastISel.cpp in ARMFastISel::FinishCall.

The most straightforward solutions are to either wrap the OCB block typedef in a struct, invoking the struct return code path in clang (which works fine, but will be slow here), or to pass a reference to the block as an argument to the function. Of the two choices, passing a reference requires that we modify ocb.cc on all platforms, which is unfavorable.

This patch wraps the return type in a struct. It compiles with clang 3.1 and functions correctly on an iPhone 4 running iOS 5.0.1.