]> git.proxmox.com Git - rustc.git/blobdiff - compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
New upstream version 1.63.0+dfsg1
[rustc.git] / compiler / rustc_codegen_cranelift / src / intrinsics / mod.rs
index f7a83373e870bed0b8893c9e36e2a10484078913..6937e658ed5ee8a8abe7e5909637fe6611251905 100644 (file)
@@ -58,6 +58,7 @@ pub(crate) use llvm::codegen_llvm_intrinsic_call;
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::subst::SubstsRef;
 use rustc_span::symbol::{kw, sym, Symbol};
+use rustc_target::abi::InitKind;
 
 use crate::prelude::*;
 use cranelift_codegen::ir::AtomicRmwOp;
@@ -217,35 +218,42 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(
     fx: &mut FunctionCx<'_, '_, 'tcx>,
     instance: Instance<'tcx>,
     args: &[mir::Operand<'tcx>],
-    destination: Option<(CPlace<'tcx>, BasicBlock)>,
-    span: Span,
+    destination: CPlace<'tcx>,
+    target: Option<BasicBlock>,
+    source_info: mir::SourceInfo,
 ) {
     let intrinsic = fx.tcx.item_name(instance.def_id());
     let substs = instance.substs;
 
-    let ret = match destination {
-        Some((place, _)) => place,
-        None => {
-            // Insert non returning intrinsics here
-            match intrinsic {
-                sym::abort => {
-                    fx.bcx.ins().trap(TrapCode::User(0));
-                }
-                sym::transmute => {
-                    crate::base::codegen_panic(fx, "Transmuting to uninhabited type.", span);
-                }
-                _ => unimplemented!("unsupported instrinsic {}", intrinsic),
+    let target = if let Some(target) = target {
+        target
+    } else {
+        // Insert non returning intrinsics here
+        match intrinsic {
+            sym::abort => {
+                fx.bcx.ins().trap(TrapCode::User(0));
             }
-            return;
+            sym::transmute => {
+                crate::base::codegen_panic(fx, "Transmuting to uninhabited type.", source_info);
+            }
+            _ => unimplemented!("unsupported instrinsic {}", intrinsic),
         }
+        return;
     };
 
     if intrinsic.as_str().starts_with("simd_") {
-        self::simd::codegen_simd_intrinsic_call(fx, intrinsic, substs, args, ret, span);
-        let ret_block = fx.get_block(destination.expect("SIMD intrinsics don't diverge").1);
+        self::simd::codegen_simd_intrinsic_call(
+            fx,
+            intrinsic,
+            substs,
+            args,
+            destination,
+            source_info.span,
+        );
+        let ret_block = fx.get_block(target);
         fx.bcx.ins().jump(ret_block, &[]);
-    } else if codegen_float_intrinsic_call(fx, intrinsic, args, ret) {
-        let ret_block = fx.get_block(destination.expect("Float intrinsics don't diverge").1);
+    } else if codegen_float_intrinsic_call(fx, intrinsic, args, destination) {
+        let ret_block = fx.get_block(target);
         fx.bcx.ins().jump(ret_block, &[]);
     } else {
         codegen_regular_intrinsic_call(
@@ -254,9 +262,9 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(
             intrinsic,
             substs,
             args,
-            ret,
-            span,
             destination,
+            Some(target),
+            source_info,
         );
     }
 }
@@ -339,15 +347,15 @@ fn codegen_regular_intrinsic_call<'tcx>(
     substs: SubstsRef<'tcx>,
     args: &[mir::Operand<'tcx>],
     ret: CPlace<'tcx>,
-    span: Span,
-    destination: Option<(CPlace<'tcx>, BasicBlock)>,
+    destination: Option<BasicBlock>,
+    source_info: mir::SourceInfo,
 ) {
     let usize_layout = fx.layout_of(fx.tcx.types.usize);
 
     intrinsic_match! {
         fx, intrinsic, args,
         _ => {
-            fx.tcx.sess.span_fatal(span, &format!("unsupported intrinsic {}", intrinsic));
+            fx.tcx.sess.span_fatal(source_info.span, &format!("unsupported intrinsic {}", intrinsic));
         };
 
         assume, (c _a) {};
@@ -658,29 +666,39 @@ fn codegen_regular_intrinsic_call<'tcx>(
                     crate::base::codegen_panic(
                         fx,
                         &format!("attempted to instantiate uninhabited type `{}`", layout.ty),
-                        span,
+                        source_info,
                     )
                 });
                 return;
             }
 
-            if intrinsic == sym::assert_zero_valid && !layout.might_permit_raw_init(fx, /*zero:*/ true) {
+            if intrinsic == sym::assert_zero_valid
+                && !layout.might_permit_raw_init(
+                    fx,
+                    InitKind::Zero,
+                    fx.tcx.sess.opts.debugging_opts.strict_init_checks) {
+
                 with_no_trimmed_paths!({
                     crate::base::codegen_panic(
                         fx,
                         &format!("attempted to zero-initialize type `{}`, which is invalid", layout.ty),
-                        span,
+                        source_info,
                     );
                 });
                 return;
             }
 
-            if intrinsic == sym::assert_uninit_valid && !layout.might_permit_raw_init(fx, /*zero:*/ false) {
+            if intrinsic == sym::assert_uninit_valid
+                && !layout.might_permit_raw_init(
+                    fx,
+                    InitKind::Uninit,
+                    fx.tcx.sess.opts.debugging_opts.strict_init_checks) {
+
                 with_no_trimmed_paths!({
                     crate::base::codegen_panic(
                         fx,
                         &format!("attempted to leave type `{}` uninitialized, which is invalid", layout.ty),
-                        span,
+                        source_info,
                     )
                 });
                 return;
@@ -715,19 +733,19 @@ fn codegen_regular_intrinsic_call<'tcx>(
 
         ptr_offset_from | ptr_offset_from_unsigned, (v ptr, v base) {
             let ty = substs.type_at(0);
-            let isize_layout = fx.layout_of(fx.tcx.types.isize);
 
             let pointee_size: u64 = fx.layout_of(ty).size.bytes();
             let diff_bytes = fx.bcx.ins().isub(ptr, base);
             // FIXME this can be an exact division.
-            let diff = if intrinsic == sym::ptr_offset_from_unsigned {
+            let val = if intrinsic == sym::ptr_offset_from_unsigned {
+                let usize_layout = fx.layout_of(fx.tcx.types.usize);
                 // Because diff_bytes ULE isize::MAX, this would be fine as signed,
                 // but unsigned is slightly easier to codegen, so might as well.
-                fx.bcx.ins().udiv_imm(diff_bytes, pointee_size as i64)
+                CValue::by_val(fx.bcx.ins().udiv_imm(diff_bytes, pointee_size as i64), usize_layout)
             } else {
-                fx.bcx.ins().sdiv_imm(diff_bytes, pointee_size as i64)
+                let isize_layout = fx.layout_of(fx.tcx.types.isize);
+                CValue::by_val(fx.bcx.ins().sdiv_imm(diff_bytes, pointee_size as i64), isize_layout)
             };
-            let val = CValue::by_val(diff, isize_layout);
             ret.write_cvalue(fx, val);
         };
 
@@ -742,7 +760,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
         };
 
         caller_location, () {
-            let caller_location = fx.get_caller_location(span);
+            let caller_location = fx.get_caller_location(source_info);
             ret.write_cvalue(fx, caller_location);
         };
 
@@ -761,16 +779,16 @@ fn codegen_regular_intrinsic_call<'tcx>(
                     if fx.tcx.is_compiler_builtins(LOCAL_CRATE) {
                         // special case for compiler-builtins to avoid having to patch it
                         crate::trap::trap_unimplemented(fx, "128bit atomics not yet supported");
-                        let ret_block = fx.get_block(destination.unwrap().1);
+                        let ret_block = fx.get_block(destination.unwrap());
                         fx.bcx.ins().jump(ret_block, &[]);
                         return;
                     } else {
-                        fx.tcx.sess.span_fatal(span, "128bit atomics not yet supported");
+                        fx.tcx.sess.span_fatal(source_info.span, "128bit atomics not yet supported");
                     }
                 }
                 ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
                 _ => {
-                    report_atomic_type_validation_error(fx, intrinsic, span, ty);
+                    report_atomic_type_validation_error(fx, intrinsic, source_info.span, ty);
                     return;
                 }
             }
@@ -789,16 +807,16 @@ fn codegen_regular_intrinsic_call<'tcx>(
                     if fx.tcx.is_compiler_builtins(LOCAL_CRATE) {
                         // special case for compiler-builtins to avoid having to patch it
                         crate::trap::trap_unimplemented(fx, "128bit atomics not yet supported");
-                        let ret_block = fx.get_block(destination.unwrap().1);
+                        let ret_block = fx.get_block(destination.unwrap());
                         fx.bcx.ins().jump(ret_block, &[]);
                         return;
                     } else {
-                        fx.tcx.sess.span_fatal(span, "128bit atomics not yet supported");
+                        fx.tcx.sess.span_fatal(source_info.span, "128bit atomics not yet supported");
                     }
                 }
                 ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
                 _ => {
-                    report_atomic_type_validation_error(fx, intrinsic, span, ty);
+                    report_atomic_type_validation_error(fx, intrinsic, source_info.span, ty);
                     return;
                 }
             }
@@ -812,7 +830,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
             match layout.ty.kind() {
                 ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
                 _ => {
-                    report_atomic_type_validation_error(fx, intrinsic, span, layout.ty);
+                    report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
                     return;
                 }
             }
@@ -830,7 +848,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
             match layout.ty.kind() {
                 ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
                 _ => {
-                    report_atomic_type_validation_error(fx, intrinsic, span, layout.ty);
+                    report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
                     return;
                 }
             }
@@ -850,7 +868,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
             match layout.ty.kind() {
                 ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
                 _ => {
-                    report_atomic_type_validation_error(fx, intrinsic, span, layout.ty);
+                    report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
                     return;
                 }
             }
@@ -868,7 +886,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
             match layout.ty.kind() {
                 ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
                 _ => {
-                    report_atomic_type_validation_error(fx, intrinsic, span, layout.ty);
+                    report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
                     return;
                 }
             }
@@ -886,7 +904,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
             match layout.ty.kind() {
                 ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
                 _ => {
-                    report_atomic_type_validation_error(fx, intrinsic, span, layout.ty);
+                    report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
                     return;
                 }
             }
@@ -904,7 +922,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
             match layout.ty.kind() {
                 ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
                 _ => {
-                    report_atomic_type_validation_error(fx, intrinsic, span, layout.ty);
+                    report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
                     return;
                 }
             }
@@ -922,7 +940,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
             match layout.ty.kind() {
                 ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
                 _ => {
-                    report_atomic_type_validation_error(fx, intrinsic, span, layout.ty);
+                    report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
                     return;
                 }
             }
@@ -940,7 +958,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
             match layout.ty.kind() {
                 ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
                 _ => {
-                    report_atomic_type_validation_error(fx, intrinsic, span, layout.ty);
+                    report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
                     return;
                 }
             }
@@ -958,7 +976,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
             match layout.ty.kind() {
                 ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
                 _ => {
-                    report_atomic_type_validation_error(fx, intrinsic, span, layout.ty);
+                    report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
                     return;
                 }
             }
@@ -976,7 +994,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
             match layout.ty.kind() {
                 ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
                 _ => {
-                    report_atomic_type_validation_error(fx, intrinsic, span, layout.ty);
+                    report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
                     return;
                 }
             }
@@ -994,7 +1012,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
             match layout.ty.kind() {
                 ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
                 _ => {
-                    report_atomic_type_validation_error(fx, intrinsic, span, layout.ty);
+                    report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
                     return;
                 }
             }
@@ -1012,7 +1030,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
             match layout.ty.kind() {
                 ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {}
                 _ => {
-                    report_atomic_type_validation_error(fx, intrinsic, span, layout.ty);
+                    report_atomic_type_validation_error(fx, intrinsic, source_info.span, layout.ty);
                     return;
                 }
             }
@@ -1130,6 +1148,6 @@ fn codegen_regular_intrinsic_call<'tcx>(
         };
     }
 
-    let ret_block = fx.get_block(destination.unwrap().1);
+    let ret_block = fx.get_block(destination.unwrap());
     fx.bcx.ins().jump(ret_block, &[]);
 }