Skip to content

Commit 2db1a7f

Browse files
committed
cmd/compile: avoid more float32 <-> float64 conversions in compiler
Use the new custom truncate/extension code when storing or extracting float32 values from AuxInts to avoid the value being changed by the host platform's floating point conversion instructions (e.g. sNaN -> qNaN). Updates #27516. Change-Id: Id39650f1431ef74af088c895cf4738ea5fa87974 Reviewed-on: https://go-review.googlesource.com/134855 Run-TryBot: Michael Munday <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Keith Randall <[email protected]>
1 parent 859cf7f commit 2db1a7f

12 files changed

+209
-201
lines changed

src/cmd/compile/internal/ssa/gen/386.rules

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@
4444
(Xor(32|16|8) x y) -> (XORL x y)
4545

4646
(Neg(32|16|8) x) -> (NEGL x)
47-
(Neg32F x) && !config.use387 -> (PXOR x (MOVSSconst <typ.Float32> [f2i(math.Copysign(0, -1))]))
48-
(Neg64F x) && !config.use387 -> (PXOR x (MOVSDconst <typ.Float64> [f2i(math.Copysign(0, -1))]))
47+
(Neg32F x) && !config.use387 -> (PXOR x (MOVSSconst <typ.Float32> [auxFrom32F(float32(math.Copysign(0, -1)))]))
48+
(Neg64F x) && !config.use387 -> (PXOR x (MOVSDconst <typ.Float64> [auxFrom64F(math.Copysign(0, -1))]))
4949
(Neg32F x) && config.use387 -> (FCHS x)
5050
(Neg64F x) && config.use387 -> (FCHS x)
5151

src/cmd/compile/internal/ssa/gen/AMD64.rules

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@
4141
(Com(64|32|16|8) x) -> (NOT(Q|L|L|L) x)
4242

4343
(Neg(64|32|16|8) x) -> (NEG(Q|L|L|L) x)
44-
(Neg32F x) -> (PXOR x (MOVSSconst <typ.Float32> [f2i(math.Copysign(0, -1))]))
45-
(Neg64F x) -> (PXOR x (MOVSDconst <typ.Float64> [f2i(math.Copysign(0, -1))]))
44+
(Neg32F x) -> (PXOR x (MOVSSconst <typ.Float32> [auxFrom32F(float32(math.Copysign(0, -1)))]))
45+
(Neg64F x) -> (PXOR x (MOVSDconst <typ.Float64> [auxFrom64F(math.Copysign(0, -1))]))
4646

4747
// Lowering boolean ops
4848
(AndB x y) -> (ANDL x y)

src/cmd/compile/internal/ssa/gen/PPC64.rules

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,11 @@
7474
(ConstBool [b]) -> (MOVDconst [b])
7575

7676
// Constant folding
77-
(FABS (FMOVDconst [x])) -> (FMOVDconst [f2i(math.Abs(i2f(x)))])
78-
(FSQRT (FMOVDconst [x])) -> (FMOVDconst [f2i(math.Sqrt(i2f(x)))])
79-
(FFLOOR (FMOVDconst [x])) -> (FMOVDconst [f2i(math.Floor(i2f(x)))])
80-
(FCEIL (FMOVDconst [x])) -> (FMOVDconst [f2i(math.Ceil(i2f(x)))])
81-
(FTRUNC (FMOVDconst [x])) -> (FMOVDconst [f2i(math.Trunc(i2f(x)))])
77+
(FABS (FMOVDconst [x])) -> (FMOVDconst [auxFrom64F(math.Abs(auxTo64F(x)))])
78+
(FSQRT (FMOVDconst [x])) -> (FMOVDconst [auxFrom64F(math.Sqrt(auxTo64F(x)))])
79+
(FFLOOR (FMOVDconst [x])) -> (FMOVDconst [auxFrom64F(math.Floor(auxTo64F(x)))])
80+
(FCEIL (FMOVDconst [x])) -> (FMOVDconst [auxFrom64F(math.Ceil(auxTo64F(x)))])
81+
(FTRUNC (FMOVDconst [x])) -> (FMOVDconst [auxFrom64F(math.Trunc(auxTo64F(x)))])
8282

8383
// Rotate generation with const shift
8484
(ADD (SLDconst x [c]) (SRDconst x [d])) && d == 64-c -> (ROTLconst [c] x)

src/cmd/compile/internal/ssa/gen/Wasm.rules

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -363,8 +363,8 @@
363363
(I64And (I64Const [x]) (I64Const [y])) -> (I64Const [x & y])
364364
(I64Or (I64Const [x]) (I64Const [y])) -> (I64Const [x | y])
365365
(I64Xor (I64Const [x]) (I64Const [y])) -> (I64Const [x ^ y])
366-
(F64Add (F64Const [x]) (F64Const [y])) -> (F64Const [f2i(i2f(x) + i2f(y))])
367-
(F64Mul (F64Const [x]) (F64Const [y])) -> (F64Const [f2i(i2f(x) * i2f(y))])
366+
(F64Add (F64Const [x]) (F64Const [y])) -> (F64Const [auxFrom64F(auxTo64F(x) + auxTo64F(y))])
367+
(F64Mul (F64Const [x]) (F64Const [y])) -> (F64Const [auxFrom64F(auxTo64F(x) * auxTo64F(y))])
368368
(I64Eq (I64Const [x]) (I64Const [y])) && x == y -> (I64Const [1])
369369
(I64Eq (I64Const [x]) (I64Const [y])) && x != y -> (I64Const [0])
370370
(I64Ne (I64Const [x]) (I64Const [y])) && x == y -> (I64Const [0])

src/cmd/compile/internal/ssa/gen/generic.rules

Lines changed: 41 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,16 @@
4444
(Trunc64to8 (Const64 [c])) -> (Const8 [int64(int8(c))])
4545
(Trunc64to16 (Const64 [c])) -> (Const16 [int64(int16(c))])
4646
(Trunc64to32 (Const64 [c])) -> (Const32 [int64(int32(c))])
47-
(Cvt64Fto32F (Const64F [c])) -> (Const32F [f2i(float64(i2f32(c)))])
47+
(Cvt64Fto32F (Const64F [c])) -> (Const32F [auxFrom32F(float32(auxTo64F(c)))])
4848
(Cvt32Fto64F (Const32F [c])) -> (Const64F [c]) // c is already a 64 bit float
49-
(Cvt32to32F (Const32 [c])) -> (Const32F [f2i(float64(float32(int32(c))))])
50-
(Cvt32to64F (Const32 [c])) -> (Const64F [f2i(float64(int32(c)))])
51-
(Cvt64to32F (Const64 [c])) -> (Const32F [f2i(float64(float32(c)))])
52-
(Cvt64to64F (Const64 [c])) -> (Const64F [f2i(float64(c))])
53-
(Cvt32Fto32 (Const32F [c])) -> (Const32 [int64(int32(i2f(c)))])
54-
(Cvt32Fto64 (Const32F [c])) -> (Const64 [int64(i2f(c))])
55-
(Cvt64Fto32 (Const64F [c])) -> (Const32 [int64(int32(i2f(c)))])
56-
(Cvt64Fto64 (Const64F [c])) -> (Const64 [int64(i2f(c))])
49+
(Cvt32to32F (Const32 [c])) -> (Const32F [auxFrom32F(float32(int32(c)))])
50+
(Cvt32to64F (Const32 [c])) -> (Const64F [auxFrom64F(float64(int32(c)))])
51+
(Cvt64to32F (Const64 [c])) -> (Const32F [auxFrom32F(float32(c))])
52+
(Cvt64to64F (Const64 [c])) -> (Const64F [auxFrom64F(float64(c))])
53+
(Cvt32Fto32 (Const32F [c])) -> (Const32 [int64(int32(auxTo32F(c)))])
54+
(Cvt32Fto64 (Const32F [c])) -> (Const64 [int64(auxTo32F(c))])
55+
(Cvt64Fto32 (Const64F [c])) -> (Const32 [int64(int32(auxTo64F(c)))])
56+
(Cvt64Fto64 (Const64F [c])) -> (Const64 [int64(auxTo64F(c))])
5757
(Round32F x:(Const32F)) -> x
5858
(Round64F x:(Const64F)) -> x
5959

@@ -95,34 +95,31 @@
9595
(Neg16 (Const16 [c])) -> (Const16 [int64(-int16(c))])
9696
(Neg32 (Const32 [c])) -> (Const32 [int64(-int32(c))])
9797
(Neg64 (Const64 [c])) -> (Const64 [-c])
98-
(Neg32F (Const32F [c])) && i2f(c) != 0 -> (Const32F [f2i(-i2f(c))])
99-
(Neg64F (Const64F [c])) && i2f(c) != 0 -> (Const64F [f2i(-i2f(c))])
98+
(Neg32F (Const32F [c])) && auxTo32F(c) != 0 -> (Const32F [auxFrom32F(-auxTo32F(c))])
99+
(Neg64F (Const64F [c])) && auxTo64F(c) != 0 -> (Const64F [auxFrom64F(-auxTo64F(c))])
100100

101101
(Add8 (Const8 [c]) (Const8 [d])) -> (Const8 [int64(int8(c+d))])
102102
(Add16 (Const16 [c]) (Const16 [d])) -> (Const16 [int64(int16(c+d))])
103103
(Add32 (Const32 [c]) (Const32 [d])) -> (Const32 [int64(int32(c+d))])
104104
(Add64 (Const64 [c]) (Const64 [d])) -> (Const64 [c+d])
105-
(Add32F (Const32F [c]) (Const32F [d])) ->
106-
(Const32F [f2i(float64(i2f32(c) + i2f32(d)))]) // ensure we combine the operands with 32 bit precision
107-
(Add64F (Const64F [c]) (Const64F [d])) -> (Const64F [f2i(i2f(c) + i2f(d))])
105+
(Add32F (Const32F [c]) (Const32F [d])) -> (Const32F [auxFrom32F(auxTo32F(c) + auxTo32F(d))])
106+
(Add64F (Const64F [c]) (Const64F [d])) -> (Const64F [auxFrom64F(auxTo64F(c) + auxTo64F(d))])
108107
(AddPtr <t> x (Const64 [c])) -> (OffPtr <t> x [c])
109108
(AddPtr <t> x (Const32 [c])) -> (OffPtr <t> x [c])
110109

111110
(Sub8 (Const8 [c]) (Const8 [d])) -> (Const8 [int64(int8(c-d))])
112111
(Sub16 (Const16 [c]) (Const16 [d])) -> (Const16 [int64(int16(c-d))])
113112
(Sub32 (Const32 [c]) (Const32 [d])) -> (Const32 [int64(int32(c-d))])
114113
(Sub64 (Const64 [c]) (Const64 [d])) -> (Const64 [c-d])
115-
(Sub32F (Const32F [c]) (Const32F [d])) ->
116-
(Const32F [f2i(float64(i2f32(c) - i2f32(d)))])
117-
(Sub64F (Const64F [c]) (Const64F [d])) -> (Const64F [f2i(i2f(c) - i2f(d))])
114+
(Sub32F (Const32F [c]) (Const32F [d])) -> (Const32F [auxFrom32F(auxTo32F(c) - auxTo32F(d))])
115+
(Sub64F (Const64F [c]) (Const64F [d])) -> (Const64F [auxFrom64F(auxTo64F(c) - auxTo64F(d))])
118116

119117
(Mul8 (Const8 [c]) (Const8 [d])) -> (Const8 [int64(int8(c*d))])
120118
(Mul16 (Const16 [c]) (Const16 [d])) -> (Const16 [int64(int16(c*d))])
121119
(Mul32 (Const32 [c]) (Const32 [d])) -> (Const32 [int64(int32(c*d))])
122120
(Mul64 (Const64 [c]) (Const64 [d])) -> (Const64 [c*d])
123-
(Mul32F (Const32F [c]) (Const32F [d])) ->
124-
(Const32F [f2i(float64(i2f32(c) * i2f32(d)))])
125-
(Mul64F (Const64F [c]) (Const64F [d])) -> (Const64F [f2i(i2f(c) * i2f(d))])
121+
(Mul32F (Const32F [c]) (Const32F [d])) -> (Const32F [auxFrom32F(auxTo32F(c) * auxTo32F(d))])
122+
(Mul64F (Const64F [c]) (Const64F [d])) -> (Const64F [auxFrom64F(auxTo64F(c) * auxTo64F(d))])
126123

127124
(And8 (Const8 [c]) (Const8 [d])) -> (Const8 [int64(int8(c&d))])
128125
(And16 (Const16 [c]) (Const16 [d])) -> (Const16 [int64(int16(c&d))])
@@ -147,8 +144,8 @@
147144
(Div16u (Const16 [c]) (Const16 [d])) && d != 0 -> (Const16 [int64(int16(uint16(c)/uint16(d)))])
148145
(Div32u (Const32 [c]) (Const32 [d])) && d != 0 -> (Const32 [int64(int32(uint32(c)/uint32(d)))])
149146
(Div64u (Const64 [c]) (Const64 [d])) && d != 0 -> (Const64 [int64(uint64(c)/uint64(d))])
150-
(Div32F (Const32F [c]) (Const32F [d])) -> (Const32F [f2i(float64(i2f32(c) / i2f32(d)))])
151-
(Div64F (Const64F [c]) (Const64F [d])) -> (Const64F [f2i(i2f(c) / i2f(d))])
147+
(Div32F (Const32F [c]) (Const32F [d])) -> (Const32F [auxFrom32F(auxTo32F(c) / auxTo32F(d))])
148+
(Div64F (Const64F [c]) (Const64F [d])) -> (Const64F [auxFrom64F(auxTo64F(c) / auxTo64F(d))])
152149

153150
(Not (ConstBool [c])) -> (ConstBool [1-c])
154151

@@ -444,12 +441,18 @@
444441
(Leq8U (Const8 [c]) (Const8 [d])) -> (ConstBool [b2i(uint8(c) <= uint8(d))])
445442

446443
// constant floating point comparisons
447-
(Eq(64|32)F (Const(64|32)F [c]) (Const(64|32)F [d])) -> (ConstBool [b2i(i2f(c) == i2f(d))])
448-
(Neq(64|32)F (Const(64|32)F [c]) (Const(64|32)F [d])) -> (ConstBool [b2i(i2f(c) != i2f(d))])
449-
(Greater(64|32)F (Const(64|32)F [c]) (Const(64|32)F [d])) -> (ConstBool [b2i(i2f(c) > i2f(d))])
450-
(Geq(64|32)F (Const(64|32)F [c]) (Const(64|32)F [d])) -> (ConstBool [b2i(i2f(c) >= i2f(d))])
451-
(Less(64|32)F (Const(64|32)F [c]) (Const(64|32)F [d])) -> (ConstBool [b2i(i2f(c) < i2f(d))])
452-
(Leq(64|32)F (Const(64|32)F [c]) (Const(64|32)F [d])) -> (ConstBool [b2i(i2f(c) <= i2f(d))])
444+
(Eq32F (Const32F [c]) (Const32F [d])) -> (ConstBool [b2i(auxTo32F(c) == auxTo32F(d))])
445+
(Eq64F (Const64F [c]) (Const64F [d])) -> (ConstBool [b2i(auxTo64F(c) == auxTo64F(d))])
446+
(Neq32F (Const32F [c]) (Const32F [d])) -> (ConstBool [b2i(auxTo32F(c) != auxTo32F(d))])
447+
(Neq64F (Const64F [c]) (Const64F [d])) -> (ConstBool [b2i(auxTo64F(c) != auxTo64F(d))])
448+
(Greater32F (Const32F [c]) (Const32F [d])) -> (ConstBool [b2i(auxTo32F(c) > auxTo32F(d))])
449+
(Greater64F (Const64F [c]) (Const64F [d])) -> (ConstBool [b2i(auxTo64F(c) > auxTo64F(d))])
450+
(Geq32F (Const32F [c]) (Const32F [d])) -> (ConstBool [b2i(auxTo32F(c) >= auxTo32F(d))])
451+
(Geq64F (Const64F [c]) (Const64F [d])) -> (ConstBool [b2i(auxTo64F(c) >= auxTo64F(d))])
452+
(Less32F (Const32F [c]) (Const32F [d])) -> (ConstBool [b2i(auxTo32F(c) < auxTo32F(d))])
453+
(Less64F (Const64F [c]) (Const64F [d])) -> (ConstBool [b2i(auxTo64F(c) < auxTo64F(d))])
454+
(Leq32F (Const32F [c]) (Const32F [d])) -> (ConstBool [b2i(auxTo32F(c) <= auxTo32F(d))])
455+
(Leq64F (Const64F [c]) (Const64F [d])) -> (ConstBool [b2i(auxTo64F(c) <= auxTo64F(d))])
453456

454457
// simplifications
455458
(Or(64|32|16|8) x x) -> x
@@ -572,9 +575,9 @@
572575

573576
// Pass constants through math.Float{32,64}bits and math.Float{32,64}frombits
574577
(Load <t1> p1 (Store {t2} p2 (Const64 [x]) _)) && isSamePtr(p1,p2) && sizeof(t2) == 8 && is64BitFloat(t1) -> (Const64F [x])
575-
(Load <t1> p1 (Store {t2} p2 (Const32 [x]) _)) && isSamePtr(p1,p2) && sizeof(t2) == 4 && is32BitFloat(t1) -> (Const32F [f2i(extend32Fto64F(math.Float32frombits(uint32(x))))])
578+
(Load <t1> p1 (Store {t2} p2 (Const32 [x]) _)) && isSamePtr(p1,p2) && sizeof(t2) == 4 && is32BitFloat(t1) -> (Const32F [auxFrom32F(math.Float32frombits(uint32(x)))])
576579
(Load <t1> p1 (Store {t2} p2 (Const64F [x]) _)) && isSamePtr(p1,p2) && sizeof(t2) == 8 && is64BitInt(t1) -> (Const64 [x])
577-
(Load <t1> p1 (Store {t2} p2 (Const32F [x]) _)) && isSamePtr(p1,p2) && sizeof(t2) == 4 && is32BitInt(t1) -> (Const32 [int64(int32(math.Float32bits(truncate64Fto32F(i2f(x)))))])
580+
(Load <t1> p1 (Store {t2} p2 (Const32F [x]) _)) && isSamePtr(p1,p2) && sizeof(t2) == 4 && is32BitInt(t1) -> (Const32 [int64(int32(math.Float32bits(auxTo32F(x))))])
578581

579582
// Float Loads up to Zeros so they can be constant folded.
580583
(Load <t1> op:(OffPtr [o1] p1)
@@ -1329,16 +1332,16 @@
13291332
(Add(32|64)F x (Const(32|64)F [0])) -> x
13301333
(Sub(32|64)F x (Const(32|64)F [0])) -> x
13311334

1332-
(Mul(32|64)F x (Const(32|64)F [f2i(1)])) -> x
1333-
(Mul32F x (Const32F [f2i(-1)])) -> (Neg32F x)
1334-
(Mul64F x (Const64F [f2i(-1)])) -> (Neg64F x)
1335-
(Mul32F x (Const32F [f2i(2)])) -> (Add32F x x)
1336-
(Mul64F x (Const64F [f2i(2)])) -> (Add64F x x)
1335+
(Mul(32|64)F x (Const(32|64)F [auxFrom64F(1)])) -> x
1336+
(Mul32F x (Const32F [auxFrom32F(-1)])) -> (Neg32F x)
1337+
(Mul64F x (Const64F [auxFrom64F(-1)])) -> (Neg64F x)
1338+
(Mul32F x (Const32F [auxFrom32F(2)])) -> (Add32F x x)
1339+
(Mul64F x (Const64F [auxFrom64F(2)])) -> (Add64F x x)
13371340

1338-
(Div32F x (Const32F <t> [c])) && reciprocalExact32(float32(i2f(c))) -> (Mul32F x (Const32F <t> [f2i(1/i2f(c))]))
1339-
(Div64F x (Const64F <t> [c])) && reciprocalExact64(i2f(c)) -> (Mul64F x (Const64F <t> [f2i(1/i2f(c))]))
1341+
(Div32F x (Const32F <t> [c])) && reciprocalExact32(auxTo32F(c)) -> (Mul32F x (Const32F <t> [auxFrom32F(1/auxTo32F(c))]))
1342+
(Div64F x (Const64F <t> [c])) && reciprocalExact64(auxTo64F(c)) -> (Mul64F x (Const64F <t> [auxFrom64F(1/auxTo64F(c))]))
13401343

1341-
(Sqrt (Const64F [c])) -> (Const64F [f2i(math.Sqrt(i2f(c)))])
1344+
(Sqrt (Const64F [c])) -> (Const64F [auxFrom64F(math.Sqrt(auxTo64F(c)))])
13421345

13431346
// recognize runtime.newobject and don't Zero/Nilcheck it
13441347
(Zero (Load (OffPtr [c] (SP)) mem) mem)

src/cmd/compile/internal/ssa/rewrite.go

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -450,19 +450,24 @@ func extend32Fto64F(f float32) float64 {
450450
return math.Float64frombits(r)
451451
}
452452

453-
// i2f is used in rules for converting from an AuxInt to a float.
454-
func i2f(i int64) float64 {
455-
return math.Float64frombits(uint64(i))
453+
// auxFrom64F encodes a float64 value so it can be stored in an AuxInt.
454+
func auxFrom64F(f float64) int64 {
455+
return int64(math.Float64bits(f))
456456
}
457457

458-
// i2f32 is used in rules for converting from an AuxInt to a float32.
459-
func i2f32(i int64) float32 {
460-
return float32(math.Float64frombits(uint64(i)))
458+
// auxFrom32F encodes a float32 value so it can be stored in an AuxInt.
459+
func auxFrom32F(f float32) int64 {
460+
return int64(math.Float64bits(extend32Fto64F(f)))
461461
}
462462

463-
// f2i is used in the rules for storing a float in AuxInt.
464-
func f2i(f float64) int64 {
465-
return int64(math.Float64bits(f))
463+
// auxTo32F decodes a float32 from the AuxInt value provided.
464+
func auxTo32F(i int64) float32 {
465+
return truncate64Fto32F(math.Float64frombits(uint64(i)))
466+
}
467+
468+
// auxTo64F decodes a float64 from the AuxInt value provided.
469+
func auxTo64F(i int64) float64 {
470+
return math.Float64frombits(uint64(i))
466471
}
467472

468473
// uaddOvf returns true if unsigned a+b would overflow.

src/cmd/compile/internal/ssa/rewrite386.go

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/cmd/compile/internal/ssa/rewriteAMD64.go

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/cmd/compile/internal/ssa/rewritePPC64.go

Lines changed: 10 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)