Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 8 additions & 11 deletions compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,18 @@ use rustc_codegen_ssa::traits::{
ArgAbiBuilderMethods, BaseTypeCodegenMethods, BuilderMethods, ConstCodegenMethods,
IntrinsicCallBuilderMethods, LayoutTypeCodegenMethods,
};
use rustc_data_structures::fx::FxHashSet;
use rustc_middle::bug;
use rustc_middle::ty::layout::{FnAbiOf, LayoutOf};
#[cfg(feature = "master")]
use rustc_middle::ty::layout::FnAbiOf;
use rustc_middle::ty::layout::LayoutOf;
use rustc_middle::ty::{self, Instance, Ty};
use rustc_span::{Span, Symbol, sym};
use rustc_target::callconv::{ArgAbi, PassMode};

use crate::abi::{FnAbiGccExt, GccType};
#[cfg(feature = "master")]
use crate::abi::FnAbiGccExt;
use crate::abi::GccType;
use crate::builder::Builder;
use crate::common::{SignType, TypeReflection};
use crate::context::CodegenCx;
Expand Down Expand Up @@ -620,8 +625,6 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
*func
} else {
self.linkage.set(FunctionType::Extern);
let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty());
let fn_ty = fn_abi.gcc_type(self);

let func = match sym {
"llvm.fma.f16" => {
Expand All @@ -634,13 +637,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc

self.intrinsics.borrow_mut().insert(sym.to_string(), func);

self.on_stack_function_params
.borrow_mut()
.insert(func, fn_ty.on_stack_param_indices);
#[cfg(feature = "master")]
for fn_attr in fn_ty.fn_attributes {
func.add_attribute(fn_attr);
}
self.on_stack_function_params.borrow_mut().insert(func, FxHashSet::default());

crate::attributes::from_fn_attrs(self, func, instance);

Expand Down
33 changes: 27 additions & 6 deletions compiler/rustc_codegen_llvm/src/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -646,10 +646,32 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
) -> Self::Value {
let tcx = self.tcx();

// FIXME remove usage of fn_abi
let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty());
assert!(!fn_abi.ret.is_indirect());
let fn_ty = fn_abi.llvm_type(self);
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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because varargs are not handled. For varargs the LLVM function signature must only contain the non-varargs + an indication that the function is a vararg. Given that afaik we don't currently use any LLVM intrinsics that use varargs, I didn't implement that.


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
Expand All @@ -665,12 +687,11 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
let llfn = declare_raw_fn(
self,
sym,
fn_abi.llvm_cconv(self),
llvm::CCallConv,
llvm::UnnamedAddr::Global,
llvm::Visibility::Default,
fn_ty,
);
fn_abi.apply_attrs_llfn(self, llfn, Some(instance));

llfn
};
Expand Down
Loading