Browse Source

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.
Jorge Aparicio 8 years ago
parent
commit
384c48ce9b
7 changed files with 141 additions and 106 deletions
  1. 8 2
      Cargo.toml
  2. 6 4
      src/float/add.rs
  3. 24 21
      src/int/mul.rs
  4. 41 33
      src/int/sdiv.rs
  5. 18 13
      src/int/shift.rs
  6. 41 33
      src/int/udiv.rs
  7. 3 0
      src/lib.rs

+ 8 - 2
Cargo.toml

@@ -5,11 +5,17 @@ name = "rustc_builtins"
 version = "0.1.0"
 
 [dependencies]
-rlibc = { git = "https://github.com/alexcrichton/rlibc", optional = true }
+
+[dependencies.rlibc]
+git = "https://github.com/alexcrichton/rlibc"
+optional = true
 
 [dev-dependencies]
-gcc_s = { path = "gcc_s" }
 quickcheck = "0.3.1"
+rand = "0.3.14"
+
+[dev-dependencies.gcc_s]
+path = "gcc_s"
 
 [features]
 default = ["rlibc/weak"]

+ 6 - 4
src/float/add.rs

@@ -200,9 +200,11 @@ pub extern fn __aeabi_fadd(a: f32, b: f32) -> f32 {
 mod tests {
     use core::{f32, f64};
 
-    use gcc_s;
-    use qc::{U32, U64};
     use float::Float;
+    use qc::{U32, U64};
+
+    use gcc_s;
+    use rand;
 
     // NOTE The tests below have special handing for NaN values.
     // 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
                 // and matches its gcc_s counterpart on *soft* float targets.
                 #[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),
             }
         }
@@ -235,7 +237,7 @@ mod tests {
             match gcc_s::adddf3() {
                 // NOTE(cfg) See NOTE above
                 #[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),
 
             }

+ 24 - 21
src/int/mul.rs

@@ -72,18 +72,19 @@ mulo!(__mulodi4: i64);
 
 #[cfg(test)]
 mod tests {
-    use gcc_s;
     use qc::{I32, I64, U64};
 
+    use gcc_s;
+    use rand;
+
     quickcheck! {
         fn muldi(a: U64, b: U64) -> bool {
             let (a, b) = (a.0, b.0);
             let r = super::__muldi3(a, b);
 
-            if let Some(muldi3) = gcc_s::muldi3() {
-                r == unsafe { muldi3(a, b) }
-            } else {
-                r == a.wrapping_mul(b)
+            match gcc_s::muldi3() {
+                Some(muldi3) if rand::random() => r == unsafe { muldi3(a, b) },
+                _ => r == a.wrapping_mul(b),
             }
         }
 
@@ -95,15 +96,16 @@ mod tests {
                 return false;
             }
 
-            if let Some(mulosi4) = gcc_s::mulosi4() {
-                let mut gcc_s_overflow = 2;
-                let gcc_s_r = unsafe {
-                    mulosi4(a, b, &mut gcc_s_overflow)
-                };
+            match gcc_s::mulosi4() {
+                Some(mulosi4) if rand::random() => {
+                    let mut gcc_s_overflow = 2;
+                    let gcc_s_r = unsafe {
+                        mulosi4(a, b, &mut gcc_s_overflow)
+                    };
 
-                (r, overflow) == (gcc_s_r, gcc_s_overflow)
-            } else {
-                (r, overflow != 0) == a.overflowing_mul(b)
+                    (r, overflow) == (gcc_s_r, gcc_s_overflow)
+                },
+                _ => (r, overflow != 0) == a.overflowing_mul(b),
             }
         }
 
@@ -115,15 +117,16 @@ mod tests {
                 return false;
             }
 
-            if let Some(mulodi4) = gcc_s::mulodi4() {
-                let mut gcc_s_overflow = 2;
-                let gcc_s_r = unsafe {
-                    mulodi4(a, b, &mut gcc_s_overflow)
-                };
+            match gcc_s::mulodi4() {
+                Some(mulodi4) if rand::random() => {
+                    let mut gcc_s_overflow = 2;
+                    let gcc_s_r = unsafe {
+                        mulodi4(a, b, &mut gcc_s_overflow)
+                    };
 
-                (r, overflow) == (gcc_s_r, gcc_s_overflow)
-            } else {
-                (r, overflow != 0) == a.overflowing_mul(b)
+                    (r, overflow) == (gcc_s_r, gcc_s_overflow)
+                },
+                _ => (r, overflow != 0) == a.overflowing_mul(b),
             }
         }
     }

+ 41 - 33
src/int/sdiv.rs

@@ -52,9 +52,11 @@ divmod!(__divmoddi4, __divdi3: i64);
 
 #[cfg(test)]
 mod tests {
+    use qc::{U32, U64};
+
     use gcc_s;
     use quickcheck::TestResult;
-    use qc::{U32, U64};
+    use rand;
 
     quickcheck!{
         fn divdi3(n: U64, d: U64) -> TestResult {
@@ -64,10 +66,11 @@ mod tests {
             } else {
                 let q = super::__divdi3(n, d);
 
-                if let Some(divdi3) = gcc_s::divdi3() {
-                    TestResult::from_bool(q == unsafe { divdi3(n, d) })
-                } else {
-                    TestResult::from_bool(q == n / d)
+                match gcc_s::divdi3() {
+                    Some(divdi3) if rand::random() => {
+                        TestResult::from_bool(q == unsafe { divdi3(n, d) })
+                    },
+                    _ => TestResult::from_bool(q == n / d),
                 }
             }
         }
@@ -79,10 +82,11 @@ mod tests {
             } else {
                 let r = super::__moddi3(n, d);
 
-                if let Some(moddi3) = gcc_s::moddi3() {
-                    TestResult::from_bool(r == unsafe { moddi3(n, d) })
-                } else {
-                    TestResult::from_bool(r == n % d)
+                match gcc_s::moddi3() {
+                    Some(moddi3) if rand::random() => {
+                        TestResult::from_bool(r == unsafe { moddi3(n, d) })
+                    },
+                    _ => TestResult::from_bool(r == n % d),
                 }
             }
         }
@@ -95,15 +99,16 @@ mod tests {
                 let mut r = 0;
                 let q = super::__divmoddi4(n, d, &mut r);
 
-                if let Some(divmoddi4) = gcc_s::divmoddi4() {
-                    let mut gcc_s_r = 0;
-                    let gcc_s_q = unsafe {
-                        divmoddi4(n, d, &mut gcc_s_r)
-                    };
+                match gcc_s::divmoddi4() {
+                    Some(divmoddi4) if rand::random() => {
+                        let mut gcc_s_r = 0;
+                        let gcc_s_q = unsafe {
+                            divmoddi4(n, d, &mut 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 == gcc_s_q && r == gcc_s_r)
+                    },
+                    _ => TestResult::from_bool(q == n / d && r == n % d),
                 }
             }
         }
@@ -115,10 +120,11 @@ mod tests {
             } else {
                 let q = super::__divsi3(n, d);
 
-                if let Some(divsi3) = gcc_s::divsi3() {
-                    TestResult::from_bool(q == unsafe { divsi3(n, d)})
-                } else {
-                    TestResult::from_bool(q == n / d)
+                match gcc_s::divsi3() {
+                    Some(divsi3) if rand::random() => {
+                        TestResult::from_bool(q == unsafe { divsi3(n, d)})
+                    },
+                    _ => TestResult::from_bool(q == n / d),
                 }
             }
         }
@@ -130,10 +136,11 @@ mod tests {
             } else {
                 let r = super::__modsi3(n, d);
 
-                if let Some(modsi3) = gcc_s::modsi3() {
-                    TestResult::from_bool(r == unsafe { modsi3(n, d) })
-                } else {
-                    TestResult::from_bool(r == n % d)
+                match gcc_s::modsi3() {
+                    Some(modsi3) if rand::random() => {
+                        TestResult::from_bool(r == unsafe { modsi3(n, d) })
+                    },
+                    _ => TestResult::from_bool(r == n % d),
                 }
             }
         }
@@ -146,15 +153,16 @@ mod tests {
                 let mut r = 0;
                 let q = super::__divmodsi4(n, d, &mut r);
 
-                if let Some(divmodsi4) = gcc_s::divmodsi4() {
-                    let mut gcc_s_r = 0;
-                    let gcc_s_q = unsafe {
-                        divmodsi4(n, d, &mut gcc_s_r)
-                    };
+                match gcc_s::divmodsi4() {
+                    Some(divmodsi4) if rand::random() => {
+                        let mut gcc_s_r = 0;
+                        let gcc_s_q = unsafe {
+                            divmodsi4(n, d, &mut 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 == gcc_s_q && r == gcc_s_r)
+                    },
+                    _ => TestResult::from_bool(q == n / d && r == n % d),
                 }
             }
         }

+ 18 - 13
src/int/shift.rs

@@ -60,9 +60,11 @@ lshr!(__lshrdi3: u64);
 
 #[cfg(test)]
 mod tests {
+    use qc::{I64, U64};
+
     use gcc_s;
     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)
     quickcheck! {
@@ -73,10 +75,11 @@ mod tests {
             } else {
                 let r = super::__ashldi3(a, b);
 
-                if let Some(ashldi3) = gcc_s::ashldi3() {
-                    TestResult::from_bool(r == unsafe { ashldi3(a, b) })
-                } else {
-                    TestResult::from_bool(r == a << b)
+                match gcc_s::ashldi3() {
+                    Some(ashldi3) if rand::random() => {
+                        TestResult::from_bool(r == unsafe { ashldi3(a, b) })
+                    },
+                    _ => TestResult::from_bool(r == a << b),
                 }
             }
         }
@@ -88,10 +91,11 @@ mod tests {
             } else {
                 let r = super::__ashrdi3(a, b);
 
-                if let Some(ashrdi3) = gcc_s::ashrdi3() {
-                    TestResult::from_bool(r == unsafe { ashrdi3(a, b) })
-                } else {
-                    TestResult::from_bool(r == a >> b)
+                match gcc_s::ashrdi3() {
+                    Some(ashrdi3) if rand::random() => {
+                        TestResult::from_bool(r == unsafe { ashrdi3(a, b) })
+                    },
+                    _ => TestResult::from_bool(r == a >> b),
                 }
             }
         }
@@ -103,10 +107,11 @@ mod tests {
             } else {
                 let r = super::__lshrdi3(a, b);
 
-                if let Some(lshrdi3) = gcc_s::lshrdi3() {
-                    TestResult::from_bool(r == unsafe { lshrdi3(a, b) })
-                } else {
-                    TestResult::from_bool(r == a >> b)
+                match gcc_s::lshrdi3() {
+                    Some(lshrdi3) if rand::random() => {
+                        TestResult::from_bool(r == unsafe { lshrdi3(a, b) })
+                    },
+                    _ => TestResult::from_bool(r == a >> b),
                 }
             }
         }

+ 41 - 33
src/int/udiv.rs

@@ -228,9 +228,11 @@ pub extern "C" fn __udivmoddi4(n: u64, d: u64, rem: Option<&mut u64>) -> u64 {
 
 #[cfg(test)]
 mod tests {
+    use qc::{U32, U64};
+
     use gcc_s;
     use quickcheck::TestResult;
-    use qc::{U32, U64};
+    use rand;
 
     quickcheck!{
         fn udivdi3(n: U64, d: U64) -> TestResult {
@@ -240,10 +242,11 @@ mod tests {
             } else {
                 let q = super::__udivdi3(n, d);
 
-                if let Some(udivdi3) = gcc_s::udivdi3() {
-                    TestResult::from_bool(q == unsafe { udivdi3(n, d) })
-                } else {
-                    TestResult::from_bool(q == n / d)
+                match gcc_s::udivdi3() {
+                    Some(udivdi3) if rand::random() => {
+                        TestResult::from_bool(q == unsafe { udivdi3(n, d) })
+                    },
+                    _ => TestResult::from_bool(q == n / d),
                 }
             }
         }
@@ -255,10 +258,11 @@ mod tests {
             } else {
                 let r = super::__umoddi3(n, d);
 
-                if let Some(umoddi3) = gcc_s::umoddi3() {
-                    TestResult::from_bool(r == unsafe { umoddi3(n, d) })
-                } else {
-                    TestResult::from_bool(r == n % d)
+                match gcc_s::umoddi3() {
+                    Some(umoddi3) if rand::random() => {
+                        TestResult::from_bool(r == unsafe { umoddi3(n, d) })
+                    },
+                    _ => TestResult::from_bool(r == n % d),
                 }
             }
         }
@@ -271,15 +275,16 @@ mod tests {
                 let mut r = 0;
                 let q = super::__udivmoddi4(n, d, Some(&mut r));
 
-                if let Some(udivmoddi4) = gcc_s::udivmoddi4() {
-                    let mut gcc_s_r = 0;
-                    let gcc_s_q = unsafe {
-                        udivmoddi4(n, d, Some(&mut gcc_s_r))
-                    };
+                match gcc_s::udivmoddi4() {
+                    Some(udivmoddi4) if rand::random() => {
+                        let mut gcc_s_r = 0;
+                        let gcc_s_q = unsafe {
+                            udivmoddi4(n, d, Some(&mut 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 == gcc_s_q && r == gcc_s_r)
+                    },
+                    _ => TestResult::from_bool(q == n / d && r == n % d),
                 }
             }
         }
@@ -291,10 +296,11 @@ mod tests {
             } else {
                 let q = super::__udivsi3(n, d);
 
-                if let Some(udivsi3) = gcc_s::udivsi3() {
-                    TestResult::from_bool(q == unsafe { udivsi3(n, d) })
-                } else {
-                    TestResult::from_bool(q == n / d)
+                match gcc_s::udivsi3() {
+                    Some(udivsi3) if rand::random() => {
+                        TestResult::from_bool(q == unsafe { udivsi3(n, d) })
+                    },
+                    _ => TestResult::from_bool(q == n / d),
                 }
             }
         }
@@ -306,10 +312,11 @@ mod tests {
             } else {
                 let r = super::__umodsi3(n, d);
 
-                if let Some(umodsi3) = gcc_s::umodsi3() {
-                    TestResult::from_bool(r == unsafe { umodsi3(n, d) })
-                } else {
-                    TestResult::from_bool(r == n % d)
+                match gcc_s::umodsi3() {
+                    Some(umodsi3) if rand::random() => {
+                        TestResult::from_bool(r == unsafe { umodsi3(n, d) })
+                    },
+                    _ => TestResult::from_bool(r == n % d),
                 }
             }
         }
@@ -322,15 +329,16 @@ mod tests {
                 let mut r = 0;
                 let q = super::__udivmodsi4(n, d, Some(&mut r));
 
-                if let Some(udivmodsi4) = gcc_s::udivmodsi4() {
-                    let mut gcc_s_r = 0;
-                    let gcc_s_q = unsafe {
-                        udivmodsi4(n, d, Some(&mut gcc_s_r))
-                    };
+                match gcc_s::udivmodsi4() {
+                    Some(udivmodsi4) if rand::random() => {
+                        let mut gcc_s_r = 0;
+                        let gcc_s_q = unsafe {
+                            udivmodsi4(n, d, Some(&mut 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 == gcc_s_q && r == gcc_s_r)
+                    },
+                    _ => TestResult::from_bool(q == n / d && r == n % d),
                 }
             }
         }

+ 3 - 0
src/lib.rs

@@ -20,6 +20,9 @@ extern crate core;
 #[cfg(test)]
 extern crate gcc_s;
 
+#[cfg(test)]
+extern crate rand;
+
 #[cfg(all(not(windows), not(target_os = "macos")))]
 extern crate rlibc;