1
Fork 0

Calculate sign in trans{,_checked}_int_binop instead of caller

This commit is contained in:
bjorn3 2019-08-14 13:01:55 +02:00
parent 32cb5b8c8e
commit db071db95a
4 changed files with 17 additions and 42 deletions

View file

@ -261,40 +261,33 @@ fn trans_stmt<'a, 'tcx: 'a>(
place.write_place_ref(fx, lval); place.write_place_ref(fx, lval);
} }
Rvalue::BinaryOp(bin_op, lhs, rhs) => { Rvalue::BinaryOp(bin_op, lhs, rhs) => {
let ty = fx.monomorphize(&lhs.ty(fx.mir, fx.tcx));
let lhs = trans_operand(fx, lhs); let lhs = trans_operand(fx, lhs);
let rhs = trans_operand(fx, rhs); let rhs = trans_operand(fx, rhs);
let res = match ty.sty { let res = match lhs.layout().ty.sty {
ty::Bool => crate::num::trans_bool_binop(fx, *bin_op, lhs, rhs), ty::Bool => crate::num::trans_bool_binop(fx, *bin_op, lhs, rhs),
ty::Uint(_) => { ty::Uint(_) | ty::Int(_ )=> {
crate::num::trans_int_binop(fx, *bin_op, lhs, rhs, lval.layout().ty, false) crate::num::trans_int_binop(fx, *bin_op, lhs, rhs, lval.layout().ty)
}
ty::Int(_) => {
crate::num::trans_int_binop(fx, *bin_op, lhs, rhs, lval.layout().ty, true)
} }
ty::Float(_) => crate::num::trans_float_binop(fx, *bin_op, lhs, rhs, lval.layout().ty), ty::Float(_) => crate::num::trans_float_binop(fx, *bin_op, lhs, rhs, lval.layout().ty),
ty::Char => crate::num::trans_char_binop(fx, *bin_op, lhs, rhs, lval.layout().ty), ty::Char => crate::num::trans_char_binop(fx, *bin_op, lhs, rhs, lval.layout().ty),
ty::RawPtr(..) | ty::FnPtr(..) => { ty::RawPtr(..) | ty::FnPtr(..) => {
crate::num::trans_ptr_binop(fx, *bin_op, lhs, rhs, lval.layout().ty) crate::num::trans_ptr_binop(fx, *bin_op, lhs, rhs, lval.layout().ty)
} }
_ => unimplemented!("binop {:?} for {:?}", bin_op, ty), _ => unimplemented!("{:?}({:?}, {:?})", bin_op, lhs.layout().ty, rhs.layout().ty),
}; };
lval.write_cvalue(fx, res); lval.write_cvalue(fx, res);
} }
Rvalue::CheckedBinaryOp(bin_op, lhs, rhs) => { Rvalue::CheckedBinaryOp(bin_op, lhs, rhs) => {
let ty = fx.monomorphize(&lhs.ty(fx.mir, fx.tcx));
let lhs = trans_operand(fx, lhs); let lhs = trans_operand(fx, lhs);
let rhs = trans_operand(fx, rhs); let rhs = trans_operand(fx, rhs);
let signed = type_sign(ty);
let res = if !fx.tcx.sess.overflow_checks() { let res = if !fx.tcx.sess.overflow_checks() {
let val = crate::num::trans_int_binop(fx, *bin_op, lhs, rhs, lhs.layout().ty, signed).load_scalar(fx); let val = crate::num::trans_int_binop(fx, *bin_op, lhs, rhs, lhs.layout().ty).load_scalar(fx);
let is_overflow = fx.bcx.ins().iconst(types::I8, 0); let is_overflow = fx.bcx.ins().iconst(types::I8, 0);
CValue::by_val_pair(val, is_overflow, lval.layout()) CValue::by_val_pair(val, is_overflow, lval.layout())
} else { } else {
crate::num::trans_checked_int_binop(fx, *bin_op, lhs, rhs, lval.layout().ty, signed) crate::num::trans_checked_int_binop(fx, *bin_op, lhs, rhs, lval.layout().ty)
}; };
lval.write_cvalue(fx, res); lval.write_cvalue(fx, res);

View file

@ -6,7 +6,6 @@ pub fn maybe_codegen<'a, 'tcx>(
fx: &mut FunctionCx<'a, 'tcx, impl Backend>, fx: &mut FunctionCx<'a, 'tcx, impl Backend>,
bin_op: BinOp, bin_op: BinOp,
checked: bool, checked: bool,
is_signed: bool,
lhs: CValue<'tcx>, lhs: CValue<'tcx>,
rhs: CValue<'tcx>, rhs: CValue<'tcx>,
out_ty: Ty<'tcx>, out_ty: Ty<'tcx>,
@ -18,6 +17,8 @@ pub fn maybe_codegen<'a, 'tcx>(
let lhs_val = lhs.load_scalar(fx); let lhs_val = lhs.load_scalar(fx);
let rhs_val = rhs.load_scalar(fx); let rhs_val = rhs.load_scalar(fx);
let is_signed = type_sign(lhs.layout().ty);
match bin_op { match bin_op {
BinOp::BitAnd | BinOp::BitOr | BinOp::BitXor => { BinOp::BitAnd | BinOp::BitOr | BinOp::BitXor => {
assert!(!checked); assert!(!checked);

View file

@ -446,28 +446,10 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
"unchecked_shr" => BinOp::Shr, "unchecked_shr" => BinOp::Shr,
_ => unimplemented!("intrinsic {}", intrinsic), _ => unimplemented!("intrinsic {}", intrinsic),
}; };
let res = match ret.layout().ty.sty { let res = crate::num::trans_int_binop(fx, bin_op, x, y, ret.layout().ty);
ty::Uint(_) => crate::num::trans_int_binop(
fx,
bin_op,
x,
y,
ret.layout().ty,
false,
),
ty::Int(_) => crate::num::trans_int_binop(
fx,
bin_op,
x,
y,
ret.layout().ty,
true,
),
_ => panic!(),
};
ret.write_cvalue(fx, res); ret.write_cvalue(fx, res);
}; };
_ if intrinsic.ends_with("_with_overflow"), <T> (c x, c y) { _ if intrinsic.ends_with("_with_overflow"), (c x, c y) {
assert_eq!(x.layout().ty, y.layout().ty); assert_eq!(x.layout().ty, y.layout().ty);
let bin_op = match intrinsic { let bin_op = match intrinsic {
"add_with_overflow" => BinOp::Add, "add_with_overflow" => BinOp::Add,
@ -482,11 +464,10 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
x, x,
y, y,
ret.layout().ty, ret.layout().ty,
type_sign(T),
); );
ret.write_cvalue(fx, res); ret.write_cvalue(fx, res);
}; };
_ if intrinsic.starts_with("overflowing_"), <T> (c x, c y) { _ if intrinsic.starts_with("overflowing_"), (c x, c y) {
assert_eq!(x.layout().ty, y.layout().ty); assert_eq!(x.layout().ty, y.layout().ty);
let bin_op = match intrinsic { let bin_op = match intrinsic {
"overflowing_add" => BinOp::Add, "overflowing_add" => BinOp::Add,
@ -500,7 +481,6 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
x, x,
y, y,
ret.layout().ty, ret.layout().ty,
type_sign(T),
); );
ret.write_cvalue(fx, res); ret.write_cvalue(fx, res);
}; };
@ -520,7 +500,6 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
x, x,
y, y,
fx.tcx.mk_tup([T, fx.tcx.types.bool].into_iter()), fx.tcx.mk_tup([T, fx.tcx.types.bool].into_iter()),
signed,
); );
let (val, has_overflow) = checked_res.load_scalar_pair(fx); let (val, has_overflow) = checked_res.load_scalar_pair(fx);

View file

@ -78,7 +78,6 @@ pub fn trans_int_binop<'a, 'tcx: 'a>(
lhs: CValue<'tcx>, lhs: CValue<'tcx>,
rhs: CValue<'tcx>, rhs: CValue<'tcx>,
out_ty: Ty<'tcx>, out_ty: Ty<'tcx>,
signed: bool,
) -> CValue<'tcx> { ) -> CValue<'tcx> {
if bin_op != BinOp::Shl && bin_op != BinOp::Shr { if bin_op != BinOp::Shl && bin_op != BinOp::Shr {
assert_eq!( assert_eq!(
@ -93,10 +92,12 @@ pub fn trans_int_binop<'a, 'tcx: 'a>(
_ => unreachable!("Out ty {:?} is not an integer or bool", out_ty), _ => unreachable!("Out ty {:?} is not an integer or bool", out_ty),
} }
if let Some(res) = crate::codegen_i128::maybe_codegen(fx, bin_op, false, signed, lhs, rhs, out_ty) { if let Some(res) = crate::codegen_i128::maybe_codegen(fx, bin_op, false, lhs, rhs, out_ty) {
return res; return res;
} }
let signed = type_sign(lhs.layout().ty);
let (lhs, rhs) = if let (lhs, rhs) = if
(bin_op == BinOp::Eq || bin_op == BinOp::Ne) (bin_op == BinOp::Eq || bin_op == BinOp::Ne)
&& (lhs.layout().ty.sty == fx.tcx.types.i8.sty || lhs.layout().ty.sty == fx.tcx.types.i16.sty) && (lhs.layout().ty.sty == fx.tcx.types.i8.sty || lhs.layout().ty.sty == fx.tcx.types.i16.sty)
@ -149,7 +150,6 @@ pub fn trans_checked_int_binop<'a, 'tcx: 'a>(
in_lhs: CValue<'tcx>, in_lhs: CValue<'tcx>,
in_rhs: CValue<'tcx>, in_rhs: CValue<'tcx>,
out_ty: Ty<'tcx>, out_ty: Ty<'tcx>,
signed: bool,
) -> CValue<'tcx> { ) -> CValue<'tcx> {
if bin_op != BinOp::Shl && bin_op != BinOp::Shr { if bin_op != BinOp::Shl && bin_op != BinOp::Shr {
assert_eq!( assert_eq!(
@ -162,10 +162,12 @@ pub fn trans_checked_int_binop<'a, 'tcx: 'a>(
let lhs = in_lhs.load_scalar(fx); let lhs = in_lhs.load_scalar(fx);
let rhs = in_rhs.load_scalar(fx); let rhs = in_rhs.load_scalar(fx);
if let Some(res) = crate::codegen_i128::maybe_codegen(fx, bin_op, true, signed, in_lhs, in_rhs, out_ty) { if let Some(res) = crate::codegen_i128::maybe_codegen(fx, bin_op, true, in_lhs, in_rhs, out_ty) {
return res; return res;
} }
let signed = type_sign(in_lhs.layout().ty);
let (res, has_overflow) = match bin_op { let (res, has_overflow) = match bin_op {
BinOp::Add => { BinOp::Add => {
/*let (val, c_out) = fx.bcx.ins().iadd_cout(lhs, rhs); /*let (val, c_out) = fx.bcx.ins().iadd_cout(lhs, rhs);