@@ -21,7 +21,7 @@ fn report_simd_type_validation_error(
2121pub ( super )  fn  codegen_simd_intrinsic_call < ' tcx > ( 
2222    fx :  & mut  FunctionCx < ' _ ,  ' _ ,  ' tcx > , 
2323    intrinsic :  Symbol , 
24-     _args :  GenericArgsRef < ' tcx > , 
24+     generic_args :  GenericArgsRef < ' tcx > , 
2525    args :  & [ mir:: Operand < ' tcx > ] , 
2626    ret :  CPlace < ' tcx > , 
2727    target :  BasicBlock , 
@@ -117,6 +117,54 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
117117            } ) ; 
118118        } 
119119
120+         // simd_shuffle_generic<T, U, const I: &[u32]>(x: T, y: T) -> U 
121+         sym:: simd_shuffle_generic => { 
122+             let  [ x,  y]  = args else  { 
123+                 bug ! ( "wrong number of args for intrinsic {intrinsic}" ) ; 
124+             } ; 
125+             let  x = codegen_operand ( fx,  x) ; 
126+             let  y = codegen_operand ( fx,  y) ; 
127+ 
128+             if  !x. layout ( ) . ty . is_simd ( )  { 
129+                 report_simd_type_validation_error ( fx,  intrinsic,  span,  x. layout ( ) . ty ) ; 
130+                 return ; 
131+             } 
132+ 
133+             let  idx = generic_args[ 2 ] 
134+                 . expect_const ( ) 
135+                 . eval ( fx. tcx ,  ty:: ParamEnv :: reveal_all ( ) ,  Some ( span) ) 
136+                 . unwrap ( ) 
137+                 . unwrap_branch ( ) ; 
138+ 
139+             assert_eq ! ( x. layout( ) ,  y. layout( ) ) ; 
140+             let  layout = x. layout ( ) ; 
141+ 
142+             let  ( lane_count,  lane_ty)  = layout. ty . simd_size_and_type ( fx. tcx ) ; 
143+             let  ( ret_lane_count,  ret_lane_ty)  = ret. layout ( ) . ty . simd_size_and_type ( fx. tcx ) ; 
144+ 
145+             assert_eq ! ( lane_ty,  ret_lane_ty) ; 
146+             assert_eq ! ( idx. len( )  as  u64 ,  ret_lane_count) ; 
147+ 
148+             let  total_len = lane_count *  2 ; 
149+ 
150+             let  indexes =
151+                 idx. iter ( ) . map ( |idx| idx. unwrap_leaf ( ) . try_to_u16 ( ) . unwrap ( ) ) . collect :: < Vec < u16 > > ( ) ; 
152+ 
153+             for  & idx in  & indexes { 
154+                 assert ! ( u64 :: from( idx)  < total_len,  "idx {} out of range 0..{}" ,  idx,  total_len) ; 
155+             } 
156+ 
157+             for  ( out_idx,  in_idx)  in  indexes. into_iter ( ) . enumerate ( )  { 
158+                 let  in_lane = if  u64:: from ( in_idx)  < lane_count { 
159+                     x. value_lane ( fx,  in_idx. into ( ) ) 
160+                 }  else  { 
161+                     y. value_lane ( fx,  u64:: from ( in_idx)  - lane_count) 
162+                 } ; 
163+                 let  out_lane = ret. place_lane ( fx,  u64:: try_from ( out_idx) . unwrap ( ) ) ; 
164+                 out_lane. write_cvalue ( fx,  in_lane) ; 
165+             } 
166+         } 
167+ 
120168        // simd_shuffle<T, I, U>(x: T, y: T, idx: I) -> U 
121169        sym:: simd_shuffle => { 
122170            let  ( x,  y,  idx)  = match  args { 
0 commit comments