From d22e88ee7e4f1eab421c17f207cac89f19c721a3 Mon Sep 17 00:00:00 2001 From: Luca Bruno Date: Sat, 24 Jan 2015 12:00:35 +0100 Subject: [PATCH 1/2] rustc_trans: don't hardcode llvm version for conditional intrinsics This commit introduce a third parameter for compatible_ifn!, as new intrinsics are being added in recent LLVM releases and there is no need to hardcode a specific case. Signed-off-by: Luca Bruno --- src/librustc_trans/trans/context.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/librustc_trans/trans/context.rs b/src/librustc_trans/trans/context.rs index e54962dc08552..c449bd7037cbf 100644 --- a/src/librustc_trans/trans/context.rs +++ b/src/librustc_trans/trans/context.rs @@ -874,11 +874,10 @@ fn declare_intrinsic(ccx: &CrateContext, key: & &'static str) -> Option void); // Some intrinsics were introduced in later versions of LLVM, but they have - // fallbacks in libc or libm and such. Currently, all of these intrinsics - // were introduced in LLVM 3.4, so we case on that. + // fallbacks in libc or libm and such. macro_rules! compatible_ifn { - ($name:expr, $cname:ident ($($arg:expr),*) -> $ret:expr) => ( - if unsafe { llvm::LLVMVersionMinor() >= 4 } { + ($name:expr, $cname:ident ($($arg:expr),*) -> $ret:expr, $llvm_version:expr) => ( + if unsafe { llvm::LLVMVersionMinor() >= $llvm_version } { // The `if key == $name` is already in ifn! ifn!($name, fn($($arg),*) -> $ret); } else if *key == $name { @@ -891,10 +890,10 @@ fn declare_intrinsic(ccx: &CrateContext, key: & &'static str) -> Option t_f32); - compatible_ifn!("llvm.copysign.f64", copysign(t_f64, t_f64) -> t_f64); - compatible_ifn!("llvm.round.f32", roundf(t_f32) -> t_f32); - compatible_ifn!("llvm.round.f64", round(t_f64) -> t_f64); + compatible_ifn!("llvm.copysign.f32", copysignf(t_f32, t_f32) -> t_f32, 4); + compatible_ifn!("llvm.copysign.f64", copysign(t_f64, t_f64) -> t_f64, 4); + compatible_ifn!("llvm.round.f32", roundf(t_f32) -> t_f32, 4); + compatible_ifn!("llvm.round.f64", round(t_f64) -> t_f64, 4); if ccx.sess().opts.debuginfo != NoDebugInfo { From 25f194ed46cbc622f84982dd7e00a9e3c2fae4f5 Mon Sep 17 00:00:00 2001 From: David Voit Date: Sat, 23 May 2015 23:33:37 +0200 Subject: [PATCH 2/2] rustc_trans: 'assume' intrinsic is only available on LLVM >= 3.6 Based on the patch from Luca Bruno. Instead of creating an empty C function in the rt, this version creates an shim noop function using llvm. This function is declared as internal, and the unsupported assume intrinsic and the shim gets completly removed by the optimizer. --- src/librustc_trans/trans/context.rs | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/librustc_trans/trans/context.rs b/src/librustc_trans/trans/context.rs index c449bd7037cbf..d4253f61ad0d1 100644 --- a/src/librustc_trans/trans/context.rs +++ b/src/librustc_trans/trans/context.rs @@ -871,11 +871,33 @@ fn declare_intrinsic(ccx: &CrateContext, key: & &'static str) -> Option void); ifn!("llvm.expect.i1", fn(i1, i1) -> i1); - ifn!("llvm.assume", fn(i1) -> void); // Some intrinsics were introduced in later versions of LLVM, but they have // fallbacks in libc or libm and such. macro_rules! compatible_ifn { + ($name:expr, noop($cname:ident ($($arg:expr),*) -> void), $llvm_version:expr) => ( + if unsafe { llvm::LLVMVersionMinor() >= $llvm_version } { + // The `if key == $name` is already in ifn! + ifn!($name, fn($($arg),*) -> void); + } else if *key == $name { + let f = declare::declare_cfn(ccx, stringify!($cname), + Type::func(&[$($arg),*], &void), + ty::mk_nil(ccx.tcx())); + llvm::SetLinkage(f, llvm::InternalLinkage); + + let bld = ccx.builder(); + let llbb = unsafe { + llvm::LLVMAppendBasicBlockInContext(ccx.llcx(), f, + "entry-block\0".as_ptr() as *const _) + }; + + bld.position_at_end(llbb); + bld.ret_void(); + + ccx.intrinsics().borrow_mut().insert($name, f.clone()); + return Some(f); + } + ); ($name:expr, $cname:ident ($($arg:expr),*) -> $ret:expr, $llvm_version:expr) => ( if unsafe { llvm::LLVMVersionMinor() >= $llvm_version } { // The `if key == $name` is already in ifn! @@ -894,6 +916,7 @@ fn declare_intrinsic(ccx: &CrateContext, key: & &'static str) -> Option t_f64, 4); compatible_ifn!("llvm.round.f32", roundf(t_f32) -> t_f32, 4); compatible_ifn!("llvm.round.f64", round(t_f64) -> t_f64, 4); + compatible_ifn!("llvm.assume", noop(llvmcompat_assume(i1) -> void), 6); if ccx.sess().opts.debuginfo != NoDebugInfo {