Skip to content

Commit cea6ba7

Browse files
authored
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.
2 parents 06126df + 0296f05 commit cea6ba7

File tree

7 files changed

+70
-51
lines changed

7 files changed

+70
-51
lines changed

compiler/rustc_const_eval/src/interpret/intrinsics.rs

+25
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

+5-5
Original file line numberDiff line numberDiff line change
@@ -2430,35 +2430,35 @@ pub unsafe fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> In
24302430
/// Stabilized as [`f16::algebraic_add`], [`f32::algebraic_add`], [`f64::algebraic_add`] and [`f128::algebraic_add`].
24312431
#[rustc_nounwind]
24322432
#[rustc_intrinsic]
2433-
pub fn fadd_algebraic<T: Copy>(a: T, b: T) -> T;
2433+
pub const fn fadd_algebraic<T: Copy>(a: T, b: T) -> T;
24342434

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

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

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

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

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

library/core/src/num/f128.rs

+10-5
Original file line numberDiff line numberDiff line change
@@ -1382,8 +1382,9 @@ impl f128 {
13821382
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
13831383
#[must_use = "method returns a new number and does not mutate the original value"]
13841384
#[unstable(feature = "float_algebraic", issue = "136469")]
1385+
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
13851386
#[inline]
1386-
pub fn algebraic_add(self, rhs: f128) -> f128 {
1387+
pub const fn algebraic_add(self, rhs: f128) -> f128 {
13871388
intrinsics::fadd_algebraic(self, rhs)
13881389
}
13891390

@@ -1392,8 +1393,9 @@ impl f128 {
13921393
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
13931394
#[must_use = "method returns a new number and does not mutate the original value"]
13941395
#[unstable(feature = "float_algebraic", issue = "136469")]
1396+
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
13951397
#[inline]
1396-
pub fn algebraic_sub(self, rhs: f128) -> f128 {
1398+
pub const fn algebraic_sub(self, rhs: f128) -> f128 {
13971399
intrinsics::fsub_algebraic(self, rhs)
13981400
}
13991401

@@ -1402,8 +1404,9 @@ impl f128 {
14021404
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
14031405
#[must_use = "method returns a new number and does not mutate the original value"]
14041406
#[unstable(feature = "float_algebraic", issue = "136469")]
1407+
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
14051408
#[inline]
1406-
pub fn algebraic_mul(self, rhs: f128) -> f128 {
1409+
pub const fn algebraic_mul(self, rhs: f128) -> f128 {
14071410
intrinsics::fmul_algebraic(self, rhs)
14081411
}
14091412

@@ -1412,8 +1415,9 @@ impl f128 {
14121415
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
14131416
#[must_use = "method returns a new number and does not mutate the original value"]
14141417
#[unstable(feature = "float_algebraic", issue = "136469")]
1418+
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
14151419
#[inline]
1416-
pub fn algebraic_div(self, rhs: f128) -> f128 {
1420+
pub const fn algebraic_div(self, rhs: f128) -> f128 {
14171421
intrinsics::fdiv_algebraic(self, rhs)
14181422
}
14191423

@@ -1422,8 +1426,9 @@ impl f128 {
14221426
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
14231427
#[must_use = "method returns a new number and does not mutate the original value"]
14241428
#[unstable(feature = "float_algebraic", issue = "136469")]
1429+
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
14251430
#[inline]
1426-
pub fn algebraic_rem(self, rhs: f128) -> f128 {
1431+
pub const fn algebraic_rem(self, rhs: f128) -> f128 {
14271432
intrinsics::frem_algebraic(self, rhs)
14281433
}
14291434
}

library/core/src/num/f16.rs

+10-5
Original file line numberDiff line numberDiff line change
@@ -1358,8 +1358,9 @@ impl f16 {
13581358
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
13591359
#[must_use = "method returns a new number and does not mutate the original value"]
13601360
#[unstable(feature = "float_algebraic", issue = "136469")]
1361+
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
13611362
#[inline]
1362-
pub fn algebraic_add(self, rhs: f16) -> f16 {
1363+
pub const fn algebraic_add(self, rhs: f16) -> f16 {
13631364
intrinsics::fadd_algebraic(self, rhs)
13641365
}
13651366

@@ -1368,8 +1369,9 @@ impl f16 {
13681369
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
13691370
#[must_use = "method returns a new number and does not mutate the original value"]
13701371
#[unstable(feature = "float_algebraic", issue = "136469")]
1372+
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
13711373
#[inline]
1372-
pub fn algebraic_sub(self, rhs: f16) -> f16 {
1374+
pub const fn algebraic_sub(self, rhs: f16) -> f16 {
13731375
intrinsics::fsub_algebraic(self, rhs)
13741376
}
13751377

@@ -1378,8 +1380,9 @@ impl f16 {
13781380
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
13791381
#[must_use = "method returns a new number and does not mutate the original value"]
13801382
#[unstable(feature = "float_algebraic", issue = "136469")]
1383+
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
13811384
#[inline]
1382-
pub fn algebraic_mul(self, rhs: f16) -> f16 {
1385+
pub const fn algebraic_mul(self, rhs: f16) -> f16 {
13831386
intrinsics::fmul_algebraic(self, rhs)
13841387
}
13851388

@@ -1388,8 +1391,9 @@ impl f16 {
13881391
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
13891392
#[must_use = "method returns a new number and does not mutate the original value"]
13901393
#[unstable(feature = "float_algebraic", issue = "136469")]
1394+
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
13911395
#[inline]
1392-
pub fn algebraic_div(self, rhs: f16) -> f16 {
1396+
pub const fn algebraic_div(self, rhs: f16) -> f16 {
13931397
intrinsics::fdiv_algebraic(self, rhs)
13941398
}
13951399

@@ -1398,8 +1402,9 @@ impl f16 {
13981402
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
13991403
#[must_use = "method returns a new number and does not mutate the original value"]
14001404
#[unstable(feature = "float_algebraic", issue = "136469")]
1405+
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
14011406
#[inline]
1402-
pub fn algebraic_rem(self, rhs: f16) -> f16 {
1407+
pub const fn algebraic_rem(self, rhs: f16) -> f16 {
14031408
intrinsics::frem_algebraic(self, rhs)
14041409
}
14051410
}

library/core/src/num/f32.rs

+10-5
Original file line numberDiff line numberDiff line change
@@ -1523,8 +1523,9 @@ impl f32 {
15231523
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
15241524
#[must_use = "method returns a new number and does not mutate the original value"]
15251525
#[unstable(feature = "float_algebraic", issue = "136469")]
1526+
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
15261527
#[inline]
1527-
pub fn algebraic_add(self, rhs: f32) -> f32 {
1528+
pub const fn algebraic_add(self, rhs: f32) -> f32 {
15281529
intrinsics::fadd_algebraic(self, rhs)
15291530
}
15301531

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

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

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

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

library/core/src/num/f64.rs

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

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

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

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

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

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

-26
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)