mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-28 00:56:05 +00:00

This patch adds a function attribute `riscv_vls_cc` for RISCV VLS calling convention which takes 0 or 1 argument, the argument is the `ABI_VLEN` which is the `VLEN` for passing the fixed-vector arguments, it wraps the argument as a scalable vector(VLA) using the `ABI_VLEN` and uses the corresponding mechanism to handle it. The range of `ABI_VLEN` is [32, 65536], if not specified, the default value is 128. Here is an example of VLS argument passing: Non-VLS call: ``` void original_call(__attribute__((vector_size(16))) int arg) {} => define void @original_call(i128 noundef %arg) { entry: ... ret void } ``` VLS call: ``` void __attribute__((riscv_vls_cc(256))) vls_call(__attribute__((vector_size(16))) int arg) {} => define riscv_vls_cc void @vls_call(<vscale x 1 x i32> %arg) { entry: ... ret void } } ``` The first Non-VLS call passes generic vector argument of 16 bytes by flattened integer. On the contrary, the VLS call uses `ABI_VLEN=256` which wraps the vector to <vscale x 1 x i32> where the number of scalable vector elements is calaulated by: `ORIG_ELTS * RVV_BITS_PER_BLOCK / ABI_VLEN`. Note: ORIG_ELTS = Vector Size / Type Size = 128 / 32 = 4. PsABI PR: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/418 C-API PR: https://github.com/riscv-non-isa/riscv-c-api-doc/pull/68
54 lines
2.4 KiB
C++
54 lines
2.4 KiB
C++
// RUN: %clang_cc1 %s -triple riscv64 -target-feature +v -verify
|
|
|
|
__attribute__((riscv_vector_cc)) int var; // expected-warning {{'riscv_vector_cc' only applies to function types; type here is 'int'}}
|
|
|
|
__attribute__((riscv_vector_cc)) void func();
|
|
__attribute__((riscv_vector_cc(1))) void func_invalid(); // expected-error {{'riscv_vector_cc' attribute takes no arguments}}
|
|
|
|
void test_no_attribute(int); // expected-note {{previous declaration is here}}
|
|
void __attribute__((riscv_vector_cc)) test_no_attribute(int x) { } // expected-error {{function declared 'riscv_vector_cc' here was previously declared without calling convention}}
|
|
|
|
class test_cc {
|
|
__attribute__((riscv_vector_cc)) void member_func();
|
|
};
|
|
|
|
void test_lambda() {
|
|
__attribute__((riscv_vector_cc)) auto lambda = []() { // expected-warning {{'riscv_vector_cc' only applies to function types; type here is 'auto'}}
|
|
};
|
|
}
|
|
|
|
[[riscv::vector_cc]] int var2; // expected-warning {{'vector_cc' only applies to function types; type here is 'int'}}
|
|
|
|
[[riscv::vector_cc]] void func2();
|
|
[[riscv::vector_cc(1)]] void func_invalid2(); // expected-error {{'vector_cc' attribute takes no arguments}}
|
|
|
|
void test_no_attribute2(int); // expected-note {{previous declaration is here}}
|
|
[[riscv::vector_cc]] void test_no_attribute2(int x) { } // expected-error {{function declared 'riscv_vector_cc' here was previously declared without calling convention}}
|
|
|
|
class test_cc2 {
|
|
[[riscv::vector_cc]] void member_func();
|
|
};
|
|
|
|
void test_lambda2() {
|
|
[[riscv::vector_cc]] auto lambda = []() { // expected-warning {{'vector_cc' only applies to function types; type here is 'auto'}}
|
|
};
|
|
}
|
|
|
|
[[riscv::vls_cc]] int var_vls; // expected-warning {{'vls_cc' only applies to function types; type here is 'int'}}
|
|
|
|
[[riscv::vls_cc]] void func_vls();
|
|
[[riscv::vls_cc(1)]] void func_invalid_vls(); // expected-error {{argument value 1 is outside the valid range [32, 65536]}}
|
|
[[riscv::vls_cc(129)]] void func_invalid_vls(); // expected-error {{argument should be a power of 2}}
|
|
|
|
void test_no_attribute_vls(int); // expected-note {{previous declaration is here}}
|
|
[[riscv::vls_cc]] void test_no_attribute_vls(int x) { } // expected-error {{function declared 'riscv_vls_cc(128)' here was previously declared without calling convention}}
|
|
|
|
class test_cc_vls {
|
|
[[riscv::vls_cc]] void member_func();
|
|
};
|
|
|
|
void test_lambda_vls() {
|
|
[[riscv::vls_cc]] auto lambda = []() { // expected-warning {{'vls_cc' only applies to function types; type here is 'auto'}}
|
|
};
|
|
}
|