about summary refs log tree commit diff
path: root/compiler/rustc_const_eval/src
diff options
context:
space:
mode:
authorMatthias Krüger <476013+matthiaskrgr@users.noreply.github.com>2025-04-24 17:19:46 +0200
committerGitHub <noreply@github.com>2025-04-24 17:19:46 +0200
commitcea6ba7a06359e929a66d39ee513566d9b4f5527 (patch)
tree811cfe00eceda9fbeac52932eb9e3c144c1904ff /compiler/rustc_const_eval/src
parent06126df8b83b27a108f8c72d4ab040d843700882 (diff)
parent0296f05ce568e644363daa2f37b3a4d245d13951 (diff)
downloadrust-cea6ba7a06359e929a66d39ee513566d9b4f5527.tar.gz
rust-cea6ba7a06359e929a66d39ee513566d9b4f5527.zip
Rollup merge of #140172 - bjoernager:const-float-algebraic, r=RalfJung
Make algebraic functions into `const fn` items.

Tracking issue: #136469

This PR makes the algebraic intrinsics and the unstable, algebraic functions of `f16`, `f32`, `f64`, and `f128` into `const fn` items:

```rust
impl f16 {
    pub const fn algebraic_add(self, rhs: f16) -> f16;
    pub const fn algebraic_sub(self, rhs: f16) -> f16;
    pub const fn algebraic_mul(self, rhs: f16) -> f16;
    pub const fn algebraic_div(self, rhs: f16) -> f16;
    pub const fn algebraic_rem(self, rhs: f16) -> f16;
}

impl f32 {
    pub const fn algebraic_add(self, rhs: f32) -> f32;
    pub const fn algebraic_sub(self, rhs: f32) -> f32;
    pub const fn algebraic_mul(self, rhs: f32) -> f32;
    pub const fn algebraic_div(self, rhs: f32) -> f32;
    pub const fn algebraic_rem(self, rhs: f32) -> f32;
}

impl f64 {
    pub const fn algebraic_add(self, rhs: f64) -> f64;
    pub const fn algebraic_sub(self, rhs: f64) -> f64;
    pub const fn algebraic_mul(self, rhs: f64) -> f64;
    pub const fn algebraic_div(self, rhs: f64) -> f64;
    pub const fn algebraic_rem(self, rhs: f64) -> f64;
}

impl f128 {
    pub const fn algebraic_add(self, rhs: f128) -> f128;
    pub const fn algebraic_sub(self, rhs: f128) -> f128;
    pub const fn algebraic_mul(self, rhs: f128) -> f128;
    pub const fn algebraic_div(self, rhs: f128) -> f128;
    pub const fn algebraic_rem(self, rhs: f128) -> f128;
}

// core::intrinsics

pub const fn fadd_algebraic<T: Copy>(a: T, b: T) -> T;
pub const fn fsub_algebraic<T: Copy>(a: T, b: T) -> T;
pub const fn fmul_algebraic<T: Copy>(a: T, b: T) -> T;
pub const fn fdiv_algebraic<T: Copy>(a: T, b: T) -> T;
pub const fn frem_algebraic<T: Copy>(a: T, b: T) -> T;
```

This PR does not preserve the initial behaviour of these functions yielding non-deterministic output under Miri; it is most likely desired to reimplement this behaviour at some point.
Diffstat (limited to 'compiler/rustc_const_eval/src')
-rw-r--r--compiler/rustc_const_eval/src/interpret/intrinsics.rs25
1 files changed, 25 insertions, 0 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
index 4ca317e3a1e..40c63f2b250 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
@@ -158,6 +158,31 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                 self.copy_op(&val, dest)?;
             }
 
+            sym::fadd_algebraic
+            | sym::fsub_algebraic
+            | sym::fmul_algebraic
+            | sym::fdiv_algebraic
+            | sym::frem_algebraic => {
+                let a = self.read_immediate(&args[0])?;
+                let b = self.read_immediate(&args[1])?;
+
+                let op = match intrinsic_name {
+                    sym::fadd_algebraic => BinOp::Add,
+                    sym::fsub_algebraic => BinOp::Sub,
+                    sym::fmul_algebraic => BinOp::Mul,
+                    sym::fdiv_algebraic => BinOp::Div,
+                    sym::frem_algebraic => BinOp::Rem,
+
+                    _ => bug!(),
+                };
+
+                let res = self.binary_op(op, &a, &b)?;
+                // `binary_op` already called `generate_nan` if needed.
+
+                // FIXME: Miri should add some non-determinism to the result here to catch any dependences on exact computations. This has previously been done, but the behaviour was removed as part of constification.
+                self.write_immediate(*res, dest)?;
+            }
+
             sym::ctpop
             | sym::cttz
             | sym::cttz_nonzero