[cfe-dev] X86_64 ABI - Non-determiistic coersion
Nickolas Pohilets via cfe-dev
cfe-dev at lists.llvm.org
Sat Jun 18 11:33:59 PDT 2016
In the case of the following enum, result of coersion depends on the order
of union elements, which IMHO, is counter intuitive.
typedef union {
void* INT[2];
long double X87_X87UP;
double SSE;
} InReg;
InReg in_reg(InReg x) { return x; }
typedef union {
long double X87_X87UP;
double SSE;
void* INT[2];
} InMem;
InMem in_mem(InMem x) { return x; }
In IR these functions have the following signatures and are binary
incompatible:
define { i64, i64 } @in_reg(i64 %x.coerce0, i64 %x.coerce1)
define void @in_mem(%union.InMem* noalias sret %agg.result, %union.InMem*
byval align 16 %x)
This does not conflict with ABI specification, because the later does not
specify order in which union elements should be visited.
Do you think this is a real problem that is worth fixing in the ABI?
It is possible to fix this in the ABI by:
a) formalizing order in which fields are visited
b) changing merging and post-processing rules to have a consistent result
The first option is backward-compatible, the second allows to achieve
better performance of argument passing (I'm not expert in this field, but I
assume there are some performance concerns behind the current argument
classification rules).
Below is proposed algorithm to perform merging with consistent result:
To end up with { MEMORY, MEMORY } in the end:
- Add two more classes NO_SSE and NO_X87
- Merging INT with X87, X87_UP, COMPLEX_X87 results in NO_SSE
- Merging INT with SSE or SSEUP results in NO_X87
- Merging NO_SSE with SSE results in MEMORY
- Merging NO_X87 with X87, X87_UP or COMPLEX_X87 results in MEMORY
- Merging NO_SSE with NO_X87 cannot occur, because these classes may
appear only as a result of merging - no field may have a class of NO_???
- During post-merge phase NO_SSE and NO_X87 are replaced with INT
To end up with { INT, INT } in the end:
- Add one more class MAYBE_MEMORY
- Merging X87/X87_UP/COMPLEX_X87 with SSE/SSEUP results in MAYBE_MEMORY
- Merging MAYBE_MEMORY with INT results in INT
- During post-merge MAYBE_MEMORY is replaced with MEMORY
Thanks,
Nickolas
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20160618/a6cae085/attachment.html>
More information about the cfe-dev
mailing list