@@ -214,6 +214,33 @@ backend. It must one of the following types:
214214It is not permitted to project into scalable vector types and access the type
215215marker 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++.
309342Implementing ` rustc_scalable_vector ` largely involves lowering scalable vectors
310343to the appropriate type in the codegen backend. LLVM has robust support for
311344scalable 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
319352LLVM'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
328361The ` N ` in the ` #[rustc_scalable_vector(N)] ` determines the ` element_count ` used
329362in 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+
331372Tuples in RISC-V's V Extension lower to target-specific types in LLVM rather
332373than generic scalable vector types, so ` rustc_scalable_vector ` will not
333374initially 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
11461156relaxed at a later time either by extending rustc's codegen or leveraging newly
11471157added 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
11501160used in production code, it is unlikely there will be much demand for those
11511161restrictions 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