about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/lib/llvm.rs13
-rw-r--r--src/librustc/middle/trans/base.rs2
2 files changed, 14 insertions, 1 deletions
diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs
index 5ec439ce386..40fe9bd5fc6 100644
--- a/src/librustc/lib/llvm.rs
+++ b/src/librustc/lib/llvm.rs
@@ -87,6 +87,8 @@ pub enum Attribute {
     NonLazyBindAttribute = 1 << 31,
 
     // Not added to LLVM yet, so may need to stay updated if LLVM changes.
+    // FIXME(#8199): if this changes, be sure to change the relevant constant
+    //               down below
     FixedStackSegment = 1 << 41,
 }
 
@@ -2116,6 +2118,17 @@ pub fn SetFunctionAttribute(Fn: ValueRef, attr: Attribute) {
         llvm::LLVMAddFunctionAttr(Fn, lower as c_uint, upper as c_uint);
     }
 }
+
+// FIXME(#8199): this shouldn't require this hackery. On i686
+//               (FixedStackSegment as u64) will return 0 instead of 1 << 41.
+//               Furthermore, if we use a match of any sort then an LLVM
+//               assertion is generated!
+pub fn SetFixedStackSegmentAttribute(Fn: ValueRef) {
+        let attr = 1u64 << 41;
+        let lower = attr & 0xffffffff;
+        let upper = (attr >> 32) & 0xffffffff;
+        llvm::LLVMAddFunctionAttr(Fn, lower as c_uint, upper as c_uint);
+}
 /* Memory-managed object interface to type handles. */
 
 pub struct TypeNames {
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index e727907f88e..fc39af095b7 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -456,7 +456,7 @@ pub fn set_always_inline(f: ValueRef) {
 }
 
 pub fn set_fixed_stack_segment(f: ValueRef) {
-    lib::llvm::SetFunctionAttribute(f, lib::llvm::FixedStackSegment)
+    lib::llvm::SetFixedStackSegmentAttribute(f);
 }
 
 pub fn set_glue_inlining(f: ValueRef, t: ty::t) {