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

Code before:

        if result.layout.ty.is_bool() {
            let val = self.from_immediate(llval);
            self.store_to_place(val, result.val);
        } else if !result.layout.ty.is_unit() {
            self.store_to_place(llval, result.val);
        }
        Ok(())
    }

    fn codegen_llvm_intrinsic_call(
        &mut self,
        instance: ty::Instance<'tcx>,
        args: &[OperandRef<'tcx, Self::Value>],
        is_cleanup: bool,
    ) -> 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) {

Review comment (bug):
why this assertion? I mean I get the point that there are very few LLVM intrinsics that use vararg arguments, but I don't get what exactly fails for vararg functions

Code after:

        if result.layout.ty.is_bool() {
            let val = self.from_immediate(llval);
            self.store_to_place(val, result.val);
        } else if !result.layout.ty.is_unit() {
            self.store_to_place(llval, result.val);
        }
        Ok(())
    }

    fn codegen_llvm_intrinsic_call(
        &mut self,
        instance: ty::Instance<'tcx>,
        args: &[OperandRef<'tcx, Self::Value>],
        is_cleanup: bool,
    ) -> 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