about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-10-09 12:47:01 +0000
committerbors <bors@rust-lang.org>2014-10-09 12:47:01 +0000
commitdfd52817ee81676e0cdba4ab2c5badf195fcfda7 (patch)
tree3e86928c8ae80c19b128ac50bbce3ff439eea4ec
parente6cfb56a5cee28b08ae9d2dcbb2552497ce922c1 (diff)
parent6fa5a2f66fddd473d265e646b41da43d20e87ec2 (diff)
downloadrust-dfd52817ee81676e0cdba4ab2c5badf195fcfda7.tar.gz
rust-dfd52817ee81676e0cdba4ab2c5badf195fcfda7.zip
auto merge of #17875 : dotdash/rust/static_bool, r=alexcrichton
While booleans are represented as i1 in SSA values, LLVM expects them
to be stored/loaded as i8 values. Using i1 as we do now works, but
kills some optimizations, so we should switch to i8, just like we do
everywhere else.

Fixes #16959.
-rw-r--r--src/librustc/middle/trans/base.rs10
-rw-r--r--src/librustc/middle/trans/consts.rs7
2 files changed, 15 insertions, 2 deletions
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index f65827753aa..d175919fb81 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -2680,12 +2680,18 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
 
                     // We need the translated value here, because for enums the
                     // LLVM type is not fully determined by the Rust type.
-                    let (v, inlineable, _) = consts::const_expr(ccx, &**expr, is_local);
+                    let (v, inlineable, ty) = consts::const_expr(ccx, &**expr, is_local);
                     ccx.const_values().borrow_mut().insert(id, v);
                     let mut inlineable = inlineable;
 
                     unsafe {
-                        let llty = llvm::LLVMTypeOf(v);
+                        // boolean SSA values are i1, but they have to be stored in i8 slots,
+                        // otherwise some LLVM optimization passes don't work as expected
+                        let llty = if ty::type_is_bool(ty) {
+                            llvm::LLVMInt8TypeInContext(ccx.llcx())
+                        } else {
+                            llvm::LLVMTypeOf(v)
+                        };
                         if contains_null(sym.as_slice()) {
                             ccx.sess().fatal(
                                 format!("Illegal null byte in export_name value: `{}`",
diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs
index c8356ccd2f0..5e4692bd0f6 100644
--- a/src/librustc/middle/trans/consts.rs
+++ b/src/librustc/middle/trans/consts.rs
@@ -701,6 +701,13 @@ pub fn trans_const(ccx: &CrateContext, m: ast::Mutability, id: ast::NodeId) {
         // At this point, get_item_val has already translated the
         // constant's initializer to determine its LLVM type.
         let v = ccx.const_values().borrow().get_copy(&id);
+        // boolean SSA values are i1, but they have to be stored in i8 slots,
+        // otherwise some LLVM optimization passes don't work as expected
+        let v = if llvm::LLVMTypeOf(v) == Type::i1(ccx).to_ref() {
+            llvm::LLVMConstZExt(v, Type::i8(ccx).to_ref())
+        } else {
+            v
+        };
         llvm::LLVMSetInitializer(g, v);
 
         // `get_item_val` left `g` with external linkage, but we just set an