From db071db95aa1ab24d961c961e18daee66fdc4af4 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Wed, 14 Aug 2019 13:01:55 +0200 Subject: [PATCH] Calculate sign in trans{,_checked}_int_binop instead of caller --- src/base.rs | 19 ++++++------------- src/codegen_i128.rs | 3 ++- src/intrinsics.rs | 27 +++------------------------ src/num.rs | 10 ++++++---- 4 files changed, 17 insertions(+), 42 deletions(-) diff --git a/src/base.rs b/src/base.rs index 444e39c359d..26dfb1548da 100644 --- a/src/base.rs +++ b/src/base.rs @@ -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); diff --git a/src/codegen_i128.rs b/src/codegen_i128.rs index f173b4dbd5d..6fdd3042c52 100644 --- a/src/codegen_i128.rs +++ b/src/codegen_i128.rs @@ -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); diff --git a/src/intrinsics.rs b/src/intrinsics.rs index 73d8bb8b0d2..45f8d82448e 100644 --- a/src/intrinsics.rs +++ b/src/intrinsics.rs @@ -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"), (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_"), (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); diff --git a/src/num.rs b/src/num.rs index 41448b388db..9210c040ff3 100644 --- a/src/num.rs +++ b/src/num.rs @@ -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);