don't test always against gcc_s
instead test half of the time against gcc_s and the other half test against the native operation (\*). (\*) Not all the targets have available a native version of the intrinsics under test. On those targets we'll end up testing our implementation against itself half of the time. This is not much of a problem because we do several quickcheck runs per intrinsic.
This commit is contained in:
parent
337bd7e209
commit
384c48ce9b
10
Cargo.toml
10
Cargo.toml
|
@ -5,11 +5,17 @@ name = "rustc_builtins"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rlibc = { git = "https://github.com/alexcrichton/rlibc", optional = true }
|
|
||||||
|
[dependencies.rlibc]
|
||||||
|
git = "https://github.com/alexcrichton/rlibc"
|
||||||
|
optional = true
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
gcc_s = { path = "gcc_s" }
|
|
||||||
quickcheck = "0.3.1"
|
quickcheck = "0.3.1"
|
||||||
|
rand = "0.3.14"
|
||||||
|
|
||||||
|
[dev-dependencies.gcc_s]
|
||||||
|
path = "gcc_s"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["rlibc/weak"]
|
default = ["rlibc/weak"]
|
||||||
|
|
|
@ -200,9 +200,11 @@ pub extern fn __aeabi_fadd(a: f32, b: f32) -> f32 {
|
||||||
mod tests {
|
mod tests {
|
||||||
use core::{f32, f64};
|
use core::{f32, f64};
|
||||||
|
|
||||||
use gcc_s;
|
|
||||||
use qc::{U32, U64};
|
|
||||||
use float::Float;
|
use float::Float;
|
||||||
|
use qc::{U32, U64};
|
||||||
|
|
||||||
|
use gcc_s;
|
||||||
|
use rand;
|
||||||
|
|
||||||
// NOTE The tests below have special handing for NaN values.
|
// NOTE The tests below have special handing for NaN values.
|
||||||
// Because NaN != NaN, the floating-point representations must be used
|
// Because NaN != NaN, the floating-point representations must be used
|
||||||
|
@ -223,7 +225,7 @@ mod tests {
|
||||||
// implementation matches the output of the FPU instruction on *hard* float targets
|
// implementation matches the output of the FPU instruction on *hard* float targets
|
||||||
// and matches its gcc_s counterpart on *soft* float targets.
|
// and matches its gcc_s counterpart on *soft* float targets.
|
||||||
#[cfg(not(gnueabihf))]
|
#[cfg(not(gnueabihf))]
|
||||||
Some(addsf3) => x.eq_repr(unsafe { addsf3(a, b) }),
|
Some(addsf3) if rand::random() => x.eq_repr(unsafe { addsf3(a, b) }),
|
||||||
_ => x.eq_repr(a + b),
|
_ => x.eq_repr(a + b),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -235,7 +237,7 @@ mod tests {
|
||||||
match gcc_s::adddf3() {
|
match gcc_s::adddf3() {
|
||||||
// NOTE(cfg) See NOTE above
|
// NOTE(cfg) See NOTE above
|
||||||
#[cfg(not(gnueabihf))]
|
#[cfg(not(gnueabihf))]
|
||||||
Some(adddf3) => x.eq_repr(unsafe { adddf3(a, b) }),
|
Some(adddf3) if rand::random() => x.eq_repr(unsafe { adddf3(a, b) }),
|
||||||
_ => x.eq_repr(a + b),
|
_ => x.eq_repr(a + b),
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,18 +72,19 @@ mulo!(__mulodi4: i64);
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use gcc_s;
|
|
||||||
use qc::{I32, I64, U64};
|
use qc::{I32, I64, U64};
|
||||||
|
|
||||||
|
use gcc_s;
|
||||||
|
use rand;
|
||||||
|
|
||||||
quickcheck! {
|
quickcheck! {
|
||||||
fn muldi(a: U64, b: U64) -> bool {
|
fn muldi(a: U64, b: U64) -> bool {
|
||||||
let (a, b) = (a.0, b.0);
|
let (a, b) = (a.0, b.0);
|
||||||
let r = super::__muldi3(a, b);
|
let r = super::__muldi3(a, b);
|
||||||
|
|
||||||
if let Some(muldi3) = gcc_s::muldi3() {
|
match gcc_s::muldi3() {
|
||||||
r == unsafe { muldi3(a, b) }
|
Some(muldi3) if rand::random() => r == unsafe { muldi3(a, b) },
|
||||||
} else {
|
_ => r == a.wrapping_mul(b),
|
||||||
r == a.wrapping_mul(b)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,15 +96,16 @@ mod tests {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(mulosi4) = gcc_s::mulosi4() {
|
match gcc_s::mulosi4() {
|
||||||
|
Some(mulosi4) if rand::random() => {
|
||||||
let mut gcc_s_overflow = 2;
|
let mut gcc_s_overflow = 2;
|
||||||
let gcc_s_r = unsafe {
|
let gcc_s_r = unsafe {
|
||||||
mulosi4(a, b, &mut gcc_s_overflow)
|
mulosi4(a, b, &mut gcc_s_overflow)
|
||||||
};
|
};
|
||||||
|
|
||||||
(r, overflow) == (gcc_s_r, gcc_s_overflow)
|
(r, overflow) == (gcc_s_r, gcc_s_overflow)
|
||||||
} else {
|
},
|
||||||
(r, overflow != 0) == a.overflowing_mul(b)
|
_ => (r, overflow != 0) == a.overflowing_mul(b),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,15 +117,16 @@ mod tests {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(mulodi4) = gcc_s::mulodi4() {
|
match gcc_s::mulodi4() {
|
||||||
|
Some(mulodi4) if rand::random() => {
|
||||||
let mut gcc_s_overflow = 2;
|
let mut gcc_s_overflow = 2;
|
||||||
let gcc_s_r = unsafe {
|
let gcc_s_r = unsafe {
|
||||||
mulodi4(a, b, &mut gcc_s_overflow)
|
mulodi4(a, b, &mut gcc_s_overflow)
|
||||||
};
|
};
|
||||||
|
|
||||||
(r, overflow) == (gcc_s_r, gcc_s_overflow)
|
(r, overflow) == (gcc_s_r, gcc_s_overflow)
|
||||||
} else {
|
},
|
||||||
(r, overflow != 0) == a.overflowing_mul(b)
|
_ => (r, overflow != 0) == a.overflowing_mul(b),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,9 +52,11 @@ divmod!(__divmoddi4, __divdi3: i64);
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use qc::{U32, U64};
|
||||||
|
|
||||||
use gcc_s;
|
use gcc_s;
|
||||||
use quickcheck::TestResult;
|
use quickcheck::TestResult;
|
||||||
use qc::{U32, U64};
|
use rand;
|
||||||
|
|
||||||
quickcheck!{
|
quickcheck!{
|
||||||
fn divdi3(n: U64, d: U64) -> TestResult {
|
fn divdi3(n: U64, d: U64) -> TestResult {
|
||||||
|
@ -64,10 +66,11 @@ mod tests {
|
||||||
} else {
|
} else {
|
||||||
let q = super::__divdi3(n, d);
|
let q = super::__divdi3(n, d);
|
||||||
|
|
||||||
if let Some(divdi3) = gcc_s::divdi3() {
|
match gcc_s::divdi3() {
|
||||||
|
Some(divdi3) if rand::random() => {
|
||||||
TestResult::from_bool(q == unsafe { divdi3(n, d) })
|
TestResult::from_bool(q == unsafe { divdi3(n, d) })
|
||||||
} else {
|
},
|
||||||
TestResult::from_bool(q == n / d)
|
_ => TestResult::from_bool(q == n / d),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,10 +82,11 @@ mod tests {
|
||||||
} else {
|
} else {
|
||||||
let r = super::__moddi3(n, d);
|
let r = super::__moddi3(n, d);
|
||||||
|
|
||||||
if let Some(moddi3) = gcc_s::moddi3() {
|
match gcc_s::moddi3() {
|
||||||
|
Some(moddi3) if rand::random() => {
|
||||||
TestResult::from_bool(r == unsafe { moddi3(n, d) })
|
TestResult::from_bool(r == unsafe { moddi3(n, d) })
|
||||||
} else {
|
},
|
||||||
TestResult::from_bool(r == n % d)
|
_ => TestResult::from_bool(r == n % d),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -95,15 +99,16 @@ mod tests {
|
||||||
let mut r = 0;
|
let mut r = 0;
|
||||||
let q = super::__divmoddi4(n, d, &mut r);
|
let q = super::__divmoddi4(n, d, &mut r);
|
||||||
|
|
||||||
if let Some(divmoddi4) = gcc_s::divmoddi4() {
|
match gcc_s::divmoddi4() {
|
||||||
|
Some(divmoddi4) if rand::random() => {
|
||||||
let mut gcc_s_r = 0;
|
let mut gcc_s_r = 0;
|
||||||
let gcc_s_q = unsafe {
|
let gcc_s_q = unsafe {
|
||||||
divmoddi4(n, d, &mut gcc_s_r)
|
divmoddi4(n, d, &mut gcc_s_r)
|
||||||
};
|
};
|
||||||
|
|
||||||
TestResult::from_bool(q == gcc_s_q && r == gcc_s_r)
|
TestResult::from_bool(q == gcc_s_q && r == gcc_s_r)
|
||||||
} else {
|
},
|
||||||
TestResult::from_bool(q == n / d && r == n % d)
|
_ => TestResult::from_bool(q == n / d && r == n % d),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,10 +120,11 @@ mod tests {
|
||||||
} else {
|
} else {
|
||||||
let q = super::__divsi3(n, d);
|
let q = super::__divsi3(n, d);
|
||||||
|
|
||||||
if let Some(divsi3) = gcc_s::divsi3() {
|
match gcc_s::divsi3() {
|
||||||
|
Some(divsi3) if rand::random() => {
|
||||||
TestResult::from_bool(q == unsafe { divsi3(n, d)})
|
TestResult::from_bool(q == unsafe { divsi3(n, d)})
|
||||||
} else {
|
},
|
||||||
TestResult::from_bool(q == n / d)
|
_ => TestResult::from_bool(q == n / d),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -130,10 +136,11 @@ mod tests {
|
||||||
} else {
|
} else {
|
||||||
let r = super::__modsi3(n, d);
|
let r = super::__modsi3(n, d);
|
||||||
|
|
||||||
if let Some(modsi3) = gcc_s::modsi3() {
|
match gcc_s::modsi3() {
|
||||||
|
Some(modsi3) if rand::random() => {
|
||||||
TestResult::from_bool(r == unsafe { modsi3(n, d) })
|
TestResult::from_bool(r == unsafe { modsi3(n, d) })
|
||||||
} else {
|
},
|
||||||
TestResult::from_bool(r == n % d)
|
_ => TestResult::from_bool(r == n % d),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -146,15 +153,16 @@ mod tests {
|
||||||
let mut r = 0;
|
let mut r = 0;
|
||||||
let q = super::__divmodsi4(n, d, &mut r);
|
let q = super::__divmodsi4(n, d, &mut r);
|
||||||
|
|
||||||
if let Some(divmodsi4) = gcc_s::divmodsi4() {
|
match gcc_s::divmodsi4() {
|
||||||
|
Some(divmodsi4) if rand::random() => {
|
||||||
let mut gcc_s_r = 0;
|
let mut gcc_s_r = 0;
|
||||||
let gcc_s_q = unsafe {
|
let gcc_s_q = unsafe {
|
||||||
divmodsi4(n, d, &mut gcc_s_r)
|
divmodsi4(n, d, &mut gcc_s_r)
|
||||||
};
|
};
|
||||||
|
|
||||||
TestResult::from_bool(q == gcc_s_q && r == gcc_s_r)
|
TestResult::from_bool(q == gcc_s_q && r == gcc_s_r)
|
||||||
} else {
|
},
|
||||||
TestResult::from_bool(q == n / d && r == n % d)
|
_ => TestResult::from_bool(q == n / d && r == n % d),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,9 +60,11 @@ lshr!(__lshrdi3: u64);
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use qc::{I64, U64};
|
||||||
|
|
||||||
use gcc_s;
|
use gcc_s;
|
||||||
use quickcheck::TestResult;
|
use quickcheck::TestResult;
|
||||||
use qc::{I64, U64};
|
use rand;
|
||||||
|
|
||||||
// NOTE We purposefully stick to `u32` for `b` here because we want "small" values (b < 64)
|
// NOTE We purposefully stick to `u32` for `b` here because we want "small" values (b < 64)
|
||||||
quickcheck! {
|
quickcheck! {
|
||||||
|
@ -73,10 +75,11 @@ mod tests {
|
||||||
} else {
|
} else {
|
||||||
let r = super::__ashldi3(a, b);
|
let r = super::__ashldi3(a, b);
|
||||||
|
|
||||||
if let Some(ashldi3) = gcc_s::ashldi3() {
|
match gcc_s::ashldi3() {
|
||||||
|
Some(ashldi3) if rand::random() => {
|
||||||
TestResult::from_bool(r == unsafe { ashldi3(a, b) })
|
TestResult::from_bool(r == unsafe { ashldi3(a, b) })
|
||||||
} else {
|
},
|
||||||
TestResult::from_bool(r == a << b)
|
_ => TestResult::from_bool(r == a << b),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,10 +91,11 @@ mod tests {
|
||||||
} else {
|
} else {
|
||||||
let r = super::__ashrdi3(a, b);
|
let r = super::__ashrdi3(a, b);
|
||||||
|
|
||||||
if let Some(ashrdi3) = gcc_s::ashrdi3() {
|
match gcc_s::ashrdi3() {
|
||||||
|
Some(ashrdi3) if rand::random() => {
|
||||||
TestResult::from_bool(r == unsafe { ashrdi3(a, b) })
|
TestResult::from_bool(r == unsafe { ashrdi3(a, b) })
|
||||||
} else {
|
},
|
||||||
TestResult::from_bool(r == a >> b)
|
_ => TestResult::from_bool(r == a >> b),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,10 +107,11 @@ mod tests {
|
||||||
} else {
|
} else {
|
||||||
let r = super::__lshrdi3(a, b);
|
let r = super::__lshrdi3(a, b);
|
||||||
|
|
||||||
if let Some(lshrdi3) = gcc_s::lshrdi3() {
|
match gcc_s::lshrdi3() {
|
||||||
|
Some(lshrdi3) if rand::random() => {
|
||||||
TestResult::from_bool(r == unsafe { lshrdi3(a, b) })
|
TestResult::from_bool(r == unsafe { lshrdi3(a, b) })
|
||||||
} else {
|
},
|
||||||
TestResult::from_bool(r == a >> b)
|
_ => TestResult::from_bool(r == a >> b),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -228,9 +228,11 @@ pub extern "C" fn __udivmoddi4(n: u64, d: u64, rem: Option<&mut u64>) -> u64 {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use qc::{U32, U64};
|
||||||
|
|
||||||
use gcc_s;
|
use gcc_s;
|
||||||
use quickcheck::TestResult;
|
use quickcheck::TestResult;
|
||||||
use qc::{U32, U64};
|
use rand;
|
||||||
|
|
||||||
quickcheck!{
|
quickcheck!{
|
||||||
fn udivdi3(n: U64, d: U64) -> TestResult {
|
fn udivdi3(n: U64, d: U64) -> TestResult {
|
||||||
|
@ -240,10 +242,11 @@ mod tests {
|
||||||
} else {
|
} else {
|
||||||
let q = super::__udivdi3(n, d);
|
let q = super::__udivdi3(n, d);
|
||||||
|
|
||||||
if let Some(udivdi3) = gcc_s::udivdi3() {
|
match gcc_s::udivdi3() {
|
||||||
|
Some(udivdi3) if rand::random() => {
|
||||||
TestResult::from_bool(q == unsafe { udivdi3(n, d) })
|
TestResult::from_bool(q == unsafe { udivdi3(n, d) })
|
||||||
} else {
|
},
|
||||||
TestResult::from_bool(q == n / d)
|
_ => TestResult::from_bool(q == n / d),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -255,10 +258,11 @@ mod tests {
|
||||||
} else {
|
} else {
|
||||||
let r = super::__umoddi3(n, d);
|
let r = super::__umoddi3(n, d);
|
||||||
|
|
||||||
if let Some(umoddi3) = gcc_s::umoddi3() {
|
match gcc_s::umoddi3() {
|
||||||
|
Some(umoddi3) if rand::random() => {
|
||||||
TestResult::from_bool(r == unsafe { umoddi3(n, d) })
|
TestResult::from_bool(r == unsafe { umoddi3(n, d) })
|
||||||
} else {
|
},
|
||||||
TestResult::from_bool(r == n % d)
|
_ => TestResult::from_bool(r == n % d),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -271,15 +275,16 @@ mod tests {
|
||||||
let mut r = 0;
|
let mut r = 0;
|
||||||
let q = super::__udivmoddi4(n, d, Some(&mut r));
|
let q = super::__udivmoddi4(n, d, Some(&mut r));
|
||||||
|
|
||||||
if let Some(udivmoddi4) = gcc_s::udivmoddi4() {
|
match gcc_s::udivmoddi4() {
|
||||||
|
Some(udivmoddi4) if rand::random() => {
|
||||||
let mut gcc_s_r = 0;
|
let mut gcc_s_r = 0;
|
||||||
let gcc_s_q = unsafe {
|
let gcc_s_q = unsafe {
|
||||||
udivmoddi4(n, d, Some(&mut gcc_s_r))
|
udivmoddi4(n, d, Some(&mut gcc_s_r))
|
||||||
};
|
};
|
||||||
|
|
||||||
TestResult::from_bool(q == gcc_s_q && r == gcc_s_r)
|
TestResult::from_bool(q == gcc_s_q && r == gcc_s_r)
|
||||||
} else {
|
},
|
||||||
TestResult::from_bool(q == n / d && r == n % d)
|
_ => TestResult::from_bool(q == n / d && r == n % d),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -291,10 +296,11 @@ mod tests {
|
||||||
} else {
|
} else {
|
||||||
let q = super::__udivsi3(n, d);
|
let q = super::__udivsi3(n, d);
|
||||||
|
|
||||||
if let Some(udivsi3) = gcc_s::udivsi3() {
|
match gcc_s::udivsi3() {
|
||||||
|
Some(udivsi3) if rand::random() => {
|
||||||
TestResult::from_bool(q == unsafe { udivsi3(n, d) })
|
TestResult::from_bool(q == unsafe { udivsi3(n, d) })
|
||||||
} else {
|
},
|
||||||
TestResult::from_bool(q == n / d)
|
_ => TestResult::from_bool(q == n / d),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -306,10 +312,11 @@ mod tests {
|
||||||
} else {
|
} else {
|
||||||
let r = super::__umodsi3(n, d);
|
let r = super::__umodsi3(n, d);
|
||||||
|
|
||||||
if let Some(umodsi3) = gcc_s::umodsi3() {
|
match gcc_s::umodsi3() {
|
||||||
|
Some(umodsi3) if rand::random() => {
|
||||||
TestResult::from_bool(r == unsafe { umodsi3(n, d) })
|
TestResult::from_bool(r == unsafe { umodsi3(n, d) })
|
||||||
} else {
|
},
|
||||||
TestResult::from_bool(r == n % d)
|
_ => TestResult::from_bool(r == n % d),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -322,15 +329,16 @@ mod tests {
|
||||||
let mut r = 0;
|
let mut r = 0;
|
||||||
let q = super::__udivmodsi4(n, d, Some(&mut r));
|
let q = super::__udivmodsi4(n, d, Some(&mut r));
|
||||||
|
|
||||||
if let Some(udivmodsi4) = gcc_s::udivmodsi4() {
|
match gcc_s::udivmodsi4() {
|
||||||
|
Some(udivmodsi4) if rand::random() => {
|
||||||
let mut gcc_s_r = 0;
|
let mut gcc_s_r = 0;
|
||||||
let gcc_s_q = unsafe {
|
let gcc_s_q = unsafe {
|
||||||
udivmodsi4(n, d, Some(&mut gcc_s_r))
|
udivmodsi4(n, d, Some(&mut gcc_s_r))
|
||||||
};
|
};
|
||||||
|
|
||||||
TestResult::from_bool(q == gcc_s_q && r == gcc_s_r)
|
TestResult::from_bool(q == gcc_s_q && r == gcc_s_r)
|
||||||
} else {
|
},
|
||||||
TestResult::from_bool(q == n / d && r == n % d)
|
_ => TestResult::from_bool(q == n / d && r == n % d),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,9 @@ extern crate core;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
extern crate gcc_s;
|
extern crate gcc_s;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
extern crate rand;
|
||||||
|
|
||||||
#[cfg(all(not(windows), not(target_os = "macos")))]
|
#[cfg(all(not(windows), not(target_os = "macos")))]
|
||||||
extern crate rlibc;
|
extern crate rlibc;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue