@@ -2,8 +2,8 @@ use std::cmp;
22
33use libc:: c_uint;
44use rustc_abi:: {
5- ArmCall , BackendRepr , CanonAbi , HasDataLayout , InterruptKind , Primitive , Reg , RegKind , Size ,
6- X86Call ,
5+ ArmCall , BackendRepr , CanonAbi , Float , HasDataLayout , Integer , InterruptKind , Primitive , Reg ,
6+ RegKind , Size , X86Call ,
77} ;
88use rustc_codegen_ssa:: MemFlags ;
99use rustc_codegen_ssa:: mir:: operand:: { OperandRef , OperandValue } ;
@@ -137,7 +137,31 @@ impl LlvmType for Reg {
137137 128 => cx. type_f128 ( ) ,
138138 _ => bug ! ( "unsupported float: {:?}" , self ) ,
139139 } ,
140- RegKind :: Vector => cx. type_vector ( cx. type_i8 ( ) , self . size . bytes ( ) ) ,
140+ RegKind :: Vector { hint_vector_elem } => {
141+ // NOTE: it is valid to ignore the element type hint (and always pick i8).
142+ // But providing a more accurate type means fewer casts in LLVM IR,
143+ // which helps with optimization.
144+ let ty = match hint_vector_elem {
145+ Primitive :: Int ( integer, _) => match integer {
146+ Integer :: I8 => cx. type_ix ( 8 ) ,
147+ Integer :: I16 => cx. type_ix ( 16 ) ,
148+ Integer :: I32 => cx. type_ix ( 32 ) ,
149+ Integer :: I64 => cx. type_ix ( 64 ) ,
150+ Integer :: I128 => cx. type_ix ( 128 ) ,
151+ } ,
152+ Primitive :: Float ( float) => match float {
153+ Float :: F16 => cx. type_f16 ( ) ,
154+ Float :: F32 => cx. type_f32 ( ) ,
155+ Float :: F64 => cx. type_f64 ( ) ,
156+ Float :: F128 => cx. type_f128 ( ) ,
157+ } ,
158+ Primitive :: Pointer ( _) => cx. type_ptr ( ) ,
159+ } ;
160+
161+ assert ! ( self . size. bytes( ) . is_multiple_of( hint_vector_elem. size( cx) . bytes( ) ) ) ;
162+ let len = self . size . bytes ( ) / hint_vector_elem. size ( cx) . bytes ( ) ;
163+ cx. type_vector ( ty, len)
164+ }
141165 }
142166 }
143167}
0 commit comments