]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: teach prove about and operation
authorWayne Zuo <wdvxdr@golangcn.org>
Sat, 7 May 2022 05:58:24 +0000 (13:58 +0800)
committerGopher Robot <gobot@golang.org>
Sun, 8 May 2022 20:10:06 +0000 (20:10 +0000)
For this code:
z &= 63
_ = x<<z | x>>(64-z)
Now can prove 'x<<z' in bound. In ppc64 lowering pass, it will not
produce an extra '(ANDconst <typ.Int64> [63] z)' causing
codegen/rotate.go failed. Just remove the type check in rewrite rules
as the workaround.

Removes 32 bounds checks during make.bat.

Fixes #52563.

Change-Id: I14ed2c093ff5638dfea7de9bc7649c0f756dd71a
Reviewed-on: https://go-review.googlesource.com/c/go/+/404315
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: David Chase <drchase@google.com>
Auto-Submit: Keith Randall <khr@golang.org>
Run-TryBot: Wayne Zuo <wdvxdr@golangcn.org>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/cmd/compile/internal/ssa/gen/PPC64.rules
src/cmd/compile/internal/ssa/prove.go
src/cmd/compile/internal/ssa/rewritePPC64.go
test/prove.go

index bb3ac8ad1be83aa0251898be3907fddbb6f8fa2a..f522e7b9b7d2b51e42f047f95fb9dd5fd7c473fc 100644 (file)
 
 // Rotate generation with non-const shift
 // these match patterns from math/bits/RotateLeft[32|64], but there could be others
-(ADD (SLD x (ANDconst <typ.Int64> [63] y)) (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))) => (ROTL x y)
-(ADD (SLD x (ANDconst <typ.Int64> [63] y)) (SRD x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y)))) => (ROTL x y)
-( OR (SLD x (ANDconst <typ.Int64> [63] y)) (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))) => (ROTL x y)
-( OR (SLD x (ANDconst <typ.Int64> [63] y)) (SRD x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y)))) => (ROTL x y)
-(XOR (SLD x (ANDconst <typ.Int64> [63] y)) (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))) => (ROTL x y)
-(XOR (SLD x (ANDconst <typ.Int64> [63] y)) (SRD x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y)))) => (ROTL x y)
-
-
-(ADD (SLW x (ANDconst <typ.Int32> [31] y)) (SRW x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y)))) => (ROTLW x y)
-(ADD (SLW x (ANDconst <typ.Int32> [31] y)) (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))) => (ROTLW x y)
-( OR (SLW x (ANDconst <typ.Int32> [31] y)) (SRW x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y)))) => (ROTLW x y)
-( OR (SLW x (ANDconst <typ.Int32> [31] y)) (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))) => (ROTLW x y)
-(XOR (SLW x (ANDconst <typ.Int32> [31] y)) (SRW x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y)))) => (ROTLW x y)
-(XOR (SLW x (ANDconst <typ.Int32> [31] y)) (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))) => (ROTLW x y)
+(ADD (SLD x (ANDconst [63] y)) (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))) => (ROTL x y)
+(ADD (SLD x (ANDconst [63] y)) (SRD x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y)))) => (ROTL x y)
+( OR (SLD x (ANDconst [63] y)) (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))) => (ROTL x y)
+( OR (SLD x (ANDconst [63] y)) (SRD x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y)))) => (ROTL x y)
+(XOR (SLD x (ANDconst [63] y)) (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))) => (ROTL x y)
+(XOR (SLD x (ANDconst [63] y)) (SRD x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y)))) => (ROTL x y)
+
+
+(ADD (SLW x (ANDconst [31] y)) (SRW x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y)))) => (ROTLW x y)
+(ADD (SLW x (ANDconst [31] y)) (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))) => (ROTLW x y)
+( OR (SLW x (ANDconst [31] y)) (SRW x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y)))) => (ROTLW x y)
+( OR (SLW x (ANDconst [31] y)) (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))) => (ROTLW x y)
+(XOR (SLW x (ANDconst [31] y)) (SRW x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y)))) => (ROTLW x y)
+(XOR (SLW x (ANDconst [31] y)) (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))) => (ROTLW x y)
 
 
 // Lowering rotates
index 3d1b5007b36975343632757804fa4eeb5bd23a96..a6cd687999d7a24e45dd5b06c13dfe7b5a0f0ee0 100644 (file)
@@ -831,6 +831,9 @@ func prove(f *Func) {
                        case OpCtz64, OpCtz32, OpCtz16, OpCtz8, OpBitLen64, OpBitLen32, OpBitLen16, OpBitLen8:
                                ft.update(b, v, ft.zero, signed, gt|eq)
                                // TODO: we could also do <= 64/32/16/8, if that helped.
+                       case OpAnd64, OpAnd32, OpAnd16, OpAnd8:
+                               ft.update(b, v, v.Args[1], unsigned, lt|eq)
+                               ft.update(b, v, v.Args[0], unsigned, lt|eq)
                        }
                }
        }
index a21b757ca925a450eb54833588b2ab9c6fbfecdd..28c1c25e369323fcdd73463da4a6fab37e7d86e7 100644 (file)
@@ -3947,7 +3947,7 @@ func rewriteValuePPC64_OpPPC64ADD(v *Value) bool {
                }
                break
        }
-       // match: (ADD (SLD x (ANDconst <typ.Int64> [63] y)) (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y))))
+       // match: (ADD (SLD x (ANDconst [63] y)) (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y))))
        // result: (ROTL x y)
        for {
                for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
@@ -3957,7 +3957,7 @@ func rewriteValuePPC64_OpPPC64ADD(v *Value) bool {
                        _ = v_0.Args[1]
                        x := v_0.Args[0]
                        v_0_1 := v_0.Args[1]
-                       if v_0_1.Op != OpPPC64ANDconst || v_0_1.Type != typ.Int64 || auxIntToInt64(v_0_1.AuxInt) != 63 {
+                       if v_0_1.Op != OpPPC64ANDconst || auxIntToInt64(v_0_1.AuxInt) != 63 {
                                continue
                        }
                        y := v_0_1.Args[0]
@@ -3987,7 +3987,7 @@ func rewriteValuePPC64_OpPPC64ADD(v *Value) bool {
                }
                break
        }
-       // match: (ADD (SLD x (ANDconst <typ.Int64> [63] y)) (SRD x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y))))
+       // match: (ADD (SLD x (ANDconst [63] y)) (SRD x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y))))
        // result: (ROTL x y)
        for {
                for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
@@ -3997,7 +3997,7 @@ func rewriteValuePPC64_OpPPC64ADD(v *Value) bool {
                        _ = v_0.Args[1]
                        x := v_0.Args[0]
                        v_0_1 := v_0.Args[1]
-                       if v_0_1.Op != OpPPC64ANDconst || v_0_1.Type != typ.Int64 || auxIntToInt64(v_0_1.AuxInt) != 63 {
+                       if v_0_1.Op != OpPPC64ANDconst || auxIntToInt64(v_0_1.AuxInt) != 63 {
                                continue
                        }
                        y := v_0_1.Args[0]
@@ -4022,7 +4022,7 @@ func rewriteValuePPC64_OpPPC64ADD(v *Value) bool {
                }
                break
        }
-       // match: (ADD (SLW x (ANDconst <typ.Int32> [31] y)) (SRW x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y))))
+       // match: (ADD (SLW x (ANDconst [31] y)) (SRW x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y))))
        // result: (ROTLW x y)
        for {
                for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
@@ -4032,7 +4032,7 @@ func rewriteValuePPC64_OpPPC64ADD(v *Value) bool {
                        _ = v_0.Args[1]
                        x := v_0.Args[0]
                        v_0_1 := v_0.Args[1]
-                       if v_0_1.Op != OpPPC64ANDconst || v_0_1.Type != typ.Int32 || auxIntToInt64(v_0_1.AuxInt) != 31 {
+                       if v_0_1.Op != OpPPC64ANDconst || auxIntToInt64(v_0_1.AuxInt) != 31 {
                                continue
                        }
                        y := v_0_1.Args[0]
@@ -4057,7 +4057,7 @@ func rewriteValuePPC64_OpPPC64ADD(v *Value) bool {
                }
                break
        }
-       // match: (ADD (SLW x (ANDconst <typ.Int32> [31] y)) (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y))))
+       // match: (ADD (SLW x (ANDconst [31] y)) (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y))))
        // result: (ROTLW x y)
        for {
                for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
@@ -4067,7 +4067,7 @@ func rewriteValuePPC64_OpPPC64ADD(v *Value) bool {
                        _ = v_0.Args[1]
                        x := v_0.Args[0]
                        v_0_1 := v_0.Args[1]
-                       if v_0_1.Op != OpPPC64ANDconst || v_0_1.Type != typ.Int32 || auxIntToInt64(v_0_1.AuxInt) != 31 {
+                       if v_0_1.Op != OpPPC64ANDconst || auxIntToInt64(v_0_1.AuxInt) != 31 {
                                continue
                        }
                        y := v_0_1.Args[0]
@@ -11540,7 +11540,7 @@ func rewriteValuePPC64_OpPPC64OR(v *Value) bool {
                }
                break
        }
-       // match: ( OR (SLD x (ANDconst <typ.Int64> [63] y)) (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y))))
+       // match: ( OR (SLD x (ANDconst [63] y)) (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y))))
        // result: (ROTL x y)
        for {
                for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
@@ -11550,7 +11550,7 @@ func rewriteValuePPC64_OpPPC64OR(v *Value) bool {
                        _ = v_0.Args[1]
                        x := v_0.Args[0]
                        v_0_1 := v_0.Args[1]
-                       if v_0_1.Op != OpPPC64ANDconst || v_0_1.Type != typ.Int64 || auxIntToInt64(v_0_1.AuxInt) != 63 {
+                       if v_0_1.Op != OpPPC64ANDconst || auxIntToInt64(v_0_1.AuxInt) != 63 {
                                continue
                        }
                        y := v_0_1.Args[0]
@@ -11580,7 +11580,7 @@ func rewriteValuePPC64_OpPPC64OR(v *Value) bool {
                }
                break
        }
-       // match: ( OR (SLD x (ANDconst <typ.Int64> [63] y)) (SRD x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y))))
+       // match: ( OR (SLD x (ANDconst [63] y)) (SRD x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y))))
        // result: (ROTL x y)
        for {
                for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
@@ -11590,7 +11590,7 @@ func rewriteValuePPC64_OpPPC64OR(v *Value) bool {
                        _ = v_0.Args[1]
                        x := v_0.Args[0]
                        v_0_1 := v_0.Args[1]
-                       if v_0_1.Op != OpPPC64ANDconst || v_0_1.Type != typ.Int64 || auxIntToInt64(v_0_1.AuxInt) != 63 {
+                       if v_0_1.Op != OpPPC64ANDconst || auxIntToInt64(v_0_1.AuxInt) != 63 {
                                continue
                        }
                        y := v_0_1.Args[0]
@@ -11615,7 +11615,7 @@ func rewriteValuePPC64_OpPPC64OR(v *Value) bool {
                }
                break
        }
-       // match: ( OR (SLW x (ANDconst <typ.Int32> [31] y)) (SRW x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y))))
+       // match: ( OR (SLW x (ANDconst [31] y)) (SRW x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y))))
        // result: (ROTLW x y)
        for {
                for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
@@ -11625,7 +11625,7 @@ func rewriteValuePPC64_OpPPC64OR(v *Value) bool {
                        _ = v_0.Args[1]
                        x := v_0.Args[0]
                        v_0_1 := v_0.Args[1]
-                       if v_0_1.Op != OpPPC64ANDconst || v_0_1.Type != typ.Int32 || auxIntToInt64(v_0_1.AuxInt) != 31 {
+                       if v_0_1.Op != OpPPC64ANDconst || auxIntToInt64(v_0_1.AuxInt) != 31 {
                                continue
                        }
                        y := v_0_1.Args[0]
@@ -11650,7 +11650,7 @@ func rewriteValuePPC64_OpPPC64OR(v *Value) bool {
                }
                break
        }
-       // match: ( OR (SLW x (ANDconst <typ.Int32> [31] y)) (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y))))
+       // match: ( OR (SLW x (ANDconst [31] y)) (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y))))
        // result: (ROTLW x y)
        for {
                for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
@@ -11660,7 +11660,7 @@ func rewriteValuePPC64_OpPPC64OR(v *Value) bool {
                        _ = v_0.Args[1]
                        x := v_0.Args[0]
                        v_0_1 := v_0.Args[1]
-                       if v_0_1.Op != OpPPC64ANDconst || v_0_1.Type != typ.Int32 || auxIntToInt64(v_0_1.AuxInt) != 31 {
+                       if v_0_1.Op != OpPPC64ANDconst || auxIntToInt64(v_0_1.AuxInt) != 31 {
                                continue
                        }
                        y := v_0_1.Args[0]
@@ -13770,7 +13770,7 @@ func rewriteValuePPC64_OpPPC64XOR(v *Value) bool {
                }
                break
        }
-       // match: (XOR (SLD x (ANDconst <typ.Int64> [63] y)) (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y))))
+       // match: (XOR (SLD x (ANDconst [63] y)) (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y))))
        // result: (ROTL x y)
        for {
                for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
@@ -13780,7 +13780,7 @@ func rewriteValuePPC64_OpPPC64XOR(v *Value) bool {
                        _ = v_0.Args[1]
                        x := v_0.Args[0]
                        v_0_1 := v_0.Args[1]
-                       if v_0_1.Op != OpPPC64ANDconst || v_0_1.Type != typ.Int64 || auxIntToInt64(v_0_1.AuxInt) != 63 {
+                       if v_0_1.Op != OpPPC64ANDconst || auxIntToInt64(v_0_1.AuxInt) != 63 {
                                continue
                        }
                        y := v_0_1.Args[0]
@@ -13810,7 +13810,7 @@ func rewriteValuePPC64_OpPPC64XOR(v *Value) bool {
                }
                break
        }
-       // match: (XOR (SLD x (ANDconst <typ.Int64> [63] y)) (SRD x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y))))
+       // match: (XOR (SLD x (ANDconst [63] y)) (SRD x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y))))
        // result: (ROTL x y)
        for {
                for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
@@ -13820,7 +13820,7 @@ func rewriteValuePPC64_OpPPC64XOR(v *Value) bool {
                        _ = v_0.Args[1]
                        x := v_0.Args[0]
                        v_0_1 := v_0.Args[1]
-                       if v_0_1.Op != OpPPC64ANDconst || v_0_1.Type != typ.Int64 || auxIntToInt64(v_0_1.AuxInt) != 63 {
+                       if v_0_1.Op != OpPPC64ANDconst || auxIntToInt64(v_0_1.AuxInt) != 63 {
                                continue
                        }
                        y := v_0_1.Args[0]
@@ -13845,7 +13845,7 @@ func rewriteValuePPC64_OpPPC64XOR(v *Value) bool {
                }
                break
        }
-       // match: (XOR (SLW x (ANDconst <typ.Int32> [31] y)) (SRW x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y))))
+       // match: (XOR (SLW x (ANDconst [31] y)) (SRW x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y))))
        // result: (ROTLW x y)
        for {
                for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
@@ -13855,7 +13855,7 @@ func rewriteValuePPC64_OpPPC64XOR(v *Value) bool {
                        _ = v_0.Args[1]
                        x := v_0.Args[0]
                        v_0_1 := v_0.Args[1]
-                       if v_0_1.Op != OpPPC64ANDconst || v_0_1.Type != typ.Int32 || auxIntToInt64(v_0_1.AuxInt) != 31 {
+                       if v_0_1.Op != OpPPC64ANDconst || auxIntToInt64(v_0_1.AuxInt) != 31 {
                                continue
                        }
                        y := v_0_1.Args[0]
@@ -13880,7 +13880,7 @@ func rewriteValuePPC64_OpPPC64XOR(v *Value) bool {
                }
                break
        }
-       // match: (XOR (SLW x (ANDconst <typ.Int32> [31] y)) (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y))))
+       // match: (XOR (SLW x (ANDconst [31] y)) (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y))))
        // result: (ROTLW x y)
        for {
                for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
@@ -13890,7 +13890,7 @@ func rewriteValuePPC64_OpPPC64XOR(v *Value) bool {
                        _ = v_0.Args[1]
                        x := v_0.Args[0]
                        v_0_1 := v_0.Args[1]
-                       if v_0_1.Op != OpPPC64ANDconst || v_0_1.Type != typ.Int32 || auxIntToInt64(v_0_1.AuxInt) != 31 {
+                       if v_0_1.Op != OpPPC64ANDconst || auxIntToInt64(v_0_1.AuxInt) != 31 {
                                continue
                        }
                        y := v_0_1.Args[0]
index 83b03808384cb659779ba3f73b3884517d1e7f4f..b7cc511f53f46e4eb4f16a2c7054917c51f90379 100644 (file)
@@ -1036,6 +1036,14 @@ func divShiftClean32(n int32) int32 {
        return n / int32(16) // ERROR "Proved Rsh32x64 shifts to zero"
 }
 
+func and(p []byte) ([]byte, []byte) { // issue #52563
+       const blocksize = 16
+       fullBlocks := len(p) &^ (blocksize - 1)
+       blk := p[:fullBlocks] // ERROR "Proved IsSliceInBounds$"
+       rem := p[fullBlocks:] // ERROR "Proved IsSliceInBounds$"
+       return blk, rem
+}
+
 //go:noinline
 func useInt(a int) {
 }