Skip to content

Commit 6186245

Browse files
committed
updated representation of tuples of vectors
1 parent 494da8a commit 6186245

File tree

1 file changed

+50
-38
lines changed

1 file changed

+50
-38
lines changed

text/3838-scalable-vectors.md

Lines changed: 50 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,33 @@ backend. It must one of the following types:
214214
It is not permitted to project into scalable vector types and access the type
215215
marker field.
216216

217+
## Tuples of vectors
218+
[tuples-of-vectors]: #tuples-of-vectors
219+
220+
Structs of scalable vectors are supported, but every element of the struct must
221+
have the same scalable vector type. This will enable definition of "tuple of
222+
vector" types, such as `svfloat32x2_t` below, that are used in some load and
223+
store intrinsics.
224+
225+
```rust
226+
#[rustc_scalable_vector]
227+
pub struct svfloat32x2_t(svfloat32_t, svfloat32_t);
228+
```
229+
230+
```text
231+
◁───────────── vscale x f32 x 4 ─────────────▷ ◁────── f32 x 4 ──────▷
232+
┌──────────────────────────────────────────────┬───────────────────────┐ ┐
233+
│ ... │ f32 │ f32 │ f32 │ f32 │ │
234+
└──────────────────────────────────────────────┴───────────────────────┘ ├─ svfloat32x2_t
235+
┌──────────────────────────────────────────────┬───────────────────────┐ │
236+
│ ... │ f32 │ f32 │ f32 │ f32 │ │
237+
└──────────────────────────────────────────────┴───────────────────────┘ ┘
238+
```
239+
240+
Structs must be still be annotated with `#[rustc_scalable_vector]`, so end-users
241+
cannot define their own structs of scalable vectors. It is not permitted to
242+
project into structs and access the individual vectors.
243+
217244
## Properties of scalable vectors
218245
[properties-of-scalable-vector-types]: #properties-of-scalable-vectors
219246

@@ -236,6 +263,12 @@ codegen backend:
236263

237264
- `repr(transparent)` newtypes could be permitted with scalable vectors
238265

266+
- **Exception:** Scalable vectors can be stored in arrays
267+
268+
- **Exception:** Scalable vectors can be stored in structs with every
269+
element of the same type (but only if that struct is annotated with
270+
`#[rustc_scalable_vector]`)
271+
239272
- Cannot be used in arrays
240273

241274
- Cannot be the type of a static variable
@@ -309,12 +342,12 @@ behaviour, consistent with C and C++.
309342
Implementing `rustc_scalable_vector` largely involves lowering scalable vectors
310343
to the appropriate type in the codegen backend. LLVM has robust support for
311344
scalable vectors and is the default backend, so this section will focus on
312-
implementation in the LLVM codegen backend. Other codegen backends can implement
313-
support when scalable vectors are supported by the backend.
345+
implementation in the LLVM codegen backend. Other backends should be able to
346+
support scalable vectors in Rust once they support scalable vectors in general.
314347

315-
Most of the complexity of SVE is handled by LLVM: lowering Rust's scalable
316-
vectors to the correct type in LLVM and the `vscale` modifier that is applied to
317-
LLVM's vector types.
348+
Most of the complexity of scalable vectors are handled by LLVM: lowering Rust's
349+
scalable vectors to the correct type in LLVM and the `vscale` modifier that is
350+
applied to LLVM's vector types.
318351

319352
LLVM's scalable vector type is of the form `<vscale × element_count × type>`.
320353
`vscale` is the scaling factor determined by the hardware at runtime, it can be
@@ -328,6 +361,14 @@ result in register sizes of 128, 256, 512, 1024 or 2048 and 4, 8, 16, 32, or 64
328361
The `N` in the `#[rustc_scalable_vector(N)]` determines the `element_count` used
329362
in the LLVM type for a scalable vector.
330363

364+
Structs of vectors are lowered to LLVM as struct types containing scalable
365+
vector types. This is supported since the
366+
[*Permit load/store/alloca for struct of the same scalable vector type* LLVM RFC][llvm-rfc-structs].
367+
368+
Arrays of vectors are lowered to LLVM as array types containing scalable vector
369+
types. Arrays of vectors are also supported by LLVM since the
370+
[*Enable arrays of scalable vector types* LLVM RFC][llvm-rfc-arrays].
371+
331372
Tuples in RISC-V's V Extension lower to target-specific types in LLVM rather
332373
than generic scalable vector types, so `rustc_scalable_vector` will not
333374
initially support RVV tuples (see
@@ -437,38 +478,7 @@ calculations for `N` or architecture-specific knowledge:
437478
attribute accepting arbitrary specification of `N` or a type to calculate `N`
438479
with.
439480

440-
3. Also with Arm SVE, some load and store intrinsics take tuples of vectors,
441-
such as `svfloat32x2_t`:
442-
443-
```text
444-
◁───────────── vscale x f32 x 4 ─────────────▷ ◁────── f32 x 4 ──────▷
445-
┌──────────────────────────────────────────────┬───────────────────────┐ ┐
446-
│ ... │ f32 │ f32 │ f32 │ f32 │ │
447-
└──────────────────────────────────────────────┴───────────────────────┘ ├─ svfloat32x2_t
448-
┌──────────────────────────────────────────────┬───────────────────────┐ │ vscale x f32 x 8
449-
│ ... │ f32 │ f32 │ f32 │ f32 │ │
450-
└──────────────────────────────────────────────┴───────────────────────┘ ┘
451-
```
452-
453-
These types are the opposite of the previous complicating case, containing
454-
more elements than `vunit / element_size`. These use two or more registers to
455-
represent the vector.
456-
457-
`vscale x f32 x 8` cannot be defined without the attribute accepting
458-
arbitrary specification of `N` or an argument to the attribute to specify the
459-
number of registers used:
460-
461-
```rust
462-
// alternative: user-provided arbitrary `N`
463-
#[rustc_scalable_vector(8)]
464-
struct svfloat32x2_t(f32);
465-
466-
// alternative: add `tuple_of` to attribute
467-
#[rustc_scalable_vector(tuple_of = "2")] // either `1` (default), `2`, `3` or `4`
468-
struct svfloat32x2_t(f32);
469-
```
470-
471-
4. RISC-V RVV's scalable vectors are quite different from Arm's SVE, while
481+
3. RISC-V RVV's scalable vectors are quite different from Arm's SVE, while
472482
sharing the same underlying infrastructure in LLVM.
473483

474484
SVE's scalable vector types map directly onto LLVM scalable vector types, and
@@ -1146,7 +1156,7 @@ The restriction that scalable vectors cannot be used in compound types could be
11461156
relaxed at a later time either by extending rustc's codegen or leveraging newly
11471157
added support in LLVM.
11481158

1149-
However, as C also has thus restriction and scalable vectors are nevertheless
1159+
However, as C also has this restriction and scalable vectors are nevertheless
11501160
used in production code, it is unlikely there will be much demand for those
11511161
restrictions to be relaxed in LLVM.
11521162

@@ -1182,6 +1192,8 @@ support for scalable vectors into Portable SIMD.
11821192
[lang-team#309]: https://github.com/rust-lang/lang-team/issues/309
11831193
[lang-team#317-notes]: https://hackmd.io/xydafCtMQ1aqUbm6wqmEmA?view
11841194
[lang-team#317]: https://github.com/rust-lang/lang-team/issues/317
1195+
[llvm-rfc-arrays]: https://discourse.llvm.org/t/rfc-enable-arrays-of-scalable-vector-types/72935
1196+
[llvm-rfc-structs]: https://discourse.llvm.org/t/rfc-ir-permit-load-store-alloca-for-struct-of-the-same-scalable-vector-type/69527
11851197
[llvm#70563]: https://github.com/llvm/llvm-project/issues/70563
11861198
[portable-simd#339]: https://github.com/rust-lang/portable-simd/issues/339
11871199
[prctl]: https://www.kernel.org/doc/Documentation/arm64/sve.txt

0 commit comments

Comments
 (0)