Issues with signext i1 on aarch64

My group is doing translation validation for the AArch64 backend, and we’ve run into an issue where we’re not sure what obligations are placed on a function that returns a signext i1.

Before getting into signext, my understanding is that a compiled AArch64 function returning a regular i1 (that is, an i1 without signext or zeroext) must return either 0x00 or 0x01 in the bottom byte of the return register, and the other 7 bytes are unspecified. This requirement comes from AAPCS.

Ok, now on to signext i1. One one hand, one might argue that first we apply the implicit zeroext to i8 and then we apply the signext. In this interpretation, a function returning signext i1 must return either 0x00000000 or 0x00000001 in the bottom 32 bits of the return register, with the top half containing unspecified. This may or not be what we want, but it’s what we assumed here:

On the other hand, we might argue (as @miyuki does in the issue above) that the explicit signext takes priority over the implicit zeroext, in which case a function returning signext i1 must return either 0x00000000 or 0xffffffff in the bottom half of the return register, with the top half again being unspecified.

The existing documentation, as far as I can tell, doesn’t really help us choose one of these, so let’s choose the one that is either easiest to converge on or else results in the best codegen. Then of course let’s document the choice.

alternatively, if we don’t feel like assigning a semantics to signext i1, we can make it illegal. I tried out adding this constraint to the module verifier and the resulting llvm+clang can bootstrap itself. this is hardly conclusive but it suggests that at least clang doesn’t emit signext i1 much. of course there are test failures, but the ones I looked at were code that contains explicit signext i1, so those would simply get deleted.

1 Like

At the very least it’ll give us an idea of who uses it and for what. I cannot think of a good (even bad reason).

But I think that an explicit signext being trumped by an implicit zeroext is asking for baffled posts here. An error is much simpler to explain, accept and fix later, if there’s a better idea.