This change is part of the RegCall calling convention support for LLVM. Existing RegCall implementation was extended to include correct handling of Complex Long Double type. Complex long double types should be returned/passed in memory and not register stack. This patch implements this behavior.
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
Oren discovered this miss to the original implementation. I'd reviewed this internally quite a bit.
The reason for the Win32ABI test is that MSVC 'long double' is actually small enough for SSE registers in this case. I DO now (looking again, sorry Elizabeth) wonder if there is a better way to exclude extended-length LongDouble type? Could we us the 'length' of it instead? @rnk : opinion?
Yeah, you can ask clang::TargetInfo for the format of most basic FP types. The code to do that looks like:
&TI.getLongDoubleFormat() == &llvm::APFloat::x87DoubleExtended()
Any reason you can't just add that condition to isX86VectorTypeForVectorCall? I assume we don't want to pass x86_fp80s in SSE registers for vectorcall either, right? That would eliminate the need for the isRegCallReturnableHA helper and the IsWin32StructABI parameter, which is a poorly named variable.
It actually WOULD make sense to apply this to vectorcall as well, wouldn't it? I presumed we didnt want to change its behavior, however vectorcall is MSVC-only (other than us), so the long-double issue isn't a thing over there.@eandrews?
I can apply this condition to isX86VectorTypeForVectorCall like Reid suggested. The only reason I did not do that originally was because I wasn't sure how to differentiate between the calling conventions without changing function declaration. If I don't need to explicitly differentiate between RegCall and VectorCall and can use the 'length' instead, I think this works better. Like Reid mentioned, it would eliminate the need for isRegCallReturnableHA and IsWin32StructABI.
As per revision comments, I moved the condition for extended precision floating type to isX86VectorTypeForVectorCall. This update will now alter behavior for complex long double type under vectorcall calling convention as well. Returns/parameters will be passed in memory.
lib/CodeGen/TargetInfo.cpp | ||
---|---|---|
3516 ↗ | (On Diff #107343) | This is incorrect. We should consult the CXXABI first, and then only do these regcall-specific things if it returns false. Consider adding this test case to find the bug: struct NonTrivial { int x, y; ~NonTrivial(); }; NonTrivial __regcall f() { return NonTrivial(); } This should not return in registers, but it does today. |
3526 ↗ | (On Diff #107343) | This isn't necessarily a bug, but please always do C++ ABI classifications first so it's easy to spot the bug above. |
Regcall-specific checks for Lin64 now occur only if CXXABI returns false. An existing test has also been modified to verify behavior with non trivial destructors.