Skip to content

Commit 6fa5a2f

Browse files
committed
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.
1 parent 57af34b commit 6fa5a2f

File tree

2 files changed

+15
-2
lines changed

2 files changed

+15
-2
lines changed

src/librustc/middle/trans/base.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2680,12 +2680,18 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
26802680

26812681
// We need the translated value here, because for enums the
26822682
// LLVM type is not fully determined by the Rust type.
2683-
let (v, inlineable, _) = consts::const_expr(ccx, &**expr, is_local);
2683+
let (v, inlineable, ty) = consts::const_expr(ccx, &**expr, is_local);
26842684
ccx.const_values().borrow_mut().insert(id, v);
26852685
let mut inlineable = inlineable;
26862686

26872687
unsafe {
2688-
let llty = llvm::LLVMTypeOf(v);
2688+
// boolean SSA values are i1, but they have to be stored in i8 slots,
2689+
// otherwise some LLVM optimization passes don't work as expected
2690+
let llty = if ty::type_is_bool(ty) {
2691+
llvm::LLVMInt8TypeInContext(ccx.llcx())
2692+
} else {
2693+
llvm::LLVMTypeOf(v)
2694+
};
26892695
if contains_null(sym.as_slice()) {
26902696
ccx.sess().fatal(
26912697
format!("Illegal null byte in export_name value: `{}`",

src/librustc/middle/trans/consts.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -701,6 +701,13 @@ pub fn trans_const(ccx: &CrateContext, m: ast::Mutability, id: ast::NodeId) {
701701
// At this point, get_item_val has already translated the
702702
// constant's initializer to determine its LLVM type.
703703
let v = ccx.const_values().borrow().get_copy(&id);
704+
// boolean SSA values are i1, but they have to be stored in i8 slots,
705+
// otherwise some LLVM optimization passes don't work as expected
706+
let v = if llvm::LLVMTypeOf(v) == Type::i1(ccx).to_ref() {
707+
llvm::LLVMConstZExt(v, Type::i8(ccx).to_ref())
708+
} else {
709+
v
710+
};
704711
llvm::LLVMSetInitializer(g, v);
705712

706713
// `get_item_val` left `g` with external linkage, but we just set an

0 commit comments

Comments
 (0)