Merge branch 'master' into patch-1
This commit is contained in:
commit
6f5529a05b
@ -1 +1 @@
|
||||
d8f50ab0ea6c529c24e575279acc72093caeb679
|
||||
374c63e0fc356eb61b1966cb6026a2a49fe9226d
|
||||
|
@ -43,7 +43,7 @@ impl rustc_driver::Callbacks for MiriCompilerCalls {
|
||||
compiler.session().abort_if_errors();
|
||||
compiler.global_ctxt().unwrap().peek_mut().enter(|tcx| {
|
||||
if std::env::args().any(|arg| arg == "--test") {
|
||||
struct Visitor<'tcx>(TyCtxt<'tcx, 'tcx>);
|
||||
struct Visitor<'tcx>(TyCtxt<'tcx>);
|
||||
impl<'tcx, 'hir> itemlikevisit::ItemLikeVisitor<'hir> for Visitor<'tcx> {
|
||||
fn visit_item(&mut self, i: &'hir hir::Item) {
|
||||
if let hir::ItemKind::Fn(.., body_id) = i.node {
|
||||
|
@ -560,18 +560,56 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
||||
let n = this.memory().get(ptr.alloc_id)?.read_c_str(tcx, ptr)?.len();
|
||||
this.write_scalar(Scalar::from_uint(n as u64, dest.layout.size), dest)?;
|
||||
}
|
||||
"cbrt" => {
|
||||
|
||||
// math functions
|
||||
|
||||
"cbrtf" | "coshf" | "sinhf" |"tanf" => {
|
||||
// FIXME: Using host floats.
|
||||
let f = f64::from_bits(this.read_scalar(args[0])?.to_u64()?);
|
||||
let n = f.cbrt();
|
||||
this.write_scalar(Scalar::from_u64(n.to_bits()), dest)?;
|
||||
let f = f32::from_bits(this.read_scalar(args[0])?.to_u32()?);
|
||||
let f = match link_name {
|
||||
"cbrtf" => f.cbrt(),
|
||||
"coshf" => f.cosh(),
|
||||
"sinhf" => f.sinh(),
|
||||
"tanf" => f.tan(),
|
||||
_ => bug!(),
|
||||
};
|
||||
this.write_scalar(Scalar::from_u32(f.to_bits()), dest)?;
|
||||
}
|
||||
// underscore case for windows
|
||||
"_hypot" | "hypot" => {
|
||||
"_hypotf" | "hypotf" | "atan2f" => {
|
||||
// FIXME: Using host floats.
|
||||
let f1 = f32::from_bits(this.read_scalar(args[0])?.to_u32()?);
|
||||
let f2 = f32::from_bits(this.read_scalar(args[1])?.to_u32()?);
|
||||
let n = match link_name {
|
||||
"_hypotf" | "hypotf" => f1.hypot(f2),
|
||||
"atan2f" => f1.atan2(f2),
|
||||
_ => bug!(),
|
||||
};
|
||||
this.write_scalar(Scalar::from_u32(n.to_bits()), dest)?;
|
||||
}
|
||||
|
||||
"cbrt" | "cosh" | "sinh" | "tan" => {
|
||||
// FIXME: Using host floats.
|
||||
let f = f64::from_bits(this.read_scalar(args[0])?.to_u64()?);
|
||||
let f = match link_name {
|
||||
"cbrt" => f.cbrt(),
|
||||
"cosh" => f.cosh(),
|
||||
"sinh" => f.sinh(),
|
||||
"tan" => f.tan(),
|
||||
_ => bug!(),
|
||||
};
|
||||
this.write_scalar(Scalar::from_u64(f.to_bits()), dest)?;
|
||||
}
|
||||
// underscore case for windows
|
||||
"_hypot" | "hypot" | "atan2" => {
|
||||
// FIXME: Using host floats.
|
||||
let f1 = f64::from_bits(this.read_scalar(args[0])?.to_u64()?);
|
||||
let f2 = f64::from_bits(this.read_scalar(args[1])?.to_u64()?);
|
||||
let n = f1.hypot(f2);
|
||||
let n = match link_name {
|
||||
"_hypot" | "hypot" => f1.hypot(f2),
|
||||
"atan2" => f1.atan2(f2),
|
||||
_ => bug!(),
|
||||
};
|
||||
this.write_scalar(Scalar::from_u64(n.to_bits()), dest)?;
|
||||
}
|
||||
|
||||
|
@ -272,7 +272,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
||||
let b = this.read_immediate(args[1])?;
|
||||
// check x % y != 0
|
||||
if this.binary_op(mir::BinOp::Rem, a, b)?.0.to_bits(dest.layout.size)? != 0 {
|
||||
return err!(ValidationFailure(format!("exact_div: {:?} cannot be divided by {:?}", a, b)));
|
||||
// Check if `b` is -1, which is the "min_value / -1" case.
|
||||
let minus1 = Scalar::from_int(-1, dest.layout.size);
|
||||
return if b.to_scalar().unwrap() == minus1 {
|
||||
err!(Intrinsic(format!("exact_div: result of dividing MIN by -1 cannot be represented")))
|
||||
} else {
|
||||
err!(Intrinsic(format!("exact_div: {:?} cannot be divided by {:?} without remainder", *a, *b)))
|
||||
};
|
||||
}
|
||||
this.binop_ignore_overflow(mir::BinOp::Div, a, b, dest)?;
|
||||
},
|
||||
@ -459,6 +465,22 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
||||
)?;
|
||||
}
|
||||
|
||||
"unchecked_add" | "unchecked_sub" | "unchecked_mul" => {
|
||||
let l = this.read_immediate(args[0])?;
|
||||
let r = this.read_immediate(args[1])?;
|
||||
let op = match intrinsic_name.get() {
|
||||
"unchecked_add" => mir::BinOp::Add,
|
||||
"unchecked_sub" => mir::BinOp::Sub,
|
||||
"unchecked_mul" => mir::BinOp::Mul,
|
||||
_ => bug!(),
|
||||
};
|
||||
let (res, overflowed) = this.binary_op(op, l, r)?;
|
||||
if overflowed {
|
||||
return err!(Intrinsic(format!("Overflowing arithmetic in {}", intrinsic_name.get())));
|
||||
}
|
||||
this.write_scalar(res, dest)?;
|
||||
}
|
||||
|
||||
"uninit" => {
|
||||
// Check fast path: we don't want to force an allocation in case the destination is a simple value,
|
||||
// but we also do not want to create a new allocation with 0s and then copy that over.
|
||||
|
@ -72,7 +72,7 @@ pub struct MiriConfig {
|
||||
|
||||
// Used by priroda.
|
||||
pub fn create_ecx<'mir, 'tcx: 'mir>(
|
||||
tcx: TyCtxt<'tcx, 'tcx>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
main_id: DefId,
|
||||
config: MiriConfig,
|
||||
) -> InterpResult<'tcx, InterpretCx<'mir, 'tcx, Evaluator<'tcx>>> {
|
||||
@ -212,7 +212,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
|
||||
}
|
||||
|
||||
pub fn eval_main<'tcx>(
|
||||
tcx: TyCtxt<'tcx, 'tcx>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
main_id: DefId,
|
||||
config: MiriConfig,
|
||||
) {
|
||||
@ -475,7 +475,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
|
||||
|
||||
fn find_foreign_static(
|
||||
def_id: DefId,
|
||||
tcx: TyCtxtAt<'tcx, 'tcx>,
|
||||
tcx: TyCtxtAt<'tcx>,
|
||||
) -> InterpResult<'tcx, Cow<'tcx, Allocation>> {
|
||||
let attrs = tcx.get_attrs(def_id);
|
||||
let link_name = match attr::first_attr_value_str_by_name(&attrs, sym::link_name) {
|
||||
|
11
tests/compile-fail/div-by-zero-3.rs
Normal file
11
tests/compile-fail/div-by-zero-3.rs
Normal file
@ -0,0 +1,11 @@
|
||||
#![feature(core_intrinsics)]
|
||||
|
||||
use std::intrinsics::*;
|
||||
|
||||
//error-pattern: Division by 0 in unchecked_rem
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
let _n = unchecked_rem(3u32, 0);
|
||||
}
|
||||
}
|
5
tests/compile-fail/exact_div1.rs
Normal file
5
tests/compile-fail/exact_div1.rs
Normal file
@ -0,0 +1,5 @@
|
||||
#![feature(core_intrinsics)]
|
||||
fn main() {
|
||||
// divison by 0
|
||||
unsafe { std::intrinsics::exact_div(2, 0); } //~ ERROR divisor of zero
|
||||
}
|
5
tests/compile-fail/exact_div2.rs
Normal file
5
tests/compile-fail/exact_div2.rs
Normal file
@ -0,0 +1,5 @@
|
||||
#![feature(core_intrinsics)]
|
||||
fn main() {
|
||||
// divison with a remainder
|
||||
unsafe { std::intrinsics::exact_div(2u16, 3); } //~ ERROR Scalar(0x0002) cannot be divided by Scalar(0x0003) without remainder
|
||||
}
|
5
tests/compile-fail/exact_div3.rs
Normal file
5
tests/compile-fail/exact_div3.rs
Normal file
@ -0,0 +1,5 @@
|
||||
#![feature(core_intrinsics)]
|
||||
fn main() {
|
||||
// signed divison with a remainder
|
||||
unsafe { std::intrinsics::exact_div(-19i8, 2); } //~ ERROR Scalar(0xed) cannot be divided by Scalar(0x02) without remainder
|
||||
}
|
5
tests/compile-fail/exact_div4.rs
Normal file
5
tests/compile-fail/exact_div4.rs
Normal file
@ -0,0 +1,5 @@
|
||||
#![feature(core_intrinsics)]
|
||||
fn main() {
|
||||
// divison of min_value by -1
|
||||
unsafe { std::intrinsics::exact_div(i64::min_value(), -1); } //~ ERROR result of dividing MIN by -1 cannot be represented
|
||||
}
|
5
tests/compile-fail/unchecked_add1.rs
Normal file
5
tests/compile-fail/unchecked_add1.rs
Normal file
@ -0,0 +1,5 @@
|
||||
#![feature(core_intrinsics)]
|
||||
fn main() {
|
||||
// MAX overflow
|
||||
unsafe { std::intrinsics::unchecked_add(40000u16, 30000); } //~ ERROR Overflowing arithmetic in unchecked_add
|
||||
}
|
5
tests/compile-fail/unchecked_add2.rs
Normal file
5
tests/compile-fail/unchecked_add2.rs
Normal file
@ -0,0 +1,5 @@
|
||||
#![feature(core_intrinsics)]
|
||||
fn main() {
|
||||
// MIN overflow
|
||||
unsafe { std::intrinsics::unchecked_add(-30000i16, -8000); } //~ ERROR Overflowing arithmetic in unchecked_add
|
||||
}
|
5
tests/compile-fail/unchecked_mul1.rs
Normal file
5
tests/compile-fail/unchecked_mul1.rs
Normal file
@ -0,0 +1,5 @@
|
||||
#![feature(core_intrinsics)]
|
||||
fn main() {
|
||||
// MAX overflow
|
||||
unsafe { std::intrinsics::unchecked_mul(300u16, 250u16); } //~ ERROR Overflowing arithmetic in unchecked_mul
|
||||
}
|
5
tests/compile-fail/unchecked_mul2.rs
Normal file
5
tests/compile-fail/unchecked_mul2.rs
Normal file
@ -0,0 +1,5 @@
|
||||
#![feature(core_intrinsics)]
|
||||
fn main() {
|
||||
// MIN overflow
|
||||
unsafe { std::intrinsics::unchecked_mul(1_000_000_000i32, -4); } //~ ERROR Overflowing arithmetic in unchecked_mul
|
||||
}
|
5
tests/compile-fail/unchecked_sub1.rs
Normal file
5
tests/compile-fail/unchecked_sub1.rs
Normal file
@ -0,0 +1,5 @@
|
||||
#![feature(core_intrinsics)]
|
||||
fn main() {
|
||||
// MIN overflow
|
||||
unsafe { std::intrinsics::unchecked_sub(14u32, 22); } //~ ERROR Overflowing arithmetic in unchecked_sub
|
||||
}
|
5
tests/compile-fail/unchecked_sub2.rs
Normal file
5
tests/compile-fail/unchecked_sub2.rs
Normal file
@ -0,0 +1,5 @@
|
||||
#![feature(core_intrinsics)]
|
||||
fn main() {
|
||||
// MAX overflow
|
||||
unsafe { std::intrinsics::unchecked_sub(30000i16, -7000); } //~ ERROR Overflowing arithmetic in unchecked_sub
|
||||
}
|
@ -8,23 +8,11 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(intrinsics)]
|
||||
|
||||
mod rusti {
|
||||
extern "rust-intrinsic" {
|
||||
pub fn ctpop<T>(x: T) -> T;
|
||||
pub fn ctlz<T>(x: T) -> T;
|
||||
pub fn ctlz_nonzero<T>(x: T) -> T;
|
||||
pub fn cttz<T>(x: T) -> T;
|
||||
pub fn cttz_nonzero<T>(x: T) -> T;
|
||||
pub fn bswap<T>(x: T) -> T;
|
||||
}
|
||||
}
|
||||
#![feature(core_intrinsics)]
|
||||
use std::intrinsics::*;
|
||||
|
||||
pub fn main() {
|
||||
unsafe {
|
||||
use crate::rusti::*;
|
||||
|
||||
assert_eq!(ctpop(0u8), 0); assert_eq!(ctpop(0i8), 0);
|
||||
assert_eq!(ctpop(0u16), 0); assert_eq!(ctpop(0i16), 0);
|
||||
assert_eq!(ctpop(0u32), 0); assert_eq!(ctpop(0i32), 0);
|
||||
@ -138,5 +126,29 @@ pub fn main() {
|
||||
assert_eq!(bswap(0x0ABBCC0Di32), 0x0DCCBB0A);
|
||||
assert_eq!(bswap(0x0122334455667708u64), 0x0877665544332201);
|
||||
assert_eq!(bswap(0x0122334455667708i64), 0x0877665544332201);
|
||||
|
||||
assert_eq!(exact_div(9*9u32, 3), 27);
|
||||
assert_eq!(exact_div(-9*9i32, 3), -27);
|
||||
assert_eq!(exact_div(9*9i8, -3), -27);
|
||||
assert_eq!(exact_div(-9*9i64, -3), 27);
|
||||
|
||||
assert_eq!(unchecked_div(9*9u32, 2), 40);
|
||||
assert_eq!(unchecked_div(-9*9i32, 2), -40);
|
||||
assert_eq!(unchecked_div(9*9i8, -2), -40);
|
||||
assert_eq!(unchecked_div(-9*9i64, -2), 40);
|
||||
|
||||
assert_eq!(unchecked_rem(9*9u32, 2), 1);
|
||||
assert_eq!(unchecked_rem(-9*9i32, 2), -1);
|
||||
assert_eq!(unchecked_rem(9*9i8, -2), 1);
|
||||
assert_eq!(unchecked_rem(-9*9i64, -2), -1);
|
||||
|
||||
assert_eq!(unchecked_add(23u8, 19), 42);
|
||||
assert_eq!(unchecked_add(5, -10), -5);
|
||||
|
||||
assert_eq!(unchecked_sub(23u8, 19), 4);
|
||||
assert_eq!(unchecked_sub(-17, -27), 10);
|
||||
|
||||
assert_eq!(unchecked_mul(6u8, 7), 42);
|
||||
assert_eq!(unchecked_mul(13, -5), -65);
|
||||
}
|
||||
}
|
||||
|
@ -67,6 +67,22 @@ pub fn main() {
|
||||
assert_approx_eq!(0.1f32.trunc(), 0.0f32);
|
||||
assert_approx_eq!((-0.1f64).trunc(), 0.0f64);
|
||||
|
||||
assert_approx_eq!(27f64.cbrt(), 3.0f64);
|
||||
assert_approx_eq!(3f64.hypot(4f64), 5.0f64);
|
||||
assert_approx_eq!(27.0f32.cbrt(), 3.0f32);
|
||||
assert_approx_eq!(27.0f64.cbrt(), 3.0f64);
|
||||
|
||||
assert_approx_eq!(3.0f32.hypot(4.0f32), 5.0f32);
|
||||
assert_approx_eq!(3.0f64.hypot(4.0f64), 5.0f64);
|
||||
|
||||
assert_approx_eq!(1.0f32.atan2(2.0f32), 0.46364761f32);
|
||||
assert_approx_eq!(1.0f32.atan2(2.0f32), 0.46364761f32);
|
||||
|
||||
assert_approx_eq!(1.0f32.cosh(), 1.54308f32);
|
||||
assert_approx_eq!(1.0f64.cosh(), 1.54308f64);
|
||||
|
||||
assert_approx_eq!(1.0f32.sinh(), 1.1752012f32);
|
||||
assert_approx_eq!(1.0f64.sinh(), 1.1752012f64);
|
||||
|
||||
assert_approx_eq!(1.0f32.tan(), 1.557408f32);
|
||||
assert_approx_eq!(1.0f64.tan(), 1.557408f64);
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user