]> git.lizzy.rs Git - rust.git/commitdiff
rustc: Fix support for LLVM 3.3
authorAlex Crichton <alex@alexcrichton.com>
Wed, 5 Mar 2014 23:14:16 +0000 (15:14 -0800)
committerAlex Crichton <alex@alexcrichton.com>
Thu, 6 Mar 2014 02:05:05 +0000 (18:05 -0800)
The llvm.copysign and llvm.round intrinsics weren't added until LLVM 3.4, so if
we're on LLVM 3.3 we lower these to calls in libm instead of LLVM intrinsics.

This should fix our travis failures.

src/librustc/lib/llvm.rs
src/librustc/middle/trans/base.rs
src/rustllvm/RustWrapper.cpp

index bea08366db3926356ade8f5d61acc9f4aa2019f7..448b9e30dcd3df551460808b70d44dc48f0eba3d 100644 (file)
@@ -1771,6 +1771,7 @@ pub fn LLVMRustArchiveReadSection(AR: ArchiveRef, name: *c_char,
         pub fn LLVMRustDestroyArchive(AR: ArchiveRef);
 
         pub fn LLVMRustSetDLLExportStorageClass(V: ValueRef);
+        pub fn LLVMVersionMinor() -> c_int;
     }
 }
 
index f838bcf9c5ec25406784650ca8e50e3c76ef9581..bd4ef16d19d79733f5ab1931f77cd46dda066ef7 100644 (file)
@@ -2286,8 +2286,6 @@ pub fn declare_intrinsics(llmod: ModuleRef) -> HashMap<&'static str, ValueRef> {
 
     ifn!(intrinsics, "llvm.fabs.f32", [Type::f32()], Type::f32());
     ifn!(intrinsics, "llvm.fabs.f64", [Type::f64()], Type::f64());
-    ifn!(intrinsics, "llvm.copysign.f32", [Type::f32(), Type::f32()], Type::f32());
-    ifn!(intrinsics, "llvm.copysign.f64", [Type::f64(), Type::f64()], Type::f64());
 
     ifn!(intrinsics, "llvm.floor.f32",[Type::f32()], Type::f32());
     ifn!(intrinsics, "llvm.floor.f64",[Type::f64()], Type::f64());
@@ -2300,8 +2298,6 @@ pub fn declare_intrinsics(llmod: ModuleRef) -> HashMap<&'static str, ValueRef> {
     ifn!(intrinsics, "llvm.rint.f64", [Type::f64()], Type::f64());
     ifn!(intrinsics, "llvm.nearbyint.f32", [Type::f32()], Type::f32());
     ifn!(intrinsics, "llvm.nearbyint.f64", [Type::f64()], Type::f64());
-    ifn!(intrinsics, "llvm.round.f32", [Type::f32()], Type::f32());
-    ifn!(intrinsics, "llvm.round.f64", [Type::f64()], Type::f64());
 
     ifn!(intrinsics, "llvm.ctpop.i8", [Type::i8()], Type::i8());
     ifn!(intrinsics, "llvm.ctpop.i16",[Type::i16()], Type::i16());
@@ -2378,6 +2374,32 @@ pub fn declare_intrinsics(llmod: ModuleRef) -> HashMap<&'static str, ValueRef> {
 
     ifn!(intrinsics, "llvm.expect.i1", [Type::i1(), Type::i1()], Type::i1());
 
+    // 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.
+    macro_rules! compatible_ifn (
+        ($intrinsics:ident, $name:expr, $cname:expr, $args:expr, $ret:expr) => ({
+            let name = $name;
+            if unsafe { llvm::LLVMVersionMinor() >= 4 } {
+                ifn!($intrinsics, $name, $args, $ret);
+            } else {
+                let f = decl_cdecl_fn(llmod, $cname,
+                                      Type::func($args, &$ret),
+                                      ty::mk_nil());
+                $intrinsics.insert(name, f);
+            }
+        })
+    )
+
+    compatible_ifn!(intrinsics, "llvm.copysign.f32", "copysignf",
+                    [Type::f32(), Type::f32()], Type::f32());
+    compatible_ifn!(intrinsics, "llvm.copysign.f64", "copysign",
+                    [Type::f64(), Type::f64()], Type::f64());
+    compatible_ifn!(intrinsics, "llvm.round.f32", "roundf",
+                    [Type::f32()], Type::f32());
+    compatible_ifn!(intrinsics, "llvm.round.f64", "round",
+                    [Type::f64()], Type::f64());
+
     return intrinsics;
 }
 
index d8fc5b15850e127cef3f7eff618876ed2e484200..aaaf512bcf3fe2cc5ae471523669498f5251b3d7 100644 (file)
@@ -652,3 +652,8 @@ LLVMRustSetDLLExportStorageClass(LLVMValueRef Value) {
     LLVMSetLinkage(Value, LLVMDLLExportLinkage);
 }
 #endif
+
+extern "C" int
+LLVMVersionMinor() {
+    return LLVM_VERSION_MINOR;
+}