Skip to content

Commit 42bc414

Browse files
authored
Rollup merge of rust-lang#140172 - bjoernager:const-float-algebraic, r=RalfJung
Make algebraic functions into `const fn` items. Tracking issue: rust-lang#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.
2 parents 8e8293e + 0296f05 commit 42bc414

File tree

7 files changed

+70
-51
lines changed

7 files changed

+70
-51
lines changed

compiler/rustc_const_eval/src/interpret/intrinsics.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,31 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
158158
self.copy_op(&val, dest)?;
159159
}
160160

161+
sym::fadd_algebraic
162+
| sym::fsub_algebraic
163+
| sym::fmul_algebraic
164+
| sym::fdiv_algebraic
165+
| sym::frem_algebraic => {
166+
let a = self.read_immediate(&args[0])?;
167+
let b = self.read_immediate(&args[1])?;
168+
169+
let op = match intrinsic_name {
170+
sym::fadd_algebraic => BinOp::Add,
171+
sym::fsub_algebraic => BinOp::Sub,
172+
sym::fmul_algebraic => BinOp::Mul,
173+
sym::fdiv_algebraic => BinOp::Div,
174+
sym::frem_algebraic => BinOp::Rem,
175+
176+
_ => bug!(),
177+
};
178+
179+
let res = self.binary_op(op, &a, &b)?;
180+
// `binary_op` already called `generate_nan` if needed.
181+
182+
// 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.
183+
self.write_immediate(*res, dest)?;
184+
}
185+
161186
sym::ctpop
162187
| sym::cttz
163188
| sym::cttz_nonzero

library/core/src/intrinsics/mod.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2429,35 +2429,35 @@ pub unsafe fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> In
24292429
/// Stabilized as [`f16::algebraic_add`], [`f32::algebraic_add`], [`f64::algebraic_add`] and [`f128::algebraic_add`].
24302430
#[rustc_nounwind]
24312431
#[rustc_intrinsic]
2432-
pub fn fadd_algebraic<T: Copy>(a: T, b: T) -> T;
2432+
pub const fn fadd_algebraic<T: Copy>(a: T, b: T) -> T;
24332433

24342434
/// Float subtraction that allows optimizations based on algebraic rules.
24352435
///
24362436
/// Stabilized as [`f16::algebraic_sub`], [`f32::algebraic_sub`], [`f64::algebraic_sub`] and [`f128::algebraic_sub`].
24372437
#[rustc_nounwind]
24382438
#[rustc_intrinsic]
2439-
pub fn fsub_algebraic<T: Copy>(a: T, b: T) -> T;
2439+
pub const fn fsub_algebraic<T: Copy>(a: T, b: T) -> T;
24402440

24412441
/// Float multiplication that allows optimizations based on algebraic rules.
24422442
///
24432443
/// Stabilized as [`f16::algebraic_mul`], [`f32::algebraic_mul`], [`f64::algebraic_mul`] and [`f128::algebraic_mul`].
24442444
#[rustc_nounwind]
24452445
#[rustc_intrinsic]
2446-
pub fn fmul_algebraic<T: Copy>(a: T, b: T) -> T;
2446+
pub const fn fmul_algebraic<T: Copy>(a: T, b: T) -> T;
24472447

24482448
/// Float division that allows optimizations based on algebraic rules.
24492449
///
24502450
/// Stabilized as [`f16::algebraic_div`], [`f32::algebraic_div`], [`f64::algebraic_div`] and [`f128::algebraic_div`].
24512451
#[rustc_nounwind]
24522452
#[rustc_intrinsic]
2453-
pub fn fdiv_algebraic<T: Copy>(a: T, b: T) -> T;
2453+
pub const fn fdiv_algebraic<T: Copy>(a: T, b: T) -> T;
24542454

24552455
/// Float remainder that allows optimizations based on algebraic rules.
24562456
///
24572457
/// Stabilized as [`f16::algebraic_rem`], [`f32::algebraic_rem`], [`f64::algebraic_rem`] and [`f128::algebraic_rem`].
24582458
#[rustc_nounwind]
24592459
#[rustc_intrinsic]
2460-
pub fn frem_algebraic<T: Copy>(a: T, b: T) -> T;
2460+
pub const fn frem_algebraic<T: Copy>(a: T, b: T) -> T;
24612461

24622462
/// Returns the number of bits set in an integer type `T`
24632463
///

library/core/src/num/f128.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1379,8 +1379,9 @@ impl f128 {
13791379
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
13801380
#[must_use = "method returns a new number and does not mutate the original value"]
13811381
#[unstable(feature = "float_algebraic", issue = "136469")]
1382+
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
13821383
#[inline]
1383-
pub fn algebraic_add(self, rhs: f128) -> f128 {
1384+
pub const fn algebraic_add(self, rhs: f128) -> f128 {
13841385
intrinsics::fadd_algebraic(self, rhs)
13851386
}
13861387

@@ -1389,8 +1390,9 @@ impl f128 {
13891390
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
13901391
#[must_use = "method returns a new number and does not mutate the original value"]
13911392
#[unstable(feature = "float_algebraic", issue = "136469")]
1393+
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
13921394
#[inline]
1393-
pub fn algebraic_sub(self, rhs: f128) -> f128 {
1395+
pub const fn algebraic_sub(self, rhs: f128) -> f128 {
13941396
intrinsics::fsub_algebraic(self, rhs)
13951397
}
13961398

@@ -1399,8 +1401,9 @@ impl f128 {
13991401
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
14001402
#[must_use = "method returns a new number and does not mutate the original value"]
14011403
#[unstable(feature = "float_algebraic", issue = "136469")]
1404+
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
14021405
#[inline]
1403-
pub fn algebraic_mul(self, rhs: f128) -> f128 {
1406+
pub const fn algebraic_mul(self, rhs: f128) -> f128 {
14041407
intrinsics::fmul_algebraic(self, rhs)
14051408
}
14061409

@@ -1409,8 +1412,9 @@ impl f128 {
14091412
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
14101413
#[must_use = "method returns a new number and does not mutate the original value"]
14111414
#[unstable(feature = "float_algebraic", issue = "136469")]
1415+
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
14121416
#[inline]
1413-
pub fn algebraic_div(self, rhs: f128) -> f128 {
1417+
pub const fn algebraic_div(self, rhs: f128) -> f128 {
14141418
intrinsics::fdiv_algebraic(self, rhs)
14151419
}
14161420

@@ -1419,8 +1423,9 @@ impl f128 {
14191423
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
14201424
#[must_use = "method returns a new number and does not mutate the original value"]
14211425
#[unstable(feature = "float_algebraic", issue = "136469")]
1426+
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
14221427
#[inline]
1423-
pub fn algebraic_rem(self, rhs: f128) -> f128 {
1428+
pub const fn algebraic_rem(self, rhs: f128) -> f128 {
14241429
intrinsics::frem_algebraic(self, rhs)
14251430
}
14261431
}

library/core/src/num/f16.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1355,8 +1355,9 @@ impl f16 {
13551355
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
13561356
#[must_use = "method returns a new number and does not mutate the original value"]
13571357
#[unstable(feature = "float_algebraic", issue = "136469")]
1358+
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
13581359
#[inline]
1359-
pub fn algebraic_add(self, rhs: f16) -> f16 {
1360+
pub const fn algebraic_add(self, rhs: f16) -> f16 {
13601361
intrinsics::fadd_algebraic(self, rhs)
13611362
}
13621363

@@ -1365,8 +1366,9 @@ impl f16 {
13651366
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
13661367
#[must_use = "method returns a new number and does not mutate the original value"]
13671368
#[unstable(feature = "float_algebraic", issue = "136469")]
1369+
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
13681370
#[inline]
1369-
pub fn algebraic_sub(self, rhs: f16) -> f16 {
1371+
pub const fn algebraic_sub(self, rhs: f16) -> f16 {
13701372
intrinsics::fsub_algebraic(self, rhs)
13711373
}
13721374

@@ -1375,8 +1377,9 @@ impl f16 {
13751377
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
13761378
#[must_use = "method returns a new number and does not mutate the original value"]
13771379
#[unstable(feature = "float_algebraic", issue = "136469")]
1380+
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
13781381
#[inline]
1379-
pub fn algebraic_mul(self, rhs: f16) -> f16 {
1382+
pub const fn algebraic_mul(self, rhs: f16) -> f16 {
13801383
intrinsics::fmul_algebraic(self, rhs)
13811384
}
13821385

@@ -1385,8 +1388,9 @@ impl f16 {
13851388
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
13861389
#[must_use = "method returns a new number and does not mutate the original value"]
13871390
#[unstable(feature = "float_algebraic", issue = "136469")]
1391+
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
13881392
#[inline]
1389-
pub fn algebraic_div(self, rhs: f16) -> f16 {
1393+
pub const fn algebraic_div(self, rhs: f16) -> f16 {
13901394
intrinsics::fdiv_algebraic(self, rhs)
13911395
}
13921396

@@ -1395,8 +1399,9 @@ impl f16 {
13951399
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
13961400
#[must_use = "method returns a new number and does not mutate the original value"]
13971401
#[unstable(feature = "float_algebraic", issue = "136469")]
1402+
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
13981403
#[inline]
1399-
pub fn algebraic_rem(self, rhs: f16) -> f16 {
1404+
pub const fn algebraic_rem(self, rhs: f16) -> f16 {
14001405
intrinsics::frem_algebraic(self, rhs)
14011406
}
14021407
}

library/core/src/num/f32.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1521,8 +1521,9 @@ impl f32 {
15211521
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
15221522
#[must_use = "method returns a new number and does not mutate the original value"]
15231523
#[unstable(feature = "float_algebraic", issue = "136469")]
1524+
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
15241525
#[inline]
1525-
pub fn algebraic_add(self, rhs: f32) -> f32 {
1526+
pub const fn algebraic_add(self, rhs: f32) -> f32 {
15261527
intrinsics::fadd_algebraic(self, rhs)
15271528
}
15281529

@@ -1531,8 +1532,9 @@ impl f32 {
15311532
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
15321533
#[must_use = "method returns a new number and does not mutate the original value"]
15331534
#[unstable(feature = "float_algebraic", issue = "136469")]
1535+
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
15341536
#[inline]
1535-
pub fn algebraic_sub(self, rhs: f32) -> f32 {
1537+
pub const fn algebraic_sub(self, rhs: f32) -> f32 {
15361538
intrinsics::fsub_algebraic(self, rhs)
15371539
}
15381540

@@ -1541,8 +1543,9 @@ impl f32 {
15411543
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
15421544
#[must_use = "method returns a new number and does not mutate the original value"]
15431545
#[unstable(feature = "float_algebraic", issue = "136469")]
1546+
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
15441547
#[inline]
1545-
pub fn algebraic_mul(self, rhs: f32) -> f32 {
1548+
pub const fn algebraic_mul(self, rhs: f32) -> f32 {
15461549
intrinsics::fmul_algebraic(self, rhs)
15471550
}
15481551

@@ -1551,8 +1554,9 @@ impl f32 {
15511554
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
15521555
#[must_use = "method returns a new number and does not mutate the original value"]
15531556
#[unstable(feature = "float_algebraic", issue = "136469")]
1557+
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
15541558
#[inline]
1555-
pub fn algebraic_div(self, rhs: f32) -> f32 {
1559+
pub const fn algebraic_div(self, rhs: f32) -> f32 {
15561560
intrinsics::fdiv_algebraic(self, rhs)
15571561
}
15581562

@@ -1561,8 +1565,9 @@ impl f32 {
15611565
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
15621566
#[must_use = "method returns a new number and does not mutate the original value"]
15631567
#[unstable(feature = "float_algebraic", issue = "136469")]
1568+
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
15641569
#[inline]
1565-
pub fn algebraic_rem(self, rhs: f32) -> f32 {
1570+
pub const fn algebraic_rem(self, rhs: f32) -> f32 {
15661571
intrinsics::frem_algebraic(self, rhs)
15671572
}
15681573
}

library/core/src/num/f64.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1520,8 +1520,9 @@ impl f64 {
15201520
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
15211521
#[must_use = "method returns a new number and does not mutate the original value"]
15221522
#[unstable(feature = "float_algebraic", issue = "136469")]
1523+
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
15231524
#[inline]
1524-
pub fn algebraic_add(self, rhs: f64) -> f64 {
1525+
pub const fn algebraic_add(self, rhs: f64) -> f64 {
15251526
intrinsics::fadd_algebraic(self, rhs)
15261527
}
15271528

@@ -1530,8 +1531,9 @@ impl f64 {
15301531
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
15311532
#[must_use = "method returns a new number and does not mutate the original value"]
15321533
#[unstable(feature = "float_algebraic", issue = "136469")]
1534+
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
15331535
#[inline]
1534-
pub fn algebraic_sub(self, rhs: f64) -> f64 {
1536+
pub const fn algebraic_sub(self, rhs: f64) -> f64 {
15351537
intrinsics::fsub_algebraic(self, rhs)
15361538
}
15371539

@@ -1540,8 +1542,9 @@ impl f64 {
15401542
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
15411543
#[must_use = "method returns a new number and does not mutate the original value"]
15421544
#[unstable(feature = "float_algebraic", issue = "136469")]
1545+
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
15431546
#[inline]
1544-
pub fn algebraic_mul(self, rhs: f64) -> f64 {
1547+
pub const fn algebraic_mul(self, rhs: f64) -> f64 {
15451548
intrinsics::fmul_algebraic(self, rhs)
15461549
}
15471550

@@ -1550,8 +1553,9 @@ impl f64 {
15501553
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
15511554
#[must_use = "method returns a new number and does not mutate the original value"]
15521555
#[unstable(feature = "float_algebraic", issue = "136469")]
1556+
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
15531557
#[inline]
1554-
pub fn algebraic_div(self, rhs: f64) -> f64 {
1558+
pub const fn algebraic_div(self, rhs: f64) -> f64 {
15551559
intrinsics::fdiv_algebraic(self, rhs)
15561560
}
15571561

@@ -1560,8 +1564,9 @@ impl f64 {
15601564
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
15611565
#[must_use = "method returns a new number and does not mutate the original value"]
15621566
#[unstable(feature = "float_algebraic", issue = "136469")]
1567+
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
15631568
#[inline]
1564-
pub fn algebraic_rem(self, rhs: f64) -> f64 {
1569+
pub const fn algebraic_rem(self, rhs: f64) -> f64 {
15651570
intrinsics::frem_algebraic(self, rhs)
15661571
}
15671572
}

src/tools/miri/src/intrinsics/mod.rs

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -391,32 +391,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
391391
this.write_scalar(res, dest)?;
392392
}
393393

394-
#[rustfmt::skip]
395-
| "fadd_algebraic"
396-
| "fsub_algebraic"
397-
| "fmul_algebraic"
398-
| "fdiv_algebraic"
399-
| "frem_algebraic"
400-
=> {
401-
let [a, b] = check_intrinsic_arg_count(args)?;
402-
let a = this.read_immediate(a)?;
403-
let b = this.read_immediate(b)?;
404-
let op = match intrinsic_name {
405-
"fadd_algebraic" => mir::BinOp::Add,
406-
"fsub_algebraic" => mir::BinOp::Sub,
407-
"fmul_algebraic" => mir::BinOp::Mul,
408-
"fdiv_algebraic" => mir::BinOp::Div,
409-
"frem_algebraic" => mir::BinOp::Rem,
410-
_ => bug!(),
411-
};
412-
let res = this.binary_op(op, &a, &b)?;
413-
// `binary_op` already called `generate_nan` if needed.
414-
// Apply a relative error of 4ULP to simulate non-deterministic precision loss
415-
// due to optimizations.
416-
let res = apply_random_float_error_to_imm(this, res, 2 /* log2(4) */)?;
417-
this.write_immediate(*res, dest)?;
418-
}
419-
420394
#[rustfmt::skip]
421395
| "fadd_fast"
422396
| "fsub_fast"

0 commit comments

Comments
 (0)