Constant Folding For Floating Point

Skip to first unread message

Ryan Berger

May 24, 2024, 9:27:28 PMMay 24
to golang-dev
I was taking a look at the constant folding SSA rules for floating points and ran across some interesting preconditions across a few different operations floating point operations. For example, addition:

(Add32F (Const32F [c]) (Const32F [d])) && c+d == c+d => (Const32F [c+d])

It took me a bit to realize that the `==` is doing a `NaN` check, but now that I know it is doing a `NaN` I'm curious as to why the result of a constant float addition can't be NaN? Is there some sort of restriction on the language?

Meng Zhuo

May 24, 2024, 9:38:00 PMMay 24
to golang-dev
I think this is related to the spec, since "float const value never NaN"
  • T is a floating-point type and x can be rounded to T's precision without overflow. Rounding uses IEEE 754 round-to-even rules but with an IEEE negative zero further simplified to an unsigned zero. Note that constant values never result in an IEEE negative zero, NaN, or infinity.

Ryan Berger

May 24, 2024, 9:52:04 PMMay 24
to golang-dev
Ah, interesting.

Now I guess I'm wondering why such a check exists at this low of a level? The type check happens well before things are converted to SSA, so theoretically it should be unreachable, and if it isn't unreachable, it just makes all floating point operations "lazily NaN"

Keith Randall

May 25, 2024, 2:33:12 AMMay 25
to Ryan Berger, golang-dev
This has nothing to do with constant values, at least as the spec defines them. This rule applies in cases like:

var x float64 = 3.0
var y float64 = 4.0
z := x+y

It does not apply in cases like:

var s float64 = 3.0 + 4.0

That latter sort of constant folding is defined as a constant expression in the spec ( and has arbitrary(-ish) precision, no NaN, etc.

The former sort of constant folding must adhere to IEEE 754 and has to worry about things like NaN. That is the situation we're in when applying rewrite rules like those quoted.
(I believe the rule is written like that because we don't want to generate NaN at compile time. NaNs are strange and their encoding is somewhat dependent on the platform, so we'd like runtime platform operations to generate them.)

You received this message because you are subscribed to the Google Groups "golang-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to
To view this discussion on the web visit
Reply all
Reply to author
0 new messages