]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.ssa] cmd/compile/internal/ssa: constant fold truncates and bool comparisons
authorAlexandru Moșoi <mosoi@google.com>
Wed, 17 Feb 2016 11:17:11 +0000 (12:17 +0100)
committerDavid Chase <drchase@google.com>
Fri, 19 Feb 2016 21:56:26 +0000 (21:56 +0000)
Change-Id: I731722eb77f373ff7d6101f93830ab0a50497e2c
Reviewed-on: https://go-review.googlesource.com/19542
Run-TryBot: David Chase <drchase@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
src/cmd/compile/internal/ssa/gen/generic.rules
src/cmd/compile/internal/ssa/rewritegeneric.go

index 09ab9187876be9cf05a64503ea49ac431eb346ec..f83634c3943431af19a50d002c4a473c7554ea6d 100644 (file)
 // For now, the generated successors must be a permutation of the matched successors.
 
 // constant folding
+(Trunc16to8 (Const16 [c])) -> (Const8 [int64(int8(c))])
+(Trunc32to8 (Const32 [c])) -> (Const8 [int64(int8(c))])
+(Trunc32to16 (Const32 [c])) -> (Const16 [int64(int16(c))])
+(Trunc64to8 (Const64 [c])) -> (Const8 [int64(int8(c))])
+(Trunc64to16 (Const64 [c])) -> (Const16 [int64(int16(c))])
+(Trunc64to32 (Const64 [c])) -> (Const32 [int64(int32(c))])
+
 (Neg8 (Const8 [c])) -> (Const8 [-c])
 (Neg16 (Const16 [c])) -> (Const16 [-c])
 (Neg32 (Const32 [c])) -> (Const32 [-c])
 (IsInBounds (Const64 [c]) (Const64 [d])) -> (ConstBool [b2i(inBounds64(c,d))])
 (IsSliceInBounds (Const32 [c]) (Const32 [d])) -> (ConstBool [b2i(sliceInBounds32(c,d))])
 (IsSliceInBounds (Const64 [c]) (Const64 [d])) -> (ConstBool [b2i(sliceInBounds64(c,d))])
+
 (Eq64 x x) -> (ConstBool [1])
 (Eq32 x x) -> (ConstBool [1])
 (Eq16 x x) -> (ConstBool [1])
 (Eq8 x x) -> (ConstBool [1])
+(Eq8 (ConstBool [c]) (ConstBool [d])) -> (ConstBool [b2i((int8(c) != 0) == (int8(d) != 0))])
+(Eq8 (ConstBool [0]) x) -> (Not x)
+(Eq8 (ConstBool [1]) x) -> x
+
 (Neq64 x x) -> (ConstBool [0])
 (Neq32 x x) -> (ConstBool [0])
 (Neq16 x x) -> (ConstBool [0])
 (Neq8 x x) -> (ConstBool [0])
+(Neq8 (ConstBool [c]) (ConstBool [d])) -> (ConstBool [b2i((int8(c) != 0) != (int8(d) != 0))])
+(Neq8 (ConstBool [0]) x) -> x
+(Neq8 (ConstBool [1]) x) -> (Not x)
 
 (Eq64 (Const64 <t> [c]) (Add64 (Const64 <t> [d]) x)) -> (Eq64 (Const64 <t> [c-d]) x)
 (Eq32 (Const32 <t> [c]) (Add32 (Const32 <t> [d]) x)) -> (Eq32 (Const32 <t> [c-d]) x)
 (Eq32 x (Const32 <t> [c])) && x.Op != OpConst32 -> (Eq32 (Const32 <t> [c]) x)
 (Eq16 x (Const16 <t> [c])) && x.Op != OpConst16 -> (Eq16 (Const16 <t> [c]) x)
 (Eq8 x (Const8 <t> [c])) && x.Op != OpConst8 -> (Eq8 (Const8 <t> [c]) x)
+(Eq8 x (ConstBool <t> [c])) && x.Op != OpConstBool -> (Eq8 (ConstBool <t> [c]) x)
 
 (Neq64 x (Const64 <t> [c])) && x.Op != OpConst64 -> (Neq64 (Const64 <t> [c]) x)
 (Neq32 x (Const32 <t> [c])) && x.Op != OpConst32 -> (Neq32 (Const32 <t> [c]) x)
 (Neq16 x (Const16 <t> [c])) && x.Op != OpConst16 -> (Neq16 (Const16 <t> [c]) x)
 (Neq8 x (Const8 <t> [c])) && x.Op != OpConst8 -> (Neq8 (Const8 <t> [c]) x)
+(Neq8 x (ConstBool <t> [c])) && x.Op != OpConstBool -> (Neq8 (ConstBool <t> [c]) x)
 
 (Add64 x (Const64 <t> [c])) && x.Op != OpConst64 -> (Add64 (Const64 <t> [c]) x)
 (Add32 x (Const32 <t> [c])) && x.Op != OpConst32 -> (Add32 (Const32 <t> [c]) x)
index c6fcb225654a394272c857bf134a73a8f5ff10a1..ae36112a508a85918f6e8b16153dd32aa6e6197c 100644 (file)
@@ -303,6 +303,18 @@ func rewriteValuegeneric(v *Value, config *Config) bool {
                return rewriteValuegeneric_OpSub64(v, config)
        case OpSub8:
                return rewriteValuegeneric_OpSub8(v, config)
+       case OpTrunc16to8:
+               return rewriteValuegeneric_OpTrunc16to8(v, config)
+       case OpTrunc32to16:
+               return rewriteValuegeneric_OpTrunc32to16(v, config)
+       case OpTrunc32to8:
+               return rewriteValuegeneric_OpTrunc32to8(v, config)
+       case OpTrunc64to16:
+               return rewriteValuegeneric_OpTrunc64to16(v, config)
+       case OpTrunc64to32:
+               return rewriteValuegeneric_OpTrunc64to32(v, config)
+       case OpTrunc64to8:
+               return rewriteValuegeneric_OpTrunc64to8(v, config)
        case OpXor16:
                return rewriteValuegeneric_OpXor16(v, config)
        case OpXor32:
@@ -1899,6 +1911,53 @@ func rewriteValuegeneric_OpEq8(v *Value, config *Config) bool {
                v.AuxInt = 1
                return true
        }
+       // match: (Eq8 (ConstBool [c]) (ConstBool [d]))
+       // cond:
+       // result: (ConstBool [b2i((int8(c) != 0) == (int8(d) != 0))])
+       for {
+               if v.Args[0].Op != OpConstBool {
+                       break
+               }
+               c := v.Args[0].AuxInt
+               if v.Args[1].Op != OpConstBool {
+                       break
+               }
+               d := v.Args[1].AuxInt
+               v.reset(OpConstBool)
+               v.AuxInt = b2i((int8(c) != 0) == (int8(d) != 0))
+               return true
+       }
+       // match: (Eq8 (ConstBool [0]) x)
+       // cond:
+       // result: (Not x)
+       for {
+               if v.Args[0].Op != OpConstBool {
+                       break
+               }
+               if v.Args[0].AuxInt != 0 {
+                       break
+               }
+               x := v.Args[1]
+               v.reset(OpNot)
+               v.AddArg(x)
+               return true
+       }
+       // match: (Eq8 (ConstBool [1]) x)
+       // cond:
+       // result: x
+       for {
+               if v.Args[0].Op != OpConstBool {
+                       break
+               }
+               if v.Args[0].AuxInt != 1 {
+                       break
+               }
+               x := v.Args[1]
+               v.reset(OpCopy)
+               v.Type = x.Type
+               v.AddArg(x)
+               return true
+       }
        // match: (Eq8 (Const8 <t> [c]) (Add8 (Const8 <t> [d]) x))
        // cond:
        // result: (Eq8 (Const8 <t> [c-d]) x)
@@ -1946,6 +2005,26 @@ func rewriteValuegeneric_OpEq8(v *Value, config *Config) bool {
                v.AddArg(x)
                return true
        }
+       // match: (Eq8 x (ConstBool <t> [c]))
+       // cond: x.Op != OpConstBool
+       // result: (Eq8 (ConstBool <t> [c]) x)
+       for {
+               x := v.Args[0]
+               if v.Args[1].Op != OpConstBool {
+                       break
+               }
+               t := v.Args[1].Type
+               c := v.Args[1].AuxInt
+               if !(x.Op != OpConstBool) {
+                       break
+               }
+               v.reset(OpEq8)
+               v0 := b.NewValue0(v.Line, OpConstBool, t)
+               v0.AuxInt = c
+               v.AddArg(v0)
+               v.AddArg(x)
+               return true
+       }
        // match: (Eq8  (Const8  [c]) (Const8  [d]))
        // cond:
        // result: (ConstBool [b2i(int8(c)  == int8(d))])
@@ -4429,6 +4508,53 @@ func rewriteValuegeneric_OpNeq8(v *Value, config *Config) bool {
                v.AuxInt = 0
                return true
        }
+       // match: (Neq8 (ConstBool [c]) (ConstBool [d]))
+       // cond:
+       // result: (ConstBool [b2i((int8(c) != 0) != (int8(d) != 0))])
+       for {
+               if v.Args[0].Op != OpConstBool {
+                       break
+               }
+               c := v.Args[0].AuxInt
+               if v.Args[1].Op != OpConstBool {
+                       break
+               }
+               d := v.Args[1].AuxInt
+               v.reset(OpConstBool)
+               v.AuxInt = b2i((int8(c) != 0) != (int8(d) != 0))
+               return true
+       }
+       // match: (Neq8 (ConstBool [0]) x)
+       // cond:
+       // result: x
+       for {
+               if v.Args[0].Op != OpConstBool {
+                       break
+               }
+               if v.Args[0].AuxInt != 0 {
+                       break
+               }
+               x := v.Args[1]
+               v.reset(OpCopy)
+               v.Type = x.Type
+               v.AddArg(x)
+               return true
+       }
+       // match: (Neq8 (ConstBool [1]) x)
+       // cond:
+       // result: (Not x)
+       for {
+               if v.Args[0].Op != OpConstBool {
+                       break
+               }
+               if v.Args[0].AuxInt != 1 {
+                       break
+               }
+               x := v.Args[1]
+               v.reset(OpNot)
+               v.AddArg(x)
+               return true
+       }
        // match: (Neq8 (Const8 <t> [c]) (Add8 (Const8 <t> [d]) x))
        // cond:
        // result: (Neq8 (Const8 <t> [c-d]) x)
@@ -4476,6 +4602,26 @@ func rewriteValuegeneric_OpNeq8(v *Value, config *Config) bool {
                v.AddArg(x)
                return true
        }
+       // match: (Neq8 x (ConstBool <t> [c]))
+       // cond: x.Op != OpConstBool
+       // result: (Neq8 (ConstBool <t> [c]) x)
+       for {
+               x := v.Args[0]
+               if v.Args[1].Op != OpConstBool {
+                       break
+               }
+               t := v.Args[1].Type
+               c := v.Args[1].AuxInt
+               if !(x.Op != OpConstBool) {
+                       break
+               }
+               v.reset(OpNeq8)
+               v0 := b.NewValue0(v.Line, OpConstBool, t)
+               v0.AuxInt = c
+               v.AddArg(v0)
+               v.AddArg(x)
+               return true
+       }
        // match: (Neq8  (Const8  [c]) (Const8  [d]))
        // cond:
        // result: (ConstBool [b2i(int8(c)  != int8(d))])
@@ -7275,6 +7421,108 @@ func rewriteValuegeneric_OpSub8(v *Value, config *Config) bool {
        }
        return false
 }
+func rewriteValuegeneric_OpTrunc16to8(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Trunc16to8 (Const16 [c]))
+       // cond:
+       // result: (Const8 [int64(int8(c))])
+       for {
+               if v.Args[0].Op != OpConst16 {
+                       break
+               }
+               c := v.Args[0].AuxInt
+               v.reset(OpConst8)
+               v.AuxInt = int64(int8(c))
+               return true
+       }
+       return false
+}
+func rewriteValuegeneric_OpTrunc32to16(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Trunc32to16 (Const32 [c]))
+       // cond:
+       // result: (Const16 [int64(int16(c))])
+       for {
+               if v.Args[0].Op != OpConst32 {
+                       break
+               }
+               c := v.Args[0].AuxInt
+               v.reset(OpConst16)
+               v.AuxInt = int64(int16(c))
+               return true
+       }
+       return false
+}
+func rewriteValuegeneric_OpTrunc32to8(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Trunc32to8 (Const32 [c]))
+       // cond:
+       // result: (Const8 [int64(int8(c))])
+       for {
+               if v.Args[0].Op != OpConst32 {
+                       break
+               }
+               c := v.Args[0].AuxInt
+               v.reset(OpConst8)
+               v.AuxInt = int64(int8(c))
+               return true
+       }
+       return false
+}
+func rewriteValuegeneric_OpTrunc64to16(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Trunc64to16 (Const64 [c]))
+       // cond:
+       // result: (Const16 [int64(int16(c))])
+       for {
+               if v.Args[0].Op != OpConst64 {
+                       break
+               }
+               c := v.Args[0].AuxInt
+               v.reset(OpConst16)
+               v.AuxInt = int64(int16(c))
+               return true
+       }
+       return false
+}
+func rewriteValuegeneric_OpTrunc64to32(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Trunc64to32 (Const64 [c]))
+       // cond:
+       // result: (Const32 [int64(int32(c))])
+       for {
+               if v.Args[0].Op != OpConst64 {
+                       break
+               }
+               c := v.Args[0].AuxInt
+               v.reset(OpConst32)
+               v.AuxInt = int64(int32(c))
+               return true
+       }
+       return false
+}
+func rewriteValuegeneric_OpTrunc64to8(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Trunc64to8 (Const64 [c]))
+       // cond:
+       // result: (Const8 [int64(int8(c))])
+       for {
+               if v.Args[0].Op != OpConst64 {
+                       break
+               }
+               c := v.Args[0].AuxInt
+               v.reset(OpConst8)
+               v.AuxInt = int64(int8(c))
+               return true
+       }
+       return false
+}
 func rewriteValuegeneric_OpXor16(v *Value, config *Config) bool {
        b := v.Block
        _ = b