]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: rewrite to elide Slicemask from len==c>0 slicing
authorDavid Chase <drchase@google.com>
Wed, 20 Aug 2025 16:29:02 +0000 (12:29 -0400)
committerCherry Mui <cherryyz@google.com>
Fri, 3 Oct 2025 19:30:21 +0000 (12:30 -0700)
This might have been something that prove could be educated
into figuring out, but this also works, and it also helps
prove downstream.

Adjusted the prove test, because this change moved a message.

Cherry-picked from the dev.simd branch. This CL is not
necessarily SIMD specific. Apply early to reduce risk.

Change-Id: I5eabe639eff5db9cd9766a6a8666fdb4973829cb
Reviewed-on: https://go-review.googlesource.com/c/go/+/697715
Commit-Queue: David Chase <drchase@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
TryBot-Bypass: David Chase <drchase@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/708858
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Junyang Shao <shaojunyang@google.com>
src/cmd/compile/internal/ssa/_gen/generic.rules
src/cmd/compile/internal/ssa/rewritegeneric.go
test/prove.go

index b16aa473cd59615e0601ce7ba2a0e23668a01678..6fdea7cc7a3cdc41725583bc8646d1fb02f683ea 100644 (file)
     (Const64 <typ.Int> [0])
     (Const64 <typ.Int> [0]))
 
+// Special rule to help constant slicing; len > 0 implies cap > 0 implies Slicemask is all 1
+(SliceMake (AddPtr <t> x (And64 y (Slicemask _))) w:(Const64 [c]) z) && c > 0 => (SliceMake (AddPtr <t> x y) w z)
+(SliceMake (AddPtr <t> x (And32 y (Slicemask _))) w:(Const32 [c]) z) && c > 0 => (SliceMake (AddPtr <t> x y) w z)
+
 // interface ops
 (ConstInterface) =>
   (IMake
index 5e0135be3a5be5c141565c3d8c3fa4dda4179690..5720063f34b267eef7651d17b7a28257bca7db68 100644 (file)
@@ -422,6 +422,8 @@ func rewriteValuegeneric(v *Value) bool {
                return rewriteValuegeneric_OpSliceCap(v)
        case OpSliceLen:
                return rewriteValuegeneric_OpSliceLen(v)
+       case OpSliceMake:
+               return rewriteValuegeneric_OpSliceMake(v)
        case OpSlicePtr:
                return rewriteValuegeneric_OpSlicePtr(v)
        case OpSlicemask:
@@ -30514,6 +30516,91 @@ func rewriteValuegeneric_OpSliceLen(v *Value) bool {
        }
        return false
 }
+func rewriteValuegeneric_OpSliceMake(v *Value) bool {
+       v_2 := v.Args[2]
+       v_1 := v.Args[1]
+       v_0 := v.Args[0]
+       b := v.Block
+       // match: (SliceMake (AddPtr <t> x (And64 y (Slicemask _))) w:(Const64 [c]) z)
+       // cond: c > 0
+       // result: (SliceMake (AddPtr <t> x y) w z)
+       for {
+               if v_0.Op != OpAddPtr {
+                       break
+               }
+               t := v_0.Type
+               _ = v_0.Args[1]
+               x := v_0.Args[0]
+               v_0_1 := v_0.Args[1]
+               if v_0_1.Op != OpAnd64 {
+                       break
+               }
+               _ = v_0_1.Args[1]
+               v_0_1_0 := v_0_1.Args[0]
+               v_0_1_1 := v_0_1.Args[1]
+               for _i0 := 0; _i0 <= 1; _i0, v_0_1_0, v_0_1_1 = _i0+1, v_0_1_1, v_0_1_0 {
+                       y := v_0_1_0
+                       if v_0_1_1.Op != OpSlicemask {
+                               continue
+                       }
+                       w := v_1
+                       if w.Op != OpConst64 {
+                               continue
+                       }
+                       c := auxIntToInt64(w.AuxInt)
+                       z := v_2
+                       if !(c > 0) {
+                               continue
+                       }
+                       v.reset(OpSliceMake)
+                       v0 := b.NewValue0(v.Pos, OpAddPtr, t)
+                       v0.AddArg2(x, y)
+                       v.AddArg3(v0, w, z)
+                       return true
+               }
+               break
+       }
+       // match: (SliceMake (AddPtr <t> x (And32 y (Slicemask _))) w:(Const32 [c]) z)
+       // cond: c > 0
+       // result: (SliceMake (AddPtr <t> x y) w z)
+       for {
+               if v_0.Op != OpAddPtr {
+                       break
+               }
+               t := v_0.Type
+               _ = v_0.Args[1]
+               x := v_0.Args[0]
+               v_0_1 := v_0.Args[1]
+               if v_0_1.Op != OpAnd32 {
+                       break
+               }
+               _ = v_0_1.Args[1]
+               v_0_1_0 := v_0_1.Args[0]
+               v_0_1_1 := v_0_1.Args[1]
+               for _i0 := 0; _i0 <= 1; _i0, v_0_1_0, v_0_1_1 = _i0+1, v_0_1_1, v_0_1_0 {
+                       y := v_0_1_0
+                       if v_0_1_1.Op != OpSlicemask {
+                               continue
+                       }
+                       w := v_1
+                       if w.Op != OpConst32 {
+                               continue
+                       }
+                       c := auxIntToInt32(w.AuxInt)
+                       z := v_2
+                       if !(c > 0) {
+                               continue
+                       }
+                       v.reset(OpSliceMake)
+                       v0 := b.NewValue0(v.Pos, OpAddPtr, t)
+                       v0.AddArg2(x, y)
+                       v.AddArg3(v0, w, z)
+                       return true
+               }
+               break
+       }
+       return false
+}
 func rewriteValuegeneric_OpSlicePtr(v *Value) bool {
        v_0 := v.Args[0]
        // match: (SlicePtr (SliceMake (SlicePtr x) _ _))
index 70a27865cfd7c32805a5edeee173bd9fa5c0badc..6d2bb0962be89471ead55c1065da0114fc34fe4f 100644 (file)
@@ -511,10 +511,10 @@ func f19() (e int64, err error) {
 
 func sm1(b []int, x int) {
        // Test constant argument to slicemask.
-       useSlice(b[2:8]) // ERROR "Proved slicemask not needed$"
+       useSlice(b[2:8]) // optimized away earlier by rewrite
        // Test non-constant argument with known limits.
        if cap(b) > 10 {
-               useSlice(b[2:])
+               useSlice(b[2:]) // ERROR "Proved slicemask not needed$"
        }
 }