From 21edec4ea5bec5b4da691232b3d832cc5d35acf7 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 3 Jul 2020 16:39:36 +0200 Subject: [PATCH 1/7] Fix core::hint::black_box support --- src/base.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/base.rs b/src/base.rs index 85c0c21c33d..053f6e81d5e 100644 --- a/src/base.rs +++ b/src/base.rs @@ -689,6 +689,9 @@ fn trans_stmt<'tcx>( asm_str_style: _, } = asm; match &*asm_code.as_str() { + "" => { + // Black box + } cpuid if cpuid.contains("cpuid") => { crate::trap::trap_unimplemented( fx, From 798fb856515fd2e9aeedbfe21a903c09cf85c165 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 3 Jul 2020 16:40:57 +0200 Subject: [PATCH 2/7] Fix assert_assignable --- src/value_and_place.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/value_and_place.rs b/src/value_and_place.rs index 1d0990163bb..c9516a98bfe 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -406,6 +406,10 @@ impl<'tcx> CPlace<'tcx> { to_ty: Ty<'tcx>, ) { match (&from_ty.kind, &to_ty.kind) { + (ty::Ref(_, a, _), ty::Ref(_, b, _)) + | (ty::RawPtr(TypeAndMut { ty: a, mutbl: _}), ty::RawPtr(TypeAndMut { ty: b, mutbl: _})) => { + assert_assignable(fx, a, b); + } (ty::FnPtr(_), ty::FnPtr(_)) => { let from_sig = fx.tcx.normalize_erasing_late_bound_regions( ParamEnv::reveal_all(), From 92dc61aba200b8df43720da2e3e9f302db03a2e3 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 3 Jul 2020 16:43:26 +0200 Subject: [PATCH 3/7] Only display codegen time when CG_CLIF_DISPLAY_CG_TIME=1 --- Readme.md | 2 +- src/driver/mod.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Readme.md b/Readme.md index 6759403b64f..61595e97730 100644 --- a/Readme.md +++ b/Readme.md @@ -69,7 +69,7 @@ function jit_calc() { to make it possible to use incremental mode for all analyses performed by rustc without caching object files when their content should have been changed by a change to cg_clif.
CG_CLIF_DISPLAY_CG_TIME
-
Display the time it took to perform codegen for a crate
+
If "1", display the time it took to perform codegen for a crate
## Not yet supported diff --git a/src/driver/mod.rs b/src/driver/mod.rs index d75b6e05f32..9a60b1e6a33 100644 --- a/src/driver/mod.rs +++ b/src/driver/mod.rs @@ -109,7 +109,7 @@ fn trans_mono_item<'tcx, B: Backend + 'static>( } fn time(tcx: TyCtxt<'_>, name: &'static str, f: impl FnOnce() -> R) -> R { - if std::env::var("CG_CLIF_DISPLAY_CG_TIME").is_ok() { + if std::env::var("CG_CLIF_DISPLAY_CG_TIME").as_ref().map(|val| &**val) == Ok("1") { println!("[{:<30}: {}] start", tcx.crate_name(LOCAL_CRATE), name); let before = std::time::Instant::now(); let res = tcx.sess.time(name, f); From 4ada18fd77dd27da06a6233bf4b99c90e986b541 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 3 Jul 2020 16:43:59 +0200 Subject: [PATCH 4/7] Add sess.abort_if_errors() to link --- src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 3e562977b8e..b1e624d87f0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -234,6 +234,8 @@ impl CodegenBackend for CraneliftCodegenBackend { ) -> Result<(), ErrorReported> { use rustc_codegen_ssa::back::link::link_binary; + sess.abort_if_errors(); + let codegen_results = *res .downcast::() .expect("Expected CraneliftCodegenBackend's CodegenResult, found Box"); From 8d639cd778bb11fed2c230d8071664e24d30a84f Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 3 Jul 2020 16:44:26 +0200 Subject: [PATCH 5/7] Test signed 128bit discriminants --- example/std_example.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/example/std_example.rs b/example/std_example.rs index ebac391f1e5..0c8fa8c0ba9 100644 --- a/example/std_example.rs +++ b/example/std_example.rs @@ -103,6 +103,14 @@ fn main() { Box::pin(move |mut _task_context| { yield (); }).as_mut().resume(0); + + #[derive(Copy, Clone)] + enum Nums { + NegOne = -1, + } + + let kind = Nums::NegOne; + assert_eq!(-1i128, kind as i128); } #[target_feature(enable = "sse2")] From 699da394ccd44de318da444bae28e472882ca830 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 3 Jul 2020 16:52:37 +0200 Subject: [PATCH 6/7] Validate simd and atomic intrinsic types --- src/intrinsics/mod.rs | 75 +++++++++++++++++++++++++++++++++++------- src/intrinsics/simd.rs | 23 +++++++++++++ 2 files changed, 87 insertions(+), 11 deletions(-) diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index a5aec52a7e4..5fb47729c11 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.rs @@ -138,6 +138,27 @@ macro atomic_minmax($fx:expr, $cc:expr, <$T:ident> ($ptr:ident, $src:ident) -> $ crate::atomic_shim::unlock_global_lock($fx); } +macro validate_atomic_type($fx:ident, $intrinsic:ident, $span:ident, $ty:expr) { + match $ty.kind { + ty::Uint(_) | ty::Int(_) => {} + _ => { + $fx.tcx.sess.span_err($span, &format!("`{}` intrinsic: expected basic integer type, found `{:?}`", $intrinsic, $ty)); + // Prevent verifier error + crate::trap::trap_unreachable($fx, "compilation should not have succeeded"); + return; + } + } +} + +macro validate_simd_type($fx:ident, $intrinsic:ident, $span:ident, $ty:expr) { + if !$ty.is_simd() { + $fx.tcx.sess.span_err($span, &format!("invalid monomorphization of `{}` intrinsic: expected SIMD input type, found non-SIMD `{}`", $intrinsic, $ty)); + // Prevent verifier error + crate::trap::trap_unreachable($fx, "compilation should not have succeeded"); + return; + } +} + fn lane_type_and_count<'tcx>( tcx: TyCtxt<'tcx>, layout: TyAndLayout<'tcx>, @@ -866,12 +887,15 @@ pub(crate) fn codegen_intrinsic_call<'tcx>( let inner_layout = fx.layout_of(ptr.layout().ty.builtin_deref(true).unwrap().ty); + validate_atomic_type!(fx, intrinsic, span, inner_layout.ty); let val = CValue::by_ref(Pointer::new(ptr.load_scalar(fx)), inner_layout); ret.write_cvalue(fx, val); crate::atomic_shim::unlock_global_lock(fx); }; _ if intrinsic.starts_with("atomic_store"), (v ptr, c val) { + validate_atomic_type!(fx, intrinsic, span, val.layout().ty); + crate::atomic_shim::lock_global_lock(fx); let dest = CPlace::for_ptr(Pointer::new(ptr), val.layout()); @@ -880,6 +904,8 @@ pub(crate) fn codegen_intrinsic_call<'tcx>( crate::atomic_shim::unlock_global_lock(fx); }; _ if intrinsic.starts_with("atomic_xchg"), (v ptr, c src) { + validate_atomic_type!(fx, intrinsic, span, T); + crate::atomic_shim::lock_global_lock(fx); // Read old @@ -893,7 +919,12 @@ pub(crate) fn codegen_intrinsic_call<'tcx>( crate::atomic_shim::unlock_global_lock(fx); }; - _ if intrinsic.starts_with("atomic_cxchg"), (v ptr, v test_old, v new) { // both atomic_cxchg_* and atomic_cxchgweak_* + _ if intrinsic.starts_with("atomic_cxchg"), (v ptr, c test_old, c new) { // both atomic_cxchg_* and atomic_cxchgweak_* + validate_atomic_type!(fx, intrinsic, span, T); + + let test_old = test_old.load_scalar(fx); + let new = new.load_scalar(fx); + crate::atomic_shim::lock_global_lock(fx); // Read old @@ -913,16 +944,26 @@ pub(crate) fn codegen_intrinsic_call<'tcx>( crate::atomic_shim::unlock_global_lock(fx); }; - _ if intrinsic.starts_with("atomic_xadd"), (v ptr, v amount) { + _ if intrinsic.starts_with("atomic_xadd"), (v ptr, c amount) { + validate_atomic_type!(fx, intrinsic, span, ret.layout().ty); + let amount = amount.load_scalar(fx); atomic_binop_return_old! (fx, iadd(ptr, amount) -> ret); }; - _ if intrinsic.starts_with("atomic_xsub"), (v ptr, v amount) { + _ if intrinsic.starts_with("atomic_xsub"), (v ptr, c amount) { + validate_atomic_type!(fx, intrinsic, span, ret.layout().ty); + let amount = amount.load_scalar(fx); atomic_binop_return_old! (fx, isub(ptr, amount) -> ret); }; - _ if intrinsic.starts_with("atomic_and"), (v ptr, v src) { + _ if intrinsic.starts_with("atomic_and"), (v ptr, c src) { + validate_atomic_type!(fx, intrinsic, span, ret.layout().ty); + let src = src.load_scalar(fx); atomic_binop_return_old! (fx, band(ptr, src) -> ret); }; - _ if intrinsic.starts_with("atomic_nand"), (v ptr, v src) { + _ if intrinsic.starts_with("atomic_nand"), (v ptr, c src) { + validate_atomic_type!(fx, intrinsic, span, T); + + let src = src.load_scalar(fx); + crate::atomic_shim::lock_global_lock(fx); let clif_ty = fx.clif_type(T).unwrap(); @@ -934,23 +975,35 @@ pub(crate) fn codegen_intrinsic_call<'tcx>( crate::atomic_shim::unlock_global_lock(fx); }; - _ if intrinsic.starts_with("atomic_or"), (v ptr, v src) { + _ if intrinsic.starts_with("atomic_or"), (v ptr, c src) { + validate_atomic_type!(fx, intrinsic, span, ret.layout().ty); + let src = src.load_scalar(fx); atomic_binop_return_old! (fx, bor(ptr, src) -> ret); }; - _ if intrinsic.starts_with("atomic_xor"), (v ptr, v src) { + _ if intrinsic.starts_with("atomic_xor"), (v ptr, c src) { + validate_atomic_type!(fx, intrinsic, span, ret.layout().ty); + let src = src.load_scalar(fx); atomic_binop_return_old! (fx, bxor(ptr, src) -> ret); }; - _ if intrinsic.starts_with("atomic_max"), (v ptr, v src) { + _ if intrinsic.starts_with("atomic_max"), (v ptr, c src) { + validate_atomic_type!(fx, intrinsic, span, ret.layout().ty); + let src = src.load_scalar(fx); atomic_minmax!(fx, IntCC::SignedGreaterThan, (ptr, src) -> ret); }; - _ if intrinsic.starts_with("atomic_umax"), (v ptr, v src) { + _ if intrinsic.starts_with("atomic_umax"), (v ptr, c src) { + validate_atomic_type!(fx, intrinsic, span, ret.layout().ty); + let src = src.load_scalar(fx); atomic_minmax!(fx, IntCC::UnsignedGreaterThan, (ptr, src) -> ret); }; - _ if intrinsic.starts_with("atomic_min"), (v ptr, v src) { + _ if intrinsic.starts_with("atomic_min"), (v ptr, c src) { + validate_atomic_type!(fx, intrinsic, span, ret.layout().ty); + let src = src.load_scalar(fx); atomic_minmax!(fx, IntCC::SignedLessThan, (ptr, src) -> ret); }; - _ if intrinsic.starts_with("atomic_umin"), (v ptr, v src) { + _ if intrinsic.starts_with("atomic_umin"), (v ptr, c src) { + validate_atomic_type!(fx, intrinsic, span, ret.layout().ty); + let src = src.load_scalar(fx); atomic_minmax!(fx, IntCC::UnsignedLessThan, (ptr, src) -> ret); }; diff --git a/src/intrinsics/simd.rs b/src/intrinsics/simd.rs index cf7decb0464..32f561bdd36 100644 --- a/src/intrinsics/simd.rs +++ b/src/intrinsics/simd.rs @@ -21,6 +21,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( }; simd_cast, (c a) { + validate_simd_type!(fx, intrinsic, span, a.layout().ty); simd_for_each_lane(fx, a, ret, |fx, lane_layout, ret_lane_layout, lane| { let ret_lane_ty = fx.clif_type(ret_lane_layout.ty).unwrap(); @@ -33,26 +34,34 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( }; simd_eq, (c x, c y) { + validate_simd_type!(fx, intrinsic, span, x.layout().ty); simd_cmp!(fx, Equal(x, y) -> ret); }; simd_ne, (c x, c y) { + validate_simd_type!(fx, intrinsic, span, x.layout().ty); simd_cmp!(fx, NotEqual(x, y) -> ret); }; simd_lt, (c x, c y) { + validate_simd_type!(fx, intrinsic, span, x.layout().ty); simd_cmp!(fx, UnsignedLessThan|SignedLessThan(x, y) -> ret); }; simd_le, (c x, c y) { + validate_simd_type!(fx, intrinsic, span, x.layout().ty); simd_cmp!(fx, UnsignedLessThanOrEqual|SignedLessThanOrEqual(x, y) -> ret); }; simd_gt, (c x, c y) { + validate_simd_type!(fx, intrinsic, span, x.layout().ty); simd_cmp!(fx, UnsignedGreaterThan|SignedGreaterThan(x, y) -> ret); }; simd_ge, (c x, c y) { + validate_simd_type!(fx, intrinsic, span, x.layout().ty); simd_cmp!(fx, UnsignedGreaterThanOrEqual|SignedGreaterThanOrEqual(x, y) -> ret); }; // simd_shuffle32(x: T, y: T, idx: [u32; 32]) -> U _ if intrinsic.starts_with("simd_shuffle"), (c x, c y, o idx) { + validate_simd_type!(fx, intrinsic, span, x.layout().ty); + let n: u16 = intrinsic["simd_shuffle".len()..].parse().unwrap(); assert_eq!(x.layout(), y.layout()); @@ -105,6 +114,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( }; simd_insert, (c base, o idx, v _val) { + // FIXME validate let idx_const = if let Some(idx_const) = crate::constant::mir_operand_get_const_val(fx, idx) { idx_const } else { @@ -132,6 +142,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( }; simd_extract, (c v, o idx) { + validate_simd_type!(fx, intrinsic, span, v.layout().ty); let idx_const = if let Some(idx_const) = crate::constant::mir_operand_get_const_val(fx, idx) { idx_const } else { @@ -155,34 +166,44 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( }; simd_add, (c x, c y) { + validate_simd_type!(fx, intrinsic, span, x.layout().ty); simd_int_flt_binop!(fx, iadd|fadd(x, y) -> ret); }; simd_sub, (c x, c y) { + validate_simd_type!(fx, intrinsic, span, x.layout().ty); simd_int_flt_binop!(fx, isub|fsub(x, y) -> ret); }; simd_mul, (c x, c y) { + validate_simd_type!(fx, intrinsic, span, x.layout().ty); simd_int_flt_binop!(fx, imul|fmul(x, y) -> ret); }; simd_div, (c x, c y) { + validate_simd_type!(fx, intrinsic, span, x.layout().ty); simd_int_flt_binop!(fx, udiv|sdiv|fdiv(x, y) -> ret); }; simd_shl, (c x, c y) { + validate_simd_type!(fx, intrinsic, span, x.layout().ty); simd_int_binop!(fx, ishl(x, y) -> ret); }; simd_shr, (c x, c y) { + validate_simd_type!(fx, intrinsic, span, x.layout().ty); simd_int_binop!(fx, ushr|sshr(x, y) -> ret); }; simd_and, (c x, c y) { + validate_simd_type!(fx, intrinsic, span, x.layout().ty); simd_int_binop!(fx, band(x, y) -> ret); }; simd_or, (c x, c y) { + validate_simd_type!(fx, intrinsic, span, x.layout().ty); simd_int_binop!(fx, bor(x, y) -> ret); }; simd_xor, (c x, c y) { + validate_simd_type!(fx, intrinsic, span, x.layout().ty); simd_int_binop!(fx, bxor(x, y) -> ret); }; simd_fma, (c a, c b, c c) { + validate_simd_type!(fx, intrinsic, span, a.layout().ty); assert_eq!(a.layout(), b.layout()); assert_eq!(a.layout(), c.layout()); let layout = a.layout(); @@ -205,9 +226,11 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( }; simd_fmin, (c x, c y) { + validate_simd_type!(fx, intrinsic, span, x.layout().ty); simd_flt_binop!(fx, fmin(x, y) -> ret); }; simd_fmax, (c x, c y) { + validate_simd_type!(fx, intrinsic, span, x.layout().ty); simd_flt_binop!(fx, fmax(x, y) -> ret); }; } From 6345e4a1bcee38c42ee5817426beda78f43431ca Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 3 Jul 2020 16:52:56 +0200 Subject: [PATCH 7/7] Implement variant_count intrinisic --- src/intrinsics/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index 5fb47729c11..d93da0fb087 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.rs @@ -838,7 +838,7 @@ pub(crate) fn codegen_intrinsic_call<'tcx>( dest.write_cvalue(fx, val); }; - size_of | pref_align_of | min_align_of | needs_drop | type_id | type_name, () { + size_of | pref_align_of | min_align_of | needs_drop | type_id | type_name | variant_count, () { let const_val = fx.tcx.const_eval_instance(ParamEnv::reveal_all(), instance, None).unwrap(); let val = crate::constant::trans_const_value(