]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: optimize unsigned comparisons to 0
authorJunchen Li <junchen.li@arm.com>
Fri, 10 Jul 2020 03:39:23 +0000 (11:39 +0800)
committerKeith Randall <khr@golang.org>
Mon, 17 Aug 2020 20:06:35 +0000 (20:06 +0000)
There are some architecture-independent rules in #21439, since an
unsigned integer >= 0 is always true and < 0 is always false. This CL
adds these optimizations to generic rules.

Updates #21439

Change-Id: Iec7e3040b761ecb1e60908f764815fdd9bc62495
Reviewed-on: https://go-review.googlesource.com/c/go/+/246617
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/compile/internal/ssa/gen/generic.rules
src/cmd/compile/internal/ssa/rewritegeneric.go
test/codegen/comparisons.go

index ed5bfc81fd88b0714f552cb10ddcdf6e94d8e3ef..2d39d2722620b6dc8241d3458d18dc3c530c3a21 100644 (file)
 (Or(64|32|16|8) x (Or(64|32|16|8) x y)) => (Or(64|32|16|8) x y)
 (Xor(64|32|16|8) x (Xor(64|32|16|8) x y)) => y
 
+// Unsigned comparisons to zero.
+(Less(64U|32U|16U|8U) _ (Const(64|32|16|8) [0])) => (ConstBool [false])
+(Leq(64U|32U|16U|8U) (Const(64|32|16|8) [0]) _)  => (ConstBool [true])
+
 // Ands clear bits. Ors set bits.
 // If a subsequent Or will set all the bits
 // that an And cleared, we can skip the And.
index 9f4e1b95bd06752271b4e90cd88a2d5358c4d67a..68e49f46f341c870e7bb1f4aeecd7da0e93f0e3b 100644 (file)
@@ -9701,6 +9701,16 @@ func rewriteValuegeneric_OpLeq16U(v *Value) bool {
                v.AuxInt = boolToAuxInt(uint16(c) <= uint16(d))
                return true
        }
+       // match: (Leq16U (Const16 [0]) _)
+       // result: (ConstBool [true])
+       for {
+               if v_0.Op != OpConst16 || auxIntToInt16(v_0.AuxInt) != 0 {
+                       break
+               }
+               v.reset(OpConstBool)
+               v.AuxInt = boolToAuxInt(true)
+               return true
+       }
        return false
 }
 func rewriteValuegeneric_OpLeq32(v *Value) bool {
@@ -9805,6 +9815,16 @@ func rewriteValuegeneric_OpLeq32U(v *Value) bool {
                v.AuxInt = boolToAuxInt(uint32(c) <= uint32(d))
                return true
        }
+       // match: (Leq32U (Const32 [0]) _)
+       // result: (ConstBool [true])
+       for {
+               if v_0.Op != OpConst32 || auxIntToInt32(v_0.AuxInt) != 0 {
+                       break
+               }
+               v.reset(OpConstBool)
+               v.AuxInt = boolToAuxInt(true)
+               return true
+       }
        return false
 }
 func rewriteValuegeneric_OpLeq64(v *Value) bool {
@@ -9909,6 +9929,16 @@ func rewriteValuegeneric_OpLeq64U(v *Value) bool {
                v.AuxInt = boolToAuxInt(uint64(c) <= uint64(d))
                return true
        }
+       // match: (Leq64U (Const64 [0]) _)
+       // result: (ConstBool [true])
+       for {
+               if v_0.Op != OpConst64 || auxIntToInt64(v_0.AuxInt) != 0 {
+                       break
+               }
+               v.reset(OpConstBool)
+               v.AuxInt = boolToAuxInt(true)
+               return true
+       }
        return false
 }
 func rewriteValuegeneric_OpLeq8(v *Value) bool {
@@ -9993,6 +10023,16 @@ func rewriteValuegeneric_OpLeq8U(v *Value) bool {
                v.AuxInt = boolToAuxInt(uint8(c) <= uint8(d))
                return true
        }
+       // match: (Leq8U (Const8 [0]) _)
+       // result: (ConstBool [true])
+       for {
+               if v_0.Op != OpConst8 || auxIntToInt8(v_0.AuxInt) != 0 {
+                       break
+               }
+               v.reset(OpConstBool)
+               v.AuxInt = boolToAuxInt(true)
+               return true
+       }
        return false
 }
 func rewriteValuegeneric_OpLess16(v *Value) bool {
@@ -10033,6 +10073,16 @@ func rewriteValuegeneric_OpLess16U(v *Value) bool {
                v.AuxInt = boolToAuxInt(uint16(c) < uint16(d))
                return true
        }
+       // match: (Less16U _ (Const16 [0]))
+       // result: (ConstBool [false])
+       for {
+               if v_1.Op != OpConst16 || auxIntToInt16(v_1.AuxInt) != 0 {
+                       break
+               }
+               v.reset(OpConstBool)
+               v.AuxInt = boolToAuxInt(false)
+               return true
+       }
        return false
 }
 func rewriteValuegeneric_OpLess32(v *Value) bool {
@@ -10093,6 +10143,16 @@ func rewriteValuegeneric_OpLess32U(v *Value) bool {
                v.AuxInt = boolToAuxInt(uint32(c) < uint32(d))
                return true
        }
+       // match: (Less32U _ (Const32 [0]))
+       // result: (ConstBool [false])
+       for {
+               if v_1.Op != OpConst32 || auxIntToInt32(v_1.AuxInt) != 0 {
+                       break
+               }
+               v.reset(OpConstBool)
+               v.AuxInt = boolToAuxInt(false)
+               return true
+       }
        return false
 }
 func rewriteValuegeneric_OpLess64(v *Value) bool {
@@ -10153,6 +10213,16 @@ func rewriteValuegeneric_OpLess64U(v *Value) bool {
                v.AuxInt = boolToAuxInt(uint64(c) < uint64(d))
                return true
        }
+       // match: (Less64U _ (Const64 [0]))
+       // result: (ConstBool [false])
+       for {
+               if v_1.Op != OpConst64 || auxIntToInt64(v_1.AuxInt) != 0 {
+                       break
+               }
+               v.reset(OpConstBool)
+               v.AuxInt = boolToAuxInt(false)
+               return true
+       }
        return false
 }
 func rewriteValuegeneric_OpLess8(v *Value) bool {
@@ -10193,6 +10263,16 @@ func rewriteValuegeneric_OpLess8U(v *Value) bool {
                v.AuxInt = boolToAuxInt(uint8(c) < uint8(d))
                return true
        }
+       // match: (Less8U _ (Const8 [0]))
+       // result: (ConstBool [false])
+       for {
+               if v_1.Op != OpConst8 || auxIntToInt8(v_1.AuxInt) != 0 {
+                       break
+               }
+               v.reset(OpConstBool)
+               v.AuxInt = boolToAuxInt(false)
+               return true
+       }
        return false
 }
 func rewriteValuegeneric_OpLoad(v *Value) bool {
index 90808573c201903bdb305110fca7c94ab7d4701e..f3c15538a8a15dd8de2c7fe5a3315ca618ef480b 100644 (file)
@@ -407,3 +407,20 @@ func CmpToZero_ex5(e, f int32, u uint32) int {
        }
        return 0
 }
+func UintLtZero(a uint8, b uint16, c uint32, d uint64) int {
+       // amd64: -`(TESTB|TESTW|TESTL|TESTQ|JCC|JCS)`
+       // arm64: -`(CMPW|CMP|BHS|BLO)`
+       if a < 0 || b < 0 || c < 0 || d < 0 {
+               return 1
+       }
+       return 0
+}
+
+func UintGeqZero(a uint8, b uint16, c uint32, d uint64) int {
+       // amd64: -`(TESTB|TESTW|TESTL|TESTQ|JCS|JCC)`
+       // arm64: -`(CMPW|CMP|BLO|BHS)`
+       if a >= 0 || b >= 0 || c >= 0 || d >= 0 {
+               return 1
+       }
+       return 0
+}