about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-06-08 11:55:04 +0000
committerbors <bors@rust-lang.org>2015-06-08 11:55:04 +0000
commit115121de3d4669a798e99aa69dfdbc7012b4181c (patch)
tree110ed67c5a218b0208013515017879efc5e79976
parent1ade076f62c9e8188c4fb5c888277a1673ac82cd (diff)
parente36e97ba51f512de2fd05e3250db4a7b72caae04 (diff)
downloadrust-115121de3d4669a798e99aa69dfdbc7012b4181c.tar.gz
rust-115121de3d4669a798e99aa69dfdbc7012b4181c.zip
Auto merge of #26088 - tamird:llvm35-fixes, r=alexcrichton
rebase of #25739, closes #25739. r? @alexcrichton 
-rw-r--r--src/librustc_llvm/lib.rs2
-rw-r--r--src/librustc_trans/trans/context.rs51
-rw-r--r--src/rustllvm/RustWrapper.cpp10
3 files changed, 52 insertions, 11 deletions
diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs
index a3b9a0e8467..379a7da459f 100644
--- a/src/librustc_llvm/lib.rs
+++ b/src/librustc_llvm/lib.rs
@@ -1772,6 +1772,8 @@ extern {
                          -> ValueRef;
 
     pub fn LLVMRustDebugMetadataVersion() -> u32;
+    pub fn LLVMVersionMajor() -> u32;
+    pub fn LLVMVersionMinor() -> u32;
 
     pub fn LLVMRustAddModuleFlag(M: ModuleRef,
                                  name: *const c_char,
diff --git a/src/librustc_trans/trans/context.rs b/src/librustc_trans/trans/context.rs
index 3818739c6cc..663a01e19f3 100644
--- a/src/librustc_trans/trans/context.rs
+++ b/src/librustc_trans/trans/context.rs
@@ -870,6 +870,11 @@ fn declare_intrinsic(ccx: &CrateContext, key: & &'static str) -> Option<ValueRef
     ifn!("llvm.trunc.f32", fn(t_f32) -> t_f32);
     ifn!("llvm.trunc.f64", fn(t_f64) -> t_f64);
 
+    ifn!("llvm.copysign.f32", fn(t_f32, t_f32) -> t_f32);
+    ifn!("llvm.copysign.f64", fn(t_f64, t_f64) -> t_f64);
+    ifn!("llvm.round.f32", fn(t_f32) -> t_f32);
+    ifn!("llvm.round.f64", fn(t_f64) -> t_f64);
+
     ifn!("llvm.rint.f32", fn(t_f32) -> t_f32);
     ifn!("llvm.rint.f64", fn(t_f64) -> t_f64);
     ifn!("llvm.nearbyint.f32", fn(t_f32) -> t_f32);
@@ -928,22 +933,48 @@ fn declare_intrinsic(ccx: &CrateContext, key: & &'static str) -> Option<ValueRef
     ifn!("llvm.lifetime.end", fn(t_i64, i8p) -> 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. 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) => (
-            ifn!($name, fn($($arg),*) -> $ret);
+        ($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!
+                ifn!($name, fn($($arg),*) -> $ret);
+            } else if *key == $name {
+                let f = declare::declare_cfn(ccx, stringify!($cname),
+                                             Type::func(&[$($arg),*], &$ret),
+                                             ty::mk_nil(ccx.tcx()));
+                ccx.intrinsics().borrow_mut().insert($name, f.clone());
+                return Some(f);
+            }
         )
     }
 
-    compatible_ifn!("llvm.copysign.f32", copysignf(t_f32, t_f32) -> 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.assume", noop(llvmcompat_assume(i1) -> void), 6);
 
     if ccx.sess().opts.debuginfo != NoDebugInfo {
         ifn!("llvm.dbg.declare", fn(Type::metadata(ccx), Type::metadata(ccx)) -> void);
diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp
index 66db7326d21..ad6533e5480 100644
--- a/src/rustllvm/RustWrapper.cpp
+++ b/src/rustllvm/RustWrapper.cpp
@@ -233,10 +233,18 @@ DIT unwrapDI(LLVMMetadataRef ref) {
     return DIT(ref ? unwrap<MDNode>(ref) : NULL);
 }
 
-extern "C" const uint32_t LLVMRustDebugMetadataVersion() {
+extern "C" uint32_t LLVMRustDebugMetadataVersion() {
     return DEBUG_METADATA_VERSION;
 }
 
+extern "C" uint32_t LLVMVersionMinor() {
+  return LLVM_VERSION_MINOR;
+}
+
+extern "C" uint32_t LLVMVersionMajor() {
+  return LLVM_VERSION_MAJOR;
+}
+
 extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M,
                                       const char *name,
                                       uint32_t value) {