Remove most trap functions and remove all trapnz usages

This commit is contained in:
bjorn3 2022-08-09 12:27:34 +00:00
parent 526553e4a3
commit fa6480e43d
8 changed files with 45 additions and 60 deletions

View File

@ -90,7 +90,8 @@ pub(crate) fn codegen_fn<'tcx>(
if !crate::constant::check_constants(&mut fx) { if !crate::constant::check_constants(&mut fx) {
fx.bcx.append_block_params_for_function_params(fx.block_map[START_BLOCK]); fx.bcx.append_block_params_for_function_params(fx.block_map[START_BLOCK]);
fx.bcx.switch_to_block(fx.block_map[START_BLOCK]); fx.bcx.switch_to_block(fx.block_map[START_BLOCK]);
crate::trap::trap_unreachable(&mut fx, "compilation should have been aborted"); // compilation should have been aborted
fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
} else if arg_uninhabited { } else if arg_uninhabited {
fx.bcx.append_block_params_for_function_params(fx.block_map[START_BLOCK]); fx.bcx.append_block_params_for_function_params(fx.block_map[START_BLOCK]);
fx.bcx.switch_to_block(fx.block_map[START_BLOCK]); fx.bcx.switch_to_block(fx.block_map[START_BLOCK]);
@ -457,17 +458,8 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, '_>) {
template, template,
operands, operands,
*options, *options,
*destination,
); );
match *destination {
Some(destination) => {
let destination_block = fx.get_block(destination);
fx.bcx.ins().jump(destination_block, &[]);
}
None => {
fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
}
}
} }
TerminatorKind::Resume | TerminatorKind::Abort => { TerminatorKind::Resume | TerminatorKind::Abort => {
// FIXME implement unwinding // FIXME implement unwinding
@ -711,9 +703,7 @@ fn is_fat_ptr<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> bool {
Rvalue::Discriminant(place) => { Rvalue::Discriminant(place) => {
let place = codegen_place(fx, place); let place = codegen_place(fx, place);
let value = place.to_cvalue(fx); let value = place.to_cvalue(fx);
let discr = crate::discriminant::codegen_get_discriminant(fx, lval, value, dest_layout);
crate::discriminant::codegen_get_discriminant(fx, value, dest_layout);
lval.write_cvalue(fx, discr);
} }
Rvalue::Repeat(ref operand, times) => { Rvalue::Repeat(ref operand, times) => {
let operand = codegen_operand(fx, operand); let operand = codegen_operand(fx, operand);

View File

@ -62,16 +62,14 @@ pub(crate) fn codegen_set_discriminant<'tcx>(
pub(crate) fn codegen_get_discriminant<'tcx>( pub(crate) fn codegen_get_discriminant<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>, fx: &mut FunctionCx<'_, '_, 'tcx>,
dest: CPlace<'tcx>,
value: CValue<'tcx>, value: CValue<'tcx>,
dest_layout: TyAndLayout<'tcx>, dest_layout: TyAndLayout<'tcx>,
) -> CValue<'tcx> { ) {
let layout = value.layout(); let layout = value.layout();
if layout.abi == Abi::Uninhabited { if layout.abi.is_uninhabited() {
let true_ = fx.bcx.ins().iconst(types::I32, 1); return;
fx.bcx.ins().trapnz(true_, TrapCode::UnreachableCodeReached);
// Return a dummy value
return CValue::by_ref(Pointer::const_addr(fx, 0), dest_layout);
} }
let (tag_scalar, tag_field, tag_encoding) = match &layout.variants { let (tag_scalar, tag_field, tag_encoding) = match &layout.variants {
@ -89,7 +87,9 @@ pub(crate) fn codegen_get_discriminant<'tcx>(
} else { } else {
ty::ScalarInt::try_from_uint(discr_val, dest_layout.size).unwrap() ty::ScalarInt::try_from_uint(discr_val, dest_layout.size).unwrap()
}; };
return CValue::const_val(fx, dest_layout, discr_val); let res = CValue::const_val(fx, dest_layout, discr_val);
dest.write_cvalue(fx, res);
return;
} }
Variants::Multiple { tag, tag_field, tag_encoding, variants: _ } => { Variants::Multiple { tag, tag_field, tag_encoding, variants: _ } => {
(tag, *tag_field, tag_encoding) (tag, *tag_field, tag_encoding)
@ -110,7 +110,8 @@ pub(crate) fn codegen_get_discriminant<'tcx>(
_ => false, _ => false,
}; };
let val = clif_intcast(fx, tag, cast_to, signed); let val = clif_intcast(fx, tag, cast_to, signed);
CValue::by_val(val, dest_layout) let res = CValue::by_val(val, dest_layout);
dest.write_cvalue(fx, res);
} }
TagEncoding::Niche { dataful_variant, ref niche_variants, niche_start } => { TagEncoding::Niche { dataful_variant, ref niche_variants, niche_start } => {
// Rebase from niche values to discriminants, and check // Rebase from niche values to discriminants, and check
@ -170,7 +171,8 @@ pub(crate) fn codegen_get_discriminant<'tcx>(
let dataful_variant = fx.bcx.ins().iconst(cast_to, i64::from(dataful_variant.as_u32())); let dataful_variant = fx.bcx.ins().iconst(cast_to, i64::from(dataful_variant.as_u32()));
let discr = fx.bcx.ins().select(is_niche, niche_discr, dataful_variant); let discr = fx.bcx.ins().select(is_niche, niche_discr, dataful_variant);
CValue::by_val(discr, dest_layout) let res = CValue::by_val(discr, dest_layout);
dest.write_cvalue(fx, res);
} }
} }
} }

View File

@ -15,13 +15,13 @@ pub(crate) fn codegen_inline_asm<'tcx>(
template: &[InlineAsmTemplatePiece], template: &[InlineAsmTemplatePiece],
operands: &[InlineAsmOperand<'tcx>], operands: &[InlineAsmOperand<'tcx>],
options: InlineAsmOptions, options: InlineAsmOptions,
destination: Option<mir::BasicBlock>,
) { ) {
// FIXME add .eh_frame unwind info directives // FIXME add .eh_frame unwind info directives
if !template.is_empty() { if !template.is_empty() {
if template[0] == InlineAsmTemplatePiece::String("int $$0x29".to_string()) { if template[0] == InlineAsmTemplatePiece::String("int $$0x29".to_string()) {
let true_ = fx.bcx.ins().iconst(types::I32, 1); fx.bcx.ins().trap(TrapCode::User(1));
fx.bcx.ins().trapnz(true_, TrapCode::User(1));
return; return;
} else if template[0] == InlineAsmTemplatePiece::String("movq %rbx, ".to_string()) } else if template[0] == InlineAsmTemplatePiece::String("movq %rbx, ".to_string())
&& matches!( && matches!(
@ -101,12 +101,16 @@ pub(crate) fn codegen_inline_asm<'tcx>(
ebx_place.write_cvalue(fx, CValue::by_val(ebx, fx.layout_of(fx.tcx.types.u32))); ebx_place.write_cvalue(fx, CValue::by_val(ebx, fx.layout_of(fx.tcx.types.u32)));
ecx_place.write_cvalue(fx, CValue::by_val(ecx, fx.layout_of(fx.tcx.types.u32))); ecx_place.write_cvalue(fx, CValue::by_val(ecx, fx.layout_of(fx.tcx.types.u32)));
edx_place.write_cvalue(fx, CValue::by_val(edx, fx.layout_of(fx.tcx.types.u32))); edx_place.write_cvalue(fx, CValue::by_val(edx, fx.layout_of(fx.tcx.types.u32)));
let destination_block = fx.get_block(destination.unwrap());
fx.bcx.ins().jump(destination_block, &[]);
return; return;
} else if fx.tcx.symbol_name(fx.instance).name.starts_with("___chkstk") { } else if fx.tcx.symbol_name(fx.instance).name.starts_with("___chkstk") {
// ___chkstk, ___chkstk_ms and __alloca are only used on Windows // ___chkstk, ___chkstk_ms and __alloca are only used on Windows
crate::trap::trap_unimplemented(fx, "Stack probes are not supported"); crate::trap::trap_unimplemented(fx, "Stack probes are not supported");
return;
} else if fx.tcx.symbol_name(fx.instance).name == "__alloca" { } else if fx.tcx.symbol_name(fx.instance).name == "__alloca" {
crate::trap::trap_unimplemented(fx, "Alloca is not supported"); crate::trap::trap_unimplemented(fx, "Alloca is not supported");
return;
} }
} }
@ -175,6 +179,16 @@ pub(crate) fn codegen_inline_asm<'tcx>(
} }
call_inline_asm(fx, &asm_name, asm_gen.stack_slot_size, inputs, outputs); call_inline_asm(fx, &asm_name, asm_gen.stack_slot_size, inputs, outputs);
match destination {
Some(destination) => {
let destination_block = fx.get_block(destination);
fx.bcx.ins().jump(destination_block, &[]);
}
None => {
fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
}
}
} }
struct InlineAssemblyGenerator<'a, 'tcx> { struct InlineAssemblyGenerator<'a, 'tcx> {

View File

@ -62,7 +62,7 @@ pub(crate) fn codegen_cpuid_call<'tcx>(
fx.bcx.ins().jump(dest, &[zero, zero, proc_info_ecx, proc_info_edx]); fx.bcx.ins().jump(dest, &[zero, zero, proc_info_ecx, proc_info_edx]);
fx.bcx.switch_to_block(unsupported_leaf); fx.bcx.switch_to_block(unsupported_leaf);
crate::trap::trap_unreachable( crate::trap::trap_unimplemented(
fx, fx,
"__cpuid_count arch intrinsic doesn't yet support specified leaf", "__cpuid_count arch intrinsic doesn't yet support specified leaf",
); );

View File

@ -139,6 +139,7 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>(
.sess .sess
.warn(&format!("unsupported llvm intrinsic {}; replacing with trap", intrinsic)); .warn(&format!("unsupported llvm intrinsic {}; replacing with trap", intrinsic));
crate::trap::trap_unimplemented(fx, intrinsic); crate::trap::trap_unimplemented(fx, intrinsic);
return;
} }
} }

View File

@ -44,7 +44,7 @@ fn report_atomic_type_validation_error<'tcx>(
), ),
); );
// Prevent verifier error // Prevent verifier error
crate::trap::trap_unreachable(fx, "compilation should not have succeeded"); fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
} }
pub(crate) fn clif_vector_type<'tcx>(tcx: TyCtxt<'tcx>, layout: TyAndLayout<'tcx>) -> Option<Type> { pub(crate) fn clif_vector_type<'tcx>(tcx: TyCtxt<'tcx>, layout: TyAndLayout<'tcx>) -> Option<Type> {
@ -849,8 +849,6 @@ fn swap(bcx: &mut FunctionBuilder<'_>, v: Value) -> Value {
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");
let ret_block = fx.get_block(destination.unwrap());
fx.bcx.ins().jump(ret_block, &[]);
return; return;
} else { } else {
fx.tcx fx.tcx
@ -882,8 +880,6 @@ fn swap(bcx: &mut FunctionBuilder<'_>, v: Value) -> Value {
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");
let ret_block = fx.get_block(destination.unwrap());
fx.bcx.ins().jump(ret_block, &[]);
return; return;
} else { } else {
fx.tcx fx.tcx

View File

@ -14,7 +14,7 @@ fn report_simd_type_validation_error(
) { ) {
fx.tcx.sess.span_err(span, &format!("invalid monomorphization of `{}` intrinsic: expected SIMD input type, found non-SIMD `{}`", intrinsic, ty)); fx.tcx.sess.span_err(span, &format!("invalid monomorphization of `{}` intrinsic: expected SIMD input type, found non-SIMD `{}`", intrinsic, ty));
// Prevent verifier error // Prevent verifier error
crate::trap::trap_unreachable(fx, "compilation should not have succeeded"); fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
} }
pub(super) fn codegen_simd_intrinsic_call<'tcx>( pub(super) fn codegen_simd_intrinsic_call<'tcx>(
@ -157,7 +157,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
), ),
); );
// Prevent verifier error // Prevent verifier error
crate::trap::trap_unreachable(fx, "compilation should not have succeeded"); fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
return; return;
} }
} }
@ -274,12 +274,17 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
idx_const idx_const
} else { } else {
fx.tcx.sess.span_warn(span, "Index argument for `simd_extract` is not a constant"); fx.tcx.sess.span_warn(span, "Index argument for `simd_extract` is not a constant");
let res = crate::trap::trap_unimplemented_ret_value( let trap_block = fx.bcx.create_block();
let dummy_block = fx.bcx.create_block();
let true_ = fx.bcx.ins().iconst(types::I8, 1);
fx.bcx.ins().brnz(true_, trap_block, &[]);
fx.bcx.ins().jump(dummy_block, &[]);
fx.bcx.switch_to_block(trap_block);
crate::trap::trap_unimplemented(
fx, fx,
ret.layout(),
"Index argument for `simd_extract` is not a constant", "Index argument for `simd_extract` is not a constant",
); );
ret.write_cvalue(fx, res); fx.bcx.switch_to_block(dummy_block);
return; return;
}; };

View File

@ -25,33 +25,10 @@ fn codegen_print(fx: &mut FunctionCx<'_, '_, '_>, msg: &str) {
fx.bcx.ins().call(puts, &[msg_ptr]); fx.bcx.ins().call(puts, &[msg_ptr]);
} }
/// Use this for example when a function call should never return. This will fill the current block,
/// so you can **not** add instructions to it afterwards.
///
/// Trap code: user65535
pub(crate) fn trap_unreachable(fx: &mut FunctionCx<'_, '_, '_>, msg: impl AsRef<str>) {
codegen_print(fx, msg.as_ref());
fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
}
/// Use this when something is unimplemented, but `libcore` or `libstd` requires it to codegen. /// Use this when something is unimplemented, but `libcore` or `libstd` requires it to codegen.
/// Unlike `trap_unreachable` this will not fill the current block, so you **must** add instructions
/// to it afterwards.
/// ///
/// Trap code: user65535 /// Trap code: user65535
pub(crate) fn trap_unimplemented(fx: &mut FunctionCx<'_, '_, '_>, msg: impl AsRef<str>) { pub(crate) fn trap_unimplemented(fx: &mut FunctionCx<'_, '_, '_>, msg: impl AsRef<str>) {
codegen_print(fx, msg.as_ref()); codegen_print(fx, msg.as_ref());
let true_ = fx.bcx.ins().iconst(types::I32, 1); fx.bcx.ins().trap(TrapCode::User(!0));
fx.bcx.ins().trapnz(true_, TrapCode::User(!0));
}
/// Like `trap_unimplemented` but returns a fake value of the specified type.
///
/// Trap code: user65535
pub(crate) fn trap_unimplemented_ret_value<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>,
dest_layout: TyAndLayout<'tcx>,
msg: impl AsRef<str>,
) -> CValue<'tcx> {
trap_unimplemented(fx, msg);
CValue::by_ref(Pointer::const_addr(fx, 0), dest_layout)
} }