Merge commit '6d35b4c9a0' into sync_cg_clif-2024-09-22

This commit is contained in:
bjorn3 2024-09-23 11:20:46 +00:00
commit b40fe1ee28
31 changed files with 487 additions and 347 deletions

View file

@ -508,7 +508,10 @@ pub(crate) fn codegen_terminator_call<'tcx>(
let nop_inst = fx.bcx.ins().nop();
fx.add_comment(
nop_inst,
format!("virtual call; self arg pass mode: {:?}", fn_abi.args[0]),
with_no_trimmed_paths!(format!(
"virtual call; self arg pass mode: {:?}",
fn_abi.args[0]
)),
);
}

View file

@ -490,6 +490,11 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
}
/// Used only for intrinsic implementations that need a compile-time constant
///
/// All uses of this function are a bug inside stdarch. [`eval_mir_constant`]
/// should be used everywhere, but for some vendor intrinsics stdarch forgets
/// to wrap the immediate argument in `const {}`, necesitating this hack to get
/// the correct value at compile time instead.
pub(crate) fn mir_operand_get_const_val<'tcx>(
fx: &FunctionCx<'_, '_, 'tcx>,
operand: &Operand<'tcx>,

View file

@ -91,6 +91,44 @@ pub(crate) fn codegen_aarch64_llvm_intrinsic_call<'tcx>(
);
}
_ if intrinsic.starts_with("llvm.aarch64.neon.fmax.v") => {
intrinsic_args!(fx, args => (x, y); intrinsic);
simd_pair_for_each_lane(
fx,
x,
y,
ret,
&|fx, _lane_ty, _res_lane_ty, x_lane, y_lane| fx.bcx.ins().fmax(x_lane, y_lane),
);
}
_ if intrinsic.starts_with("llvm.aarch64.neon.fmin.v") => {
intrinsic_args!(fx, args => (x, y); intrinsic);
simd_pair_for_each_lane(
fx,
x,
y,
ret,
&|fx, _lane_ty, _res_lane_ty, x_lane, y_lane| fx.bcx.ins().fmin(x_lane, y_lane),
);
}
_ if intrinsic.starts_with("llvm.aarch64.neon.faddv.f32.v") => {
intrinsic_args!(fx, args => (v); intrinsic);
simd_reduce(fx, v, None, ret, &|fx, _ty, a, b| fx.bcx.ins().fadd(a, b));
}
_ if intrinsic.starts_with("llvm.aarch64.neon.frintn.v") => {
intrinsic_args!(fx, args => (v); intrinsic);
simd_for_each_lane(fx, v, ret, &|fx, _lane_ty, _res_lane_ty, lane| {
fx.bcx.ins().nearest(lane)
});
}
_ if intrinsic.starts_with("llvm.aarch64.neon.smaxv.i") => {
intrinsic_args!(fx, args => (v); intrinsic);

View file

@ -600,9 +600,11 @@ fn codegen_regular_intrinsic_call<'tcx>(
sym::ptr_mask => {
intrinsic_args!(fx, args => (ptr, mask); intrinsic);
let ptr_layout = ptr.layout();
let ptr = ptr.load_scalar(fx);
let mask = mask.load_scalar(fx);
fx.bcx.ins().band(ptr, mask);
let res = fx.bcx.ins().band(ptr, mask);
ret.write_cvalue(fx, CValue::by_val(res, ptr_layout));
}
sym::write_bytes | sym::volatile_set_memory => {

View file

@ -181,11 +181,9 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
// Make sure this is actually a SIMD vector.
let idx_ty = fx.monomorphize(idx.node.ty(fx.mir, fx.tcx));
let n: u16 = if idx_ty.is_simd()
&& matches!(idx_ty.simd_size_and_type(fx.tcx).1.kind(), ty::Uint(ty::UintTy::U32))
if !idx_ty.is_simd()
|| !matches!(idx_ty.simd_size_and_type(fx.tcx).1.kind(), ty::Uint(ty::UintTy::U32))
{
idx_ty.simd_size_and_type(fx.tcx).0.try_into().unwrap()
} else {
fx.tcx.dcx().span_err(
span,
format!("simd_shuffle index must be a SIMD vector of `u32`, got `{}`", idx_ty),
@ -194,6 +192,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
return;
};
let n: u16 = idx_ty.simd_size_and_type(fx.tcx).0.try_into().unwrap();
assert_eq!(x.layout(), y.layout());
let layout = x.layout();
@ -268,10 +267,8 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
let val = codegen_operand(fx, &val.node);
// FIXME validate
let idx_const = if let Some(idx_const) =
crate::constant::mir_operand_get_const_val(fx, &idx.node)
{
idx_const
let idx_const = if let Some(idx_const) = idx.node.constant() {
crate::constant::eval_mir_constant(fx, idx_const).0.try_to_scalar_int().unwrap()
} else {
fx.tcx.dcx().span_fatal(span, "Index argument for `simd_insert` is not a constant");
};
@ -304,22 +301,12 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
return;
}
let idx_const = if let Some(idx_const) =
crate::constant::mir_operand_get_const_val(fx, &idx.node)
{
idx_const
let idx_const = if let Some(idx_const) = idx.node.constant() {
crate::constant::eval_mir_constant(fx, idx_const).0.try_to_scalar_int().unwrap()
} else {
fx.tcx.dcx().span_warn(span, "Index argument for `simd_extract` is not a constant");
let trap_block = fx.bcx.create_block();
let true_ = fx.bcx.ins().iconst(types::I8, 1);
let ret_block = fx.get_block(target);
fx.bcx.ins().brif(true_, trap_block, &[], ret_block, &[]);
fx.bcx.switch_to_block(trap_block);
crate::trap::trap_unimplemented(
fx,
"Index argument for `simd_extract` is not a constant",
);
return;
fx.tcx
.dcx()
.span_fatal(span, "Index argument for `simd_extract` is not a constant");
};
let idx = idx_const.to_u32();
@ -574,9 +561,12 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
(sym::simd_round, types::F64) => "round",
_ => unreachable!("{:?}", intrinsic),
};
fx.lib_call(name, vec![AbiParam::new(lane_ty)], vec![AbiParam::new(lane_ty)], &[
lane,
])[0]
fx.lib_call(
name,
vec![AbiParam::new(lane_ty)],
vec![AbiParam::new(lane_ty)],
&[lane],
)[0]
});
}