Don't compute FnAbi for LLVM intrinsics in backends

This commit is contained in:
bjorn3
2026-01-08 10:47:29 +00:00
parent acc8c0bd65
commit f1ab003658
2 changed files with 34 additions and 115 deletions
@@ -4,9 +4,9 @@
#[cfg(feature = "master")]
use std::iter;
use gccjit::{ComparisonOp, Function, FunctionType, RValue, ToRValue, UnaryOp};
#[cfg(feature = "master")]
use gccjit::{FnAttribute, Type};
use gccjit::Type;
use gccjit::{ComparisonOp, Function, FunctionType, RValue, ToRValue, UnaryOp};
#[cfg(feature = "master")]
use rustc_abi::ExternAbi;
use rustc_abi::{BackendRepr, HasDataLayout, WrappingRange};
@@ -24,16 +24,16 @@
};
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};
#[cfg(feature = "master")]
use rustc_session::config;
use rustc_span::{Span, Symbol, sym};
#[cfg(feature = "master")]
use rustc_target::callconv::ArgAttributes;
use rustc_target::callconv::{ArgAbi, PassMode};
use crate::abi::{FnAbiGcc, 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;
@@ -625,83 +625,6 @@ fn codegen_llvm_intrinsic_call(
*func
} else {
self.linkage.set(FunctionType::Extern);
let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty());
assert!(!fn_abi.ret.is_indirect());
assert!(!fn_abi.c_variadic);
let return_type = match fn_abi.ret.mode {
PassMode::Ignore => self.type_void(),
PassMode::Direct(_) | PassMode::Pair(..) => {
fn_abi.ret.layout.immediate_gcc_type(self)
}
PassMode::Cast { .. } | PassMode::Indirect { .. } => {
unreachable!()
}
};
#[cfg(feature = "master")]
let mut non_null_args = Vec::new();
#[cfg(feature = "master")]
let mut apply_attrs =
|mut ty: Type<'gcc>, attrs: &ArgAttributes, arg_index: usize| {
if self.sess().opts.optimize == config::OptLevel::No {
return ty;
}
if attrs.regular.contains(rustc_target::callconv::ArgAttribute::NoAlias) {
ty = ty.make_restrict()
}
if attrs.regular.contains(rustc_target::callconv::ArgAttribute::NonNull) {
non_null_args.push(arg_index as i32 + 1);
}
ty
};
#[cfg(not(feature = "master"))]
let apply_attrs = |ty: Type<'gcc>, _attrs: &ArgAttributes, _arg_index: usize| ty;
let mut argument_tys = Vec::with_capacity(fn_abi.args.len());
for arg in fn_abi.args.iter() {
match arg.mode {
PassMode::Ignore => {}
PassMode::Pair(a, b) => {
let arg_pos = argument_tys.len();
argument_tys.push(apply_attrs(
arg.layout.scalar_pair_element_gcc_type(self, 0),
&a,
arg_pos,
));
argument_tys.push(apply_attrs(
arg.layout.scalar_pair_element_gcc_type(self, 1),
&b,
arg_pos + 1,
));
}
PassMode::Direct(attrs) => argument_tys.push(apply_attrs(
arg.layout.immediate_gcc_type(self),
&attrs,
argument_tys.len(),
)),
PassMode::Indirect { .. } | PassMode::Cast { .. } => {
unreachable!()
}
}
}
#[cfg(feature = "master")]
let fn_attrs = if non_null_args.is_empty() {
Vec::new()
} else {
vec![FnAttribute::NonNull(non_null_args)]
};
let fn_ty = FnAbiGcc {
return_type,
arguments_type: argument_tys,
is_c_variadic: false,
on_stack_param_indices: FxHashSet::default(),
#[cfg(feature = "master")]
fn_attributes: fn_attrs,
};
let func = match sym {
"llvm.fma.f16" => {
@@ -714,13 +637,7 @@ fn codegen_llvm_intrinsic_call(
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);
+25 -23
View File
@@ -646,32 +646,34 @@ fn codegen_llvm_intrinsic_call(
) -> 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());
assert!(!fn_abi.c_variadic);
let llreturn_ty = match &fn_abi.ret.mode {
PassMode::Ignore => self.type_void(),
PassMode::Direct(_) | PassMode::Pair(..) => fn_abi.ret.layout.immediate_llvm_type(self),
PassMode::Cast { .. } | PassMode::Indirect { .. } => {
unreachable!()
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_abi.args.len());
for arg in &fn_abi.args {
match &arg.mode {
PassMode::Ignore => {}
PassMode::Direct(_) => llargument_tys.push(arg.layout.immediate_llvm_type(self)),
PassMode::Pair(..) => {
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));
}
PassMode::Indirect { .. } | PassMode::Cast { .. } => {
unreachable!()
}
};
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);