diff options
| author | Björn Steinbrink <bsteinbr@gmail.com> | 2014-10-08 23:20:18 +0200 |
|---|---|---|
| committer | Björn Steinbrink <bsteinbr@gmail.com> | 2014-10-09 11:09:17 +0200 |
| commit | 6fa5a2f66fddd473d265e646b41da43d20e87ec2 (patch) | |
| tree | 93bf344c9e2090cbb46a17ee53913f2ae41cd6dd | |
| parent | 57af34b9ad2a4a5a8932ccb06d022d5f8c5807bc (diff) | |
| download | rust-6fa5a2f66fddd473d265e646b41da43d20e87ec2.tar.gz rust-6fa5a2f66fddd473d265e646b41da43d20e87ec2.zip | |
Properly translate boolean statics to be stored as i8
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.rs | 10 | ||||
| -rw-r--r-- | src/librustc/middle/trans/consts.rs | 7 |
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 |
