Skip to content

Commit ae98d5a

Browse files
committed
Don't use data object for non-primitive scalars
Fixes rust-lang#1041
1 parent e0f3ad2 commit ae98d5a

File tree

1 file changed

+66
-60
lines changed

1 file changed

+66
-60
lines changed

src/constant.rs

Lines changed: 66 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
//! Handling of `static`s, `const`s and promoted allocations
22
3-
use rustc_span::DUMMY_SP;
4-
5-
use rustc_ast::Mutability;
63
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
74
use rustc_errors::ErrorReported;
85
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
96
use rustc_middle::mir::interpret::{
10-
alloc_range, read_target_uint, AllocId, Allocation, ConstValue, ErrorHandled, GlobalAlloc,
11-
Scalar,
7+
read_target_uint, AllocId, Allocation, ConstValue, ErrorHandled, GlobalAlloc, Scalar,
128
};
139
use rustc_middle::ty::ConstKind;
10+
use rustc_span::DUMMY_SP;
1411

1512
use cranelift_codegen::ir::GlobalValueData;
1613
use cranelift_module::*;
@@ -171,65 +168,74 @@ pub(crate) fn codegen_const_value<'tcx>(
171168
}
172169

173170
match const_val {
174-
ConstValue::Scalar(x) => {
175-
if fx.clif_type(layout.ty).is_none() {
176-
let (size, align) = (layout.size, layout.align.pref);
177-
let mut alloc = Allocation::from_bytes(
178-
std::iter::repeat(0).take(size.bytes_usize()).collect::<Vec<u8>>(),
179-
align,
180-
Mutability::Not,
181-
);
182-
alloc.write_scalar(fx, alloc_range(Size::ZERO, size), x.into()).unwrap();
183-
let alloc = fx.tcx.intern_const_alloc(alloc);
184-
return CValue::by_ref(pointer_for_allocation(fx, alloc), layout);
185-
}
186-
187-
match x {
188-
Scalar::Int(int) => CValue::const_val(fx, layout, int),
189-
Scalar::Ptr(ptr) => {
190-
let alloc_kind = fx.tcx.get_global_alloc(ptr.alloc_id);
191-
let base_addr = match alloc_kind {
192-
Some(GlobalAlloc::Memory(alloc)) => {
193-
let data_id = data_id_for_alloc_id(
194-
&mut fx.constants_cx,
195-
fx.module,
196-
ptr.alloc_id,
197-
alloc.mutability,
198-
);
199-
let local_data_id =
200-
fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
201-
if fx.clif_comments.enabled() {
202-
fx.add_comment(local_data_id, format!("{:?}", ptr.alloc_id));
203-
}
204-
fx.bcx.ins().global_value(fx.pointer_type, local_data_id)
205-
}
206-
Some(GlobalAlloc::Function(instance)) => {
207-
let func_id = crate::abi::import_function(fx.tcx, fx.module, instance);
208-
let local_func_id =
209-
fx.module.declare_func_in_func(func_id, &mut fx.bcx.func);
210-
fx.bcx.ins().func_addr(fx.pointer_type, local_func_id)
211-
}
212-
Some(GlobalAlloc::Static(def_id)) => {
213-
assert!(fx.tcx.is_static(def_id));
214-
let data_id = data_id_for_static(fx.tcx, fx.module, def_id, false);
215-
let local_data_id =
216-
fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
217-
if fx.clif_comments.enabled() {
218-
fx.add_comment(local_data_id, format!("{:?}", def_id));
219-
}
220-
fx.bcx.ins().global_value(fx.pointer_type, local_data_id)
171+
ConstValue::Scalar(x) => match x {
172+
Scalar::Int(int) => {
173+
if fx.clif_type(layout.ty).is_some() {
174+
return CValue::const_val(fx, layout, int);
175+
} else {
176+
let raw_val = int.to_bits(int.size()).unwrap();
177+
let val = match int.size().bytes() {
178+
1 => fx.bcx.ins().iconst(types::I8, raw_val as i64),
179+
2 => fx.bcx.ins().iconst(types::I16, raw_val as i64),
180+
4 => fx.bcx.ins().iconst(types::I32, raw_val as i64),
181+
8 => fx.bcx.ins().iconst(types::I64, raw_val as i64),
182+
16 => {
183+
let lsb = fx.bcx.ins().iconst(types::I64, raw_val as u64 as i64);
184+
let msb =
185+
fx.bcx.ins().iconst(types::I64, (raw_val >> 64) as u64 as i64);
186+
fx.bcx.ins().iconcat(lsb, msb)
221187
}
222-
None => bug!("missing allocation {:?}", ptr.alloc_id),
223-
};
224-
let val = if ptr.offset.bytes() != 0 {
225-
fx.bcx.ins().iadd_imm(base_addr, i64::try_from(ptr.offset.bytes()).unwrap())
226-
} else {
227-
base_addr
188+
_ => unreachable!(),
228189
};
229-
CValue::by_val(val, layout)
190+
191+
let place = CPlace::new_stack_slot(fx, layout);
192+
place.to_ptr().store(fx, val, MemFlags::trusted());
193+
place.to_cvalue(fx)
230194
}
231195
}
232-
}
196+
Scalar::Ptr(ptr) => {
197+
let alloc_kind = fx.tcx.get_global_alloc(ptr.alloc_id);
198+
let base_addr = match alloc_kind {
199+
Some(GlobalAlloc::Memory(alloc)) => {
200+
let data_id = data_id_for_alloc_id(
201+
&mut fx.constants_cx,
202+
fx.module,
203+
ptr.alloc_id,
204+
alloc.mutability,
205+
);
206+
let local_data_id =
207+
fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
208+
if fx.clif_comments.enabled() {
209+
fx.add_comment(local_data_id, format!("{:?}", ptr.alloc_id));
210+
}
211+
fx.bcx.ins().global_value(fx.pointer_type, local_data_id)
212+
}
213+
Some(GlobalAlloc::Function(instance)) => {
214+
let func_id = crate::abi::import_function(fx.tcx, fx.module, instance);
215+
let local_func_id =
216+
fx.module.declare_func_in_func(func_id, &mut fx.bcx.func);
217+
fx.bcx.ins().func_addr(fx.pointer_type, local_func_id)
218+
}
219+
Some(GlobalAlloc::Static(def_id)) => {
220+
assert!(fx.tcx.is_static(def_id));
221+
let data_id = data_id_for_static(fx.tcx, fx.module, def_id, false);
222+
let local_data_id =
223+
fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
224+
if fx.clif_comments.enabled() {
225+
fx.add_comment(local_data_id, format!("{:?}", def_id));
226+
}
227+
fx.bcx.ins().global_value(fx.pointer_type, local_data_id)
228+
}
229+
None => bug!("missing allocation {:?}", ptr.alloc_id),
230+
};
231+
let val = if ptr.offset.bytes() != 0 {
232+
fx.bcx.ins().iadd_imm(base_addr, i64::try_from(ptr.offset.bytes()).unwrap())
233+
} else {
234+
base_addr
235+
};
236+
CValue::by_val(val, layout)
237+
}
238+
},
233239
ConstValue::ByRef { alloc, offset } => CValue::by_ref(
234240
pointer_for_allocation(fx, alloc)
235241
.offset_i64(fx, i64::try_from(offset.bytes()).unwrap()),

0 commit comments

Comments
 (0)