@@ -7,7 +7,7 @@ use hir_def::{
7
7
Abi , FieldsShape , Integer , LayoutCalculator , LayoutS , Primitive , ReprOptions , Scalar , Size ,
8
8
StructKind , TargetDataLayout , WrappingRange ,
9
9
} ,
10
- LocalEnumVariantId , LocalFieldId ,
10
+ LocalEnumVariantId , LocalFieldId , StructId ,
11
11
} ;
12
12
use la_arena:: { Idx , RawIdx } ;
13
13
use stdx:: never;
@@ -77,6 +77,78 @@ impl<'a> LayoutCalculator for LayoutCx<'a> {
77
77
}
78
78
}
79
79
80
+ // FIXME: move this to the `rustc_abi`.
81
+ fn layout_of_simd_ty (
82
+ db : & dyn HirDatabase ,
83
+ id : StructId ,
84
+ subst : & Substitution ,
85
+ krate : CrateId ,
86
+ dl : & TargetDataLayout ,
87
+ ) -> Result < Arc < Layout > , LayoutError > {
88
+ let fields = db. field_types ( id. into ( ) ) ;
89
+
90
+ // Supported SIMD vectors are homogeneous ADTs with at least one field:
91
+ //
92
+ // * #[repr(simd)] struct S(T, T, T, T);
93
+ // * #[repr(simd)] struct S { x: T, y: T, z: T, w: T }
94
+ // * #[repr(simd)] struct S([T; 4])
95
+ //
96
+ // where T is a primitive scalar (integer/float/pointer).
97
+
98
+ let f0_ty = match fields. iter ( ) . next ( ) {
99
+ Some ( x) => x. 1 . clone ( ) . substitute ( Interner , subst) ,
100
+ None => {
101
+ user_error ! ( "simd type with zero fields" ) ;
102
+ }
103
+ } ;
104
+
105
+ // The element type and number of elements of the SIMD vector
106
+ // are obtained from:
107
+ //
108
+ // * the element type and length of the single array field, if
109
+ // the first field is of array type, or
110
+ //
111
+ // * the homogeneous field type and the number of fields.
112
+ let ( e_ty, e_len, is_array) = if let TyKind :: Array ( e_ty, _) = f0_ty. kind ( Interner ) {
113
+ // Extract the number of elements from the layout of the array field:
114
+ let FieldsShape :: Array { count, .. } = db. layout_of_ty ( f0_ty. clone ( ) , krate) ?. fields else {
115
+ user_error ! ( "Array with non array layout" ) ;
116
+ } ;
117
+
118
+ ( e_ty. clone ( ) , count, true )
119
+ } else {
120
+ // First ADT field is not an array:
121
+ ( f0_ty, fields. iter ( ) . count ( ) as u64 , false )
122
+ } ;
123
+
124
+ // Compute the ABI of the element type:
125
+ let e_ly = db. layout_of_ty ( e_ty, krate) ?;
126
+ let Abi :: Scalar ( e_abi) = e_ly. abi else {
127
+ user_error ! ( "simd type with inner non scalar type" ) ;
128
+ } ;
129
+
130
+ // Compute the size and alignment of the vector:
131
+ let size = e_ly. size . checked_mul ( e_len, dl) . ok_or ( LayoutError :: SizeOverflow ) ?;
132
+ let align = dl. vector_align ( size) ;
133
+ let size = size. align_to ( align. abi ) ;
134
+
135
+ // Compute the placement of the vector fields:
136
+ let fields = if is_array {
137
+ FieldsShape :: Arbitrary { offsets : [ Size :: ZERO ] . into ( ) , memory_index : [ 0 ] . into ( ) }
138
+ } else {
139
+ FieldsShape :: Array { stride : e_ly. size , count : e_len }
140
+ } ;
141
+
142
+ Ok ( Arc :: new ( Layout {
143
+ variants : Variants :: Single { index : struct_variant_idx ( ) } ,
144
+ fields,
145
+ abi : Abi :: Vector { element : e_abi, count : e_len } ,
146
+ largest_niche : e_ly. largest_niche ,
147
+ size,
148
+ align,
149
+ } ) )
150
+ }
151
+
80
152
pub fn layout_of_ty_query (
81
153
db : & dyn HirDatabase ,
82
154
ty : Ty ,
@@ -88,7 +160,16 @@ pub fn layout_of_ty_query(
88
160
let trait_env = Arc :: new ( TraitEnvironment :: empty ( krate) ) ;
89
161
let ty = normalize ( db, trait_env, ty. clone ( ) ) ;
90
162
let result = match ty. kind ( Interner ) {
91
- TyKind :: Adt ( AdtId ( def) , subst) => return db. layout_of_adt ( * def, subst. clone ( ) , krate) ,
163
+ TyKind :: Adt ( AdtId ( def) , subst) => {
164
+ if let hir_def:: AdtId :: StructId ( s) = def {
165
+ let data = db. struct_data ( * s) ;
166
+ let repr = data. repr . unwrap_or_default ( ) ;
167
+ if repr. simd ( ) {
168
+ return layout_of_simd_ty ( db, * s, subst, krate, & target) ;
169
+ }
170
+ } ;
171
+ return db. layout_of_adt ( * def, subst. clone ( ) , krate) ;
172
+ }
92
173
TyKind :: Scalar ( s) => match s {
93
174
chalk_ir:: Scalar :: Bool => Layout :: scalar (
94
175
dl,
0 commit comments