You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The AArch64 (née ARM64) backend fails many tests when self-hosting at -O0. The issue appears to be over who takes responsibility for extending bool types and by how much.
The AAPCS could really do with a clarification note here, but my interpretation is that (unlike all other types), the caller should extend it to 1 byte (i.e. ensure that the low byte is either 0 or 1). The callee is responsible for any junk in the higher bits (as with i8, i16 and small structs).
On Darwin, of course, the caller needs to extend to the full 32-bits, as with other types.
Looking at the LangRef, I think this means two things need to happen:
Preferably Clang should mark i1 arguments as "zeroext", so that LLVM makes sure the caller does so "to the extent required by the target’s ABI" (tautological as that is). Both ABIs do require extension of some kind for this type.
LLVM needs to mark i1 arguments as extended to i8 on Linux, to i32 on Darwin.
There's some highly suspect code in LowerFormalArguments that looks like it may have been intended to deal with something like this but never triggers because of a miscommunication with AArch64CallingConv.h. The actual extension on Darwin platforms is taken care of by SelectionDAGBuilder.cpp.
I'll need to come up with a way to repurpose that code as neatly as possible. Currently it wants to produce a "CopyFromReg -> AssertZExt(i1) -> Trunc(i1)", but that wouldn't represent the AAPCS situation even if it did trigger (the AssertZExt node would extend to the full i32). We might want "CopyFromReg -> Trunc(i8) -> AssertZExt(i1)" instead, but I need to think.
The text was updated successfully, but these errors were encountered:
This entire "interface" is a nightmare. The way the generic code is written, it's virtually impossible to make "zeroext i1" extend to anything except i32. There's a partial override ("getTypeForExtArgOrReturn"), but it's only used in one of the 4 required paths, and adding it to the others wreaks havoc on x86.
I've got a patch working that gives a plain "i1" the correct semantics by manually inserting sensible TRUNC/ZERO_EXTEND pairs in the required parts of AArch64ISelLowering.cpp. It's rather a hack, but gives the required semantics for both AAPCS and Darwin.
I'll think a little bit more about a clean approach, but I'm not very hopeful.
I think I'm going to go with my co-option of plain "i1". With enough hand-waving you can argue that "zeroext" should only apply to constraints that are beyond a base assumption (I'm not convinced myself, either!).
But the key factor is that the on average the DAG looks better with that solution than any permutation I can even theoretically produce using "zeroext", ignoring any practicality concerns. It seems the DAG can't express what we want well enough to get good code out.
Another thing to think about again when GlobalISel comes along, I think.
Extended Description
The AArch64 (née ARM64) backend fails many tests when self-hosting at -O0. The issue appears to be over who takes responsibility for extending bool types and by how much.
The AAPCS could really do with a clarification note here, but my interpretation is that (unlike all other types), the caller should extend it to 1 byte (i.e. ensure that the low byte is either 0 or 1). The callee is responsible for any junk in the higher bits (as with i8, i16 and small structs).
On Darwin, of course, the caller needs to extend to the full 32-bits, as with other types.
Looking at the LangRef, I think this means two things need to happen:
Preferably Clang should mark i1 arguments as "zeroext", so that LLVM makes sure the caller does so "to the extent required by the target’s ABI" (tautological as that is). Both ABIs do require extension of some kind for this type.
LLVM needs to mark i1 arguments as extended to i8 on Linux, to i32 on Darwin.
There's some highly suspect code in LowerFormalArguments that looks like it may have been intended to deal with something like this but never triggers because of a miscommunication with AArch64CallingConv.h. The actual extension on Darwin platforms is taken care of by SelectionDAGBuilder.cpp.
I'll need to come up with a way to repurpose that code as neatly as possible. Currently it wants to produce a "CopyFromReg -> AssertZExt(i1) -> Trunc(i1)", but that wouldn't represent the AAPCS situation even if it did trigger (the AssertZExt node would extend to the full i32). We might want "CopyFromReg -> Trunc(i8) -> AssertZExt(i1)" instead, but I need to think.
The text was updated successfully, but these errors were encountered: