mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-26 12:16:06 +00:00

The SVE diagnostics were guarded by a FD->hasBody() check that prevented the diagnostic from being emitted for code that still triggered the backend crashes that the errors were meant to avoid, because FD->hasBody() returns false for a function that Clang is currently processing. This is not done for the equivalent RISC-V code, and is not needed for AArch64 either, so remove it. Errors were also emitted in the wrong location, errors were emitted at the called function's location, rather than at the caller's, which meant that just removing the FD->hasBody() check resulted in incomprehensible errors. Change this as well. The aarch64-mangle-sve-vectors.cpp test was using -target-feature wrong which was exposed as a result of these changes. Different target features need to be passed in as different -target-feature options. aarch64-targetattr-arch.c has a test_errors() function that needs to be split in two. Now that svundef_s8() is diagnosed for its use of svint8_t, the "needs target feature sve" diagnostic is no longer emitted, but this affects all calls in the same function. To ensure we still check this for its __crc32cd call, move that into a separate function. Fixes #94766.
61 lines
1.6 KiB
C++
61 lines
1.6 KiB
C++
// RUN: %clang_cc1 -fsyntax-only -verify -DNONEON -std=c++11 -triple aarch64 %s
|
|
|
|
// A target without sve should not be able to use sve types.
|
|
|
|
void test_var() {
|
|
__SVFloat32_t x; // expected-error {{SVE vector type '__SVFloat32_t' cannot be used in a target without sve}}
|
|
}
|
|
|
|
__attribute__((target("sve")))
|
|
void test_var_target() {
|
|
__SVFloat32_t x;
|
|
}
|
|
|
|
__attribute__((target("sve2")))
|
|
void test_var_target2() {
|
|
__SVFloat32_t x;
|
|
}
|
|
|
|
__attribute__((target("sve2-bitperm")))
|
|
void test_var_target3() {
|
|
__SVFloat32_t x;
|
|
}
|
|
|
|
__SVFloat32_t other_ret();
|
|
__SVFloat32_t test_ret() { // expected-error {{SVE vector type '__SVFloat32_t' cannot be used in a target without sve}}
|
|
return other_ret(); // expected-error {{SVE vector type '__SVFloat32_t' cannot be used in a target without sve}}
|
|
}
|
|
|
|
__attribute__((target("sve")))
|
|
__SVFloat32_t test_ret_target() {
|
|
return other_ret();
|
|
}
|
|
|
|
void test_arg(__SVFloat32_t arg) { // expected-error {{SVE vector type '__SVFloat32_t' cannot be used in a target without sve}}
|
|
}
|
|
|
|
__attribute__((target("sve")))
|
|
void test_arg_target(__SVFloat32_t arg) {
|
|
}
|
|
|
|
__clang_svint32x4_t test4x() { // expected-error {{SVE vector type '__clang_svint32x4_t' cannot be used in a target without sve}}
|
|
__clang_svint32x4_t x; // expected-error {{SVE vector type '__clang_svint32x4_t' cannot be used in a target without sve}}
|
|
return x;
|
|
}
|
|
|
|
__attribute__((target("sve")))
|
|
__clang_svint32x4_t test4x_target() {
|
|
__clang_svint32x4_t x;
|
|
return x;
|
|
}
|
|
|
|
// Pointers are still valid to pass around.
|
|
void foo(__SVFloat32_t *&ptrA, __SVFloat32_t* &ptrB) {
|
|
ptrA = ptrB;
|
|
}
|
|
|
|
__SVFloat32_t* foo(int x, __SVFloat32_t *ptrA) {
|
|
return ptrA;
|
|
}
|
|
|