Add intrinsic body fallback to cranelift and use it

This commit is contained in:
Oli Scherer 2024-01-31 14:29:12 +00:00
parent f90a0b9a18
commit a51b61a8b6
2 changed files with 32 additions and 35 deletions

View File

@ -387,15 +387,19 @@ pub(crate) fn codegen_terminator_call<'tcx>(
match instance.def { match instance.def {
InstanceDef::Intrinsic(_) => { InstanceDef::Intrinsic(_) => {
crate::intrinsics::codegen_intrinsic_call( match crate::intrinsics::codegen_intrinsic_call(
fx, fx,
instance, instance,
args, args,
ret_place, ret_place,
target, target,
source_info, source_info,
); ) {
return; Ok(()) => return,
// Unimplemented intrinsics must have a fallback body. The fallback body is obtained
// by converting the `InstanceDef::Intrinsic` to an `InstanceDef::Item`.
Err(()) => Some(Instance::new(instance.def_id(), instance.args)),
}
} }
InstanceDef::DropGlue(_, None) => { InstanceDef::DropGlue(_, None) => {
// empty drop glue - a nop. // empty drop glue - a nop.

View File

@ -268,7 +268,7 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(
destination: CPlace<'tcx>, destination: CPlace<'tcx>,
target: Option<BasicBlock>, target: Option<BasicBlock>,
source_info: mir::SourceInfo, source_info: mir::SourceInfo,
) { ) -> Result<(), ()> {
let intrinsic = fx.tcx.item_name(instance.def_id()); let intrinsic = fx.tcx.item_name(instance.def_id());
let instance_args = instance.args; let instance_args = instance.args;
@ -295,8 +295,9 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(
destination, destination,
target, target,
source_info, source_info,
); )?;
} }
Ok(())
} }
fn codegen_float_intrinsic_call<'tcx>( fn codegen_float_intrinsic_call<'tcx>(
@ -430,25 +431,20 @@ fn codegen_regular_intrinsic_call<'tcx>(
ret: CPlace<'tcx>, ret: CPlace<'tcx>,
destination: Option<BasicBlock>, destination: Option<BasicBlock>,
source_info: mir::SourceInfo, source_info: mir::SourceInfo,
) { ) -> Result<(), ()> {
assert_eq!(generic_args, instance.args);
let usize_layout = fx.layout_of(fx.tcx.types.usize); let usize_layout = fx.layout_of(fx.tcx.types.usize);
match intrinsic { match intrinsic {
sym::abort => { sym::abort => {
fx.bcx.ins().trap(TrapCode::User(0)); fx.bcx.ins().trap(TrapCode::User(0));
return; return Ok(());
} }
sym::likely | sym::unlikely => { sym::likely | sym::unlikely => {
intrinsic_args!(fx, args => (a); intrinsic); intrinsic_args!(fx, args => (a); intrinsic);
ret.write_cvalue(fx, a); ret.write_cvalue(fx, a);
} }
sym::is_val_statically_known => {
intrinsic_args!(fx, args => (_a); intrinsic);
let res = fx.bcx.ins().iconst(types::I8, 0);
ret.write_cvalue(fx, CValue::by_val(res, ret.layout()));
}
sym::breakpoint => { sym::breakpoint => {
intrinsic_args!(fx, args => (); intrinsic); intrinsic_args!(fx, args => (); intrinsic);
@ -697,7 +693,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
}) })
}); });
crate::base::codegen_panic_nounwind(fx, &msg_str, Some(source_info.span)); crate::base::codegen_panic_nounwind(fx, &msg_str, Some(source_info.span));
return; return Ok(());
} }
} }
} }
@ -792,7 +788,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
if fx.tcx.is_compiler_builtins(LOCAL_CRATE) { if fx.tcx.is_compiler_builtins(LOCAL_CRATE) {
// special case for compiler-builtins to avoid having to patch it // special case for compiler-builtins to avoid having to patch it
crate::trap::trap_unimplemented(fx, "128bit atomics not yet supported"); crate::trap::trap_unimplemented(fx, "128bit atomics not yet supported");
return; return Ok(());
} else { } else {
fx.tcx fx.tcx
.dcx() .dcx()
@ -802,7 +798,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {} ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
_ => { _ => {
report_atomic_type_validation_error(fx, intrinsic, source_info.span, ty); report_atomic_type_validation_error(fx, intrinsic, source_info.span, ty);
return; return Ok(());
} }
} }
let clif_ty = fx.clif_type(ty).unwrap(); let clif_ty = fx.clif_type(ty).unwrap();
@ -823,7 +819,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
if fx.tcx.is_compiler_builtins(LOCAL_CRATE) { if fx.tcx.is_compiler_builtins(LOCAL_CRATE) {
// special case for compiler-builtins to avoid having to patch it // special case for compiler-builtins to avoid having to patch it
crate::trap::trap_unimplemented(fx, "128bit atomics not yet supported"); crate::trap::trap_unimplemented(fx, "128bit atomics not yet supported");
return; return Ok(());
} else { } else {
fx.tcx fx.tcx
.dcx() .dcx()
@ -833,7 +829,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {} ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
_ => { _ => {
report_atomic_type_validation_error(fx, intrinsic, source_info.span, ty); report_atomic_type_validation_error(fx, intrinsic, source_info.span, ty);
return; return Ok(());
} }
} }
@ -850,7 +846,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {} ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
_ => { _ => {
report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty); report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
return; return Ok(());
} }
} }
let ty = fx.clif_type(layout.ty).unwrap(); let ty = fx.clif_type(layout.ty).unwrap();
@ -872,7 +868,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {} ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
_ => { _ => {
report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty); report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
return; return Ok(());
} }
} }
@ -895,7 +891,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {} ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
_ => { _ => {
report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty); report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
return; return Ok(());
} }
} }
let ty = fx.clif_type(layout.ty).unwrap(); let ty = fx.clif_type(layout.ty).unwrap();
@ -917,7 +913,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {} ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
_ => { _ => {
report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty); report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
return; return Ok(());
} }
} }
let ty = fx.clif_type(layout.ty).unwrap(); let ty = fx.clif_type(layout.ty).unwrap();
@ -939,7 +935,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {} ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
_ => { _ => {
report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty); report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
return; return Ok(());
} }
} }
let ty = fx.clif_type(layout.ty).unwrap(); let ty = fx.clif_type(layout.ty).unwrap();
@ -960,7 +956,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {} ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
_ => { _ => {
report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty); report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
return; return Ok(());
} }
} }
let ty = fx.clif_type(layout.ty).unwrap(); let ty = fx.clif_type(layout.ty).unwrap();
@ -981,7 +977,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {} ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
_ => { _ => {
report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty); report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
return; return Ok(());
} }
} }
let ty = fx.clif_type(layout.ty).unwrap(); let ty = fx.clif_type(layout.ty).unwrap();
@ -1002,7 +998,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {} ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
_ => { _ => {
report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty); report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
return; return Ok(());
} }
} }
let ty = fx.clif_type(layout.ty).unwrap(); let ty = fx.clif_type(layout.ty).unwrap();
@ -1023,7 +1019,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {} ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
_ => { _ => {
report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty); report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
return; return Ok(());
} }
} }
let ty = fx.clif_type(layout.ty).unwrap(); let ty = fx.clif_type(layout.ty).unwrap();
@ -1044,7 +1040,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {} ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
_ => { _ => {
report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty); report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
return; return Ok(());
} }
} }
let ty = fx.clif_type(layout.ty).unwrap(); let ty = fx.clif_type(layout.ty).unwrap();
@ -1065,7 +1061,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {} ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
_ => { _ => {
report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty); report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
return; return Ok(());
} }
} }
let ty = fx.clif_type(layout.ty).unwrap(); let ty = fx.clif_type(layout.ty).unwrap();
@ -1086,7 +1082,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {} ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
_ => { _ => {
report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty); report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
return; return Ok(());
} }
} }
let ty = fx.clif_type(layout.ty).unwrap(); let ty = fx.clif_type(layout.ty).unwrap();
@ -1261,13 +1257,10 @@ fn codegen_regular_intrinsic_call<'tcx>(
); );
} }
_ => { _ => return Err(()),
fx.tcx
.dcx()
.span_fatal(source_info.span, format!("unsupported intrinsic {}", intrinsic));
}
} }
let ret_block = fx.get_block(destination.unwrap()); let ret_block = fx.get_block(destination.unwrap());
fx.bcx.ins().jump(ret_block, &[]); fx.bcx.ins().jump(ret_block, &[]);
Ok(())
} }