Skip to content

Commit dc13373

Browse files
committed
Don't compute FnAbi for LLVM intrinsics
1 parent ae73a05 commit dc13373

6 files changed

Lines changed: 54 additions & 168 deletions

File tree

compiler/rustc_codegen_gcc/src/intrinsic/mod.rs

Lines changed: 9 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ mod simd;
44
#[cfg(feature = "master")]
55
use std::iter;
66

7-
use gccjit::{ComparisonOp, Function, FunctionType, RValue, ToRValue, UnaryOp};
87
#[cfg(feature = "master")]
9-
use gccjit::{FnAttribute, Type};
8+
use gccjit::Type;
9+
use gccjit::{ComparisonOp, Function, FunctionType, RValue, ToRValue, UnaryOp};
1010
#[cfg(feature = "master")]
1111
use rustc_abi::ExternAbi;
1212
use rustc_abi::{BackendRepr, HasDataLayout, WrappingRange};
@@ -24,16 +24,16 @@ use rustc_codegen_ssa::traits::{
2424
};
2525
use rustc_data_structures::fx::FxHashSet;
2626
use rustc_middle::bug;
27-
use rustc_middle::ty::layout::{FnAbiOf, LayoutOf};
28-
use rustc_middle::ty::{self, Instance, Ty};
2927
#[cfg(feature = "master")]
30-
use rustc_session::config;
28+
use rustc_middle::ty::layout::FnAbiOf;
29+
use rustc_middle::ty::layout::LayoutOf;
30+
use rustc_middle::ty::{self, Instance, Ty};
3131
use rustc_span::{Span, Symbol, sym};
32-
#[cfg(feature = "master")]
33-
use rustc_target::callconv::ArgAttributes;
3432
use rustc_target::callconv::{ArgAbi, PassMode};
3533

36-
use crate::abi::{FnAbiGcc, FnAbiGccExt, GccType};
34+
#[cfg(feature = "master")]
35+
use crate::abi::FnAbiGccExt;
36+
use crate::abi::GccType;
3737
use crate::builder::Builder;
3838
use crate::common::{SignType, TypeReflection};
3939
use crate::context::CodegenCx;
@@ -625,83 +625,6 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
625625
*func
626626
} else {
627627
self.linkage.set(FunctionType::Extern);
628-
let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty());
629-
assert!(!fn_abi.ret.is_indirect());
630-
assert!(!fn_abi.c_variadic);
631-
632-
let return_type = match fn_abi.ret.mode {
633-
PassMode::Ignore => self.type_void(),
634-
PassMode::Direct(_) | PassMode::Pair(..) => {
635-
fn_abi.ret.layout.immediate_gcc_type(self)
636-
}
637-
PassMode::Cast { .. } | PassMode::Indirect { .. } => {
638-
unreachable!()
639-
}
640-
};
641-
642-
#[cfg(feature = "master")]
643-
let mut non_null_args = Vec::new();
644-
645-
#[cfg(feature = "master")]
646-
let mut apply_attrs =
647-
|mut ty: Type<'gcc>, attrs: &ArgAttributes, arg_index: usize| {
648-
if self.sess().opts.optimize == config::OptLevel::No {
649-
return ty;
650-
}
651-
if attrs.regular.contains(rustc_target::callconv::ArgAttribute::NoAlias) {
652-
ty = ty.make_restrict()
653-
}
654-
if attrs.regular.contains(rustc_target::callconv::ArgAttribute::NonNull) {
655-
non_null_args.push(arg_index as i32 + 1);
656-
}
657-
ty
658-
};
659-
#[cfg(not(feature = "master"))]
660-
let apply_attrs = |ty: Type<'gcc>, _attrs: &ArgAttributes, _arg_index: usize| ty;
661-
662-
let mut argument_tys = Vec::with_capacity(fn_abi.args.len());
663-
for arg in fn_abi.args.iter() {
664-
match arg.mode {
665-
PassMode::Ignore => {}
666-
PassMode::Pair(a, b) => {
667-
let arg_pos = argument_tys.len();
668-
argument_tys.push(apply_attrs(
669-
arg.layout.scalar_pair_element_gcc_type(self, 0),
670-
&a,
671-
arg_pos,
672-
));
673-
argument_tys.push(apply_attrs(
674-
arg.layout.scalar_pair_element_gcc_type(self, 1),
675-
&b,
676-
arg_pos + 1,
677-
));
678-
}
679-
PassMode::Direct(attrs) => argument_tys.push(apply_attrs(
680-
arg.layout.immediate_gcc_type(self),
681-
&attrs,
682-
argument_tys.len(),
683-
)),
684-
PassMode::Indirect { .. } | PassMode::Cast { .. } => {
685-
unreachable!()
686-
}
687-
}
688-
}
689-
690-
#[cfg(feature = "master")]
691-
let fn_attrs = if non_null_args.is_empty() {
692-
Vec::new()
693-
} else {
694-
vec![FnAttribute::NonNull(non_null_args)]
695-
};
696-
697-
let fn_ty = FnAbiGcc {
698-
return_type,
699-
arguments_type: argument_tys,
700-
is_c_variadic: false,
701-
on_stack_param_indices: FxHashSet::default(),
702-
#[cfg(feature = "master")]
703-
fn_attributes: fn_attrs,
704-
};
705628

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

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

717-
self.on_stack_function_params
718-
.borrow_mut()
719-
.insert(func, fn_ty.on_stack_param_indices);
720-
#[cfg(feature = "master")]
721-
for fn_attr in fn_ty.fn_attributes {
722-
func.add_attribute(fn_attr);
723-
}
640+
self.on_stack_function_params.borrow_mut().insert(func, FxHashSet::default());
724641

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

compiler/rustc_codegen_llvm/src/intrinsic.rs

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -646,32 +646,34 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
646646
) -> Self::Value {
647647
let tcx = self.tcx();
648648

649-
// FIXME remove usage of fn_abi
650-
let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty());
651-
assert!(!fn_abi.ret.is_indirect());
652-
assert!(!fn_abi.c_variadic);
653-
654-
let llreturn_ty = match &fn_abi.ret.mode {
655-
PassMode::Ignore => self.type_void(),
656-
PassMode::Direct(_) | PassMode::Pair(..) => fn_abi.ret.layout.immediate_llvm_type(self),
657-
PassMode::Cast { .. } | PassMode::Indirect { .. } => {
658-
unreachable!()
649+
let fn_ty = instance.ty(tcx, self.typing_env());
650+
let fn_sig = match *fn_ty.kind() {
651+
ty::FnDef(def_id, args) => {
652+
tcx.instantiate_bound_regions_with_erased(tcx.fn_sig(def_id).instantiate(tcx, args))
659653
}
654+
_ => unreachable!(),
660655
};
656+
assert!(!fn_sig.c_variadic);
661657

662-
let mut llargument_tys = Vec::with_capacity(fn_abi.args.len());
663-
for arg in &fn_abi.args {
664-
match &arg.mode {
665-
PassMode::Ignore => {}
666-
PassMode::Direct(_) => llargument_tys.push(arg.layout.immediate_llvm_type(self)),
667-
PassMode::Pair(..) => {
668-
llargument_tys.push(arg.layout.scalar_pair_element_llvm_type(self, 0, true));
669-
llargument_tys.push(arg.layout.scalar_pair_element_llvm_type(self, 1, true));
670-
}
671-
PassMode::Indirect { .. } | PassMode::Cast { .. } => {
672-
unreachable!()
673-
}
674-
};
658+
let ret_layout = self.layout_of(fn_sig.output());
659+
let llreturn_ty = if ret_layout.is_zst() {
660+
self.type_void()
661+
} else {
662+
ret_layout.immediate_llvm_type(self)
663+
};
664+
665+
let mut llargument_tys = Vec::with_capacity(fn_sig.inputs().len());
666+
for &arg in fn_sig.inputs() {
667+
let arg_layout = self.layout_of(arg);
668+
if arg_layout.is_zst() {
669+
continue;
670+
}
671+
if let BackendRepr::ScalarPair(_, _) = arg_layout.backend_repr {
672+
llargument_tys.push(arg_layout.scalar_pair_element_llvm_type(self, 0, true));
673+
llargument_tys.push(arg_layout.scalar_pair_element_llvm_type(self, 1, true));
674+
continue;
675+
}
676+
llargument_tys.push(arg_layout.immediate_llvm_type(self));
675677
}
676678

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

compiler/rustc_monomorphize/src/mono_checks/abi_check.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,13 @@ fn check_call_site_abi<'tcx>(
207207
return;
208208
}
209209
let instance = ty::Instance::expect_resolve(tcx, typing_env, def_id, args, DUMMY_SP);
210+
211+
if let Some(name) = tcx.codegen_fn_attrs(instance.def_id()).symbol_name
212+
&& name.as_str().starts_with("llvm.")
213+
{
214+
return;
215+
}
216+
210217
tcx.fn_abi_of_instance(typing_env.as_query_input((instance, ty::List::empty())))
211218
}
212219
_ => {

compiler/rustc_target/src/callconv/mod.rs

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -417,20 +417,6 @@ impl<'a, Ty> ArgAbi<'a, Ty> {
417417
PassMode::Indirect { attrs, meta_attrs, on_stack: false }
418418
}
419419

420-
/// Pass this argument directly instead. Should NOT be used!
421-
/// Only exists because of past ABI mistakes that will take time to fix
422-
/// (see <https://github.com/rust-lang/rust/issues/115666>).
423-
#[track_caller]
424-
pub fn make_direct_deprecated(&mut self) {
425-
match self.mode {
426-
PassMode::Indirect { .. } => {
427-
self.mode = PassMode::Direct(ArgAttributes::new());
428-
}
429-
PassMode::Ignore | PassMode::Direct(_) | PassMode::Pair(_, _) => {} // already direct
430-
_ => panic!("Tried to make {:?} direct", self.mode),
431-
}
432-
}
433-
434420
/// Pass this argument indirectly, by passing a (thin or wide) pointer to the argument instead.
435421
/// This is valid for both sized and unsized arguments.
436422
#[track_caller]

compiler/rustc_target/src/spec/abi_map.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ impl AbiMap {
8484
// infallible lowerings
8585
(ExternAbi::C { .. }, _) => CanonAbi::C,
8686
(ExternAbi::Rust | ExternAbi::RustCall, _) => CanonAbi::Rust,
87+
88+
// Dummy mapping to prevent reporting an error in the frontend
8789
(ExternAbi::Unadjusted, _) => CanonAbi::C,
8890

8991
(ExternAbi::RustCold, _) if self.os == OsKind::Windows => CanonAbi::Rust,

compiler/rustc_ty_utils/src/abi.rs

Lines changed: 11 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,6 @@ fn fn_abi_sanity_check<'tcx>(
379379
) {
380380
fn fn_arg_sanity_check<'tcx>(
381381
cx: &LayoutCx<'tcx>,
382-
fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
383382
spec_abi: ExternAbi,
384383
arg: &ArgAbi<'tcx, Ty<'tcx>>,
385384
) {
@@ -409,28 +408,17 @@ fn fn_abi_sanity_check<'tcx>(
409408
PassMode::Direct(_) => {
410409
// Here the Rust type is used to determine the actual ABI, so we have to be very
411410
// careful. Scalar/Vector is fine, since backends will generally use
412-
// `layout.backend_repr` and ignore everything else. We should just reject
413-
//`Aggregate` entirely here, but some targets need to be fixed first.
411+
// `layout.backend_repr` and ignore everything else.
414412
match arg.layout.backend_repr {
415413
BackendRepr::Scalar(_)
416414
| BackendRepr::SimdVector { .. }
417415
| BackendRepr::ScalableVector { .. } => {}
418416
BackendRepr::ScalarPair(..) => {
419417
panic!("`PassMode::Direct` used for ScalarPair type {}", arg.layout.ty)
420418
}
421-
BackendRepr::Memory { sized } => {
422-
// For an unsized type we'd only pass the sized prefix, so there is no universe
423-
// in which we ever want to allow this.
424-
assert!(sized, "`PassMode::Direct` for unsized type in ABI: {:#?}", fn_abi);
425-
426-
// This really shouldn't happen even for sized aggregates, since
427-
// `immediate_llvm_type` will use `layout.fields` to turn this Rust type into an
428-
// LLVM type. This means all sorts of Rust type details leak into the ABI.
429-
// The unadjusted ABI however uses Direct for all args. It is ill-specified,
430-
// but unfortunately we need it for calling certain LLVM intrinsics.
431-
assert!(
432-
matches!(spec_abi, ExternAbi::Unadjusted),
433-
"`PassMode::Direct` for aggregates only allowed for \"unadjusted\"\n\
419+
BackendRepr::Memory { .. } => {
420+
panic!(
421+
"`PassMode::Direct` for aggregates not allowed\n\
434422
Problematic type: {:#?}",
435423
arg.layout,
436424
);
@@ -474,9 +462,9 @@ fn fn_abi_sanity_check<'tcx>(
474462
}
475463

476464
for arg in fn_abi.args.iter() {
477-
fn_arg_sanity_check(cx, fn_abi, spec_abi, arg);
465+
fn_arg_sanity_check(cx, spec_abi, arg);
478466
}
479-
fn_arg_sanity_check(cx, fn_abi, spec_abi, &fn_abi.ret);
467+
fn_arg_sanity_check(cx, spec_abi, &fn_abi.ret);
480468
}
481469

482470
#[tracing::instrument(level = "debug", skip(cx, instance))]
@@ -603,27 +591,11 @@ fn fn_abi_adjust_for_abi<'tcx>(
603591
abi: ExternAbi,
604592
fn_def_id: Option<DefId>,
605593
) {
606-
if abi == ExternAbi::Unadjusted {
607-
// The "unadjusted" ABI passes aggregates in "direct" mode. That's fragile but needed for
608-
// some LLVM intrinsics.
609-
fn unadjust<'tcx>(arg: &mut ArgAbi<'tcx, Ty<'tcx>>) {
610-
// This still uses `PassMode::Pair` for ScalarPair types. That's unlikely to be intended,
611-
// but who knows what breaks if we change this now.
612-
if matches!(arg.layout.backend_repr, BackendRepr::Memory { .. }) {
613-
assert!(
614-
arg.layout.backend_repr.is_sized(),
615-
"'unadjusted' ABI does not support unsized arguments"
616-
);
617-
}
618-
arg.make_direct_deprecated();
619-
}
620-
621-
unadjust(&mut fn_abi.ret);
622-
for arg in fn_abi.args.iter_mut() {
623-
unadjust(arg);
624-
}
625-
return;
626-
}
594+
assert_ne!(
595+
abi,
596+
ExternAbi::Unadjusted,
597+
"fn_abi_of_instance should not be called on LLVM intrinsics"
598+
);
627599

628600
let tcx = cx.tcx();
629601

0 commit comments

Comments
 (0)