1
1
use rustc_middle:: mir:: interpret:: ErrorHandled ;
2
2
use rustc_middle:: ty:: layout:: HasTyCtxt ;
3
- use rustc_middle:: ty:: { self , Ty } ;
3
+ use rustc_middle:: ty:: { self , Ty , ValTree } ;
4
4
use rustc_middle:: { bug, mir, span_bug} ;
5
5
use rustc_target:: abi:: Abi ;
6
6
@@ -28,7 +28,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
28
28
. expect ( "erroneous constant missed by mono item collection" )
29
29
}
30
30
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
32
32
/// that the given `constant` is an `Const::Unevaluated` and must be convertible to
33
33
/// a `ValTree`. If you want a more general version of this, talk to `wg-const-eval` on zulip.
34
34
///
@@ -59,23 +59,33 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
59
59
self . cx . tcx ( ) . const_eval_resolve_for_typeck ( ty:: ParamEnv :: reveal_all ( ) , uv, constant. span )
60
60
}
61
61
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 (
64
64
& mut self ,
65
65
bx : & Bx ,
66
66
constant : & mir:: ConstOperand < ' tcx > ,
67
67
) -> ( Bx :: Value , Ty < ' tcx > ) {
68
68
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
+
69
76
let val = self
70
77
. eval_unevaluated_mir_constant_to_valtree ( constant)
71
78
. ok ( )
72
79
. map ( |x| x. ok ( ) )
73
80
. flatten ( )
74
81
. 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
79
89
. map ( |field| {
80
90
if let Some ( prim) = field. try_to_scalar ( ) {
81
91
let layout = bx. layout_of ( field_ty) ;
@@ -84,11 +94,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
84
94
} ;
85
95
bx. scalar_to_backend ( prim, scalar, bx. immediate_backend_type ( layout) )
86
96
} else {
87
- bug ! ( "simd shuffle field {:?}" , field)
97
+ bug ! ( "field is not a scalar {:?}" , field)
88
98
}
89
99
} )
90
100
. collect ( ) ;
91
- bx. const_struct ( & values, false )
101
+ if ty_is_simd { bx. const_vector ( & values ) } else { bx . const_struct ( & values, false ) }
92
102
} )
93
103
. unwrap_or_else ( || {
94
104
bx. tcx ( ) . dcx ( ) . emit_err ( errors:: ShuffleIndicesEvaluation { span : constant. span } ) ;
0 commit comments