Skip to content

Commit 9ba3ed5

Browse files
committed
Move llvm intrinsic call to backend
1 parent bf5283c commit 9ba3ed5

1 file changed

Lines changed: 50 additions & 2 deletions

File tree

src/intrinsic/mod.rs

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use gccjit::Type;
99
use gccjit::{ComparisonOp, Function, FunctionType, RValue, ToRValue, UnaryOp};
1010
#[cfg(feature = "master")]
1111
use rustc_abi::ExternAbi;
12-
use rustc_abi::{BackendRepr, HasDataLayout};
12+
use rustc_abi::{BackendRepr, HasDataLayout, WrappingRange};
1313
use rustc_codegen_ssa::MemFlags;
1414
use rustc_codegen_ssa::base::wants_msvc_seh;
1515
use rustc_codegen_ssa::common::IntPredicate;
@@ -20,7 +20,7 @@ use rustc_codegen_ssa::mir::place::{PlaceRef, PlaceValue};
2020
use rustc_codegen_ssa::traits::MiscCodegenMethods;
2121
use rustc_codegen_ssa::traits::{
2222
ArgAbiBuilderMethods, BaseTypeCodegenMethods, BuilderMethods, ConstCodegenMethods,
23-
IntrinsicCallBuilderMethods,
23+
IntrinsicCallBuilderMethods, LayoutTypeCodegenMethods,
2424
};
2525
use rustc_middle::bug;
2626
#[cfg(feature = "master")]
@@ -609,6 +609,54 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
609609
Ok(())
610610
}
611611

612+
fn codegen_llvm_intrinsic_call(
613+
&mut self,
614+
instance: ty::Instance<'tcx>,
615+
args: &[OperandRef<'tcx, Self::Value>],
616+
is_cleanup: bool,
617+
) -> Self::Value {
618+
let fn_ptr = self.get_fn_addr(instance);
619+
let fn_ty = fn_ptr.get_type();
620+
621+
let mut llargs = vec![];
622+
623+
for arg in args {
624+
match arg.val {
625+
OperandValue::ZeroSized => {}
626+
OperandValue::Immediate(_) => llargs.push(arg.immediate()),
627+
OperandValue::Pair(a, b) => {
628+
llargs.push(a);
629+
llargs.push(b);
630+
}
631+
OperandValue::Ref(op_place_val) => {
632+
let mut llval = op_place_val.llval;
633+
// We can't use `PlaceRef::load` here because the argument
634+
// may have a type we don't treat as immediate, but the ABI
635+
// used for this call is passing it by-value. In that case,
636+
// the load would just produce `OperandValue::Ref` instead
637+
// of the `OperandValue::Immediate` we need for the call.
638+
llval = self.load(self.backend_type(arg.layout), llval, op_place_val.align);
639+
if let BackendRepr::Scalar(scalar) = arg.layout.backend_repr {
640+
if scalar.is_bool() {
641+
self.range_metadata(llval, WrappingRange { start: 0, end: 1 });
642+
}
643+
// We store bools as `i8` so we need to truncate to `i1`.
644+
llval = self.to_immediate_scalar(llval, scalar);
645+
}
646+
llargs.push(llval);
647+
}
648+
}
649+
}
650+
651+
// FIXME directly use the llvm intrinsic adjustment functions here
652+
let llret = self.call(fn_ty, None, None, fn_ptr, &llargs, None, None);
653+
if is_cleanup {
654+
self.apply_attrs_to_cleanup_callsite(llret);
655+
}
656+
657+
llret
658+
}
659+
612660
fn abort(&mut self) {
613661
let func = self.context.get_builtin_function("abort");
614662
let func: RValue<'gcc> = unsafe { std::mem::transmute(func) };

0 commit comments

Comments
 (0)