Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Function attribute for standard fixed-length vector calling convention variant #68

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

kito-cheng
Copy link
Collaborator

…n variant

Fixed-length vector are passed via general purposed register or memory within current ABI design, we proposed a standard fixed-length vector calling convention variant for passing the fixed-length vector via vector register.

This is the syntax part in the proposal, further detail for that calling convention variant see riscv-non-isa/riscv-elf-psabi-doc#418

…n variant

Fixed-length vector are passed via general purposed register or memory
within current ABI design, we proposed a standard fixed-length vector calling
convention variant for passing the fixed-length vector via vector register.

This is the syntax part in the proposal, further detail for that calling
convention variant see riscv-non-isa/riscv-elf-psabi-doc#418
@sorear
Copy link

sorear commented Feb 2, 2024

Stylistically, since this is a well-defined RISC-V specific ABI attribute independent of any GNU extensions, I wonder if it should be [[riscv:vls_cc]] instead of [[gnu:riscv_vls_cs]]. Probably not since other architectures still seem to be using attributes in the compiler-specific namespace?

I believe that this needs to be included in C++ function pointer mangling to support natural uses (although this doesn't work on aarch64). Do the rules for that need to be specified here?

LGTM otherwise.

@kito-cheng
Copy link
Collaborator Author

@sorear thanks for remind that, I almost forgot [[]] style function attribute, for C++ function pointer mangling , I guess we still have few time to fix that before GCC 14 and LLVM 18 release.

@kito-cheng
Copy link
Collaborator Author

Update:

  • Added C++11 and C23 style syntax

@cmuellner cmuellner changed the title Function attribute for standard fixed-length vector calling conventio… Function attribute for standard fixed-length vector calling convention Feb 25, 2024
@cmuellner cmuellner changed the title Function attribute for standard fixed-length vector calling convention Function attribute for standard fixed-length vector calling convention variant Feb 25, 2024
The attribute can accept an optional unsigned integer argument within the value
range of `[32, 65536]`, which must be a power of two. This argument specifies
the `ABI_VLEN`. If not provided, the default value is set to 128. However, this
default value can be changed via command-line options or pragma directives.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where are the command line options or pragma defined?

// foo is declared to use the standard fixed-length vector calling convention variant
// with ABI_VLEN=256. Compilation will succeed with -march=rv64gcv_zvl256b, as it
// supports VLEN of 256. However, compiling with -march=rv64gcv will result in an error,
// because rv64gcv's VLEN is 128, which is less than the specified ABI_VLEN of 256.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This disagrees with the preceding paragraph that says ABI_VLEN must be larger or equal than the minimval VLEN.

void bar __attribute__((riscv_vls_cc(256)));
```

One constraint on `ABI_VLEN` is that it must be larger than or equal to the
Copy link
Contributor

@topperc topperc Jul 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"ABI_VLEN must be less than or equal to`." No need for the "One constraint on".


The attribute can accept an optional unsigned integer argument within the value
range of `[32, 65536]`, which must be a power of two. This argument specifies
the `ABI_VLEN`. If not provided, the default value is set to 128. However, this
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is set to -> is

4vtomat added a commit to llvm/llvm-project that referenced this pull request Mar 3, 2025
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: riscv-non-isa/riscv-elf-psabi-doc#418
C-API PR: riscv-non-isa/riscv-c-api-doc#68
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request Mar 3, 2025
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: riscv-non-isa/riscv-elf-psabi-doc#418
C-API PR: riscv-non-isa/riscv-c-api-doc#68
jph-13 pushed a commit to jph-13/llvm-project that referenced this pull request Mar 21, 2025
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: riscv-non-isa/riscv-elf-psabi-doc#418
C-API PR: riscv-non-isa/riscv-c-api-doc#68
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants