]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: store constant floats using integer constants
authorKeith Randall <khr@golang.org>
Thu, 13 Jun 2024 01:25:55 +0000 (18:25 -0700)
committerKeith Randall <khr@golang.org>
Tue, 23 Jul 2024 20:53:57 +0000 (20:53 +0000)
x86 is better at storing constant ints than constant floats.
(It uses a constant directly in the instruction stream, instead of
loading it from a constant global memory.)

Noticed as part of #67957

Change-Id: I9b7b586ad8e0fe9ce245324f020e9526f82b209d
Reviewed-on: https://go-review.googlesource.com/c/go/+/592596
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
src/cmd/compile/internal/ssa/_gen/AMD64.rules
src/cmd/compile/internal/ssa/rewriteAMD64.go
test/codegen/floats.go

index 2a4c59ebfc7176028ed9bd5eefa83f11b1a81a23..0f7b0bb6d8a34b67a4cac2e1073acb4c32621126 100644 (file)
 (MOVSDstore [off] {sym} ptr (MOVQi2f val) mem) => (MOVQstore  [off] {sym} ptr val mem)
 (MOVSSstore [off] {sym} ptr (MOVLi2f val) mem) => (MOVLstore  [off] {sym} ptr val mem)
 
+(MOVSDstore [off] {sym} ptr (MOVSDconst [f]) mem) && f == f => (MOVQstore [off] {sym} ptr (MOVQconst [int64(math.Float64bits(f))]) mem)
+(MOVSSstore [off] {sym} ptr (MOVSSconst [f]) mem) && f == f => (MOVLstore [off] {sym} ptr (MOVLconst [int32(math.Float32bits(f))]) mem)
+
 // Load args directly into the register class where it will be used.
 // We do this by just modifying the type of the Arg.
 (MOVQf2i <t> (Arg <u> [off] {sym})) && t.Size() == u.Size() => @b.Func.Entry (Arg <t> [off] {sym})
index ba71189703ddffa6d432eb991ff63dbba7bd1cb0..2670ba91b8e173fe8c75576215915b17bf917845 100644 (file)
@@ -12304,6 +12304,8 @@ func rewriteValueAMD64_OpAMD64MOVSDstore(v *Value) bool {
        v_2 := v.Args[2]
        v_1 := v.Args[1]
        v_0 := v.Args[0]
+       b := v.Block
+       typ := &b.Func.Config.Types
        // match: (MOVSDstore [off1] {sym} (ADDQconst [off2] ptr) val mem)
        // cond: is32Bit(int64(off1)+int64(off2))
        // result: (MOVSDstore [off1+off2] {sym} ptr val mem)
@@ -12366,6 +12368,29 @@ func rewriteValueAMD64_OpAMD64MOVSDstore(v *Value) bool {
                v.AddArg3(ptr, val, mem)
                return true
        }
+       // match: (MOVSDstore [off] {sym} ptr (MOVSDconst [f]) mem)
+       // cond: f == f
+       // result: (MOVQstore [off] {sym} ptr (MOVQconst [int64(math.Float64bits(f))]) mem)
+       for {
+               off := auxIntToInt32(v.AuxInt)
+               sym := auxToSym(v.Aux)
+               ptr := v_0
+               if v_1.Op != OpAMD64MOVSDconst {
+                       break
+               }
+               f := auxIntToFloat64(v_1.AuxInt)
+               mem := v_2
+               if !(f == f) {
+                       break
+               }
+               v.reset(OpAMD64MOVQstore)
+               v.AuxInt = int32ToAuxInt(off)
+               v.Aux = symToAux(sym)
+               v0 := b.NewValue0(v.Pos, OpAMD64MOVQconst, typ.UInt64)
+               v0.AuxInt = int64ToAuxInt(int64(math.Float64bits(f)))
+               v.AddArg3(ptr, v0, mem)
+               return true
+       }
        return false
 }
 func rewriteValueAMD64_OpAMD64MOVSSload(v *Value) bool {
@@ -12437,6 +12462,8 @@ func rewriteValueAMD64_OpAMD64MOVSSstore(v *Value) bool {
        v_2 := v.Args[2]
        v_1 := v.Args[1]
        v_0 := v.Args[0]
+       b := v.Block
+       typ := &b.Func.Config.Types
        // match: (MOVSSstore [off1] {sym} (ADDQconst [off2] ptr) val mem)
        // cond: is32Bit(int64(off1)+int64(off2))
        // result: (MOVSSstore [off1+off2] {sym} ptr val mem)
@@ -12499,6 +12526,29 @@ func rewriteValueAMD64_OpAMD64MOVSSstore(v *Value) bool {
                v.AddArg3(ptr, val, mem)
                return true
        }
+       // match: (MOVSSstore [off] {sym} ptr (MOVSSconst [f]) mem)
+       // cond: f == f
+       // result: (MOVLstore [off] {sym} ptr (MOVLconst [int32(math.Float32bits(f))]) mem)
+       for {
+               off := auxIntToInt32(v.AuxInt)
+               sym := auxToSym(v.Aux)
+               ptr := v_0
+               if v_1.Op != OpAMD64MOVSSconst {
+                       break
+               }
+               f := auxIntToFloat32(v_1.AuxInt)
+               mem := v_2
+               if !(f == f) {
+                       break
+               }
+               v.reset(OpAMD64MOVLstore)
+               v.AuxInt = int32ToAuxInt(off)
+               v.Aux = symToAux(sym)
+               v0 := b.NewValue0(v.Pos, OpAMD64MOVLconst, typ.UInt32)
+               v0.AuxInt = int32ToAuxInt(int32(math.Float32bits(f)))
+               v.AddArg3(ptr, v0, mem)
+               return true
+       }
        return false
 }
 func rewriteValueAMD64_OpAMD64MOVWQSX(v *Value) bool {
index baa745bdeece5bf92e805ef8f02ea3b97f9162c4..d38df1cacbb8a7e1243b9c779f64dfea0ca7e269 100644 (file)
@@ -227,3 +227,12 @@ func Float64DenormalFloat32Constant() float64 {
        // ppc64x:"FMOVD\t[$]f64\\.3800000000000000\\(SB\\)"
        return 0x1p-127
 }
+
+func Float64ConstantStore(p *float64) {
+       // amd64: "MOVQ\t[$]4617801906721357038"
+       *p = 5.432
+}
+func Float32ConstantStore(p *float32) {
+       // amd64: "MOVL\t[$]1085133554"
+       *p = 5.432
+}