Skip to content

Commit e4703ec

Browse files
committed
Advance the port to llvm/llvm-project@a258894
(last APFloat-related LLVM commit from June 2020, concluding the addition of BFloat16).
1 parent 6a67d49 commit e4703ec

File tree

5 files changed

+50
-23
lines changed

5 files changed

+50
-23
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
members = ["fuzz"]
33

44
[workspace.package]
5-
version = "0.0.4+llvm-b198f1f86ce0"
5+
version = "0.0.5+llvm-a2588948febc"
66
edition = "2021"
77
license = "Apache-2.0 WITH LLVM-exception"
88

fuzz/ops.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,11 +280,13 @@ struct FuzzOp {
280280
(32, "APFloat::IEEEsingle()"),
281281
(64, "APFloat::IEEEdouble()"),
282282
(128, "APFloat::IEEEquad()"),
283+
(16, "APFloat::BFloat()"),
283284
(80, "APFloat::x87DoubleExtended()"),
284285
]
285286
.into_iter()
286287
.map(|(w, cxx_apf_semantics)| {
287288
let (name_prefix, uint_width) = match w {
289+
16 if cxx_apf_semantics.contains("BFloat") => ("BrainF", 16),
288290
80 => ("X87_F", 128),
289291
_ => ("IEEE", w),
290292
};

fuzz/src/main.rs

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ trait FloatRepr: Copy + Default + Eq + fmt::Display {
5454

5555
const NAME: &'static str;
5656

57+
// HACK(eddyb) this has to be overwritable because we have more than one
58+
// format with the same `BIT_WIDTH`, so it's not unambiguous on its own.
59+
const REPR_TAG: u8 = Self::BIT_WIDTH as u8;
60+
5761
// FIXME(eddyb) these should ideally be using `[u8; Self::BYTE_LEN]`.
5862
fn from_le_bytes(bytes: &[u8]) -> Self;
5963
fn write_as_le_bytes_into(self, out_bytes: &mut Vec<u8>);
@@ -70,17 +74,24 @@ trait FloatRepr: Copy + Default + Eq + fmt::Display {
7074
macro_rules! float_reprs {
7175
($($name:ident($repr:ty) {
7276
type RustcApFloat = $rs_apf_ty:ty;
77+
$(const REPR_TAG = $repr_tag:expr;)?
7378
extern fn = $cxx_apf_eval_fuzz_op:ident;
7479
$(type HardFloat = $hard_float_ty:ty;)?
7580
})+) => {
7681
// HACK(eddyb) helper macro used to actually handle all types uniformly.
77-
macro_rules! dispatch_all_reprs {
78-
($ty_var:ident => $e:expr) => {{
79-
$({
80-
type $ty_var = $name;
81-
$e
82-
})+
83-
}}
82+
macro_rules! dispatch_any_float_repr_by_repr_tag {
83+
(match $repr_tag_value:ident { for<$ty_var:ident: FloatRepr> => $e:expr }) => {
84+
// NOTE(eddyb) this doubles as an overlap check: `REPR_TAG`
85+
// values across *all* `FloatRepr` `impl` *must* be unique.
86+
#[deny(unreachable_patterns)]
87+
match $repr_tag_value {
88+
$($name::REPR_TAG => {
89+
type $ty_var = $name;
90+
$e;
91+
})+
92+
_ => {}
93+
}
94+
}
8495
}
8596

8697
$(
@@ -96,6 +107,8 @@ macro_rules! float_reprs {
96107

97108
const NAME: &'static str = stringify!($name);
98109

110+
$(const REPR_TAG: u8 = $repr_tag;)?
111+
99112
fn from_le_bytes(bytes: &[u8]) -> Self {
100113
// HACK(eddyb) this allows using e.g. `u128` to hold 80 bits.
101114
let mut repr_bytes = [0; std::mem::size_of::<$repr>()];
@@ -180,6 +193,13 @@ float_reprs! {
180193
type RustcApFloat = rustc_apfloat::ieee::Quad;
181194
extern fn = cxx_apf_fuzz_eval_op_ieee128;
182195
}
196+
197+
// Non-standard IEEE-like formats.
198+
BrainF16(u16) {
199+
type RustcApFloat = rustc_apfloat::ieee::BFloat;
200+
const REPR_TAG = 16 + 1;
201+
extern fn = cxx_apf_fuzz_eval_op_brainf16;
202+
}
183203
X87_F80(u128) {
184204
type RustcApFloat = rustc_apfloat::ieee::X87DoubleExtended;
185205
extern fn = cxx_apf_fuzz_eval_op_x87_f80;
@@ -380,15 +400,16 @@ fn main() {
380400

381401
data.split_first()
382402
.ok_or("empty file")
383-
.and_then(|(&bit_width, data)| {
384-
dispatch_all_reprs!(F => if bit_width as usize == F::BIT_WIDTH {
385-
FuzzOp::<F>::try_decode(data)
386-
.ok()
387-
.ok_or(std::any::type_name::<FuzzOp<F>>())?
388-
.print_op_and_eval_outputs(&cli_args);
389-
return Ok(());
403+
.and_then(|(&repr_tag, data)| {
404+
dispatch_any_float_repr_by_repr_tag!(match repr_tag {
405+
for<F: FloatRepr> => return Ok(
406+
FuzzOp::<F>::try_decode(data)
407+
.ok()
408+
.ok_or(std::any::type_name::<FuzzOp<F>>())?
409+
.print_op_and_eval_outputs(&cli_args)
410+
)
390411
});
391-
Err("first byte not valid bit width")
412+
Err("first byte not valid `FloatRepr::REPR_TAG`")
392413
})
393414
.unwrap_or_else(|e| println!(" invalid data ({e})"));
394415
}
@@ -399,10 +420,11 @@ fn main() {
399420

400421
#[cfg_attr(not(fuzzing), allow(unused))]
401422
let fuzz_one_op = |data: &[u8]| {
402-
data.split_first().and_then(|(&bit_width, data)| {
403-
dispatch_all_reprs!(F => if bit_width as usize == F::BIT_WIDTH {
404-
FuzzOp::<F>::try_decode(data).ok()?.eval(&cli_args).assert_all_match();
405-
return Some(());
423+
data.split_first().and_then(|(&repr_tag, data)| {
424+
dispatch_any_float_repr_by_repr_tag!(match repr_tag {
425+
for<F: FloatRepr> => return Some(
426+
FuzzOp::<F>::try_decode(data).ok()?.eval(&cli_args).assert_all_match()
427+
)
406428
});
407429
None
408430
});

src/ieee.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ impl<S> Clone for IeeeFloat<S> {
165165
}
166166

167167
macro_rules! ieee_semantics {
168-
($($name:ident = $sem:ident($bits:tt : $exp_bits:tt)),*) => {
168+
($($name:ident = $sem:ident($bits:tt : $exp_bits:tt)),* $(,)?) => {
169169
$(pub struct $sem;)*
170170
$(pub type $name = IeeeFloat<$sem>;)*
171171
$(impl Semantics for $sem {
@@ -180,7 +180,10 @@ ieee_semantics! {
180180
Half = HalfS(16:5),
181181
Single = SingleS(32:8),
182182
Double = DoubleS(64:11),
183-
Quad = QuadS(128:15)
183+
Quad = QuadS(128:15),
184+
185+
// Non-standard IEEE-like semantics.
186+
BFloat = BFloatS(16:8),
184187
}
185188

186189
pub struct X87DoubleExtendedS;

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Port of LLVM's APFloat software floating-point implementation from the
22
//! following C++ sources (please update commit hash when backporting):
3-
//! https://github.com/llvm/llvm-project/commit/b198f1f86ce09b86825dd6d80de2c72a617e27f7
3+
//! https://github.com/llvm/llvm-project/commit/a2588948febccfed5ba074fc32dcb093484fa5c8
44
//! * `llvm/include/llvm/ADT/APFloat.h` -> `Float` and `FloatConvert` traits
55
//! * `llvm/lib/Support/APFloat.cpp` -> `ieee` and `ppc` modules
66
//! * `llvm/unittests/ADT/APFloatTest.cpp` -> `tests` directory

0 commit comments

Comments
 (0)