diff --git a/src/librustc_trans/trans/intrinsic.rs b/src/librustc_trans/trans/intrinsic.rs index 736803c573e..1140edeaec0 100644 --- a/src/librustc_trans/trans/intrinsic.rs +++ b/src/librustc_trans/trans/intrinsic.rs @@ -1506,22 +1506,26 @@ fn generic_simd_intrinsic<'blk, 'tcx, 'a> let total_len = in_len as u64 * 2; - let vector = match args { - Some(args) => &args[2], - None => bcx.sess().span_bug(span, - "intrinsic call with unexpected argument shape"), - }; - let vector = match consts::const_expr(bcx.ccx(), vector, substs, None, - consts::TrueConst::Yes, // this should probably help simd error reporting - ) { - Ok((vector, _)) => vector, - Err(err) => bcx.sess().span_fatal(span, &err.description()), + let (vector, indirect) = match args { + Some(args) => { + match consts::const_expr(bcx.ccx(), &args[2], substs, None, + // this should probably help simd error reporting + consts::TrueConst::Yes) { + Ok((vector, _)) => (vector, false), + Err(err) => bcx.sess().span_fatal(span, &err.description()), + } + } + None => (llargs[2], !type_is_immediate(bcx.ccx(), arg_tys[2])) }; let indices: Option<Vec<_>> = (0..n) .map(|i| { let arg_idx = i; - let val = const_get_elt(vector, &[i as libc::c_uint]); + let val = if indirect { + Load(bcx, StructGEP(bcx, vector, i)) + } else { + const_get_elt(vector, &[i as libc::c_uint]) + }; let c = const_to_opt_uint(val); match c { None => {