11use rustc_middle:: mir:: interpret:: ErrorHandled ;
22use rustc_middle:: ty:: layout:: HasTyCtxt ;
3- use rustc_middle:: ty:: { self , Ty } ;
3+ use rustc_middle:: ty:: { self , Ty , ValTree } ;
44use rustc_middle:: { bug, mir, span_bug} ;
55use rustc_target:: abi:: Abi ;
66
@@ -28,7 +28,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
2828 . expect ( "erroneous constant missed by mono item collection" )
2929 }
3030
31- /// This is a convenience helper for `simd_shuffle_indices `. It has the precondition
31+ /// This is a convenience helper for `immediate_const_vector `. It has the precondition
3232 /// that the given `constant` is an `Const::Unevaluated` and must be convertible to
3333 /// a `ValTree`. If you want a more general version of this, talk to `wg-const-eval` on zulip.
3434 ///
@@ -59,23 +59,33 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
5959 self . cx . tcx ( ) . const_eval_resolve_for_typeck ( ty:: ParamEnv :: reveal_all ( ) , uv, constant. span )
6060 }
6161
62- /// process constant containing SIMD shuffle indices
63- pub fn simd_shuffle_indices (
62+ /// process constant containing SIMD shuffle indices & constant vectors
63+ pub fn immediate_const_vector (
6464 & mut self ,
6565 bx : & Bx ,
6666 constant : & mir:: ConstOperand < ' tcx > ,
6767 ) -> ( Bx :: Value , Ty < ' tcx > ) {
6868 let ty = self . monomorphize ( constant. ty ( ) ) ;
69+ let ty_is_simd = ty. is_simd ( ) ;
70+ let field_ty = if ty_is_simd {
71+ ty. simd_size_and_type ( bx. tcx ( ) ) . 1
72+ } else {
73+ ty. builtin_index ( ) . unwrap ( )
74+ } ;
75+
6976 let val = self
7077 . eval_unevaluated_mir_constant_to_valtree ( constant)
7178 . ok ( )
7279 . map ( |x| x. ok ( ) )
7380 . flatten ( )
7481 . map ( |val| {
75- let field_ty = ty. builtin_index ( ) . unwrap ( ) ;
76- let values: Vec < _ > = val
77- . unwrap_branch ( )
78- . iter ( )
82+ let field_iter = val. unwrap_branch ( ) ;
83+ let first = field_iter. get ( 0 ) . unwrap ( ) ;
84+ let field_iter = match first {
85+ ValTree :: Branch ( _) => first. unwrap_branch ( ) . iter ( ) ,
86+ ValTree :: Leaf ( _) => field_iter. iter ( ) ,
87+ } ;
88+ let values: Vec < _ > = field_iter
7989 . map ( |field| {
8090 if let Some ( prim) = field. try_to_scalar ( ) {
8191 let layout = bx. layout_of ( field_ty) ;
@@ -84,11 +94,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
8494 } ;
8595 bx. scalar_to_backend ( prim, scalar, bx. immediate_backend_type ( layout) )
8696 } else {
87- bug ! ( "simd shuffle field {:?}" , field)
97+ bug ! ( "field is not a scalar {:?}" , field)
8898 }
8999 } )
90100 . collect ( ) ;
91- bx. const_struct ( & values, false )
101+ if ty_is_simd { bx. const_vector ( & values ) } else { bx . const_struct ( & values, false ) }
92102 } )
93103 . unwrap_or_else ( || {
94104 bx. tcx ( ) . dcx ( ) . emit_err ( errors:: ShuffleIndicesEvaluation { span : constant. span } ) ;
0 commit comments