Skip to content

Commit 4397736

Browse files
committed
Fix 128bit CValue::const_val
1 parent d5f42d4 commit 4397736

File tree

6 files changed

+41
-29
lines changed

6 files changed

+41
-29
lines changed

example/std_example.rs

+3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ fn checked_div_u128(lhs: u128, rhs: u128) -> Option<u128> {
1919
}
2020

2121
fn main() {
22+
assert_eq!(0b0000000000000000000000000010000010000000000000000000000000000000_0000000000100000000000000000000000001000000000000100000000000000u128.leading_zeros(), 26);
23+
assert_eq!(0b0000000000000000000000000010000000000000000000000000000000000000_0000000000000000000000000000000000001000000000000000000010000000u128.trailing_zeros(), 7);
24+
2225
checked_div_i128(0i128, 2i128);
2326
checked_div_u128(0u128, 2u128);
2427
assert_eq!(1u128 + 2, 3);

src/base.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ fn trans_stmt<'a, 'tcx: 'a>(
266266
.discriminant_for_variant(fx.tcx, *variant_index)
267267
.unwrap()
268268
.val;
269-
let discr = CValue::const_val(fx, ptr.layout().ty, to as u64 as i64);
269+
let discr = CValue::const_val(fx, ptr.layout().ty, to);
270270
ptr.write_cvalue(fx, discr);
271271
}
272272
layout::Variants::Multiple {
@@ -289,7 +289,7 @@ fn trans_stmt<'a, 'tcx: 'a>(
289289
let niche_llval = if niche_value == 0 {
290290
CValue::const_val(fx, niche.layout().ty, 0)
291291
} else {
292-
CValue::const_val(fx, niche.layout().ty, niche_value as u64 as i64)
292+
CValue::const_val(fx, niche.layout().ty, niche_value)
293293
};
294294
niche.write_cvalue(fx, niche_llval);
295295
}
@@ -562,7 +562,7 @@ fn trans_stmt<'a, 'tcx: 'a>(
562562
.ty
563563
.is_sized(fx.tcx.at(DUMMY_SP), ParamEnv::reveal_all()));
564564
let ty_size = fx.layout_of(ty).size.bytes();
565-
let val = CValue::const_val(fx, fx.tcx.types.usize, ty_size as i64);
565+
let val = CValue::const_val(fx, fx.tcx.types.usize, ty_size.into());
566566
lval.write_cvalue(fx, val);
567567
}
568568
Rvalue::Aggregate(kind, operands) => match **kind {
@@ -679,7 +679,7 @@ pub fn trans_get_discriminant<'a, 'tcx: 'a>(
679679
.map_or(index.as_u32() as u128, |def| {
680680
def.discriminant_for_variant(fx.tcx, *index).val
681681
});
682-
return CValue::const_val(fx, dest_layout.ty, discr_val as u64 as i64);
682+
return CValue::const_val(fx, dest_layout.ty, discr_val);
683683
}
684684
layout::Variants::Multiple { discr, discr_index, discr_kind, variants: _ } => {
685685
(discr, *discr_index, discr_kind)

src/constant.rs

+3-7
Original file line numberDiff line numberDiff line change
@@ -113,17 +113,13 @@ pub fn trans_const_value<'a, 'tcx: 'a>(
113113
let ty = fx.monomorphize(&const_.ty);
114114
let layout = fx.layout_of(ty);
115115
match ty.sty {
116-
ty::Bool => {
116+
ty::Bool | ty::Uint(_) => {
117117
let bits = const_.val.try_to_bits(layout.size).unwrap();
118-
CValue::const_val(fx, ty, bits as u64 as i64)
119-
}
120-
ty::Uint(_) => {
121-
let bits = const_.val.try_to_bits(layout.size).unwrap();
122-
CValue::const_val(fx, ty, bits as u64 as i64)
118+
CValue::const_val(fx, ty, bits)
123119
}
124120
ty::Int(_) => {
125121
let bits = const_.val.try_to_bits(layout.size).unwrap();
126-
CValue::const_val(fx, ty, rustc::mir::interpret::sign_extend(bits, layout.size) as i128 as i64)
122+
CValue::const_val(fx, ty, rustc::mir::interpret::sign_extend(bits, layout.size))
127123
}
128124
ty::FnDef(_def_id, _substs) => CValue::by_ref(
129125
fx.bcx

src/intrinsics.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
150150
};
151151
size_of, <T> () {
152152
let size_of = fx.layout_of(T).size.bytes();
153-
let size_of = CValue::const_val(fx, usize_layout.ty, size_of as i64);
153+
let size_of = CValue::const_val(fx, usize_layout.ty, size_of.into());
154154
ret.write_cvalue(fx, size_of);
155155
};
156156
size_of_val, <T> (c ptr) {
@@ -169,7 +169,7 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
169169
};
170170
min_align_of, <T> () {
171171
let min_align = fx.layout_of(T).align.abi.bytes();
172-
let min_align = CValue::const_val(fx, usize_layout.ty, min_align as i64);
172+
let min_align = CValue::const_val(fx, usize_layout.ty, min_align.into());
173173
ret.write_cvalue(fx, min_align);
174174
};
175175
min_align_of_val, <T> (c ptr) {
@@ -188,14 +188,14 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
188188
};
189189
pref_align_of, <T> () {
190190
let pref_align = fx.layout_of(T).align.pref.bytes();
191-
let pref_align = CValue::const_val(fx, usize_layout.ty, pref_align as i64);
191+
let pref_align = CValue::const_val(fx, usize_layout.ty, pref_align.into());
192192
ret.write_cvalue(fx, pref_align);
193193
};
194194

195195

196196
type_id, <T> () {
197197
let type_id = fx.tcx.type_id_hash(T);
198-
let type_id = CValue::const_val(fx, u64_layout.ty, type_id as i64);
198+
let type_id = CValue::const_val(fx, u64_layout.ty, type_id.into());
199199
ret.write_cvalue(fx, type_id);
200200
};
201201
type_name, <T> () {
@@ -395,9 +395,9 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
395395
let (lsb, msb) = fx.bcx.ins().isplit(arg);
396396
let lsb_lz = fx.bcx.ins().clz(lsb);
397397
let msb_lz = fx.bcx.ins().clz(msb);
398-
let msb_lz_is_64 = fx.bcx.ins().icmp_imm(IntCC::Equal, msb_lz, 64);
398+
let msb_is_zero = fx.bcx.ins().icmp_imm(IntCC::Equal, msb, 0);
399399
let lsb_lz_plus_64 = fx.bcx.ins().iadd_imm(lsb_lz, 64);
400-
fx.bcx.ins().select(msb_lz_is_64, lsb_lz_plus_64, msb_lz)
400+
fx.bcx.ins().select(msb_is_zero, lsb_lz_plus_64, msb_lz)
401401
} else {
402402
fx.bcx.ins().clz(arg)
403403
};
@@ -410,9 +410,9 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
410410
let (lsb, msb) = fx.bcx.ins().isplit(arg);
411411
let lsb_tz = fx.bcx.ins().ctz(lsb);
412412
let msb_tz = fx.bcx.ins().ctz(msb);
413-
let lsb_tz_is_64 = fx.bcx.ins().icmp_imm(IntCC::Equal, lsb_tz, 64);
414-
let msb_lz_plus_64 = fx.bcx.ins().iadd_imm(msb_tz, 64);
415-
fx.bcx.ins().select(lsb_tz_is_64, msb_lz_plus_64, lsb_tz)
413+
let lsb_is_zero = fx.bcx.ins().icmp_imm(IntCC::Equal, lsb, 0);
414+
let msb_tz_plus_64 = fx.bcx.ins().iadd_imm(msb_tz, 64);
415+
fx.bcx.ins().select(lsb_is_zero, msb_tz_plus_64, lsb_tz)
416416
} else {
417417
fx.bcx.ins().ctz(arg)
418418
};

src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ mod vtable;
5454
mod prelude {
5555
pub use std::any::Any;
5656
pub use std::collections::{HashMap, HashSet};
57-
pub use std::convert::TryInto;
57+
pub use std::convert::{TryFrom, TryInto};
5858

5959
pub use syntax::ast::{FloatTy, IntTy, UintTy};
6060
pub use syntax::source_map::{Pos, Span, DUMMY_SP};

src/value_and_place.rs

+21-8
Original file line numberDiff line numberDiff line change
@@ -162,24 +162,37 @@ impl<'tcx> CValue<'tcx> {
162162
crate::unsize::coerce_unsized_into(fx, self, dest);
163163
}
164164

165+
/// If `ty` is signed, `const_val` must already be sign extended.
165166
pub fn const_val<'a>(
166167
fx: &mut FunctionCx<'a, 'tcx, impl Backend>,
167168
ty: Ty<'tcx>,
168-
const_val: i64,
169+
const_val: u128,
169170
) -> CValue<'tcx>
170171
where
171172
'tcx: 'a,
172173
{
173174
let clif_ty = fx.clif_type(ty).unwrap();
174175
let layout = fx.layout_of(ty);
175-
let val = if clif_ty == types::I128 {
176-
// FIXME don't assume little-endian arch
177-
let lsb = fx.bcx.ins().iconst(types::I64, const_val);
178-
let msb = fx.bcx.ins().iconst(types::I64, 0);
179-
fx.bcx.ins().iconcat(lsb, msb)
180-
} else {
181-
fx.bcx.ins().iconst(clif_ty, const_val)
176+
177+
let val = match ty.sty {
178+
ty::TyKind::Uint(UintTy::U128) | ty::TyKind::Int(IntTy::I128) => {
179+
let lsb = fx.bcx.ins().iconst(types::I64, const_val as u64 as i64);
180+
let msb = fx.bcx.ins().iconst(types::I64, (const_val >> 64) as u64 as i64);
181+
fx.bcx.ins().iconcat(lsb, msb)
182+
}
183+
ty::TyKind::Bool => {
184+
assert!(const_val == 0 || const_val == 1, "Invalid bool 0x{:032X}", const_val);
185+
fx.bcx.ins().iconst(types::I8, const_val as i64)
186+
}
187+
ty::TyKind::Uint(_) | ty::TyKind::Ref(..) | ty::TyKind::RawPtr(.. )=> {
188+
fx.bcx.ins().iconst(clif_ty, u64::try_from(const_val).expect("uint") as i64)
189+
}
190+
ty::TyKind::Int(_) => {
191+
fx.bcx.ins().iconst(clif_ty, const_val as i128 as i64)
192+
}
193+
_ => panic!("CValue::const_val for non bool/integer/pointer type {:?} is not allowed", ty),
182194
};
195+
183196
CValue::by_val(val, layout)
184197
}
185198

0 commit comments

Comments
 (0)