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);
}
Rvalue::BinaryOp(bin_op, lhs, rhs) => {
let ty = fx.monomorphize(&lhs.ty(fx.mir, fx.tcx));
let lhs = trans_operand(fx, lhs);
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::Uint(_) => {
crate::num::trans_int_binop(fx, *bin_op, lhs, rhs, lval.layout().ty, false)
}
ty::Int(_) => {
crate::num::trans_int_binop(fx, *bin_op, lhs, rhs, lval.layout().ty, true)
ty::Uint(_) | ty::Int(_ )=> {
crate::num::trans_int_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::RawPtr(..) | ty::FnPtr(..) => {
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);
}
Rvalue::CheckedBinaryOp(bin_op, lhs, rhs) => {
let ty = fx.monomorphize(&lhs.ty(fx.mir, fx.tcx));
let lhs = trans_operand(fx, lhs);
let rhs = trans_operand(fx, rhs);
let signed = type_sign(ty);
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);
CValue::by_val_pair(val, is_overflow, lval.layout())
} 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);

View File

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

View File

@ -446,28 +446,10 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
"unchecked_shr" => BinOp::Shr,
_ => unimplemented!("intrinsic {}", intrinsic),
};
let res = match ret.layout().ty.sty {
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!(),
};
let res = crate::num::trans_int_binop(fx, bin_op, x, y, ret.layout().ty);
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);
let bin_op = match intrinsic {
"add_with_overflow" => BinOp::Add,
@ -482,11 +464,10 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
x,
y,
ret.layout().ty,
type_sign(T),
);
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);
let bin_op = match intrinsic {
"overflowing_add" => BinOp::Add,
@ -500,7 +481,6 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
x,
y,
ret.layout().ty,
type_sign(T),
);
ret.write_cvalue(fx, res);
};
@ -520,7 +500,6 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
x,
y,
fx.tcx.mk_tup([T, fx.tcx.types.bool].into_iter()),
signed,
);
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>,
rhs: CValue<'tcx>,
out_ty: Ty<'tcx>,
signed: bool,
) -> CValue<'tcx> {
if bin_op != BinOp::Shl && bin_op != BinOp::Shr {
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),
}
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;
}
let signed = type_sign(lhs.layout().ty);
let (lhs, rhs) = if
(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)
@ -149,7 +150,6 @@ pub fn trans_checked_int_binop<'a, 'tcx: 'a>(
in_lhs: CValue<'tcx>,
in_rhs: CValue<'tcx>,
out_ty: Ty<'tcx>,
signed: bool,
) -> CValue<'tcx> {
if bin_op != BinOp::Shl && bin_op != BinOp::Shr {
assert_eq!(
@ -162,10 +162,12 @@ pub fn trans_checked_int_binop<'a, 'tcx: 'a>(
let lhs = in_lhs.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;
}
let signed = type_sign(in_lhs.layout().ty);
let (res, has_overflow) = match bin_op {
BinOp::Add => {
/*let (val, c_out) = fx.bcx.ins().iadd_cout(lhs, rhs);