]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: const folding for float32/64
authorTodd Neal <todd@tneal.org>
Sat, 12 Mar 2016 01:36:54 +0000 (19:36 -0600)
committerTodd Neal <todd@tneal.org>
Sun, 13 Mar 2016 13:32:41 +0000 (13:32 +0000)
Split the auxFloat type into 32/64 bit versions and perform checking for
exactly representable float32 values.  Perform const folding on
float32/64.  Comment out some const negation rules that the frontend
already performs.

Change-Id: Ib3f8d59fa8b30e50fe0267786cfb3c50a06169d2
Reviewed-on: https://go-review.googlesource.com/20568
Run-TryBot: Todd Neal <todd@tneal.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
src/cmd/compile/internal/ssa/check.go
src/cmd/compile/internal/ssa/func.go
src/cmd/compile/internal/ssa/gen/AMD64Ops.go
src/cmd/compile/internal/ssa/gen/generic.rules
src/cmd/compile/internal/ssa/gen/genericOps.go
src/cmd/compile/internal/ssa/op.go
src/cmd/compile/internal/ssa/opGen.go
src/cmd/compile/internal/ssa/rewrite.go
src/cmd/compile/internal/ssa/rewritegeneric.go
src/cmd/compile/internal/ssa/value.go

index 83aae3af33f793a9d6bcc984fed6de3c7e1ac653..8f8227722c215df219790af1d4d8fadfe24fd5c3 100644 (file)
@@ -171,8 +171,13 @@ func checkFunc(f *Func) {
                        canHaveAuxInt := false
                        switch opcodeTable[v.Op].auxType {
                        case auxNone:
-                       case auxBool, auxInt8, auxInt16, auxInt32, auxInt64, auxFloat:
+                       case auxBool, auxInt8, auxInt16, auxInt32, auxInt64, auxFloat64:
                                canHaveAuxInt = true
+                       case auxFloat32:
+                               canHaveAuxInt = true
+                               if !isExactFloat32(v) {
+                                       f.Fatalf("value %v has an AuxInt value that is not an exact float32", v)
+                               }
                        case auxString, auxSym:
                                canHaveAux = true
                        case auxSymOff, auxSymValAndOff:
@@ -299,3 +304,8 @@ func domCheck(f *Func, sdom sparseTree, x, y *Block) bool {
        }
        return sdom.isAncestorEq(x, y)
 }
+
+// isExactFloat32 reoprts whether v has an AuxInt that can be exactly represented as a float32.
+func isExactFloat32(v *Value) bool {
+       return v.AuxFloat() == float64(float32(v.AuxFloat()))
+}
index 19b825a1205802ea38c36ccf4220642743290af9..ba8a823c59eb58edd9fe58f42969e27353d79ad9 100644 (file)
@@ -341,7 +341,7 @@ func (f *Func) ConstInt64(line int32, t Type, c int64) *Value {
        return f.constVal(line, OpConst64, t, c, true)
 }
 func (f *Func) ConstFloat32(line int32, t Type, c float64) *Value {
-       return f.constVal(line, OpConst32F, t, int64(math.Float64bits(c)), true)
+       return f.constVal(line, OpConst32F, t, int64(math.Float64bits(float64(float32(c)))), true)
 }
 func (f *Func) ConstFloat64(line int32, t Type, c float64) *Value {
        return f.constVal(line, OpConst64F, t, int64(math.Float64bits(c)), true)
index 04b9d61727c3faf30dd8ba5a9a48e215b6b5d09f..f23a5896a42c7f21312286ea5bcbcb2983710ed2 100644 (file)
@@ -153,12 +153,12 @@ func init() {
                {name: "DIVSS", argLength: 2, reg: fp21x15, asm: "DIVSS", resultInArg0: true},                 // fp32 div
                {name: "DIVSD", argLength: 2, reg: fp21x15, asm: "DIVSD", resultInArg0: true},                 // fp64 div
 
-               {name: "MOVSSload", argLength: 2, reg: fpload, asm: "MOVSS", aux: "SymOff"},          // fp32 load
-               {name: "MOVSDload", argLength: 2, reg: fpload, asm: "MOVSD", aux: "SymOff"},          // fp64 load
-               {name: "MOVSSconst", reg: fp01, asm: "MOVSS", aux: "Float", rematerializeable: true}, // fp32 constant
-               {name: "MOVSDconst", reg: fp01, asm: "MOVSD", aux: "Float", rematerializeable: true}, // fp64 constant
-               {name: "MOVSSloadidx4", argLength: 3, reg: fploadidx, asm: "MOVSS", aux: "SymOff"},   // fp32 load
-               {name: "MOVSDloadidx8", argLength: 3, reg: fploadidx, asm: "MOVSD", aux: "SymOff"},   // fp64 load
+               {name: "MOVSSload", argLength: 2, reg: fpload, asm: "MOVSS", aux: "SymOff"},            // fp32 load
+               {name: "MOVSDload", argLength: 2, reg: fpload, asm: "MOVSD", aux: "SymOff"},            // fp64 load
+               {name: "MOVSSconst", reg: fp01, asm: "MOVSS", aux: "Float32", rematerializeable: true}, // fp32 constant
+               {name: "MOVSDconst", reg: fp01, asm: "MOVSD", aux: "Float64", rematerializeable: true}, // fp64 constant
+               {name: "MOVSSloadidx4", argLength: 3, reg: fploadidx, asm: "MOVSS", aux: "SymOff"},     // fp32 load
+               {name: "MOVSDloadidx8", argLength: 3, reg: fploadidx, asm: "MOVSD", aux: "SymOff"},     // fp64 load
 
                {name: "MOVSSstore", argLength: 3, reg: fpstore, asm: "MOVSS", aux: "SymOff"},        // fp32 store
                {name: "MOVSDstore", argLength: 3, reg: fpstore, asm: "MOVSD", aux: "SymOff"},        // fp64 store
index f9799d663344c2221238d0095f8f152bf42b4c7f..cc24269418587144509012e90c7085c173e58c4c 100644 (file)
 (Trunc64to8 (Const64 [c])) -> (Const8 [int64(int8(c))])
 (Trunc64to16 (Const64 [c])) -> (Const16 [int64(int16(c))])
 (Trunc64to32 (Const64 [c])) -> (Const32 [int64(int32(c))])
+(Cvt64Fto32F (Const64F [c])) -> (Const32F [f2i(float64(i2f32(c)))])
+(Cvt32Fto64F (Const32F [c])) -> (Const64F [c]) // c is already a 64 bit float
 
-(Neg8 (Const8 [c])) -> (Const8 [-c])
-(Neg16 (Const16 [c])) -> (Const16 [-c])
-(Neg32 (Const32 [c])) -> (Const32 [-c])
-(Neg64 (Const64 [c])) -> (Const64 [-c])
+// const negation is currently handled by frontend
+//(Neg8 (Const8 [c])) -> (Const8 [-c])
+//(Neg16 (Const16 [c])) -> (Const16 [-c])
+//(Neg32 (Const32 [c])) -> (Const32 [-c])
+//(Neg64 (Const64 [c])) -> (Const64 [-c])
+//(Neg32F (Const32F [c])) -> (Const32F [f2i(-i2f(c))])
+//(Neg64F (Const64F [c])) -> (Const64F [f2i(-i2f(c))])
 
 (Add8 (Const8 [c]) (Const8 [d])) -> (Const8 [c+d])
 (Add16 (Const16 [c]) (Const16 [d])) -> (Const16 [c+d])
 (Add32 (Const32 [c]) (Const32 [d])) -> (Const32 [c+d])
 (Add64 (Const64 [c]) (Const64 [d])) -> (Const64 [c+d])
+(Add32F (Const32F [c]) (Const32F [d])) -> 
+        (Const32F [f2i(float64(i2f32(c) + i2f32(d)))]) // ensure we combine the operands with 32 bit precision
+(Add64F (Const64F [c]) (Const64F [d])) -> (Const64F [f2i(i2f(c) + i2f(d))])
 
 (Sub8 (Const8 [c]) (Const8 [d])) -> (Const8 [c-d])
 (Sub16 (Const16 [c]) (Const16 [d])) -> (Const16 [c-d])
 (Sub32 (Const32 [c]) (Const32 [d])) -> (Const32 [c-d])
 (Sub64 (Const64 [c]) (Const64 [d])) -> (Const64 [c-d])
+(Sub32F (Const32F [c]) (Const32F [d])) -> 
+        (Const32F [f2i(float64(i2f32(c) - i2f32(d)))])
+(Sub64F (Const64F [c]) (Const64F [d])) -> (Const64F [f2i(i2f(c) - i2f(d))])
 
 (Mul8 (Const8 [c]) (Const8 [d])) -> (Const8 [c*d])
 (Mul16 (Const16 [c]) (Const16 [d])) -> (Const16 [c*d])
 (Mul32 (Const32 [c]) (Const32 [d])) -> (Const32 [c*d])
 (Mul64 (Const64 [c]) (Const64 [d])) -> (Const64 [c*d])
+(Mul32F (Const32F [c]) (Const32F [d])) -> 
+        (Const32F [f2i(float64(i2f32(c) * i2f32(d)))])
+(Mul64F (Const64F [c]) (Const64F [d])) -> (Const64F [f2i(i2f(c) * i2f(d))])
 
 (Lsh64x64  (Const64 [c]) (Const64 [d])) -> (Const64 [c << uint64(d)])
 (Rsh64x64  (Const64 [c]) (Const64 [d])) -> (Const64 [c >> uint64(d)])
index 6a49cb7afc1e610c6f5beee8269a5035d66a0b13..d901c1c7c3d15ee792c3b93e4e722b68bbf63c05 100644 (file)
@@ -259,8 +259,8 @@ var genericOps = []opData{
        {name: "Const16", aux: "Int16"},      // value is low 16 bits of auxint
        {name: "Const32", aux: "Int32"},      // value is low 32 bits of auxint
        {name: "Const64", aux: "Int64"},      // value is auxint
-       {name: "Const32F", aux: "Float"},     // value is math.Float64frombits(uint64(auxint))
-       {name: "Const64F", aux: "Float"},     // value is math.Float64frombits(uint64(auxint))
+       {name: "Const32F", aux: "Float32"},   // value is math.Float64frombits(uint64(auxint)) and is exactly prepresentable as float 32
+       {name: "Const64F", aux: "Float64"},   // value is math.Float64frombits(uint64(auxint))
        {name: "ConstInterface"},             // nil interface
        {name: "ConstSlice"},                 // nil slice
 
index b2ee82c41efa993ad3da76dc1546e70243189ac8..ecffb5aff961a035f32e7ee82bf06e07f6105f89 100644 (file)
@@ -49,7 +49,8 @@ const (
        auxInt16                // auxInt is a 16-bit integer
        auxInt32                // auxInt is a 32-bit integer
        auxInt64                // auxInt is a 64-bit integer
-       auxFloat                // auxInt is a float64 (encoded with math.Float64bits)
+       auxFloat32              // auxInt is a float32 (encoded with math.Float64bits)
+       auxFloat64              // auxInt is a float64 (encoded with math.Float64bits)
        auxString               // auxInt is a string
        auxSym                  // aux is a symbol
        auxSymOff               // aux is a symbol, auxInt is an offset
index 7454e51aeb2c10a3c13cb04f70e57c00ecc67594..99c851d52e89a28eb5d4b3e6d4b64869b0461acb 100644 (file)
@@ -748,7 +748,7 @@ var opcodeTable = [...]opInfo{
        },
        {
                name:              "MOVSSconst",
-               auxType:           auxFloat,
+               auxType:           auxFloat32,
                argLen:            0,
                rematerializeable: true,
                asm:               x86.AMOVSS,
@@ -760,7 +760,7 @@ var opcodeTable = [...]opInfo{
        },
        {
                name:              "MOVSDconst",
-               auxType:           auxFloat,
+               auxType:           auxFloat64,
                argLen:            0,
                rematerializeable: true,
                asm:               x86.AMOVSD,
@@ -4957,13 +4957,13 @@ var opcodeTable = [...]opInfo{
        },
        {
                name:    "Const32F",
-               auxType: auxFloat,
+               auxType: auxFloat32,
                argLen:  0,
                generic: true,
        },
        {
                name:    "Const64F",
-               auxType: auxFloat,
+               auxType: auxFloat64,
                argLen:  0,
                generic: true,
        },
index 356b375657df35160c883b993ce51d24e7a0fbde..8581b7d55cdf2422e80d024046c1a77066468292 100644 (file)
@@ -192,6 +192,16 @@ func b2i(b bool) int64 {
        return 0
 }
 
+// i2f is used in rules for converting from an AuxInt to a float.
+func i2f(i int64) float64 {
+       return math.Float64frombits(uint64(i))
+}
+
+// i2f32 is used in rules for converting from an AuxInt to a float32.
+func i2f32(i int64) float32 {
+       return float32(math.Float64frombits(uint64(i)))
+}
+
 // f2i is used in the rules for storing a float in AuxInt.
 func f2i(f float64) int64 {
        return int64(math.Float64bits(f))
index bf1930063ed229cf73441cbb4d1a236c4a0ac523..116d11e3d65d55ab16efb23744b8b99cf89c2555 100644 (file)
@@ -12,8 +12,12 @@ func rewriteValuegeneric(v *Value, config *Config) bool {
                return rewriteValuegeneric_OpAdd16(v, config)
        case OpAdd32:
                return rewriteValuegeneric_OpAdd32(v, config)
+       case OpAdd32F:
+               return rewriteValuegeneric_OpAdd32F(v, config)
        case OpAdd64:
                return rewriteValuegeneric_OpAdd64(v, config)
+       case OpAdd64F:
+               return rewriteValuegeneric_OpAdd64F(v, config)
        case OpAdd8:
                return rewriteValuegeneric_OpAdd8(v, config)
        case OpAnd16:
@@ -48,6 +52,10 @@ func rewriteValuegeneric(v *Value, config *Config) bool {
                return rewriteValuegeneric_OpConstString(v, config)
        case OpConvert:
                return rewriteValuegeneric_OpConvert(v, config)
+       case OpCvt32Fto64F:
+               return rewriteValuegeneric_OpCvt32Fto64F(v, config)
+       case OpCvt64Fto32F:
+               return rewriteValuegeneric_OpCvt64Fto32F(v, config)
        case OpDiv64:
                return rewriteValuegeneric_OpDiv64(v, config)
        case OpDiv64u:
@@ -180,8 +188,12 @@ func rewriteValuegeneric(v *Value, config *Config) bool {
                return rewriteValuegeneric_OpMul16(v, config)
        case OpMul32:
                return rewriteValuegeneric_OpMul32(v, config)
+       case OpMul32F:
+               return rewriteValuegeneric_OpMul32F(v, config)
        case OpMul64:
                return rewriteValuegeneric_OpMul64(v, config)
+       case OpMul64F:
+               return rewriteValuegeneric_OpMul64F(v, config)
        case OpMul8:
                return rewriteValuegeneric_OpMul8(v, config)
        case OpNeg16:
@@ -304,8 +316,12 @@ func rewriteValuegeneric(v *Value, config *Config) bool {
                return rewriteValuegeneric_OpSub16(v, config)
        case OpSub32:
                return rewriteValuegeneric_OpSub32(v, config)
+       case OpSub32F:
+               return rewriteValuegeneric_OpSub32F(v, config)
        case OpSub64:
                return rewriteValuegeneric_OpSub64(v, config)
+       case OpSub64F:
+               return rewriteValuegeneric_OpSub64F(v, config)
        case OpSub8:
                return rewriteValuegeneric_OpSub8(v, config)
        case OpTrunc16to8:
@@ -445,6 +461,27 @@ func rewriteValuegeneric_OpAdd32(v *Value, config *Config) bool {
        }
        return false
 }
+func rewriteValuegeneric_OpAdd32F(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Add32F (Const32F [c]) (Const32F [d]))
+       // cond:
+       // result: (Const32F [f2i(float64(i2f32(c) + i2f32(d)))])
+       for {
+               if v.Args[0].Op != OpConst32F {
+                       break
+               }
+               c := v.Args[0].AuxInt
+               if v.Args[1].Op != OpConst32F {
+                       break
+               }
+               d := v.Args[1].AuxInt
+               v.reset(OpConst32F)
+               v.AuxInt = f2i(float64(i2f32(c) + i2f32(d)))
+               return true
+       }
+       return false
+}
 func rewriteValuegeneric_OpAdd64(v *Value, config *Config) bool {
        b := v.Block
        _ = b
@@ -502,6 +539,27 @@ func rewriteValuegeneric_OpAdd64(v *Value, config *Config) bool {
        }
        return false
 }
+func rewriteValuegeneric_OpAdd64F(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Add64F (Const64F [c]) (Const64F [d]))
+       // cond:
+       // result: (Const64F [f2i(i2f(c) + i2f(d))])
+       for {
+               if v.Args[0].Op != OpConst64F {
+                       break
+               }
+               c := v.Args[0].AuxInt
+               if v.Args[1].Op != OpConst64F {
+                       break
+               }
+               d := v.Args[1].AuxInt
+               v.reset(OpConst64F)
+               v.AuxInt = f2i(i2f(c) + i2f(d))
+               return true
+       }
+       return false
+}
 func rewriteValuegeneric_OpAdd8(v *Value, config *Config) bool {
        b := v.Block
        _ = b
@@ -1423,6 +1481,40 @@ func rewriteValuegeneric_OpConvert(v *Value, config *Config) bool {
        }
        return false
 }
+func rewriteValuegeneric_OpCvt32Fto64F(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Cvt32Fto64F (Const32F [c]))
+       // cond:
+       // result: (Const64F [c])
+       for {
+               if v.Args[0].Op != OpConst32F {
+                       break
+               }
+               c := v.Args[0].AuxInt
+               v.reset(OpConst64F)
+               v.AuxInt = c
+               return true
+       }
+       return false
+}
+func rewriteValuegeneric_OpCvt64Fto32F(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Cvt64Fto32F (Const64F [c]))
+       // cond:
+       // result: (Const32F [f2i(float64(i2f32(c)))])
+       for {
+               if v.Args[0].Op != OpConst64F {
+                       break
+               }
+               c := v.Args[0].AuxInt
+               v.reset(OpConst32F)
+               v.AuxInt = f2i(float64(i2f32(c)))
+               return true
+       }
+       return false
+}
 func rewriteValuegeneric_OpDiv64(v *Value, config *Config) bool {
        b := v.Block
        _ = b
@@ -4248,6 +4340,27 @@ func rewriteValuegeneric_OpMul32(v *Value, config *Config) bool {
        }
        return false
 }
+func rewriteValuegeneric_OpMul32F(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Mul32F (Const32F [c]) (Const32F [d]))
+       // cond:
+       // result: (Const32F [f2i(float64(i2f32(c) * i2f32(d)))])
+       for {
+               if v.Args[0].Op != OpConst32F {
+                       break
+               }
+               c := v.Args[0].AuxInt
+               if v.Args[1].Op != OpConst32F {
+                       break
+               }
+               d := v.Args[1].AuxInt
+               v.reset(OpConst32F)
+               v.AuxInt = f2i(float64(i2f32(c) * i2f32(d)))
+               return true
+       }
+       return false
+}
 func rewriteValuegeneric_OpMul64(v *Value, config *Config) bool {
        b := v.Block
        _ = b
@@ -4338,6 +4451,27 @@ func rewriteValuegeneric_OpMul64(v *Value, config *Config) bool {
        }
        return false
 }
+func rewriteValuegeneric_OpMul64F(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Mul64F (Const64F [c]) (Const64F [d]))
+       // cond:
+       // result: (Const64F [f2i(i2f(c) * i2f(d))])
+       for {
+               if v.Args[0].Op != OpConst64F {
+                       break
+               }
+               c := v.Args[0].AuxInt
+               if v.Args[1].Op != OpConst64F {
+                       break
+               }
+               d := v.Args[1].AuxInt
+               v.reset(OpConst64F)
+               v.AuxInt = f2i(i2f(c) * i2f(d))
+               return true
+       }
+       return false
+}
 func rewriteValuegeneric_OpMul8(v *Value, config *Config) bool {
        b := v.Block
        _ = b
@@ -4396,18 +4530,6 @@ func rewriteValuegeneric_OpMul8(v *Value, config *Config) bool {
 func rewriteValuegeneric_OpNeg16(v *Value, config *Config) bool {
        b := v.Block
        _ = b
-       // match: (Neg16 (Const16 [c]))
-       // cond:
-       // result: (Const16 [-c])
-       for {
-               if v.Args[0].Op != OpConst16 {
-                       break
-               }
-               c := v.Args[0].AuxInt
-               v.reset(OpConst16)
-               v.AuxInt = -c
-               return true
-       }
        // match: (Neg16 (Sub16 x y))
        // cond:
        // result: (Sub16 y x)
@@ -4427,18 +4549,6 @@ func rewriteValuegeneric_OpNeg16(v *Value, config *Config) bool {
 func rewriteValuegeneric_OpNeg32(v *Value, config *Config) bool {
        b := v.Block
        _ = b
-       // match: (Neg32 (Const32 [c]))
-       // cond:
-       // result: (Const32 [-c])
-       for {
-               if v.Args[0].Op != OpConst32 {
-                       break
-               }
-               c := v.Args[0].AuxInt
-               v.reset(OpConst32)
-               v.AuxInt = -c
-               return true
-       }
        // match: (Neg32 (Sub32 x y))
        // cond:
        // result: (Sub32 y x)
@@ -4458,18 +4568,6 @@ func rewriteValuegeneric_OpNeg32(v *Value, config *Config) bool {
 func rewriteValuegeneric_OpNeg64(v *Value, config *Config) bool {
        b := v.Block
        _ = b
-       // match: (Neg64 (Const64 [c]))
-       // cond:
-       // result: (Const64 [-c])
-       for {
-               if v.Args[0].Op != OpConst64 {
-                       break
-               }
-               c := v.Args[0].AuxInt
-               v.reset(OpConst64)
-               v.AuxInt = -c
-               return true
-       }
        // match: (Neg64 (Sub64 x y))
        // cond:
        // result: (Sub64 y x)
@@ -4489,18 +4587,6 @@ func rewriteValuegeneric_OpNeg64(v *Value, config *Config) bool {
 func rewriteValuegeneric_OpNeg8(v *Value, config *Config) bool {
        b := v.Block
        _ = b
-       // match: (Neg8 (Const8 [c]))
-       // cond:
-       // result: (Const8 [-c])
-       for {
-               if v.Args[0].Op != OpConst8 {
-                       break
-               }
-               c := v.Args[0].AuxInt
-               v.reset(OpConst8)
-               v.AuxInt = -c
-               return true
-       }
        // match: (Neg8 (Sub8 x y))
        // cond:
        // result: (Sub8 y x)
@@ -7632,6 +7718,27 @@ func rewriteValuegeneric_OpSub32(v *Value, config *Config) bool {
        }
        return false
 }
+func rewriteValuegeneric_OpSub32F(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Sub32F (Const32F [c]) (Const32F [d]))
+       // cond:
+       // result: (Const32F [f2i(float64(i2f32(c) - i2f32(d)))])
+       for {
+               if v.Args[0].Op != OpConst32F {
+                       break
+               }
+               c := v.Args[0].AuxInt
+               if v.Args[1].Op != OpConst32F {
+                       break
+               }
+               d := v.Args[1].AuxInt
+               v.reset(OpConst32F)
+               v.AuxInt = f2i(float64(i2f32(c) - i2f32(d)))
+               return true
+       }
+       return false
+}
 func rewriteValuegeneric_OpSub64(v *Value, config *Config) bool {
        b := v.Block
        _ = b
@@ -7719,6 +7826,27 @@ func rewriteValuegeneric_OpSub64(v *Value, config *Config) bool {
        }
        return false
 }
+func rewriteValuegeneric_OpSub64F(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Sub64F (Const64F [c]) (Const64F [d]))
+       // cond:
+       // result: (Const64F [f2i(i2f(c) - i2f(d))])
+       for {
+               if v.Args[0].Op != OpConst64F {
+                       break
+               }
+               c := v.Args[0].AuxInt
+               if v.Args[1].Op != OpConst64F {
+                       break
+               }
+               d := v.Args[1].AuxInt
+               v.reset(OpConst64F)
+               v.AuxInt = f2i(i2f(c) - i2f(d))
+               return true
+       }
+       return false
+}
 func rewriteValuegeneric_OpSub8(v *Value, config *Config) bool {
        b := v.Block
        _ = b
index a245d26f98d1075bbbf68aa89eb1b67b657698e2..e3510b135ea2ee02c82d18899be8acb7ce5c73ad 100644 (file)
@@ -97,7 +97,7 @@ func (v *Value) AuxInt2Int64() int64 {
 }
 
 func (v *Value) AuxFloat() float64 {
-       if opcodeTable[v.Op].auxType != auxFloat {
+       if opcodeTable[v.Op].auxType != auxFloat32 && opcodeTable[v.Op].auxType != auxFloat64 {
                v.Fatalf("op %s doesn't have a float aux field", v.Op)
        }
        return math.Float64frombits(uint64(v.AuxInt))
@@ -128,7 +128,7 @@ func (v *Value) LongString() string {
                s += fmt.Sprintf(" [%d]", v.AuxInt32())
        case auxInt64:
                s += fmt.Sprintf(" [%d]", v.AuxInt)
-       case auxFloat:
+       case auxFloat32, auxFloat64:
                s += fmt.Sprintf(" [%g]", v.AuxFloat())
        case auxString:
                s += fmt.Sprintf(" {%s}", v.Aux)