Skip to content

Merge fabsf16/32/64/128 into fabs::<F>#153834

Merged
rust-bors[bot] merged 2 commits intorust-lang:mainfrom
N1ark:generic-float-intrinsics
Mar 29, 2026
Merged

Merge fabsf16/32/64/128 into fabs::<F>#153834
rust-bors[bot] merged 2 commits intorust-lang:mainfrom
N1ark:generic-float-intrinsics

Conversation

@N1ark
Copy link
Copy Markdown
Contributor

@N1ark N1ark commented Mar 13, 2026

View all comments

Following a small conversation on Zulip (and because I'd be interested in starting to contribute on Rust), I thought I'd give a try at merging the float intrinsics :)

This PR just merges fabsf16, fabsf32, fabsf64, fabsf128, as it felt like an easy first target.

Notes:

  • I'm opening the PR for one intrinsic as it's probably easier if the shift is done one intrinsic at a time, but let me know if you'd rather I do several at a time to reduce the number of PRs.
  • Currently this PR increases LOCs, despite being an attempt at simplifying the intrinsics/compilers. I believe this increase is a one time thing as I had to define new functions and move some things around, and hopefully future PRs/commits will reduce overall LoCs
  • fabsf32 and fabsf64 are #[rustc_intrinsic_const_stable_indirect], while fabsf16 and fabsf128 aren't; because f32/f64 expect the function to be const, the generic version must be made indirectly stable too. We'd need to check with T-lang this change is ok; the only other intrinsics where there is such a mismatch is minnum, maxnum and copysign.
  • I haven't touched libm because I'm not familiar with how it works; any guidance would be welcome!

@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Mar 13, 2026

Some changes occurred to the CTFE machinery

cc @RalfJung, @oli-obk, @lcnr

Some changes occurred to the CTFE / Miri interpreter

cc @rust-lang/miri

Some changes occurred in compiler/rustc_codegen_gcc

cc @antoyo, @GuillaumeGomez

Some changes occurred in compiler/rustc_codegen_cranelift

cc @bjorn3

Some changes occurred to the intrinsics. Make sure the CTFE / Miri interpreter
gets adapted for the changes, if necessary.

cc @rust-lang/miri, @RalfJung, @oli-obk, @lcnr

@rustbot rustbot added A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Mar 13, 2026
@rustbot rustbot added the T-libs Relevant to the library team, which will review and decide on the PR/issue. label Mar 13, 2026
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Mar 13, 2026

r? @TaKO8Ki

rustbot has assigned @TaKO8Ki.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: compiler
  • compiler expanded to 69 candidates
  • Random selection from 15 candidates

@N1ark N1ark changed the title Merge fabsfN into fabs::<F> Merge fabsf16/32/64/128 into fabs::<F> Mar 13, 2026
@tgross35
Copy link
Copy Markdown
Contributor

r? tgross35

@rustbot rustbot assigned tgross35 and unassigned TaKO8Ki Mar 13, 2026
@rust-log-analyzer

This comment has been minimized.

@N1ark
Copy link
Copy Markdown
Contributor Author

N1ark commented Mar 13, 2026

ah oops i was wondering why gcc wasn't working locally, guess it never installed :') ill fix this soon

#[rustc_nounwind]
#[rustc_intrinsic]
pub const fn fabsf128(x: f128) -> f128;
pub const fn fabs<T: Copy>(x: T) -> T;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: like there's

/// Types with a built-in dereference operator in runtime MIR,
/// aka references and raw pointers.
///
/// # Safety
/// Must actually *be* such a type.
pub unsafe trait BuiltinDeref: Sized {
type Pointee: PointeeSized;
}
unsafe impl<T: PointeeSized> BuiltinDeref for &mut T {
type Pointee = T;
}
unsafe impl<T: PointeeSized> BuiltinDeref for &T {
type Pointee = T;
}
unsafe impl<T: PointeeSized> BuiltinDeref for *mut T {
type Pointee = T;
}
unsafe impl<T: PointeeSized> BuiltinDeref for *const T {
type Pointee = T;
}
, consider adding a trait there just to help emphasize that this is for floats only, so this could be

Suggested change
pub const fn fabs<T: Copy>(x: T) -> T;
pub const fn fabs<T: bounds::FloatPrimitive>(x: T) -> T;

or similar.

Copy link
Copy Markdown
Contributor Author

@N1ark N1ark Mar 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 74114c9; also added it to the other generic float intrinsics

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note this changes the diagnostic when these intrinsics are misused: it now gives a type error (see 043f9ad) rather than a monomorphization error; i think this is a good thing :)

ty::Float(FloatTy::F32) | ty::Float(FloatTy::F64) => fx.bcx.ins().fabs(x),
// FIXME(bytecodealliance/wasmtime#8312): Use `fabsf16` once Cranelift
// backend lowerings are implemented.
ty::Float(FloatTy::F16) => codegen_f16_f128::abs_f16(fx, x),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pondering: these make me wonder if it'd be worth just having fallback mir for this?

See how there's

pub const unsafe fn disjoint_bitor<T: [const] fallback::DisjointBitOr>(a: T, b: T) -> T {

for example to give that one a fallback; might be reasonable to do the same for fabs (since it's easy to implement) and backends can just fallback to that if they haven't implemented it natively for f16/f128 yet.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(That said, it's a copysign+fabs thing only, really, since fallback MIR for most float ops is probably not a good idea. fpow is hard.)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to have fallbacks for all of these via libcalls; have some of that in progress at #150946.

abs and copysign probably shouldn't use the libcalls though, they can copy the implementation from https://github.com/rust-lang/compiler-builtins/blob/85db9f1923007c287b894d392b880545ec70d05e/libm/src/math/generic/fabs.rs and https://github.com/rust-lang/compiler-builtins/blob/85db9f1923007c287b894d392b880545ec70d05e/libm/src/math/generic/copysign.rs.

@rust-log-analyzer

This comment has been minimized.

@N1ark
Copy link
Copy Markdown
Contributor Author

N1ark commented Mar 14, 2026

btw; I saw in rustc_codegen_ssa there's two different errors relating to expecting float types; I picked BasicFloatType because in the same function BasicIntegerType is raised, but I'm curious if there's any reason to have both of these rather than merging them :) (FloatingPointType is only used in a couple places relating to SIMD intrinsics)

#[diag("invalid monomorphization of `{$name}` intrinsic: expected basic float type, found `{$ty}`", code = E0511)]
BasicFloatType {
#[primary_span]
span: Span,
name: Symbol,
ty: Ty<'tcx>,
},

#[diag("invalid monomorphization of `{$name}` intrinsic: `{$in_ty}` is not a floating-point type", code = E0511)]
FloatingPointType {
#[primary_span]
span: Span,
name: Symbol,
in_ty: Ty<'tcx>,
},

@RalfJung
Copy link
Copy Markdown
Member

The diagnostic error types are quite the mess there, feel free to adjust or replace them by string-based errors if that simplifies the code.

@rust-log-analyzer

This comment has been minimized.

@N1ark N1ark force-pushed the generic-float-intrinsics branch from 69be112 to 9210d78 Compare March 14, 2026 12:50
@N1ark
Copy link
Copy Markdown
Contributor Author

N1ark commented Mar 14, 2026

The diagnostic error types are quite the mess there, feel free to adjust or replace them by string-based errors if that simplifies the code.

fair enough :) removed the duplicate in ebb6dfb

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@scottmcm
Copy link
Copy Markdown
Member

I saw in rustc_codegen_ssa there's two different errors relating to expecting float types

Misuse of intrinsics falls under rust-lang/compiler-team#620 -- you can feel free to rip out any inconvenient errors entirely and just have them ICE.

#[rustc_nounwind]
#[rustc_intrinsic]
pub const fn fabsf128(x: f128) -> f128;
pub const fn fabs<T: bounds::FloatPrimitive>(x: T) -> T;
Copy link
Copy Markdown
Member

@RalfJung RalfJung Mar 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rust-lang/lang this would mark fabs as indirectly const stable for all float types, not just f32 and f64. The const implementation is uniform across all types so I have no concerns about this -- the f16 and f128 implementation is and has been ready for stable for a while, it's the non-const implementation of f16 and f128 that's not ready. ;)

Nevertheless, new intrinsics being available to stable const code requires lang approval. Not sure if you think a full FCP is required for a trivial case like this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

btw if a FCP is required, we should throw in copysign in there, which is in the same situation: const stable for f32/f64 but not for f16/f128, and it's also a binary operation

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably throw in all the intrinsics you intend to generalize that are easily implemented with apfloat. Do you have a list of them?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I didn't realize all the f16/f128 rounding methods have already been allowed in const-stable since #143604. That may have been an accident, but it's also not really a problem.

Copy link
Copy Markdown
Contributor Author

@N1ark N1ark Mar 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep, it's fabs, copysign, minnum and maxnum; all other float intrinsics are all const stable across all float types or not const stable for any

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally (with my lang hat on but not speaking as team consensus) I would be fine treating this as "the previous FCP was saying that floating-point abs is allowed to be const-stable -- because it's easy to do reliably in const, being that it's only bitwise (without even NAN nondet, IIRC?) -- and how exactly that translates to specific intrinsics is a compiler/ctfe question without needing addtional lang FCPs".

But we'll see what the meeting says on Wed.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

without even NAN nondet, IIRC?

Correct, fabs just mutates the sign bit and nothing else.

@RalfJung RalfJung added the I-lang-nominated Nominated for discussion during a lang team meeting. label Mar 15, 2026
@rust-rfcbot rust-rfcbot removed the proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. label Mar 18, 2026
@traviscross traviscross removed I-lang-nominated Nominated for discussion during a lang team meeting. I-lang-easy-decision Issue: The decision needed by the team is conjectured to be easy; this does not imply nomination P-lang-drag-1 Lang team prioritization drag level 1. https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang labels Mar 18, 2026
@tgross35 tgross35 added S-waiting-on-fcp Status: PR is in FCP and is awaiting for FCP to complete. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Mar 22, 2026
@rust-rfcbot rust-rfcbot added finished-final-comment-period The final comment period is finished for this PR / Issue. to-announce Announce this issue on triage meeting and removed final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. labels Mar 28, 2026
@rust-rfcbot
Copy link
Copy Markdown
Collaborator

The final comment period, with a disposition to merge, as per the review above, is now complete.

As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed.

@RalfJung
Copy link
Copy Markdown
Member

@bors r=tgross35,RalfJung

@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors bot commented Mar 28, 2026

📋 This PR cannot be approved because it currently has the following label: S-waiting-on-fcp.

@RalfJung RalfJung removed the S-waiting-on-fcp Status: PR is in FCP and is awaiting for FCP to complete. label Mar 28, 2026
@RalfJung
Copy link
Copy Markdown
Member

@bors r=tgross35,RalfJung

@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors bot commented Mar 28, 2026

📌 Commit 11c673b has been approved by tgross35,RalfJung

It is now in the queue for this repository.

@rust-bors rust-bors bot added the S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. label Mar 28, 2026
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Mar 28, 2026
…tgross35,RalfJung

Merge `fabsf16/32/64/128` into `fabs::<F>`

Following [a small conversation on Zulip](https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/Float.20intrinsics/with/521501401) (and because I'd be interested in starting to contribute on Rust), I thought I'd give a try at merging the float intrinsics :)

This PR just merges `fabsf16`, `fabsf32`, `fabsf64`, `fabsf128`, as it felt like an easy first target.

Notes:
- I'm opening the PR for one intrinsic as it's probably easier if the shift is done one intrinsic at a time, but let me know if you'd rather I do several at a time to reduce the number of PRs.
- Currently this PR increases LOCs, despite being an attempt at simplifying the intrinsics/compilers. I believe this increase is a one time thing as I had to define new functions and move some things around, and hopefully future PRs/commits will reduce overall LoCs
- `fabsf32` and `fabsf64` are `#[rustc_intrinsic_const_stable_indirect]`, while `fabsf16` and `fabsf128` aren't; because `f32`/`f64` expect the function to be const, the generic version must be made indirectly stable too. We'd need to check with T-lang this change is ok; the only other intrinsics where there is such a mismatch is `minnum`, `maxnum` and `copysign`.
- I haven't touched libm because I'm not familiar with how it works; any guidance would be welcome!
rust-bors bot pushed a commit that referenced this pull request Mar 28, 2026
…uwer

Rollup of 7 pull requests

Successful merges:

 - #147811 (naked functions: respect `function-sections`)
 - #153834 (Merge `fabsf16/32/64/128` into `fabs::<F>`)
 - #154043 (simd_fmin/fmax: make semantics and name consistent with scalar intrinsics)
 - #154494 (triagebot: add reminder for bumping CI LLVM stamp)
 - #153374 (Fix LegacyKeyValueFormat report from docker build: dist-x86_64)
 - #154320 (`trim_prefix` for paths)
 - #154453 (Fix ice in rustdoc of private reexport)
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Mar 28, 2026
…tgross35,RalfJung

Merge `fabsf16/32/64/128` into `fabs::<F>`

Following [a small conversation on Zulip](https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/Float.20intrinsics/with/521501401) (and because I'd be interested in starting to contribute on Rust), I thought I'd give a try at merging the float intrinsics :)

This PR just merges `fabsf16`, `fabsf32`, `fabsf64`, `fabsf128`, as it felt like an easy first target.

Notes:
- I'm opening the PR for one intrinsic as it's probably easier if the shift is done one intrinsic at a time, but let me know if you'd rather I do several at a time to reduce the number of PRs.
- Currently this PR increases LOCs, despite being an attempt at simplifying the intrinsics/compilers. I believe this increase is a one time thing as I had to define new functions and move some things around, and hopefully future PRs/commits will reduce overall LoCs
- `fabsf32` and `fabsf64` are `#[rustc_intrinsic_const_stable_indirect]`, while `fabsf16` and `fabsf128` aren't; because `f32`/`f64` expect the function to be const, the generic version must be made indirectly stable too. We'd need to check with T-lang this change is ok; the only other intrinsics where there is such a mismatch is `minnum`, `maxnum` and `copysign`.
- I haven't touched libm because I'm not familiar with how it works; any guidance would be welcome!
rust-bors bot pushed a commit that referenced this pull request Mar 28, 2026
…uwer

Rollup of 9 pull requests

Successful merges:

 - #150752 (Update libc to v0.2.183)
 - #153380 (stabilize new RangeFrom type and iterator)
 - #153834 (Merge `fabsf16/32/64/128` into `fabs::<F>`)
 - #154043 (simd_fmin/fmax: make semantics and name consistent with scalar intrinsics)
 - #154494 (triagebot: add reminder for bumping CI LLVM stamp)
 - #153374 (Fix LegacyKeyValueFormat report from docker build: dist-x86_64)
 - #154320 (`trim_prefix` for paths)
 - #154453 (Fix ice in rustdoc of private reexport)
 - #154515 (Notify stdarch maintainers on changes in std_detect)
rust-bors bot pushed a commit that referenced this pull request Mar 29, 2026
Rollup of 9 pull requests

Successful merges:

 - #153380 (stabilize new RangeFrom type and iterator)
 - #153834 (Merge `fabsf16/32/64/128` into `fabs::<F>`)
 - #154043 (simd_fmin/fmax: make semantics and name consistent with scalar intrinsics)
 - #154494 (triagebot: add reminder for bumping CI LLVM stamp)
 - #153374 (Fix LegacyKeyValueFormat report from docker build: dist-x86_64)
 - #154320 (`trim_prefix` for paths)
 - #154453 (Fix ice in rustdoc of private reexport)
 - #154504 (move many tests from `structs-enums` to `structs` or `enum`)
 - #154515 (Notify stdarch maintainers on changes in std_detect)
@rust-bors rust-bors bot merged commit e6f17e4 into rust-lang:main Mar 29, 2026
11 checks passed
@rustbot rustbot added this to the 1.96.0 milestone Mar 29, 2026
rust-timer added a commit that referenced this pull request Mar 29, 2026
Rollup merge of #153834 - N1ark:generic-float-intrinsics, r=tgross35,RalfJung

Merge `fabsf16/32/64/128` into `fabs::<F>`

Following [a small conversation on Zulip](https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/Float.20intrinsics/with/521501401) (and because I'd be interested in starting to contribute on Rust), I thought I'd give a try at merging the float intrinsics :)

This PR just merges `fabsf16`, `fabsf32`, `fabsf64`, `fabsf128`, as it felt like an easy first target.

Notes:
- I'm opening the PR for one intrinsic as it's probably easier if the shift is done one intrinsic at a time, but let me know if you'd rather I do several at a time to reduce the number of PRs.
- Currently this PR increases LOCs, despite being an attempt at simplifying the intrinsics/compilers. I believe this increase is a one time thing as I had to define new functions and move some things around, and hopefully future PRs/commits will reduce overall LoCs
- `fabsf32` and `fabsf64` are `#[rustc_intrinsic_const_stable_indirect]`, while `fabsf16` and `fabsf128` aren't; because `f32`/`f64` expect the function to be const, the generic version must be made indirectly stable too. We'd need to check with T-lang this change is ok; the only other intrinsics where there is such a mismatch is `minnum`, `maxnum` and `copysign`.
- I haven't touched libm because I'm not familiar with how it works; any guidance would be welcome!
github-actions bot pushed a commit to rust-lang/miri that referenced this pull request Mar 29, 2026
Rollup of 9 pull requests

Successful merges:

 - rust-lang/rust#153380 (stabilize new RangeFrom type and iterator)
 - rust-lang/rust#153834 (Merge `fabsf16/32/64/128` into `fabs::<F>`)
 - rust-lang/rust#154043 (simd_fmin/fmax: make semantics and name consistent with scalar intrinsics)
 - rust-lang/rust#154494 (triagebot: add reminder for bumping CI LLVM stamp)
 - rust-lang/rust#153374 (Fix LegacyKeyValueFormat report from docker build: dist-x86_64)
 - rust-lang/rust#154320 (`trim_prefix` for paths)
 - rust-lang/rust#154453 (Fix ice in rustdoc of private reexport)
 - rust-lang/rust#154504 (move many tests from `structs-enums` to `structs` or `enum`)
 - rust-lang/rust#154515 (Notify stdarch maintainers on changes in std_detect)
@N1ark N1ark deleted the generic-float-intrinsics branch March 29, 2026 11:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. finished-final-comment-period The final comment period is finished for this PR / Issue. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team T-libs Relevant to the library team, which will review and decide on the PR/issue. to-announce Announce this issue on triage meeting

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants