Skip to content

Unable to induce constant float folding via assert_eq!(x, 0.0) #147646

@mqudsi

Description

@mqudsi

I have a performance-sensitive pipeline that accepts data of a shape where some of the floating point elements are known (to me) to currently always be zero, but I don't want to remove the operations from the code lest that change in the future. I was hoping to be able to assert_eq!() my way into getting the compiler to perform constant folding on the mathematical operation but found that it does not work as expected.

A test case that reproduces the issue:

#[no_mangle] pub extern "C" fn one(x: f32, y: f32, z: f32) -> f32 { unsafe { std::hint::assert_unchecked(y == 0.0); } x*9.0 + y*8.0 + z } #[no_mangle] pub extern "C" fn two(x: f32, y: f32, z: f32) -> f32 { let y = 0.0; x*9.0 + y*8.0 + z }

giving the following x86_64 (optimized) assembly:

.LCPI0_0:  .long 0x41100000 .LCPI0_1:  .long 0x41000000 one:  vmulss xmm0, xmm0, dword ptr [rip + .LCPI0_0]  vmulss xmm1, xmm1, dword ptr [rip + .LCPI0_1]  vaddss xmm0, xmm0, xmm1  vaddss xmm0, xmm2, xmm0  ret .LCPI1_0:  .long 0x41100000 two:  vmulss xmm0, xmm0, dword ptr [rip + .LCPI1_0]  vxorps xmm1, xmm1, xmm1  vaddss xmm0, xmm0, xmm1  vaddss xmm0, xmm0, xmm2  ret

and a link to the godbolt disassembly

I am using assert_unchecked() rather than assert_eq!() just to simplify the assembly output for diagnostic purposes, but the intent is to test whether or not the compiler can elide the mul with a "constant" zero. The codegen from one() does not benefit from the assert_unchecked(y == 0.0) call, and performs the same codegen with or without it, while the code in two() demonstrates that, in the general case, rust is able to fold away the multiplication with a constant, but that for $reasons, it currently isn't able to do so after asserting the value.

The obvious workaround would be to use something like the following:

assert_eq!(y, 0.0); let y = 0.0;

Tested with 1.90.0 stable and rustc 1.89.0-nightly (573a015 2025-06-12)

@rustbot label +A-codegen +T-compiler

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.A-codegenArea: Code generationA-floating-pointArea: Floating point numbers and arithmeticT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions