From 6fa5a2f66fddd473d265e646b41da43d20e87ec2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Wed, 8 Oct 2014 23:20:18 +0200 Subject: [PATCH] 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. --- src/librustc/middle/trans/base.rs | 10 ++++++++-- 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