Auto merge of #120718 - saethlin:reasonable-fast-math, r=nnethercote
Add "algebraic" fast-math intrinsics, based on fast-math ops that cannot return poison Setting all of LLVM's fast-math flags makes our fast-math intrinsics very dangerous, because some inputs are UB. This set of flags permits common algebraic transformations, but according to the [LangRef](https://llvm.org/docs/LangRef.html#fastmath), only the flags `nnan` (no nans) and `ninf` (no infs) can produce poison. And this uses the algebraic float ops to fix https://github.com/rust-lang/rust/issues/120720 cc `@orlp`
This commit is contained in:
commit
bb8b11e67d
12 changed files with 226 additions and 14 deletions
|
@ -250,6 +250,38 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
}
|
||||
}
|
||||
}
|
||||
sym::fadd_algebraic
|
||||
| sym::fsub_algebraic
|
||||
| sym::fmul_algebraic
|
||||
| sym::fdiv_algebraic
|
||||
| sym::frem_algebraic => match float_type_width(arg_tys[0]) {
|
||||
Some(_width) => match name {
|
||||
sym::fadd_algebraic => {
|
||||
bx.fadd_algebraic(args[0].immediate(), args[1].immediate())
|
||||
}
|
||||
sym::fsub_algebraic => {
|
||||
bx.fsub_algebraic(args[0].immediate(), args[1].immediate())
|
||||
}
|
||||
sym::fmul_algebraic => {
|
||||
bx.fmul_algebraic(args[0].immediate(), args[1].immediate())
|
||||
}
|
||||
sym::fdiv_algebraic => {
|
||||
bx.fdiv_algebraic(args[0].immediate(), args[1].immediate())
|
||||
}
|
||||
sym::frem_algebraic => {
|
||||
bx.frem_algebraic(args[0].immediate(), args[1].immediate())
|
||||
}
|
||||
_ => bug!(),
|
||||
},
|
||||
None => {
|
||||
bx.tcx().dcx().emit_err(InvalidMonomorphization::BasicFloatType {
|
||||
span,
|
||||
name,
|
||||
ty: arg_tys[0],
|
||||
});
|
||||
return Ok(());
|
||||
}
|
||||
},
|
||||
|
||||
sym::float_to_int_unchecked => {
|
||||
if float_type_width(arg_tys[0]).is_none() {
|
||||
|
|
|
@ -86,22 +86,27 @@ pub trait BuilderMethods<'a, 'tcx>:
|
|||
fn add(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
|
||||
fn fadd(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
|
||||
fn fadd_fast(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
|
||||
fn fadd_algebraic(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
|
||||
fn sub(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
|
||||
fn fsub(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
|
||||
fn fsub_fast(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
|
||||
fn fsub_algebraic(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
|
||||
fn mul(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
|
||||
fn fmul(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
|
||||
fn fmul_fast(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
|
||||
fn fmul_algebraic(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
|
||||
fn udiv(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
|
||||
fn exactudiv(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
|
||||
fn sdiv(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
|
||||
fn exactsdiv(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
|
||||
fn fdiv(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
|
||||
fn fdiv_fast(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
|
||||
fn fdiv_algebraic(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
|
||||
fn urem(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
|
||||
fn srem(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
|
||||
fn frem(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
|
||||
fn frem_fast(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
|
||||
fn frem_algebraic(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
|
||||
fn shl(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
|
||||
fn lshr(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
|
||||
fn ashr(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue