diff --git a/example/std_example.rs b/example/std_example.rs index 7819881b69b..61182a49b9c 100644 --- a/example/std_example.rs +++ b/example/std_example.rs @@ -75,6 +75,9 @@ unsafe fn test_simd() { test_mm_cvtepi8_epi16(); test_mm_cvtsi128_si64(); + // FIXME(#666) implement `#[rustc_arg_required_const(..)]` support + //test_mm_extract_epi8(); + let mask1 = _mm_movemask_epi8(dbg!(_mm_setr_epi8(255u8 as i8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))); assert_eq!(mask1, 1); } @@ -194,6 +197,19 @@ unsafe fn test_mm_cvtepi8_epi16() { assert_eq_m128i(r, e); } +#[target_feature(enable = "sse4.1")] +unsafe fn test_mm_extract_epi8() { + #[rustfmt::skip] + let a = _mm_setr_epi8( + -1, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15 + ); + let r1 = _mm_extract_epi8(a, 0); + let r2 = _mm_extract_epi8(a, 19); + assert_eq!(r1, 0xFF); + assert_eq!(r2, 3); +} + #[derive(PartialEq)] enum LoopState { Continue(()), diff --git a/src/constant.rs b/src/constant.rs index a71a8d0bf2c..23f550050e4 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -439,22 +439,19 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for TransPlaceInterpreter { pub fn mir_operand_get_const_val<'tcx>( fx: &FunctionCx<'_, 'tcx, impl Backend>, operand: &Operand<'tcx>, -) -> Result<&'tcx Const<'tcx>, String> { +) -> Option<&'tcx Const<'tcx>> { let place = match operand { - Operand::Copy(place) => place, - Operand::Constant(const_) => return Ok(force_eval_const(fx, const_.literal)), - _ => return Err(format!("{:?}", operand)), + Operand::Copy(place) | Operand::Move(place) => place, + Operand::Constant(const_) => return Some(force_eval_const(fx, const_.literal)), }; assert!(place.projection.is_none()); let static_ = match &place.base { - PlaceBase::Static(static_) => { - static_ - } - PlaceBase::Local(_) => return Err("local".to_string()), + PlaceBase::Static(static_) => static_, + PlaceBase::Local(_) => return None, }; - Ok(match &static_.kind { + Some(match &static_.kind { StaticKind::Static(_) => unimplemented!(), StaticKind::Promoted(promoted) => { fx.tcx.const_eval(ParamEnv::reveal_all().and(GlobalId { diff --git a/src/intrinsics.rs b/src/intrinsics.rs index 8b4d5962856..bd78271057c 100644 --- a/src/intrinsics.rs +++ b/src/intrinsics.rs @@ -951,7 +951,17 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>( }; simd_extract, (c v, o idx) { - let idx_const = crate::constant::mir_operand_get_const_val(fx, idx).expect("simd_extract* idx not const"); + let idx_const = if let Some(idx_const) = crate::constant::mir_operand_get_const_val(fx, idx) { + idx_const + } else { + fx.tcx.sess.span_warn( + fx.mir.span, + "`#[rustc_arg_required_const(..)]` is not yet supported. Calling this function will panic.", + ); + crate::trap::trap_panic(fx, "`#[rustc_arg_required_const(..)]` is not yet supported."); + return; + }; + let idx = idx_const.val.try_to_bits(Size::from_bytes(4 /* u32*/)).expect(&format!("kind not scalar: {:?}", idx_const)); let (_lane_type, lane_count) = lane_type_and_count(fx, v.layout(), intrinsic); if idx >= lane_count.into() {