implement and test unchecked_{add,sub,mul} intrinsics
This commit is contained in:
parent
cf748149ce
commit
7ce36226e6
@ -465,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.
|
||||
|
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);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user