Fix 128bit CValue::const_val

This commit is contained in:
bjorn3 2019-07-24 17:16:31 +02:00
parent 63b82238bb
commit 5180becc7c
6 changed files with 41 additions and 29 deletions

View File

@ -19,6 +19,9 @@ fn checked_div_u128(lhs: u128, rhs: u128) -> Option<u128> {
}
fn main() {
assert_eq!(0b0000000000000000000000000010000010000000000000000000000000000000_0000000000100000000000000000000000001000000000000100000000000000u128.leading_zeros(), 26);
assert_eq!(0b0000000000000000000000000010000000000000000000000000000000000000_0000000000000000000000000000000000001000000000000000000010000000u128.trailing_zeros(), 7);
checked_div_i128(0i128, 2i128);
checked_div_u128(0u128, 2u128);
assert_eq!(1u128 + 2, 3);

View File

@ -266,7 +266,7 @@ fn trans_stmt<'a, 'tcx: 'a>(
.discriminant_for_variant(fx.tcx, *variant_index)
.unwrap()
.val;
let discr = CValue::const_val(fx, ptr.layout().ty, to as u64 as i64);
let discr = CValue::const_val(fx, ptr.layout().ty, to);
ptr.write_cvalue(fx, discr);
}
layout::Variants::Multiple {
@ -289,7 +289,7 @@ fn trans_stmt<'a, 'tcx: 'a>(
let niche_llval = if niche_value == 0 {
CValue::const_val(fx, niche.layout().ty, 0)
} else {
CValue::const_val(fx, niche.layout().ty, niche_value as u64 as i64)
CValue::const_val(fx, niche.layout().ty, niche_value)
};
niche.write_cvalue(fx, niche_llval);
}
@ -562,7 +562,7 @@ fn trans_stmt<'a, 'tcx: 'a>(
.ty
.is_sized(fx.tcx.at(DUMMY_SP), ParamEnv::reveal_all()));
let ty_size = fx.layout_of(ty).size.bytes();
let val = CValue::const_val(fx, fx.tcx.types.usize, ty_size as i64);
let val = CValue::const_val(fx, fx.tcx.types.usize, ty_size.into());
lval.write_cvalue(fx, val);
}
Rvalue::Aggregate(kind, operands) => match **kind {
@ -679,7 +679,7 @@ pub fn trans_get_discriminant<'a, 'tcx: 'a>(
.map_or(index.as_u32() as u128, |def| {
def.discriminant_for_variant(fx.tcx, *index).val
});
return CValue::const_val(fx, dest_layout.ty, discr_val as u64 as i64);
return CValue::const_val(fx, dest_layout.ty, discr_val);
}
layout::Variants::Multiple { discr, discr_index, discr_kind, variants: _ } => {
(discr, *discr_index, discr_kind)

View File

@ -113,17 +113,13 @@ pub fn trans_const_value<'a, 'tcx: 'a>(
let ty = fx.monomorphize(&const_.ty);
let layout = fx.layout_of(ty);
match ty.sty {
ty::Bool => {
ty::Bool | ty::Uint(_) => {
let bits = const_.val.try_to_bits(layout.size).unwrap();
CValue::const_val(fx, ty, bits as u64 as i64)
}
ty::Uint(_) => {
let bits = const_.val.try_to_bits(layout.size).unwrap();
CValue::const_val(fx, ty, bits as u64 as i64)
CValue::const_val(fx, ty, bits)
}
ty::Int(_) => {
let bits = const_.val.try_to_bits(layout.size).unwrap();
CValue::const_val(fx, ty, rustc::mir::interpret::sign_extend(bits, layout.size) as i128 as i64)
CValue::const_val(fx, ty, rustc::mir::interpret::sign_extend(bits, layout.size))
}
ty::FnDef(_def_id, _substs) => CValue::by_ref(
fx.bcx

View File

@ -150,7 +150,7 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
};
size_of, <T> () {
let size_of = fx.layout_of(T).size.bytes();
let size_of = CValue::const_val(fx, usize_layout.ty, size_of as i64);
let size_of = CValue::const_val(fx, usize_layout.ty, size_of.into());
ret.write_cvalue(fx, size_of);
};
size_of_val, <T> (c ptr) {
@ -169,7 +169,7 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
};
min_align_of, <T> () {
let min_align = fx.layout_of(T).align.abi.bytes();
let min_align = CValue::const_val(fx, usize_layout.ty, min_align as i64);
let min_align = CValue::const_val(fx, usize_layout.ty, min_align.into());
ret.write_cvalue(fx, min_align);
};
min_align_of_val, <T> (c ptr) {
@ -188,14 +188,14 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
};
pref_align_of, <T> () {
let pref_align = fx.layout_of(T).align.pref.bytes();
let pref_align = CValue::const_val(fx, usize_layout.ty, pref_align as i64);
let pref_align = CValue::const_val(fx, usize_layout.ty, pref_align.into());
ret.write_cvalue(fx, pref_align);
};
type_id, <T> () {
let type_id = fx.tcx.type_id_hash(T);
let type_id = CValue::const_val(fx, u64_layout.ty, type_id as i64);
let type_id = CValue::const_val(fx, u64_layout.ty, type_id.into());
ret.write_cvalue(fx, type_id);
};
type_name, <T> () {
@ -395,9 +395,9 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
let (lsb, msb) = fx.bcx.ins().isplit(arg);
let lsb_lz = fx.bcx.ins().clz(lsb);
let msb_lz = fx.bcx.ins().clz(msb);
let msb_lz_is_64 = fx.bcx.ins().icmp_imm(IntCC::Equal, msb_lz, 64);
let msb_is_zero = fx.bcx.ins().icmp_imm(IntCC::Equal, msb, 0);
let lsb_lz_plus_64 = fx.bcx.ins().iadd_imm(lsb_lz, 64);
fx.bcx.ins().select(msb_lz_is_64, lsb_lz_plus_64, msb_lz)
fx.bcx.ins().select(msb_is_zero, lsb_lz_plus_64, msb_lz)
} else {
fx.bcx.ins().clz(arg)
};
@ -410,9 +410,9 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
let (lsb, msb) = fx.bcx.ins().isplit(arg);
let lsb_tz = fx.bcx.ins().ctz(lsb);
let msb_tz = fx.bcx.ins().ctz(msb);
let lsb_tz_is_64 = fx.bcx.ins().icmp_imm(IntCC::Equal, lsb_tz, 64);
let msb_lz_plus_64 = fx.bcx.ins().iadd_imm(msb_tz, 64);
fx.bcx.ins().select(lsb_tz_is_64, msb_lz_plus_64, lsb_tz)
let lsb_is_zero = fx.bcx.ins().icmp_imm(IntCC::Equal, lsb, 0);
let msb_tz_plus_64 = fx.bcx.ins().iadd_imm(msb_tz, 64);
fx.bcx.ins().select(lsb_is_zero, msb_tz_plus_64, lsb_tz)
} else {
fx.bcx.ins().ctz(arg)
};

View File

@ -54,7 +54,7 @@ mod vtable;
mod prelude {
pub use std::any::Any;
pub use std::collections::{HashMap, HashSet};
pub use std::convert::TryInto;
pub use std::convert::{TryFrom, TryInto};
pub use syntax::ast::{FloatTy, IntTy, UintTy};
pub use syntax::source_map::{Pos, Span, DUMMY_SP};

View File

@ -162,24 +162,37 @@ impl<'tcx> CValue<'tcx> {
crate::unsize::coerce_unsized_into(fx, self, dest);
}
/// If `ty` is signed, `const_val` must already be sign extended.
pub fn const_val<'a>(
fx: &mut FunctionCx<'a, 'tcx, impl Backend>,
ty: Ty<'tcx>,
const_val: i64,
const_val: u128,
) -> CValue<'tcx>
where
'tcx: 'a,
{
let clif_ty = fx.clif_type(ty).unwrap();
let layout = fx.layout_of(ty);
let val = if clif_ty == types::I128 {
// FIXME don't assume little-endian arch
let lsb = fx.bcx.ins().iconst(types::I64, const_val);
let msb = fx.bcx.ins().iconst(types::I64, 0);
fx.bcx.ins().iconcat(lsb, msb)
} else {
fx.bcx.ins().iconst(clif_ty, const_val)
let val = match ty.sty {
ty::TyKind::Uint(UintTy::U128) | ty::TyKind::Int(IntTy::I128) => {
let lsb = fx.bcx.ins().iconst(types::I64, const_val as u64 as i64);
let msb = fx.bcx.ins().iconst(types::I64, (const_val >> 64) as u64 as i64);
fx.bcx.ins().iconcat(lsb, msb)
}
ty::TyKind::Bool => {
assert!(const_val == 0 || const_val == 1, "Invalid bool 0x{:032X}", const_val);
fx.bcx.ins().iconst(types::I8, const_val as i64)
}
ty::TyKind::Uint(_) | ty::TyKind::Ref(..) | ty::TyKind::RawPtr(.. )=> {
fx.bcx.ins().iconst(clif_ty, u64::try_from(const_val).expect("uint") as i64)
}
ty::TyKind::Int(_) => {
fx.bcx.ins().iconst(clif_ty, const_val as i128 as i64)
}
_ => panic!("CValue::const_val for non bool/integer/pointer type {:?} is not allowed", ty),
};
CValue::by_val(val, layout)
}