<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/80009>80009</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[AArch64] [Windows] Functions using SVE can fail "WinCFI not supported with SVE vectors"
</td>
</tr>
<tr>
<th>Labels</th>
<td>
backend:AArch64,
SVE
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
mstorsjo
</td>
</tr>
</table>
<pre>
Compiling AArch64 code that uses SVE features, for a Windows target, can seem to work at first, but fail later when functions become more complex.
This has been observed in libaom (https://aomedia.googlesource.com/aom), since https://aomedia.googlesource.com/aom/+/04b91c17bf976b0616ab94fa6cd36892d47e9ce5%5E%21/, when compiled for an aarch64-mingw target.
When the SVE functions end up needing to back up and restore SVE vectors, they trigger the failed "WinCFI not supported with SVE vectors" assert.
This can be triggered with this reduced code snippet from libaom:
```c
#include <arm_neon_sve_bridge.h>
int64x2_t a(int64x2_t acc, int16x8_t b, int16x8_t c) {
return svget_neonq_s64(svdot_s64(svset_neonq_s64(svundef_s64(), acc),
svset_neonq_s16(svundef_s16(), b),
svset_neonq_s16(svundef_s16(), c)));
}
void e();
int16x8_t d(uint16x8x2_t g) {
int16x8_t f[8];
e();
int16x8_t j = vextq_s16(g.val[0], g.val[1], 0);
int64x2_t i = a(vdupq_n_s64(0), j, f[0]);
int64x2_t l;
int64x2_t k = vpaddq_s64(i, l);
int64x2_t m;
int32x4_t n = vcombine_s32(vmovn_s64(k), vmovn_s64(m));
int32x4_t o;
return vcombine_s16(vmovn_s32(n), vmovn_s32(o));
}
```
```console
$ clang -target aarch64-windows-gnu -c repro.c -march=armv8-a+sve -O2
clang: ../lib/Target/AArch64/AArch64InstrInfo.cpp:5444: void llvm::emitFrameOffset(llvm::MachineBasicBlock&, llvm::MachineBasicBlock::iterator, const llvm::DebugLoc&, unsigned int, unsigned int, llvm::StackOffset, const llvm::TargetInstrInfo*, llvm::MachineInstr::MIFlag, bool, bool, bool*, bool, llvm::StackOffset, unsigned int): Assertion `!(NeedsWinCFI && (NumPredicateVectors || NumDataVectors)) && "WinCFI not supported with SVE vectors"' failed.
```
It can also be reproduced with a more targeted handwritten testcase:
```c
#include <arm_sve.h>
void other(void);
void func(svfloat32_t a) {
other();
}
```
```console
$ clang -target aarch64-windows-gnu -c repro.c -march=armv8-a+sve
clang: ../lib/Target/AArch64/AArch64InstrInfo.cpp:5444: void llvm::emitFrameOffset(llvm::MachineBasicBlock&, llvm::MachineBasicBlock::iterator, const llvm::DebugLoc&, unsigned int, unsigned int, llvm::StackOffset, const llvm::TargetInstrInfo*, llvm::MachineInstr::MIFlag, bool, bool, bool*, bool, llvm::StackOffset, unsigned int): Assertion `!(NeedsWinCFI && (NumPredicateVectors || NumDataVectors)) && "WinCFI not supported with SVE vectors"' failed.
```
I guess there's not much we can do about this, until MS specifies SEH unwind opcodes for dealing with scalable vectors, or until they specify something that differs from AAPCS64 which scalable vector registers need to be preserved in the Windows calling convention.
CC @efriedma-quic
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsV0uP2zgS_jX0pWBDoh62Dj740cY2sJMZoAfJ0aDIksS0RCokZXf-_YKU_Ep3djeHwVzGMGzxUZ-K9eBXxayVtUJck2xLsv2MDa7RZt1Zp439qmelFt_XO931spWqhs3G8CZPgWuB4BrmYLBo4eXzE1TI3GDQErqDShtg8EUqoc8WHDM1Oj_PmQKL2IHTcNbmFZiDShobFsvBQcVkCy1zaODcoIJqUNxJrSyUyHWH0GmDwHXXt_i2INGeRJvx989GWmiY34gKdGnRnFCAVNDKkukOCF01zvWWJBtCD4QemO5QSLaota5btHowHBdcd-MSoYVXykrFEX5N8EDoltBDlJZFzONlWRXLvIzyOGdlkVYs5yLJVwUV6RILjhmhWfZEaEbjILobT86DzVGMtlTAWLD8vJOqPk8mfTDAFy_lGhydcbUbKgFDDwpReAc6DSXjr36KKQEGvaNHmRNy73SvgWvwOzgj6xpNwPR-QQGE0i9S7Q7PoLQDO_S9Ng4FnKVrHjEoMGvRuPc-8jFQ4gX9Iuz8kkExcBRjdFkl-x4dVEZ3kw-9B0a4PBq_fBrTRCreDgKBJDtmuqNCrY72hMfSSFHjoiHJ07hXKpenb_TogBG6uhtx7o8ulYvzt9XRQfk45IQWQJbbEQXAoBuMAnuq0YXXfTvaPCV0ZU9Cu-uzfbc6KIHVNJqiLLzbP13A_-fnATjO74HDaAIu_xrYUdvwTSaDkOV-fDhpKQCnvZfVmxkFoathGga71z_Y9ba1Itl2RbL9FQXe4d5v_wok2cMJ39xF93pxYi3JtpEHoTu4jONpHD1A3UJBBiQfHicx9N-OavJWNB3_a7jjrsA_qDOBtB_Ovo5K9kyIS0RIj9b-DKZ7nE3oW3p0oEYYrrtSKjzahHplO326qPo6qXo_1_3gsntAfTc7RfYNPRhzQgpvUo_oYU7_LCCuyfpj7mpldYuXDE6Bt0zVMB_vtuuFdx5ZZF6rAeYcDPZGLzjMO79Okj0z3Wk1Z4Ru7Qlh_jsdAQMYSTawWBB6aGVJ6OHPiYgOE43dnp6VdeZZVXrB-54kmyxNUy8cgrltT-HqSTbYSXcwrMPfq8p6pNVt7TfGG6lwy6zk21bzV0Lz4Nn_siNMS4eGOW1CYmll3Z3IHsuh_rfmE9agAlt7WnMfjW-CL47x14uW73FHS1xPTejmQ1XDhmnm-dCyOtwpWrfv_zf3Uz_V41Hhwpt4E3hCagU-LDwJrj4hCjsRTTh57tn709D9YVBIzhx-HnkGyHJHljv4NHR75tjnC_sU4U65SP7fnEXocmK6xcehG36fXeAw1lrtiSwE5MhbAZKNNcoYxSigYUqcjXTO0zNax5nFXyAye7onrxCP2jVofEZqKe4zLix65g_XdtVq5pKJ5-5v2Iv4356s_yTqP4n6lyYq1ANa6wtYg4QubQDuBt7AGUMOCw2s1IML5ed4bCdb-O0FbI9cVtL3Nk__gkH5wAbd-8rUhpJcIAsdUdDOctayssX7GlqbCS0U0yPed7C6Q9eEStx3T0JWFRo7FrmbzR-7lzyFcyP5O0wwWEvr_GZfy4dCHqE3eGt0fKF-6bk4a4N6XKsTKu-1h0p8twOSRlgZiaJj82-D5DAT60QUScFmuI6XUZ7TLI6KWbOmWGRFEmfLDOOMM7akPMpohGmR5wWLk5lc04imUZxEcZrEabFgCVKepzTJYp5Gy8S_q2OyXfh4W2hTz6S1A65XURQVs5aV2NrQgVLquxNUgiSba-5TX8FS-vL5yT9n-5lZe5x5OdSWpFErrbM3ZCddG9rZi3y2B5JtJ8P40eHaHA3W28jHlo-G0Hz-QhTOBtOuH1vDWrpmKKdmMCTX-Dfvjf6K3F9p4eSW0EM4_H8CAAD__3ZZw4A">