diff options
| author | bjorn3 <bjorn3@users.noreply.github.com> | 2021-02-21 14:39:31 +0100 |
|---|---|---|
| committer | bjorn3 <bjorn3@users.noreply.github.com> | 2021-02-21 16:51:40 +0100 |
| commit | 7fc34839acfe1d69df83f79c4c2c8802dea17cdc (patch) | |
| tree | 6a015839014992f2cd89dddbd5e88bdc68307163 /src | |
| parent | 0610490c8dc71868ba886efbb8707cb77fc35928 (diff) | |
| download | rust-7fc34839acfe1d69df83f79c4c2c8802dea17cdc.tar.gz rust-7fc34839acfe1d69df83f79c4c2c8802dea17cdc.zip | |
Revert "Remove shift amount masking"
This reverts commit c5f98b586f9c835e8e3ebecf3db260d2f0ad402a. It turns out to be necessary anyway
Diffstat (limited to 'src')
| -rw-r--r-- | src/num.rs | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/src/num.rs b/src/num.rs index 850ff3561f7..2022614841d 100644 --- a/src/num.rs +++ b/src/num.rs @@ -168,12 +168,20 @@ pub(crate) fn codegen_int_binop<'tcx>( BinOp::BitXor => b.bxor(lhs, rhs), BinOp::BitAnd => b.band(lhs, rhs), BinOp::BitOr => b.bor(lhs, rhs), - BinOp::Shl => fx.bcx.ins().ishl(lhs, rhs), + BinOp::Shl => { + let lhs_ty = fx.bcx.func.dfg.value_type(lhs); + let actual_shift = fx.bcx.ins().band_imm(rhs, i64::from(lhs_ty.bits() - 1)); + let actual_shift = clif_intcast(fx, actual_shift, types::I8, false); + fx.bcx.ins().ishl(lhs, actual_shift) + } BinOp::Shr => { + let lhs_ty = fx.bcx.func.dfg.value_type(lhs); + let actual_shift = fx.bcx.ins().band_imm(rhs, i64::from(lhs_ty.bits() - 1)); + let actual_shift = clif_intcast(fx, actual_shift, types::I8, false); if signed { - fx.bcx.ins().sshr(lhs, rhs) + fx.bcx.ins().sshr(lhs, actual_shift) } else { - fx.bcx.ins().ushr(lhs, rhs) + fx.bcx.ins().ushr(lhs, actual_shift) } } // Compare binops handles by `codegen_binop`. @@ -295,7 +303,10 @@ pub(crate) fn codegen_checked_int_binop<'tcx>( } } BinOp::Shl => { - let val = fx.bcx.ins().ishl(lhs, rhs); + let lhs_ty = fx.bcx.func.dfg.value_type(lhs); + let actual_shift = fx.bcx.ins().band_imm(rhs, i64::from(lhs_ty.bits() - 1)); + let actual_shift = clif_intcast(fx, actual_shift, types::I8, false); + let val = fx.bcx.ins().ishl(lhs, actual_shift); let ty = fx.bcx.func.dfg.value_type(val); let max_shift = i64::from(ty.bits()) - 1; let has_overflow = fx @@ -305,10 +316,13 @@ pub(crate) fn codegen_checked_int_binop<'tcx>( (val, has_overflow) } BinOp::Shr => { + let lhs_ty = fx.bcx.func.dfg.value_type(lhs); + let actual_shift = fx.bcx.ins().band_imm(rhs, i64::from(lhs_ty.bits() - 1)); + let actual_shift = clif_intcast(fx, actual_shift, types::I8, false); let val = if !signed { - fx.bcx.ins().ushr(lhs, rhs) + fx.bcx.ins().ushr(lhs, actual_shift) } else { - fx.bcx.ins().sshr(lhs, rhs) + fx.bcx.ins().sshr(lhs, actual_shift) }; let ty = fx.bcx.func.dfg.value_type(val); let max_shift = i64::from(ty.bits()) - 1; |
