Repository: rust-lang/rust
File: compiler/rustc_codegen_llvm/src/intrinsic.rs (Rust)

Code before:
    ) -> Self::Value {
        let tcx = self.tcx();

        let fn_ty = instance.ty(tcx, self.typing_env());
        let fn_sig = match *fn_ty.kind() {
            ty::FnDef(def_id, args) => {
                tcx.instantiate_bound_regions_with_erased(tcx.fn_sig(def_id).instantiate(tcx, args))
            }
            _ => unreachable!(),
        };
        assert!(!fn_sig.c_variadic);

        let ret_layout = self.layout_of(fn_sig.output());
        let llreturn_ty = if ret_layout.is_zst() {
            self.type_void()
        } else {
            ret_layout.immediate_llvm_type(self)
        };

        let mut llargument_tys = Vec::with_capacity(fn_sig.inputs().len());
        for &arg in fn_sig.inputs() {
            let arg_layout = self.layout_of(arg);
            if arg_layout.is_zst() {
                continue;
            }
            if let BackendRepr::ScalarPair(_, _) = arg_layout.backend_repr {
                llargument_tys.push(arg_layout.scalar_pair_element_llvm_type(self, 0, true));
                llargument_tys.push(arg_layout.scalar_pair_element_llvm_type(self, 1, true));
                continue;
            }
            llargument_tys.push(arg_layout.immediate_llvm_type(self));
        }

        let fn_ty = self.type_func(&llargument_tys, llreturn_ty);

        let fn_ptr = if let Some(&llfn) = self.intrinsic_instances.borrow().get(&instance) {
            llfn
        } else {
            let sym = tcx.symbol_name(instance).name;

            // FIXME use get_intrinsic
            let llfn = if let Some(llfn) = self.get_declared_value(sym) {
                llfn
            } else {
                // Function addresses in Rust are never significant, allowing functions to
                // be merged.
                let llfn = declare_raw_fn(
                    self,
                    sym,
                    llvm::CCallConv,
                    llvm::UnnamedAddr::Global,

Review comment (suggestion):
i don't know if it's a good idea to allow passing 2-tuples, slices or trait objects to LLVM intrinsics (afaik those are the only ones that use `BackendRepr::ScalarPair`). Ik it was previously allowed because the FnAbi calculation was the same for all functions, but now that we have the chance, we should probably disallow this explicitly

Code after:
    ) -> Self::Value {
        let tcx = self.tcx();

        let fn_ty = instance.ty(tcx, self.typing_env());
        let fn_sig = match *fn_ty.kind() {
            ty::FnDef(def_id, args) => {
                tcx.instantiate_bound_regions_with_erased(tcx.fn_sig(def_id).instantiate(tcx, args))
            }
            _ => unreachable!(),
        };
        assert!(!fn_sig.c_variadic);

        let ret_layout = self.layout_of(fn_sig.output());
        let llreturn_ty = if ret_layout.is_zst() {
            self.type_void()
        } else {
            ret_layout.immediate_llvm_type(self)
        };

        let mut llargument_tys = Vec::with_capacity(fn_sig.inputs().len());
        for &arg in fn_sig.inputs() {
            let arg_layout = self.layout_of(arg);
            if arg_layout.is_zst() {
                continue;
            }
            llargument_tys.push(arg_layout.immediate_llvm_type(self));
        }

        let fn_ty = self.type_func(&llargument_tys, llreturn_ty);

        let fn_ptr = if let Some(&llfn) = self.intrinsic_instances.borrow().get(&instance) {
            llfn
        } else {
            let sym = tcx.symbol_name(instance).name;

            // FIXME use get_intrinsic
            let llfn = if let Some(llfn) = self.get_declared_value(sym) {
                llfn
            } else {
                // Function addresses in Rust are never significant, allowing functions to
                // be merged.
                let llfn = declare_raw_fn(
                    self,
                    sym,
                    llvm::CCallConv,
                    llvm::UnnamedAddr::Global,
                    llvm::Visibility::Default,
                    fn_ty,
                );

                llfn