Skip to content

Commit

Permalink
Advance the port to llvm/llvm-project@768d6dd
Browse files Browse the repository at this point in the history
(last APFloat-related LLVM commit from 2017).
  • Loading branch information
eddyb committed Jul 18, 2023
1 parent 7265c11 commit a7e2deb
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 7 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
members = ["fuzz"]

[workspace.package]
version = "0.0.0+llvm-f3598e8fca83"
version = "0.0.1+llvm-768d6dd08783"
edition = "2021"
license = "Apache-2.0 WITH LLVM-exception"

Expand Down
6 changes: 3 additions & 3 deletions fuzz/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ curl -sS "$llvm_project_tgz_url" | tar -C "$OUT_DIR" -xz
llvm="$OUT_DIR"/llvm-project-"$llvm_project_git_hash"/llvm
mkdir -p "$OUT_DIR"/fake-config/llvm/Config
touch "$OUT_DIR"/fake-config/llvm/Config/{abi-breaking,llvm-config}.h
touch "$OUT_DIR"/fake-config/llvm/Config/{abi-breaking,config,llvm-config}.h
# HACK(eddyb) we want standard `assert`s to work, but `NDEBUG` also controls
# unrelated LLVM facilities that are spread all over the place and it's harder
Expand All @@ -91,8 +91,8 @@ echo | clang++ -x c++ - -std=c++17 \
$clang_codegen_flags \
-I "$llvm"/include \
-I "$OUT_DIR"/fake-config \
-DNDEBUG \
--include="$llvm"/lib/Support/{APInt,APFloat,SmallVector}.cpp \
-DNDEBUG -DHAVE_UNISTD_H \
--include="$llvm"/lib/Support/{APInt,APFloat,SmallVector,ErrorHandling}.cpp \
--include="$OUT_DIR"/cxx_apf_fuzz.cpp \
-c -emit-llvm -o "$OUT_DIR"/cxx_apf_fuzz.bc
Expand Down
9 changes: 7 additions & 2 deletions src/ieee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1003,6 +1003,8 @@ impl<S: Semantics> Float for IeeeFloat<S> {
(Category::Infinity, _) | (_, Category::Zero) => Status::INVALID_OP.and(Self::NAN),

(Category::Normal, Category::Normal) => {
let orig_sign = self.sign;

while self.is_finite_non_zero()
&& rhs.is_finite_non_zero()
&& self.cmp_abs_normal(rhs) != Ordering::Less
Expand All @@ -1017,6 +1019,9 @@ impl<S: Semantics> Float for IeeeFloat<S> {
self = unpack!(status=, self - v);
assert_eq!(status, Status::OK);
}
if self.is_zero() {
self.sign = orig_sign;
}
Status::OK.and(self)
}
}
Expand Down Expand Up @@ -1182,8 +1187,8 @@ impl<S: Semantics> Float for IeeeFloat<S> {

// Handle special cases.
match s {
"inf" | "INFINITY" => return Ok(Status::OK.and(Self::INFINITY)),
"-inf" | "-INFINITY" => return Ok(Status::OK.and(-Self::INFINITY)),
"inf" | "INFINITY" | "+Inf" => return Ok(Status::OK.and(Self::INFINITY)),
"-inf" | "-INFINITY" | "-Inf" => return Ok(Status::OK.and(-Self::INFINITY)),
"nan" | "NaN" => return Ok(Status::OK.and(Self::NAN)),
"-nan" | "-NaN" => return Ok(Status::OK.and(-Self::NAN)),
_ => {}
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Port of LLVM's APFloat software floating-point implementation from the
//! following C++ sources (please update commit hash when backporting):
//! https://github.com/llvm/llvm-project/commit/f3598e8fca83ccfb11f58ec7957c229e349765e3
//! https://github.com/llvm/llvm-project/commit/768d6dd08783440606da83dac490889329619898
//! * `llvm/include/llvm/ADT/APFloat.h` -> `Float` and `FloatConvert` traits
//! * `llvm/lib/Support/APFloat.cpp` -> `ieee` and `ppc` modules
//! * `llvm/unittests/ADT/APFloatTest.cpp` -> `tests` directory
Expand Down
14 changes: 14 additions & 0 deletions src/ppc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,10 @@ where
self.0.category()
}

fn is_integer(self) -> bool {
self.0.is_integer() && self.1.is_integer()
}

fn get_exact_inverse(self) -> Option<Self> {
Fallback::from(self).get_exact_inverse().map(Self::from)
}
Expand All @@ -428,3 +432,13 @@ where
DoubleFloat(a, b)
}
}

// HACK(eddyb) this is here instead of in `tests/ppc.rs` because `DoubleFloat`
// has private fields, and it's not worth it to make them public just for testing.
#[test]
fn is_integer() {
let double_from_f64 = |f: f64| ieee::Double::from_bits(f.to_bits().into());
assert!(DoubleFloat(double_from_f64(-0.0), double_from_f64(-0.0)).is_integer());
assert!(!DoubleFloat(double_from_f64(3.14159), double_from_f64(-0.0)).is_integer());
assert!(!DoubleFloat(double_from_f64(-0.0), double_from_f64(3.14159)).is_integer());
}
28 changes: 28 additions & 0 deletions tests/ieee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -860,6 +860,20 @@ fn from_decimal_string() {
assert_eq!(2.71828, "2.71828".parse::<Double>().unwrap().to_f64());
}

#[test]
fn from_to_string_specials() {
assert_eq!("+Inf", "+Inf".parse::<Double>().unwrap().to_string());
assert_eq!("+Inf", "INFINITY".parse::<Double>().unwrap().to_string());
assert_eq!("+Inf", "inf".parse::<Double>().unwrap().to_string());
assert_eq!("-Inf", "-Inf".parse::<Double>().unwrap().to_string());
assert_eq!("-Inf", "-INFINITY".parse::<Double>().unwrap().to_string());
assert_eq!("-Inf", "-inf".parse::<Double>().unwrap().to_string());
assert_eq!("NaN", "NaN".parse::<Double>().unwrap().to_string());
assert_eq!("NaN", "nan".parse::<Double>().unwrap().to_string());
assert_eq!("NaN", "-NaN".parse::<Double>().unwrap().to_string());
assert_eq!("NaN", "-nan".parse::<Double>().unwrap().to_string());
}

#[test]
fn from_hexadecimal_string() {
assert_eq!(1.0, "0x1p0".parse::<Double>().unwrap().to_f64());
Expand Down Expand Up @@ -3190,4 +3204,18 @@ fn modulo() {
assert!(unpack!(status=, f1 % f2).is_nan());
assert_eq!(status, Status::INVALID_OP);
}
{
let f1 = "-4.0".parse::<Double>().unwrap();
let f2 = "-2.0".parse::<Double>().unwrap();
let expected = "-0.0".parse::<Double>().unwrap();
assert!(unpack!(status=, f1 % f2).bitwise_eq(expected));
assert_eq!(status, Status::OK);
}
{
let f1 = "-4.0".parse::<Double>().unwrap();
let f2 = "2.0".parse::<Double>().unwrap();
let expected = "-0.0".parse::<Double>().unwrap();
assert!(unpack!(status=, f1 % f2).bitwise_eq(expected));
assert_eq!(status, Status::OK);
}
}

0 comments on commit a7e2deb

Please sign in to comment.