In IEEE 754, why does adding negative zero result in a no-op but adding positive zero does not?
Asked Answered
P

1

5

I'm toying with some algorithm in Rust (though the language doesn't really matter for my question). Consider the code:

#[no_mangle]
pub fn test(x: f32) -> f32 {
    let m = 0.;
    x + m
}

fn main() {
    test(2.);
}

It produces the following LLVM IR and corresponding x86_64 asm (optimizations enabled):

;; LLVM IR
define float @test(float %x) unnamed_addr #0 {
start:
    %0 = fadd float %x, 0.000000e+00
    ret float %0
}

;; x86_64
; test:
    xorps xmm1, xmm1
    addss xmm0, xmm1
    ret

If I change let m = 0.; to let m = -0.; the floating point addition is optimized away:

;; LLVM IR
define float @test(float returned %x) unnamed_addr #0 {
start:
    ret float %x
}

;; x86_64
; fn disappears entirely
Parasympathetic answered 14/1, 2018 at 23:41 Comment(5)
Consider fn(-0.0).Gera
so far as I can tell so far gcc allows two different compile time options, and for a simple C example of the question, with default settings similar results, change the setting and both positive and negative zero generate code other than a return. so it sounds like the rouding answer is the key, but the compiler does matter and the settings. Does rust provide compile time options for different rounding mode choices?Downthrow
didnt find a compile setting for clang that is supported, yet...Downthrow
@old_timer, from what I've read, LLVM have no means to change the rounding mode (and assume any other than default during its optimization pass), so have Rust.Parasympathetic
Does this answer your question? Why does Clang optimize away x * 1.0 but NOT x + 0.0?Kenwood
R
9

In the default round-to-nearest mode, that most high-level languages support exclusively, because they do not provide options to disable floating-point optimizations that become inapplicable in other modes—I assume that Rust falls in this category—, adding -0.0 happens to have no effect on any floating-point value (omitting small details about NaNs), whereas adding +0.0 has an effect on -0.0 (the result of -0.0 + (+0.0) is +0.0).

Roquefort answered 14/1, 2018 at 23:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.