]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: add MakeTuple generic SSA op to remove duplicate Select[01] rules
authorJorropo <jorropo.pgm@gmail.com>
Tue, 11 Mar 2025 08:52:10 +0000 (09:52 +0100)
committerJorropo <jorropo.pgm@gmail.com>
Wed, 12 Mar 2025 03:17:48 +0000 (20:17 -0700)
Change-Id: Id94a5e503f02aa29dc1e334b521770107d4261db
Reviewed-on: https://go-review.googlesource.com/c/go/+/656615
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: David Chase <drchase@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Jorropo <jorropo.pgm@gmail.com>

src/cmd/compile/internal/ssa/_gen/generic.rules
src/cmd/compile/internal/ssa/_gen/genericOps.go
src/cmd/compile/internal/ssa/opGen.go
src/cmd/compile/internal/ssa/rewritegeneric.go

index 49696cea2a31e12832521860fb8cf76cf803b4d7..e671568d79740ccbf53ddef000932183bf224c51 100644 (file)
 (Div64u (Const64 [c])  (Const64 [d])) && d != 0 => (Const64 [int64(uint64(c)/uint64(d))])
 (Div32F (Const32F [c]) (Const32F [d])) && c/d == c/d => (Const32F [c/d])
 (Div64F (Const64F [c]) (Const64F [d])) && c/d == c/d => (Const64F [c/d])
-(Select0 (Div128u (Const64 [0]) lo y)) => (Div64u lo y)
-(Select1 (Div128u (Const64 [0]) lo y)) => (Mod64u lo y)
+(Div128u <t> (Const64 [0]) lo y) => (MakeTuple (Div64u <t.FieldType(0)> lo y) (Mod64u <t.FieldType(1)> lo y))
 
 (Not (ConstBool [c])) => (ConstBool [!c])
 
 
 // Convert x * 1 to x.
 (Mul(8|16|32|64)  (Const(8|16|32|64)  [1]) x) => x
-(Select0 (Mul(32|64)uover (Const(32|64) [1]) x)) => x
-(Select1 (Mul(32|64)uover (Const(32|64) [1]) x)) => (ConstBool [false])
+(Mul(32|64)uover <t> (Const(32|64) [1]) x) => (MakeTuple x (ConstBool <t.FieldType(1)> [false]))
 
 // Convert x * -1 to -x.
 (Mul(8|16|32|64)  (Const(8|16|32|64)  [-1]) x) => (Neg(8|16|32|64)  x)
 (Add(64|32|16|8) (Const(64|32|16|8) [0]) x) => x
 (Sub(64|32|16|8) x x) => (Const(64|32|16|8) [0])
 (Mul(64|32|16|8) (Const(64|32|16|8) [0]) _) => (Const(64|32|16|8) [0])
-(Select0 (Mul(64|32)uover (Const(64|32) [0]) x)) => (Const(64|32) [0])
-(Select1 (Mul(64|32)uover (Const(64|32) [0]) x)) => (ConstBool [false])
+(Mul(64|32)uover <t> (Const(64|32) [0]) x) => (MakeTuple (Const(64|32) <t.FieldType(0)> [0]) (ConstBool <t.FieldType(1)> [false]))
 
 (Com(64|32|16|8) (Com(64|32|16|8)  x)) => x
 (Com(64|32|16|8) (Const(64|32|16|8) [c])) => (Const(64|32|16|8) [^c])
 
 (Sqrt (Const64F [c])) && !math.IsNaN(math.Sqrt(c)) => (Const64F [math.Sqrt(c)])
 
+// for rewriting constant folded math/bits ops
+(Select0 (MakeTuple x y)) => x
+(Select1 (MakeTuple x y)) => y
+
 // for rewriting results of some late-expanded rewrites (below)
 (SelectN [0] (MakeResult x ___)) => x
 (SelectN [1] (MakeResult x y ___)) => y
index 37de6e99190d335375259bb09a565231fbd82f42..0acb1fef55813509adfe1484cb29af110fa16a06 100644 (file)
@@ -585,6 +585,7 @@ var genericOps = []opData{
        // pseudo-ops for breaking Tuple
        {name: "Select0", argLength: 1, zeroWidth: true},  // the first component of a tuple
        {name: "Select1", argLength: 1, zeroWidth: true},  // the second component of a tuple
+       {name: "MakeTuple", argLength: 2},                 // arg0 arg1 are components of a "Tuple" (like the result from a 128bits op).
        {name: "SelectN", argLength: 1, aux: "Int64"},     // arg0=result, auxint=field index.  Returns the auxint'th member.
        {name: "SelectNAddr", argLength: 1, aux: "Int64"}, // arg0=result, auxint=field index.  Returns the address of auxint'th member. Used for un-SSA-able result types.
        {name: "MakeResult", argLength: -1},               // arg0 .. are components of a "Result" (like the result from a Call). The last arg should be memory (like the result from a call).
index 03ccc0f5d7af7dc44f7669ec7d60c0ac51fcadc8..8ceff3f449b0bc2c8ac1f9bf52a3cdd3e74236c8 100644 (file)
@@ -3327,6 +3327,7 @@ const (
        OpCvt64Fto64U
        OpSelect0
        OpSelect1
+       OpMakeTuple
        OpSelectN
        OpSelectNAddr
        OpMakeResult
@@ -42299,6 +42300,11 @@ var opcodeTable = [...]opInfo{
                zeroWidth: true,
                generic:   true,
        },
+       {
+               name:    "MakeTuple",
+               argLen:  2,
+               generic: true,
+       },
        {
                name:    "SelectN",
                auxType: auxInt64,
index b951ecdfc5a61de3d31ed6bd2eedba1d73afb394..d5a50f42049188739f3286c50f5cc4cf31f1b09c 100644 (file)
@@ -92,6 +92,8 @@ func rewriteValuegeneric(v *Value) bool {
                return rewriteValuegeneric_OpCvt64to64F(v)
        case OpCvtBoolToUint8:
                return rewriteValuegeneric_OpCvtBoolToUint8(v)
+       case OpDiv128u:
+               return rewriteValuegeneric_OpDiv128u(v)
        case OpDiv16:
                return rewriteValuegeneric_OpDiv16(v)
        case OpDiv16u:
@@ -242,10 +244,14 @@ func rewriteValuegeneric(v *Value) bool {
                return rewriteValuegeneric_OpMul32(v)
        case OpMul32F:
                return rewriteValuegeneric_OpMul32F(v)
+       case OpMul32uover:
+               return rewriteValuegeneric_OpMul32uover(v)
        case OpMul64:
                return rewriteValuegeneric_OpMul64(v)
        case OpMul64F:
                return rewriteValuegeneric_OpMul64F(v)
+       case OpMul64uover:
+               return rewriteValuegeneric_OpMul64uover(v)
        case OpMul8:
                return rewriteValuegeneric_OpMul8(v)
        case OpNeg16:
@@ -6246,6 +6252,30 @@ func rewriteValuegeneric_OpCvtBoolToUint8(v *Value) bool {
        }
        return false
 }
+func rewriteValuegeneric_OpDiv128u(v *Value) bool {
+       v_2 := v.Args[2]
+       v_1 := v.Args[1]
+       v_0 := v.Args[0]
+       b := v.Block
+       // match: (Div128u <t> (Const64 [0]) lo y)
+       // result: (MakeTuple (Div64u <t.FieldType(0)> lo y) (Mod64u <t.FieldType(1)> lo y))
+       for {
+               t := v.Type
+               if v_0.Op != OpConst64 || auxIntToInt64(v_0.AuxInt) != 0 {
+                       break
+               }
+               lo := v_1
+               y := v_2
+               v.reset(OpMakeTuple)
+               v0 := b.NewValue0(v.Pos, OpDiv64u, t.FieldType(0))
+               v0.AddArg2(lo, y)
+               v1 := b.NewValue0(v.Pos, OpMod64u, t.FieldType(1))
+               v1.AddArg2(lo, y)
+               v.AddArg2(v0, v1)
+               return true
+       }
+       return false
+}
 func rewriteValuegeneric_OpDiv16(v *Value) bool {
        v_1 := v.Args[1]
        v_0 := v.Args[0]
@@ -18696,6 +18726,47 @@ func rewriteValuegeneric_OpMul32F(v *Value) bool {
        }
        return false
 }
+func rewriteValuegeneric_OpMul32uover(v *Value) bool {
+       v_1 := v.Args[1]
+       v_0 := v.Args[0]
+       b := v.Block
+       // match: (Mul32uover <t> (Const32 [1]) x)
+       // result: (MakeTuple x (ConstBool <t.FieldType(1)> [false]))
+       for {
+               t := v.Type
+               for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+                       if v_0.Op != OpConst32 || auxIntToInt32(v_0.AuxInt) != 1 {
+                               continue
+                       }
+                       x := v_1
+                       v.reset(OpMakeTuple)
+                       v0 := b.NewValue0(v.Pos, OpConstBool, t.FieldType(1))
+                       v0.AuxInt = boolToAuxInt(false)
+                       v.AddArg2(x, v0)
+                       return true
+               }
+               break
+       }
+       // match: (Mul32uover <t> (Const32 [0]) x)
+       // result: (MakeTuple (Const32 <t.FieldType(0)> [0]) (ConstBool <t.FieldType(1)> [false]))
+       for {
+               t := v.Type
+               for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+                       if v_0.Op != OpConst32 || auxIntToInt32(v_0.AuxInt) != 0 {
+                               continue
+                       }
+                       v.reset(OpMakeTuple)
+                       v0 := b.NewValue0(v.Pos, OpConst32, t.FieldType(0))
+                       v0.AuxInt = int32ToAuxInt(0)
+                       v1 := b.NewValue0(v.Pos, OpConstBool, t.FieldType(1))
+                       v1.AuxInt = boolToAuxInt(false)
+                       v.AddArg2(v0, v1)
+                       return true
+               }
+               break
+       }
+       return false
+}
 func rewriteValuegeneric_OpMul64(v *Value) bool {
        v_1 := v.Args[1]
        v_0 := v.Args[0]
@@ -18971,6 +19042,47 @@ func rewriteValuegeneric_OpMul64F(v *Value) bool {
        }
        return false
 }
+func rewriteValuegeneric_OpMul64uover(v *Value) bool {
+       v_1 := v.Args[1]
+       v_0 := v.Args[0]
+       b := v.Block
+       // match: (Mul64uover <t> (Const64 [1]) x)
+       // result: (MakeTuple x (ConstBool <t.FieldType(1)> [false]))
+       for {
+               t := v.Type
+               for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+                       if v_0.Op != OpConst64 || auxIntToInt64(v_0.AuxInt) != 1 {
+                               continue
+                       }
+                       x := v_1
+                       v.reset(OpMakeTuple)
+                       v0 := b.NewValue0(v.Pos, OpConstBool, t.FieldType(1))
+                       v0.AuxInt = boolToAuxInt(false)
+                       v.AddArg2(x, v0)
+                       return true
+               }
+               break
+       }
+       // match: (Mul64uover <t> (Const64 [0]) x)
+       // result: (MakeTuple (Const64 <t.FieldType(0)> [0]) (ConstBool <t.FieldType(1)> [false]))
+       for {
+               t := v.Type
+               for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+                       if v_0.Op != OpConst64 || auxIntToInt64(v_0.AuxInt) != 0 {
+                               continue
+                       }
+                       v.reset(OpMakeTuple)
+                       v0 := b.NewValue0(v.Pos, OpConst64, t.FieldType(0))
+                       v0.AuxInt = int64ToAuxInt(0)
+                       v1 := b.NewValue0(v.Pos, OpConstBool, t.FieldType(1))
+                       v1.AuxInt = boolToAuxInt(false)
+                       v.AddArg2(v0, v1)
+                       return true
+               }
+               break
+       }
+       return false
+}
 func rewriteValuegeneric_OpMul8(v *Value) bool {
        v_1 := v.Args[1]
        v_0 := v.Args[0]
@@ -29095,194 +29207,30 @@ func rewriteValuegeneric_OpRsh8x8(v *Value) bool {
 }
 func rewriteValuegeneric_OpSelect0(v *Value) bool {
        v_0 := v.Args[0]
-       // match: (Select0 (Div128u (Const64 [0]) lo y))
-       // result: (Div64u lo y)
-       for {
-               if v_0.Op != OpDiv128u {
-                       break
-               }
-               y := v_0.Args[2]
-               v_0_0 := v_0.Args[0]
-               if v_0_0.Op != OpConst64 || auxIntToInt64(v_0_0.AuxInt) != 0 {
-                       break
-               }
-               lo := v_0.Args[1]
-               v.reset(OpDiv64u)
-               v.AddArg2(lo, y)
-               return true
-       }
-       // match: (Select0 (Mul32uover (Const32 [1]) x))
-       // result: x
-       for {
-               if v_0.Op != OpMul32uover {
-                       break
-               }
-               _ = v_0.Args[1]
-               v_0_0 := v_0.Args[0]
-               v_0_1 := v_0.Args[1]
-               for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
-                       if v_0_0.Op != OpConst32 || auxIntToInt32(v_0_0.AuxInt) != 1 {
-                               continue
-                       }
-                       x := v_0_1
-                       v.copyOf(x)
-                       return true
-               }
-               break
-       }
-       // match: (Select0 (Mul64uover (Const64 [1]) x))
+       // match: (Select0 (MakeTuple x y))
        // result: x
        for {
-               if v_0.Op != OpMul64uover {
-                       break
-               }
-               _ = v_0.Args[1]
-               v_0_0 := v_0.Args[0]
-               v_0_1 := v_0.Args[1]
-               for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
-                       if v_0_0.Op != OpConst64 || auxIntToInt64(v_0_0.AuxInt) != 1 {
-                               continue
-                       }
-                       x := v_0_1
-                       v.copyOf(x)
-                       return true
-               }
-               break
-       }
-       // match: (Select0 (Mul64uover (Const64 [0]) x))
-       // result: (Const64 [0])
-       for {
-               if v_0.Op != OpMul64uover {
+               if v_0.Op != OpMakeTuple {
                        break
                }
-               _ = v_0.Args[1]
-               v_0_0 := v_0.Args[0]
-               v_0_1 := v_0.Args[1]
-               for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
-                       if v_0_0.Op != OpConst64 || auxIntToInt64(v_0_0.AuxInt) != 0 {
-                               continue
-                       }
-                       v.reset(OpConst64)
-                       v.AuxInt = int64ToAuxInt(0)
-                       return true
-               }
-               break
-       }
-       // match: (Select0 (Mul32uover (Const32 [0]) x))
-       // result: (Const32 [0])
-       for {
-               if v_0.Op != OpMul32uover {
-                       break
-               }
-               _ = v_0.Args[1]
-               v_0_0 := v_0.Args[0]
-               v_0_1 := v_0.Args[1]
-               for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
-                       if v_0_0.Op != OpConst32 || auxIntToInt32(v_0_0.AuxInt) != 0 {
-                               continue
-                       }
-                       v.reset(OpConst32)
-                       v.AuxInt = int32ToAuxInt(0)
-                       return true
-               }
-               break
+               x := v_0.Args[0]
+               v.copyOf(x)
+               return true
        }
        return false
 }
 func rewriteValuegeneric_OpSelect1(v *Value) bool {
        v_0 := v.Args[0]
-       // match: (Select1 (Div128u (Const64 [0]) lo y))
-       // result: (Mod64u lo y)
+       // match: (Select1 (MakeTuple x y))
+       // result: y
        for {
-               if v_0.Op != OpDiv128u {
-                       break
-               }
-               y := v_0.Args[2]
-               v_0_0 := v_0.Args[0]
-               if v_0_0.Op != OpConst64 || auxIntToInt64(v_0_0.AuxInt) != 0 {
+               if v_0.Op != OpMakeTuple {
                        break
                }
-               lo := v_0.Args[1]
-               v.reset(OpMod64u)
-               v.AddArg2(lo, y)
+               y := v_0.Args[1]
+               v.copyOf(y)
                return true
        }
-       // match: (Select1 (Mul32uover (Const32 [1]) x))
-       // result: (ConstBool [false])
-       for {
-               if v_0.Op != OpMul32uover {
-                       break
-               }
-               _ = v_0.Args[1]
-               v_0_0 := v_0.Args[0]
-               v_0_1 := v_0.Args[1]
-               for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
-                       if v_0_0.Op != OpConst32 || auxIntToInt32(v_0_0.AuxInt) != 1 {
-                               continue
-                       }
-                       v.reset(OpConstBool)
-                       v.AuxInt = boolToAuxInt(false)
-                       return true
-               }
-               break
-       }
-       // match: (Select1 (Mul64uover (Const64 [1]) x))
-       // result: (ConstBool [false])
-       for {
-               if v_0.Op != OpMul64uover {
-                       break
-               }
-               _ = v_0.Args[1]
-               v_0_0 := v_0.Args[0]
-               v_0_1 := v_0.Args[1]
-               for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
-                       if v_0_0.Op != OpConst64 || auxIntToInt64(v_0_0.AuxInt) != 1 {
-                               continue
-                       }
-                       v.reset(OpConstBool)
-                       v.AuxInt = boolToAuxInt(false)
-                       return true
-               }
-               break
-       }
-       // match: (Select1 (Mul64uover (Const64 [0]) x))
-       // result: (ConstBool [false])
-       for {
-               if v_0.Op != OpMul64uover {
-                       break
-               }
-               _ = v_0.Args[1]
-               v_0_0 := v_0.Args[0]
-               v_0_1 := v_0.Args[1]
-               for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
-                       if v_0_0.Op != OpConst64 || auxIntToInt64(v_0_0.AuxInt) != 0 {
-                               continue
-                       }
-                       v.reset(OpConstBool)
-                       v.AuxInt = boolToAuxInt(false)
-                       return true
-               }
-               break
-       }
-       // match: (Select1 (Mul32uover (Const32 [0]) x))
-       // result: (ConstBool [false])
-       for {
-               if v_0.Op != OpMul32uover {
-                       break
-               }
-               _ = v_0.Args[1]
-               v_0_0 := v_0.Args[0]
-               v_0_1 := v_0.Args[1]
-               for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
-                       if v_0_0.Op != OpConst32 || auxIntToInt32(v_0_0.AuxInt) != 0 {
-                               continue
-                       }
-                       v.reset(OpConstBool)
-                       v.AuxInt = boolToAuxInt(false)
-                       return true
-               }
-               break
-       }
        return false
 }
 func rewriteValuegeneric_OpSelectN(v *Value) bool {