Skip to content

[AArch64] [Windows] Functions using SVE can fail "WinCFI not supported with SVE vectors" #80009

Open
@mstorsjo

Description

@mstorsjo

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:

#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));
}
$ 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:

#include <arm_sve.h>
void other(void);
void func(svfloat32_t a) {
  other();
}
$ 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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions