<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/85417>85417</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
LLVM 17.0.6 Win64 calling convention wrong for Windows x64 ABI
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
Bob64375
</td>
</tr>
</table>
<pre>
LLVM 17.0.6 generates incorrect return instructions on Windows x64 when a
composite is returned. Refer to the below example.
When calling `F` from Visual Studio x64 compiled code, CL passes in `rcx` the
address of `_rslt`. When `F` is compiled by LLVM, with `CallingConv::Win64`,
and, since the function returns a composite, `void` is passed as the return
type to `Function::Create` and the real (composite) return type is passed
through attribute `StructRet` via.
`function->addRetAttrs(AttrBuilder(cntxt).addStructRetAttr(the `Return` type))`,
see IR code below which reflects this, LLVM ignores the Windows x64 ABI
and generates instructions that return `a` and `b` in registers.
The issue is in `FunctionLoweringInfo.cpp` in method `set` around line 92:
GetReturnInfo(CC, Fn->getReturnType(), Fn->getAttributes(), Outs, *TLI,
mf.getDataLayout());
CanLowerReturn =
TLI->CanLowerReturn(CC, *MF, Fn->isVarArg(), Outs, Fn->getContext());
which sets `CanLowerReturn` true, and that is incorrect.
`CanLowerReturn` must be false, in which case, LLVM does indeed generate the
correct instructions that copy the return through the pointer in `rcx`.
A solution is to pass to `CanLowerReturn`
`Fn->hasRetAttribute( Attribute::StructRet )` so that the
target `Win64` machine can decide not to lower, or, better still, pass `Fn` so
the target has more leeway to decide. Best of all would be if there were not
two different mechanisms for making the return type known to `Function`.
**************************************************************************
struct Return { long long a; long long b; };
*****Compiled by Visual Studio x64:
Return _rslt( F( nullptr, 0 ) );
***** LlVm 17.0.6: IR
Return F( void*, int )
{
Return rtn = { 0, 1 };
return rtn;
}
define dllexport win64cc sret({ i64, i64 }) void @"F@ "(ptr %"P", ptr %"Q") {
entry:
%"P1" = alloca ptr, align 8
%"Q2" = alloca ptr, align 8
%"rtn" = alloca { i64, i64 }, align 8
store ptr %"P", ptr %"P1", align 8
store ptr %"Q", ptr %"Q2", align 8
store { i64, i64 } { i64 0, i64 1 }, ptr %"rtn", align 8
%"rtn" = load { i64, i64 }, ptr %"rtn", align 8
ret { i64, i64 } %"rtn"
}
**************************************************************************
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzcV12P4joS_TXmpTQoOCHAAw9AL6uWGO0O0-p5XJm4SLxjbGQ7TfPvV2UnfDS9o7kPV1e6LWQ6iavq1KlT5SC8V7VBnLPxko2fBqINjXXzpd2VRT4ZD3ZWnuebzetXGE2G2bCEGg06EdCDMpV1DqsADkPrDCjjg2uroKzxYA38UEbak4f3soBTgwYEy55Ytqjs4Wi9CgjKd7Yoh7DFPToIFkKDsENtT4Dv4nDUOEx2af1BniqhtTI1sDJbszKDvbMHeFW-FRq-h1YqG6NSJKVRQmUlMr6C1QaOwvuInoxd9U7mocHkXEjp0Huwe3r6H-d1YGU2hBi0D6b81fHuDMQO-T6p0NCeVcK2suaN5QuWL34oUxaszBhfdVGMJAOvTIUx231rIm0dGx4EXEiinazM3qySXfCYgQTho20ySY7D-YjEICHtXCYIK4ciINkLIzszoYHx6U2cWV_I6OYSqHPdONvWDYgQnNq1ASnI91jvLRJJ8KZEX6gy6zP6wvJ_CCm3GBYhOM_4lL6XrdISHYU34T0wPhsKKS_eaAvjU4LJymybEqQynY8Ekz43bHpEeN7GEneyOTWqasDhXmMViCXlicUoY1Ub6zBRdyvQxfL5Upw7kd9oOjTiInZWZqLnk5XZLtaGClgrH9D5O82-NMSnbyOrSXl9fTb2hE6Z-tns7bA6Hjs_BwyNjZ59Ylc42xoJWhmEGaeq3vj_J4bEEnlhfLpaUb7ryH7dP3uJ7E0jgTcPF31B_fXhv9oQGWN88bJ5vjANh_2wxvAkgtiIs21DbzFj-TJtWYmU0bZjKX_qTOPfy-aZot5vuuBlfPF1fcWm_KtwC1c_wrpgX1kT8P0TGGlNOvAYfOrLu6ikJ9fG9ko9IUKqTjfVrlp-NDy0PsAOYS-0jx6U6URXiXQjak3aqCCJeJXUddb00_NRYpU9nm96G_reo1tHq0xAdze_OqgL8Fa3cY4oT2OA-rcbBw85dGUhJUY2G-G3N2JgfArXizhDLu0JqQHB2wT3klEQrqbHZdaPPDiIqiHJVsKAxEpJBGMDgdIEh6iycd1hoLR8UFrTdcQe0aVQ_RRC6KI0wsPBOgSNeBJncpkCDGGJPtAIF1rDybZaUq3UnoA6hBMtxobO48mCVPs9OjQBDlg1wih_8LC3Dg7iJ50yt6Wg0fjT2JP5OGcvZehW_rf-3GSa1At9x0-WoK2p0yJYfnu5o0s2efrQpx-cr24O14cz_cPk66Kmk5pPYU2LabU-hiirjMQKj6PhQ0jY6NdD94rD8gU8bz8JEn3Hc5hsqOlTK6Sdk2U_6brtLsT5Fxmh0wpGn6Te68oFc30yebrdInFPHSS1xvejdQFO1FxVBd5hHH2TJaiyiIjKIsbgs4gTWJExztesIBo449NjcMD4mHH-73hjBdc73-KdGVwyQRPc-cI39IYjxnlMTGhtKwEd00Kr2sD0fvM3_gc2Ewf3uz9L7cHYB5oCv8osQv4Ny2-PnPBfWT7C62-lgtM_ox711WnK83do0FbI_0PCb7hzNIs_gXhr9Zng_vrp8md-BnKey1k-EwOcjyajbDyalEU-aOYzgVNRTfPJvpTjcVEWUpSi4PlYillWcByoOc94keWj8WhcTHg-nI7GWMxkmU9lPhrNKlZkeBBKD7V-OwytqwfxpW8-HRejyUCLHWoff2hxbvCU3gipCOOngZuTzZddW3tWZFr54K9eggoa736FxfP18iuosuYNTTz4T47mLJ1dH15uB63T8yaEo6eO5mvG17UKTbsbVvbA-JqCdV9fjs7-F6vA-DpC9IyvYwr_CwAA__-n7BU7">