From 0d54be530bed37a75d87f187dca715123aef3196 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 26 Mar 2026 13:46:13 +0100 Subject: [PATCH 1/3] cmd/compile: cleanup ARM64 shift lowering MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - use CMPW rather than CMP + Zext for <=32 bits shift counts - deduplicate rules by first rewriting 32x... 16x... and 8x... to 64x... I also had to add ANDconst → zext and REV16 + zext → into REV16W due to latent rule ordering bug. Change-Id: I394006fe09aae332a1636da7722ee5fddecec304 Reviewed-on: https://go-review.googlesource.com/c/go/+/760660 Reviewed-by: Keith Randall Reviewed-by: Dmitri Shuralyov LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com Reviewed-by: Keith Randall --- src/cmd/compile/internal/ssa/_gen/ARM64.rules | 72 +- src/cmd/compile/internal/ssa/rewriteARM64.go | 1916 ++++------------- 2 files changed, 392 insertions(+), 1596 deletions(-) diff --git a/src/cmd/compile/internal/ssa/_gen/ARM64.rules b/src/cmd/compile/internal/ssa/_gen/ARM64.rules index 40a402eccb2a33..20bcefe36796af 100644 --- a/src/cmd/compile/internal/ssa/_gen/ARM64.rules +++ b/src/cmd/compile/internal/ssa/_gen/ARM64.rules @@ -145,59 +145,38 @@ // check shiftIsBounded first, if shift value is proved to be valid then we // can do the shift directly. // left shift -(Lsh(64|32|16|8)x64 x y) && shiftIsBounded(v) => (SLL x y) -(Lsh(64|32|16|8)x32 x y) && shiftIsBounded(v) => (SLL x y) -(Lsh(64|32|16|8)x16 x y) && shiftIsBounded(v) => (SLL x y) -(Lsh(64|32|16|8)x8 x y) && shiftIsBounded(v) => (SLL x y) +(Lsh32x(64|32|16|8) ...) => (Lsh64x(64|32|16|8) ...) +(Lsh16x(64|32|16|8) ...) => (Lsh64x(64|32|16|8) ...) +(Lsh8x(64|32|16|8) ...) => (Lsh64x(64|32|16|8) ...) + +(Lsh64x(64|32|16|8) x y) && shiftIsBounded(v) => (SLL x y) // signed right shift +(Rsh32x(64|32|16|8) [bounded] x y) => (Rsh64x(64|32|16|8) [bounded] (SignExt32to64 x) y) +(Rsh16x(64|32|16|8) [bounded] x y) => (Rsh64x(64|32|16|8) [bounded] (SignExt16to64 x) y) +(Rsh8x(64|32|16|8) [bounded] x y) => (Rsh64x(64|32|16|8) [bounded] (SignExt8to64 x) y) + (Rsh64x(64|32|16|8) x y) && shiftIsBounded(v) => (SRA x y) -(Rsh32x(64|32|16|8) x y) && shiftIsBounded(v) => (SRA (SignExt32to64 x) y) -(Rsh16x(64|32|16|8) x y) && shiftIsBounded(v) => (SRA (SignExt16to64 x) y) -(Rsh8x(64|32|16|8) x y) && shiftIsBounded(v) => (SRA (SignExt8to64 x) y) // unsigned right shift +(Rsh32Ux(64|32|16|8) [bounded] x y) => (Rsh64Ux(64|32|16|8) [bounded] (ZeroExt32to64 x) y) +(Rsh16Ux(64|32|16|8) [bounded] x y) => (Rsh64Ux(64|32|16|8) [bounded] (ZeroExt16to64 x) y) +(Rsh8Ux(64|32|16|8) [bounded] x y) => (Rsh64Ux(64|32|16|8) [bounded] (ZeroExt8to64 x) y) + (Rsh64Ux(64|32|16|8) x y) && shiftIsBounded(v) => (SRL x y) -(Rsh32Ux(64|32|16|8) x y) && shiftIsBounded(v) => (SRL (ZeroExt32to64 x) y) -(Rsh16Ux(64|32|16|8) x y) && shiftIsBounded(v) => (SRL (ZeroExt16to64 x) y) -(Rsh8Ux(64|32|16|8) x y) && shiftIsBounded(v) => (SRL (ZeroExt8to64 x) y) // shift value may be out of range, use CMP + CSEL instead -(Lsh64x64 x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] y)) -(Lsh64x(32|16|8) x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] ((ZeroExt32to64|ZeroExt16to64|ZeroExt8to64) y))) - -(Lsh32x64 x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] y)) -(Lsh32x(32|16|8) x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] ((ZeroExt32to64|ZeroExt16to64|ZeroExt8to64) y))) - -(Lsh16x64 x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] y)) -(Lsh16x(32|16|8) x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] ((ZeroExt32to64|ZeroExt16to64|ZeroExt8to64) y))) - -(Lsh8x64 x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] y)) -(Lsh8x(32|16|8) x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] ((ZeroExt32to64|ZeroExt16to64|ZeroExt8to64) y))) - -(Rsh64Ux64 x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SRL x y) (Const64 [0]) (CMPconst [64] y)) -(Rsh64Ux(32|16|8) x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SRL x y) (Const64 [0]) (CMPconst [64] ((ZeroExt32to64|ZeroExt16to64|ZeroExt8to64) y))) +(Lsh64x64 x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] y)) +(Lsh64x32 x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPWconst [64] y)) +(Lsh64x(16|8) [bounded] x y) && !shiftIsBounded(v) => (Lsh64x32 [bounded] x (ZeroExt(16|8)to32 y)) -(Rsh32Ux64 x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SRL (ZeroExt32to64 x) y) (Const64 [0]) (CMPconst [64] y)) -(Rsh32Ux(32|16|8) x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SRL (ZeroExt32to64 x) y) (Const64 [0]) (CMPconst [64] ((ZeroExt32to64|ZeroExt16to64|ZeroExt8to64) y))) +(Rsh64Ux64 x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SRL x y) (Const64 [0]) (CMPconst [64] y)) +(Rsh64Ux32 x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SRL x y) (Const64 [0]) (CMPWconst [64] y)) +(Rsh64Ux(16|8) [bounded] x y) && !shiftIsBounded(v) => (Rsh64Ux32 [bounded] x (ZeroExt(16|8)to32 y)) -(Rsh16Ux64 x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SRL (ZeroExt16to64 x) y) (Const64 [0]) (CMPconst [64] y)) -(Rsh16Ux(32|16|8) x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SRL (ZeroExt16to64 x) y) (Const64 [0]) (CMPconst [64] ((ZeroExt32to64|ZeroExt16to64|ZeroExt8to64) y))) - -(Rsh8Ux64 x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SRL (ZeroExt8to64 x) y) (Const64 [0]) (CMPconst [64] y)) -(Rsh8Ux(32|16|8) x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SRL (ZeroExt8to64 x) y) (Const64 [0]) (CMPconst [64] ((ZeroExt32to64|ZeroExt16to64|ZeroExt8to64) y))) - -(Rsh64x64 x y) && !shiftIsBounded(v) => (SRA x (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] y))) -(Rsh64x(32|16|8) x y) && !shiftIsBounded(v) => (SRA x (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] ((ZeroExt32to64|ZeroExt16to64|ZeroExt8to64) y)))) - -(Rsh32x64 x y) && !shiftIsBounded(v) => (SRA (SignExt32to64 x) (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] y))) -(Rsh32x(32|16|8) x y) && !shiftIsBounded(v) => (SRA (SignExt32to64 x) (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] ((ZeroExt32to64|ZeroExt16to64|ZeroExt8to64) y)))) - -(Rsh16x64 x y) && !shiftIsBounded(v) => (SRA (SignExt16to64 x) (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] y))) -(Rsh16x(32|16|8) x y) && !shiftIsBounded(v) => (SRA (SignExt16to64 x) (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] ((ZeroExt32to64|ZeroExt16to64|ZeroExt8to64) y)))) - -(Rsh8x64 x y) && !shiftIsBounded(v) => (SRA (SignExt8to64 x) (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] y))) -(Rsh8x(32|16|8) x y) && !shiftIsBounded(v) => (SRA (SignExt8to64 x) (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] ((ZeroExt32to64|ZeroExt16to64|ZeroExt8to64) y)))) +(Rsh64x64 x y) && !shiftIsBounded(v) => (SRA x (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] y))) +(Rsh64x32 x y) && !shiftIsBounded(v) => (SRA x (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] y))) +(Rsh64x(16|8) [bounded] x y) && !shiftIsBounded(v) => (Rsh64x32 [bounded] x (ZeroExt(16|8)to32 y)) // constants (Const(64|32|16|8) [val]) => (MOVDconst [int64(val)]) @@ -1617,6 +1596,8 @@ && (uint64(c1) == 0xff00ff00 && uint64(c2) == 0x00ff00ff) => (REV16 (ANDconst [0xffffffff] x)) +(REV16 (MOVWUreg x)) => (REV16W x) + // Extract from reg pair (ADDshiftLL [c] (SRLconst x [64-c]) x2) => (EXTRconst [64-c] x2 x) ( ORshiftLL [c] (SRLconst x [64-c]) x2) => (EXTRconst [64-c] x2 x) @@ -1864,3 +1845,8 @@ // 32 mul 32 -> 64 (MUL r:(MOVWUreg x) s:(MOVWUreg y)) && r.Uses == 1 && s.Uses == 1 => (UMULL x y) (MUL r:(MOVWreg x) s:(MOVWreg y)) && r.Uses == 1 && s.Uses == 1 => (MULL x y) + +// ANDconst to zext +(ANDconst [0xffffffff] x) => (MOVWUreg x) +(ANDconst [0xffff ] x) => (MOVHUreg x) +(ANDconst [0xff ] x) => (MOVBUreg x) \ No newline at end of file diff --git a/src/cmd/compile/internal/ssa/rewriteARM64.go b/src/cmd/compile/internal/ssa/rewriteARM64.go index a75247727cc7b8..661546a088df07 100644 --- a/src/cmd/compile/internal/ssa/rewriteARM64.go +++ b/src/cmd/compile/internal/ssa/rewriteARM64.go @@ -336,6 +336,8 @@ func rewriteValueARM64(v *Value) bool { return rewriteValueARM64_OpARM64ORshiftRO(v) case OpARM64REV: return rewriteValueARM64_OpARM64REV(v) + case OpARM64REV16: + return rewriteValueARM64_OpARM64REV16(v) case OpARM64REVW: return rewriteValueARM64_OpARM64REVW(v) case OpARM64ROR: @@ -813,21 +815,29 @@ func rewriteValueARM64(v *Value) bool { case OpLocalAddr: return rewriteValueARM64_OpLocalAddr(v) case OpLsh16x16: - return rewriteValueARM64_OpLsh16x16(v) + v.Op = OpLsh64x16 + return true case OpLsh16x32: - return rewriteValueARM64_OpLsh16x32(v) + v.Op = OpLsh64x32 + return true case OpLsh16x64: - return rewriteValueARM64_OpLsh16x64(v) + v.Op = OpLsh64x64 + return true case OpLsh16x8: - return rewriteValueARM64_OpLsh16x8(v) + v.Op = OpLsh64x8 + return true case OpLsh32x16: - return rewriteValueARM64_OpLsh32x16(v) + v.Op = OpLsh64x16 + return true case OpLsh32x32: - return rewriteValueARM64_OpLsh32x32(v) + v.Op = OpLsh64x32 + return true case OpLsh32x64: - return rewriteValueARM64_OpLsh32x64(v) + v.Op = OpLsh64x64 + return true case OpLsh32x8: - return rewriteValueARM64_OpLsh32x8(v) + v.Op = OpLsh64x8 + return true case OpLsh64x16: return rewriteValueARM64_OpLsh64x16(v) case OpLsh64x32: @@ -837,13 +847,17 @@ func rewriteValueARM64(v *Value) bool { case OpLsh64x8: return rewriteValueARM64_OpLsh64x8(v) case OpLsh8x16: - return rewriteValueARM64_OpLsh8x16(v) + v.Op = OpLsh64x16 + return true case OpLsh8x32: - return rewriteValueARM64_OpLsh8x32(v) + v.Op = OpLsh64x32 + return true case OpLsh8x64: - return rewriteValueARM64_OpLsh8x64(v) + v.Op = OpLsh64x64 + return true case OpLsh8x8: - return rewriteValueARM64_OpLsh8x8(v) + v.Op = OpLsh64x8 + return true case OpMax32F: v.Op = OpARM64FMAXS return true @@ -2296,6 +2310,39 @@ func rewriteValueARM64_OpARM64ANDconst(v *Value) bool { v.AddArg(x) return true } + // match: (ANDconst [0xffffffff] x) + // result: (MOVWUreg x) + for { + if auxIntToInt64(v.AuxInt) != 0xffffffff { + break + } + x := v_0 + v.reset(OpARM64MOVWUreg) + v.AddArg(x) + return true + } + // match: (ANDconst [0xffff ] x) + // result: (MOVHUreg x) + for { + if auxIntToInt64(v.AuxInt) != 0xffff { + break + } + x := v_0 + v.reset(OpARM64MOVHUreg) + v.AddArg(x) + return true + } + // match: (ANDconst [0xff ] x) + // result: (MOVBUreg x) + for { + if auxIntToInt64(v.AuxInt) != 0xff { + break + } + x := v_0 + v.reset(OpARM64MOVBUreg) + v.AddArg(x) + return true + } return false } func rewriteValueARM64_OpARM64ANDshiftLL(v *Value) bool { @@ -14648,6 +14695,21 @@ func rewriteValueARM64_OpARM64REV(v *Value) bool { } return false } +func rewriteValueARM64_OpARM64REV16(v *Value) bool { + v_0 := v.Args[0] + // match: (REV16 (MOVWUreg x)) + // result: (REV16W x) + for { + if v_0.Op != OpARM64MOVWUreg { + break + } + x := v_0.Args[0] + v.reset(OpARM64REV16W) + v.AddArg(x) + return true + } + return false +} func rewriteValueARM64_OpARM64REVW(v *Value) bool { v_0 := v.Args[0] // match: (REVW (REVW p)) @@ -18683,12 +18745,12 @@ func rewriteValueARM64_OpLocalAddr(v *Value) bool { } return false } -func rewriteValueARM64_OpLsh16x16(v *Value) bool { +func rewriteValueARM64_OpLsh64x16(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Lsh16x16 x y) + // match: (Lsh64x16 x y) // cond: shiftIsBounded(v) // result: (SLL x y) for { @@ -18703,38 +18765,32 @@ func rewriteValueARM64_OpLsh16x16(v *Value) bool { v.AddArg2(x, y) return true } - // match: (Lsh16x16 x y) + // match: (Lsh64x16 [bounded] x y) // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] (ZeroExt16to64 y))) + // result: (Lsh64x32 [bounded] x (ZeroExt16to32 y)) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 if !(!shiftIsBounded(v)) { break } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SLL, t) - v0.AddArg2(x, y) - v1 := b.NewValue0(v.Pos, OpConst64, t) - v1.AuxInt = int64ToAuxInt(0) - v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v2.AuxInt = int64ToAuxInt(64) - v3 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v3.AddArg(y) - v2.AddArg(v3) - v.AddArg3(v0, v1, v2) + v.reset(OpLsh64x32) + v.Type = t + v.AuxInt = boolToAuxInt(bounded) + v0 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32) + v0.AddArg(y) + v.AddArg2(x, v0) return true } return false } -func rewriteValueARM64_OpLsh16x32(v *Value) bool { +func rewriteValueARM64_OpLsh64x32(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block - typ := &b.Func.Config.Types - // match: (Lsh16x32 x y) + // match: (Lsh64x32 x y) // cond: shiftIsBounded(v) // result: (SLL x y) for { @@ -18749,9 +18805,9 @@ func rewriteValueARM64_OpLsh16x32(v *Value) bool { v.AddArg2(x, y) return true } - // match: (Lsh16x32 x y) + // match: (Lsh64x32 x y) // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] (ZeroExt32to64 y))) + // result: (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPWconst [64] y)) for { t := v.Type x := v_0 @@ -18765,21 +18821,19 @@ func rewriteValueARM64_OpLsh16x32(v *Value) bool { v0.AddArg2(x, y) v1 := b.NewValue0(v.Pos, OpConst64, t) v1.AuxInt = int64ToAuxInt(0) - v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v2.AuxInt = int64ToAuxInt(64) - v3 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) - v3.AddArg(y) - v2.AddArg(v3) + v2 := b.NewValue0(v.Pos, OpARM64CMPWconst, types.TypeFlags) + v2.AuxInt = int32ToAuxInt(64) + v2.AddArg(y) v.AddArg3(v0, v1, v2) return true } return false } -func rewriteValueARM64_OpLsh16x64(v *Value) bool { +func rewriteValueARM64_OpLsh64x64(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block - // match: (Lsh16x64 x y) + // match: (Lsh64x64 x y) // cond: shiftIsBounded(v) // result: (SLL x y) for { @@ -18794,7 +18848,7 @@ func rewriteValueARM64_OpLsh16x64(v *Value) bool { v.AddArg2(x, y) return true } - // match: (Lsh16x64 x y) + // match: (Lsh64x64 x y) // cond: !shiftIsBounded(v) // result: (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] y)) for { @@ -18818,12 +18872,12 @@ func rewriteValueARM64_OpLsh16x64(v *Value) bool { } return false } -func rewriteValueARM64_OpLsh16x8(v *Value) bool { +func rewriteValueARM64_OpLsh64x8(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Lsh16x8 x y) + // match: (Lsh64x8 x y) // cond: shiftIsBounded(v) // result: (SLL x y) for { @@ -18838,697 +18892,149 @@ func rewriteValueARM64_OpLsh16x8(v *Value) bool { v.AddArg2(x, y) return true } - // match: (Lsh16x8 x y) + // match: (Lsh64x8 [bounded] x y) // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] (ZeroExt8to64 y))) + // result: (Lsh64x32 [bounded] x (ZeroExt8to32 y)) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 if !(!shiftIsBounded(v)) { break } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SLL, t) - v0.AddArg2(x, y) - v1 := b.NewValue0(v.Pos, OpConst64, t) - v1.AuxInt = int64ToAuxInt(0) - v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v2.AuxInt = int64ToAuxInt(64) - v3 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v3.AddArg(y) - v2.AddArg(v3) - v.AddArg3(v0, v1, v2) + v.reset(OpLsh64x32) + v.Type = t + v.AuxInt = boolToAuxInt(bounded) + v0 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32) + v0.AddArg(y) + v.AddArg2(x, v0) return true } return false } -func rewriteValueARM64_OpLsh32x16(v *Value) bool { +func rewriteValueARM64_OpMod16(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Lsh32x16 x y) - // cond: shiftIsBounded(v) - // result: (SLL x y) + // match: (Mod16 x y) + // result: (MODW (SignExt16to32 x) (SignExt16to32 y)) for { - t := v.Type x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SLL) - v.Type = t - v.AddArg2(x, y) + v.reset(OpARM64MODW) + v0 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32) + v0.AddArg(x) + v1 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32) + v1.AddArg(y) + v.AddArg2(v0, v1) return true } - // match: (Lsh32x16 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] (ZeroExt16to64 y))) +} +func rewriteValueARM64_OpMod16u(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types + // match: (Mod16u x y) + // result: (UMODW (ZeroExt16to32 x) (ZeroExt16to32 y)) for { - t := v.Type x := v_0 y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SLL, t) - v0.AddArg2(x, y) - v1 := b.NewValue0(v.Pos, OpConst64, t) - v1.AuxInt = int64ToAuxInt(0) - v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v2.AuxInt = int64ToAuxInt(64) - v3 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v3.AddArg(y) - v2.AddArg(v3) - v.AddArg3(v0, v1, v2) + v.reset(OpARM64UMODW) + v0 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32) + v0.AddArg(x) + v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32) + v1.AddArg(y) + v.AddArg2(v0, v1) return true } - return false } -func rewriteValueARM64_OpLsh32x32(v *Value) bool { +func rewriteValueARM64_OpMod32(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] - b := v.Block - typ := &b.Func.Config.Types - // match: (Lsh32x32 x y) - // cond: shiftIsBounded(v) - // result: (SLL x y) + // match: (Mod32 x y) + // result: (MODW x y) for { - t := v.Type x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SLL) - v.Type = t + v.reset(OpARM64MODW) v.AddArg2(x, y) return true } - // match: (Lsh32x32 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] (ZeroExt32to64 y))) +} +func rewriteValueARM64_OpMod64(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + // match: (Mod64 x y) + // result: (MOD x y) for { - t := v.Type x := v_0 y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SLL, t) - v0.AddArg2(x, y) - v1 := b.NewValue0(v.Pos, OpConst64, t) - v1.AuxInt = int64ToAuxInt(0) - v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v2.AuxInt = int64ToAuxInt(64) - v3 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) - v3.AddArg(y) - v2.AddArg(v3) - v.AddArg3(v0, v1, v2) + v.reset(OpARM64MOD) + v.AddArg2(x, y) return true } - return false } -func rewriteValueARM64_OpLsh32x64(v *Value) bool { +func rewriteValueARM64_OpMod8(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block - // match: (Lsh32x64 x y) - // cond: shiftIsBounded(v) - // result: (SLL x y) + typ := &b.Func.Config.Types + // match: (Mod8 x y) + // result: (MODW (SignExt8to32 x) (SignExt8to32 y)) for { - t := v.Type x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SLL) - v.Type = t - v.AddArg2(x, y) + v.reset(OpARM64MODW) + v0 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32) + v0.AddArg(x) + v1 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32) + v1.AddArg(y) + v.AddArg2(v0, v1) return true } - // match: (Lsh32x64 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] y)) +} +func rewriteValueARM64_OpMod8u(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types + // match: (Mod8u x y) + // result: (UMODW (ZeroExt8to32 x) (ZeroExt8to32 y)) for { - t := v.Type x := v_0 y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SLL, t) - v0.AddArg2(x, y) - v1 := b.NewValue0(v.Pos, OpConst64, t) - v1.AuxInt = int64ToAuxInt(0) - v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v2.AuxInt = int64ToAuxInt(64) - v2.AddArg(y) - v.AddArg3(v0, v1, v2) + v.reset(OpARM64UMODW) + v0 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32) + v0.AddArg(x) + v1 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32) + v1.AddArg(y) + v.AddArg2(v0, v1) return true } - return false } -func rewriteValueARM64_OpLsh32x8(v *Value) bool { +func rewriteValueARM64_OpMove(v *Value) bool { + v_2 := v.Args[2] v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Lsh32x8 x y) - // cond: shiftIsBounded(v) - // result: (SLL x y) + // match: (Move [0] _ _ mem) + // result: mem for { - t := v.Type - x := v_0 - y := v_1 - if !(shiftIsBounded(v)) { + if auxIntToInt64(v.AuxInt) != 0 { break } - v.reset(OpARM64SLL) - v.Type = t - v.AddArg2(x, y) + mem := v_2 + v.copyOf(mem) return true } - // match: (Lsh32x8 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] (ZeroExt8to64 y))) + // match: (Move [1] dst src mem) + // result: (MOVBstore dst (MOVBUload src mem) mem) for { - t := v.Type - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SLL, t) - v0.AddArg2(x, y) - v1 := b.NewValue0(v.Pos, OpConst64, t) - v1.AuxInt = int64ToAuxInt(0) - v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v2.AuxInt = int64ToAuxInt(64) - v3 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v3.AddArg(y) - v2.AddArg(v3) - v.AddArg3(v0, v1, v2) - return true - } - return false -} -func rewriteValueARM64_OpLsh64x16(v *Value) bool { - v_1 := v.Args[1] - v_0 := v.Args[0] - b := v.Block - typ := &b.Func.Config.Types - // match: (Lsh64x16 x y) - // cond: shiftIsBounded(v) - // result: (SLL x y) - for { - t := v.Type - x := v_0 - y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SLL) - v.Type = t - v.AddArg2(x, y) - return true - } - // match: (Lsh64x16 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] (ZeroExt16to64 y))) - for { - t := v.Type - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SLL, t) - v0.AddArg2(x, y) - v1 := b.NewValue0(v.Pos, OpConst64, t) - v1.AuxInt = int64ToAuxInt(0) - v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v2.AuxInt = int64ToAuxInt(64) - v3 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v3.AddArg(y) - v2.AddArg(v3) - v.AddArg3(v0, v1, v2) - return true - } - return false -} -func rewriteValueARM64_OpLsh64x32(v *Value) bool { - v_1 := v.Args[1] - v_0 := v.Args[0] - b := v.Block - typ := &b.Func.Config.Types - // match: (Lsh64x32 x y) - // cond: shiftIsBounded(v) - // result: (SLL x y) - for { - t := v.Type - x := v_0 - y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SLL) - v.Type = t - v.AddArg2(x, y) - return true - } - // match: (Lsh64x32 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] (ZeroExt32to64 y))) - for { - t := v.Type - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SLL, t) - v0.AddArg2(x, y) - v1 := b.NewValue0(v.Pos, OpConst64, t) - v1.AuxInt = int64ToAuxInt(0) - v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v2.AuxInt = int64ToAuxInt(64) - v3 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) - v3.AddArg(y) - v2.AddArg(v3) - v.AddArg3(v0, v1, v2) - return true - } - return false -} -func rewriteValueARM64_OpLsh64x64(v *Value) bool { - v_1 := v.Args[1] - v_0 := v.Args[0] - b := v.Block - // match: (Lsh64x64 x y) - // cond: shiftIsBounded(v) - // result: (SLL x y) - for { - t := v.Type - x := v_0 - y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SLL) - v.Type = t - v.AddArg2(x, y) - return true - } - // match: (Lsh64x64 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] y)) - for { - t := v.Type - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SLL, t) - v0.AddArg2(x, y) - v1 := b.NewValue0(v.Pos, OpConst64, t) - v1.AuxInt = int64ToAuxInt(0) - v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v2.AuxInt = int64ToAuxInt(64) - v2.AddArg(y) - v.AddArg3(v0, v1, v2) - return true - } - return false -} -func rewriteValueARM64_OpLsh64x8(v *Value) bool { - v_1 := v.Args[1] - v_0 := v.Args[0] - b := v.Block - typ := &b.Func.Config.Types - // match: (Lsh64x8 x y) - // cond: shiftIsBounded(v) - // result: (SLL x y) - for { - t := v.Type - x := v_0 - y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SLL) - v.Type = t - v.AddArg2(x, y) - return true - } - // match: (Lsh64x8 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] (ZeroExt8to64 y))) - for { - t := v.Type - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SLL, t) - v0.AddArg2(x, y) - v1 := b.NewValue0(v.Pos, OpConst64, t) - v1.AuxInt = int64ToAuxInt(0) - v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v2.AuxInt = int64ToAuxInt(64) - v3 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v3.AddArg(y) - v2.AddArg(v3) - v.AddArg3(v0, v1, v2) - return true - } - return false -} -func rewriteValueARM64_OpLsh8x16(v *Value) bool { - v_1 := v.Args[1] - v_0 := v.Args[0] - b := v.Block - typ := &b.Func.Config.Types - // match: (Lsh8x16 x y) - // cond: shiftIsBounded(v) - // result: (SLL x y) - for { - t := v.Type - x := v_0 - y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SLL) - v.Type = t - v.AddArg2(x, y) - return true - } - // match: (Lsh8x16 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] (ZeroExt16to64 y))) - for { - t := v.Type - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SLL, t) - v0.AddArg2(x, y) - v1 := b.NewValue0(v.Pos, OpConst64, t) - v1.AuxInt = int64ToAuxInt(0) - v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v2.AuxInt = int64ToAuxInt(64) - v3 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v3.AddArg(y) - v2.AddArg(v3) - v.AddArg3(v0, v1, v2) - return true - } - return false -} -func rewriteValueARM64_OpLsh8x32(v *Value) bool { - v_1 := v.Args[1] - v_0 := v.Args[0] - b := v.Block - typ := &b.Func.Config.Types - // match: (Lsh8x32 x y) - // cond: shiftIsBounded(v) - // result: (SLL x y) - for { - t := v.Type - x := v_0 - y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SLL) - v.Type = t - v.AddArg2(x, y) - return true - } - // match: (Lsh8x32 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] (ZeroExt32to64 y))) - for { - t := v.Type - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SLL, t) - v0.AddArg2(x, y) - v1 := b.NewValue0(v.Pos, OpConst64, t) - v1.AuxInt = int64ToAuxInt(0) - v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v2.AuxInt = int64ToAuxInt(64) - v3 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) - v3.AddArg(y) - v2.AddArg(v3) - v.AddArg3(v0, v1, v2) - return true - } - return false -} -func rewriteValueARM64_OpLsh8x64(v *Value) bool { - v_1 := v.Args[1] - v_0 := v.Args[0] - b := v.Block - // match: (Lsh8x64 x y) - // cond: shiftIsBounded(v) - // result: (SLL x y) - for { - t := v.Type - x := v_0 - y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SLL) - v.Type = t - v.AddArg2(x, y) - return true - } - // match: (Lsh8x64 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] y)) - for { - t := v.Type - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SLL, t) - v0.AddArg2(x, y) - v1 := b.NewValue0(v.Pos, OpConst64, t) - v1.AuxInt = int64ToAuxInt(0) - v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v2.AuxInt = int64ToAuxInt(64) - v2.AddArg(y) - v.AddArg3(v0, v1, v2) - return true - } - return false -} -func rewriteValueARM64_OpLsh8x8(v *Value) bool { - v_1 := v.Args[1] - v_0 := v.Args[0] - b := v.Block - typ := &b.Func.Config.Types - // match: (Lsh8x8 x y) - // cond: shiftIsBounded(v) - // result: (SLL x y) - for { - t := v.Type - x := v_0 - y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SLL) - v.Type = t - v.AddArg2(x, y) - return true - } - // match: (Lsh8x8 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SLL x y) (Const64 [0]) (CMPconst [64] (ZeroExt8to64 y))) - for { - t := v.Type - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SLL, t) - v0.AddArg2(x, y) - v1 := b.NewValue0(v.Pos, OpConst64, t) - v1.AuxInt = int64ToAuxInt(0) - v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v2.AuxInt = int64ToAuxInt(64) - v3 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v3.AddArg(y) - v2.AddArg(v3) - v.AddArg3(v0, v1, v2) - return true - } - return false -} -func rewriteValueARM64_OpMod16(v *Value) bool { - v_1 := v.Args[1] - v_0 := v.Args[0] - b := v.Block - typ := &b.Func.Config.Types - // match: (Mod16 x y) - // result: (MODW (SignExt16to32 x) (SignExt16to32 y)) - for { - x := v_0 - y := v_1 - v.reset(OpARM64MODW) - v0 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32) - v0.AddArg(x) - v1 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32) - v1.AddArg(y) - v.AddArg2(v0, v1) - return true - } -} -func rewriteValueARM64_OpMod16u(v *Value) bool { - v_1 := v.Args[1] - v_0 := v.Args[0] - b := v.Block - typ := &b.Func.Config.Types - // match: (Mod16u x y) - // result: (UMODW (ZeroExt16to32 x) (ZeroExt16to32 y)) - for { - x := v_0 - y := v_1 - v.reset(OpARM64UMODW) - v0 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32) - v0.AddArg(x) - v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32) - v1.AddArg(y) - v.AddArg2(v0, v1) - return true - } -} -func rewriteValueARM64_OpMod32(v *Value) bool { - v_1 := v.Args[1] - v_0 := v.Args[0] - // match: (Mod32 x y) - // result: (MODW x y) - for { - x := v_0 - y := v_1 - v.reset(OpARM64MODW) - v.AddArg2(x, y) - return true - } -} -func rewriteValueARM64_OpMod64(v *Value) bool { - v_1 := v.Args[1] - v_0 := v.Args[0] - // match: (Mod64 x y) - // result: (MOD x y) - for { - x := v_0 - y := v_1 - v.reset(OpARM64MOD) - v.AddArg2(x, y) - return true - } -} -func rewriteValueARM64_OpMod8(v *Value) bool { - v_1 := v.Args[1] - v_0 := v.Args[0] - b := v.Block - typ := &b.Func.Config.Types - // match: (Mod8 x y) - // result: (MODW (SignExt8to32 x) (SignExt8to32 y)) - for { - x := v_0 - y := v_1 - v.reset(OpARM64MODW) - v0 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32) - v0.AddArg(x) - v1 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32) - v1.AddArg(y) - v.AddArg2(v0, v1) - return true - } -} -func rewriteValueARM64_OpMod8u(v *Value) bool { - v_1 := v.Args[1] - v_0 := v.Args[0] - b := v.Block - typ := &b.Func.Config.Types - // match: (Mod8u x y) - // result: (UMODW (ZeroExt8to32 x) (ZeroExt8to32 y)) - for { - x := v_0 - y := v_1 - v.reset(OpARM64UMODW) - v0 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32) - v0.AddArg(x) - v1 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32) - v1.AddArg(y) - v.AddArg2(v0, v1) - return true - } -} -func rewriteValueARM64_OpMove(v *Value) bool { - v_2 := v.Args[2] - v_1 := v.Args[1] - v_0 := v.Args[0] - b := v.Block - typ := &b.Func.Config.Types - // match: (Move [0] _ _ mem) - // result: mem - for { - if auxIntToInt64(v.AuxInt) != 0 { - break - } - mem := v_2 - v.copyOf(mem) - return true - } - // match: (Move [1] dst src mem) - // result: (MOVBstore dst (MOVBUload src mem) mem) - for { - if auxIntToInt64(v.AuxInt) != 1 { + if auxIntToInt64(v.AuxInt) != 1 { break } dst := v_0 @@ -20420,784 +19926,336 @@ func rewriteValueARM64_OpRsh16Ux16(v *Value) bool { v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh16Ux16 x y) - // cond: shiftIsBounded(v) - // result: (SRL (ZeroExt16to64 x) y) - for { - t := v.Type - x := v_0 - y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRL) - v.Type = t - v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v0.AddArg(x) - v.AddArg2(v0, y) - return true - } - // match: (Rsh16Ux16 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SRL (ZeroExt16to64 x) y) (Const64 [0]) (CMPconst [64] (ZeroExt16to64 y))) - for { - t := v.Type - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SRL, t) - v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v1.AddArg(x) - v0.AddArg2(v1, y) - v2 := b.NewValue0(v.Pos, OpConst64, t) - v2.AuxInt = int64ToAuxInt(0) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v4 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v4.AddArg(y) - v3.AddArg(v4) - v.AddArg3(v0, v2, v3) - return true - } - return false -} -func rewriteValueARM64_OpRsh16Ux32(v *Value) bool { - v_1 := v.Args[1] - v_0 := v.Args[0] - b := v.Block - typ := &b.Func.Config.Types - // match: (Rsh16Ux32 x y) - // cond: shiftIsBounded(v) - // result: (SRL (ZeroExt16to64 x) y) - for { - t := v.Type - x := v_0 - y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRL) - v.Type = t - v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v0.AddArg(x) - v.AddArg2(v0, y) - return true - } - // match: (Rsh16Ux32 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SRL (ZeroExt16to64 x) y) (Const64 [0]) (CMPconst [64] (ZeroExt32to64 y))) - for { - t := v.Type - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SRL, t) - v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v1.AddArg(x) - v0.AddArg2(v1, y) - v2 := b.NewValue0(v.Pos, OpConst64, t) - v2.AuxInt = int64ToAuxInt(0) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v4 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) - v4.AddArg(y) - v3.AddArg(v4) - v.AddArg3(v0, v2, v3) - return true - } - return false -} -func rewriteValueARM64_OpRsh16Ux64(v *Value) bool { - v_1 := v.Args[1] - v_0 := v.Args[0] - b := v.Block - typ := &b.Func.Config.Types - // match: (Rsh16Ux64 x y) - // cond: shiftIsBounded(v) - // result: (SRL (ZeroExt16to64 x) y) + // match: (Rsh16Ux16 [bounded] x y) + // result: (Rsh64Ux16 [bounded] (ZeroExt16to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRL) + v.reset(OpRsh64Ux16) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v0.AddArg(x) - v.AddArg2(v0, y) - return true - } - // match: (Rsh16Ux64 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SRL (ZeroExt16to64 x) y) (Const64 [0]) (CMPconst [64] y)) - for { - t := v.Type - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SRL, t) - v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v1.AddArg(x) - v0.AddArg2(v1, y) - v2 := b.NewValue0(v.Pos, OpConst64, t) - v2.AuxInt = int64ToAuxInt(0) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v3.AddArg(y) - v.AddArg3(v0, v2, v3) + v0.AddArg(x) + v.AddArg2(v0, y) return true } - return false } -func rewriteValueARM64_OpRsh16Ux8(v *Value) bool { +func rewriteValueARM64_OpRsh16Ux32(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh16Ux8 x y) - // cond: shiftIsBounded(v) - // result: (SRL (ZeroExt16to64 x) y) + // match: (Rsh16Ux32 [bounded] x y) + // result: (Rsh64Ux32 [bounded] (ZeroExt16to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRL) + v.reset(OpRsh64Ux32) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh16Ux8 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SRL (ZeroExt16to64 x) y) (Const64 [0]) (CMPconst [64] (ZeroExt8to64 y))) +} +func rewriteValueARM64_OpRsh16Ux64(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types + // match: (Rsh16Ux64 [bounded] x y) + // result: (Rsh64Ux64 [bounded] (ZeroExt16to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SRL, t) - v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v1.AddArg(x) - v0.AddArg2(v1, y) - v2 := b.NewValue0(v.Pos, OpConst64, t) - v2.AuxInt = int64ToAuxInt(0) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v4 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v4.AddArg(y) - v3.AddArg(v4) - v.AddArg3(v0, v2, v3) + v.reset(OpRsh64Ux64) + v.Type = t + v.AuxInt = boolToAuxInt(bounded) + v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) + v0.AddArg(x) + v.AddArg2(v0, y) return true } - return false } -func rewriteValueARM64_OpRsh16x16(v *Value) bool { +func rewriteValueARM64_OpRsh16Ux8(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh16x16 x y) - // cond: shiftIsBounded(v) - // result: (SRA (SignExt16to64 x) y) + // match: (Rsh16Ux8 [bounded] x y) + // result: (Rsh64Ux8 [bounded] (ZeroExt16to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) + v.reset(OpRsh64Ux8) v.Type = t - v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) + v.AuxInt = boolToAuxInt(bounded) + v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh16x16 x y) - // cond: !shiftIsBounded(v) - // result: (SRA (SignExt16to64 x) (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] (ZeroExt16to64 y)))) +} +func rewriteValueARM64_OpRsh16x16(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types + // match: (Rsh16x16 [bounded] x y) + // result: (Rsh64x16 [bounded] (SignExt16to64 x) y) for { + t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) + v.reset(OpRsh64x16) + v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) v0.AddArg(x) - v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type) - v1.AuxInt = opToAuxInt(OpARM64LessThanU) - v2 := b.NewValue0(v.Pos, OpConst64, y.Type) - v2.AuxInt = int64ToAuxInt(63) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v4 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v4.AddArg(y) - v3.AddArg(v4) - v1.AddArg3(y, v2, v3) - v.AddArg2(v0, v1) + v.AddArg2(v0, y) return true } - return false } func rewriteValueARM64_OpRsh16x32(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh16x32 x y) - // cond: shiftIsBounded(v) - // result: (SRA (SignExt16to64 x) y) + // match: (Rsh16x32 [bounded] x y) + // result: (Rsh64x32 [bounded] (SignExt16to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) + v.reset(OpRsh64x32) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh16x32 x y) - // cond: !shiftIsBounded(v) - // result: (SRA (SignExt16to64 x) (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] (ZeroExt32to64 y)))) - for { - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) - v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) - v0.AddArg(x) - v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type) - v1.AuxInt = opToAuxInt(OpARM64LessThanU) - v2 := b.NewValue0(v.Pos, OpConst64, y.Type) - v2.AuxInt = int64ToAuxInt(63) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v4 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) - v4.AddArg(y) - v3.AddArg(v4) - v1.AddArg3(y, v2, v3) - v.AddArg2(v0, v1) - return true - } - return false } func rewriteValueARM64_OpRsh16x64(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh16x64 x y) - // cond: shiftIsBounded(v) - // result: (SRA (SignExt16to64 x) y) + // match: (Rsh16x64 [bounded] x y) + // result: (Rsh64x64 [bounded] (SignExt16to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) + v.reset(OpRsh64x64) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh16x64 x y) - // cond: !shiftIsBounded(v) - // result: (SRA (SignExt16to64 x) (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] y))) - for { - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) - v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) - v0.AddArg(x) - v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type) - v1.AuxInt = opToAuxInt(OpARM64LessThanU) - v2 := b.NewValue0(v.Pos, OpConst64, y.Type) - v2.AuxInt = int64ToAuxInt(63) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v3.AddArg(y) - v1.AddArg3(y, v2, v3) - v.AddArg2(v0, v1) - return true - } - return false } func rewriteValueARM64_OpRsh16x8(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh16x8 x y) - // cond: shiftIsBounded(v) - // result: (SRA (SignExt16to64 x) y) + // match: (Rsh16x8 [bounded] x y) + // result: (Rsh64x8 [bounded] (SignExt16to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) + v.reset(OpRsh64x8) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh16x8 x y) - // cond: !shiftIsBounded(v) - // result: (SRA (SignExt16to64 x) (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] (ZeroExt8to64 y)))) - for { - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) - v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) - v0.AddArg(x) - v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type) - v1.AuxInt = opToAuxInt(OpARM64LessThanU) - v2 := b.NewValue0(v.Pos, OpConst64, y.Type) - v2.AuxInt = int64ToAuxInt(63) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v4 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v4.AddArg(y) - v3.AddArg(v4) - v1.AddArg3(y, v2, v3) - v.AddArg2(v0, v1) - return true - } - return false } func rewriteValueARM64_OpRsh32Ux16(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh32Ux16 x y) - // cond: shiftIsBounded(v) - // result: (SRL (ZeroExt32to64 x) y) + // match: (Rsh32Ux16 [bounded] x y) + // result: (Rsh64Ux16 [bounded] (ZeroExt32to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRL) + v.reset(OpRsh64Ux16) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh32Ux16 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SRL (ZeroExt32to64 x) y) (Const64 [0]) (CMPconst [64] (ZeroExt16to64 y))) - for { - t := v.Type - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SRL, t) - v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) - v1.AddArg(x) - v0.AddArg2(v1, y) - v2 := b.NewValue0(v.Pos, OpConst64, t) - v2.AuxInt = int64ToAuxInt(0) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v4 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v4.AddArg(y) - v3.AddArg(v4) - v.AddArg3(v0, v2, v3) - return true - } - return false } func rewriteValueARM64_OpRsh32Ux32(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh32Ux32 x y) - // cond: shiftIsBounded(v) - // result: (SRL (ZeroExt32to64 x) y) + // match: (Rsh32Ux32 [bounded] x y) + // result: (Rsh64Ux32 [bounded] (ZeroExt32to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRL) + v.reset(OpRsh64Ux32) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh32Ux32 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SRL (ZeroExt32to64 x) y) (Const64 [0]) (CMPconst [64] (ZeroExt32to64 y))) - for { - t := v.Type - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SRL, t) - v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) - v1.AddArg(x) - v0.AddArg2(v1, y) - v2 := b.NewValue0(v.Pos, OpConst64, t) - v2.AuxInt = int64ToAuxInt(0) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v4 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) - v4.AddArg(y) - v3.AddArg(v4) - v.AddArg3(v0, v2, v3) - return true - } - return false } func rewriteValueARM64_OpRsh32Ux64(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh32Ux64 x y) - // cond: shiftIsBounded(v) - // result: (SRL (ZeroExt32to64 x) y) + // match: (Rsh32Ux64 [bounded] x y) + // result: (Rsh64Ux64 [bounded] (ZeroExt32to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRL) + v.reset(OpRsh64Ux64) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh32Ux64 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SRL (ZeroExt32to64 x) y) (Const64 [0]) (CMPconst [64] y)) - for { - t := v.Type - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SRL, t) - v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) - v1.AddArg(x) - v0.AddArg2(v1, y) - v2 := b.NewValue0(v.Pos, OpConst64, t) - v2.AuxInt = int64ToAuxInt(0) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v3.AddArg(y) - v.AddArg3(v0, v2, v3) - return true - } - return false } func rewriteValueARM64_OpRsh32Ux8(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh32Ux8 x y) - // cond: shiftIsBounded(v) - // result: (SRL (ZeroExt32to64 x) y) + // match: (Rsh32Ux8 [bounded] x y) + // result: (Rsh64Ux8 [bounded] (ZeroExt32to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRL) + v.reset(OpRsh64Ux8) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh32Ux8 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SRL (ZeroExt32to64 x) y) (Const64 [0]) (CMPconst [64] (ZeroExt8to64 y))) - for { - t := v.Type - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SRL, t) - v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) - v1.AddArg(x) - v0.AddArg2(v1, y) - v2 := b.NewValue0(v.Pos, OpConst64, t) - v2.AuxInt = int64ToAuxInt(0) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v4 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v4.AddArg(y) - v3.AddArg(v4) - v.AddArg3(v0, v2, v3) - return true - } - return false } func rewriteValueARM64_OpRsh32x16(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh32x16 x y) - // cond: shiftIsBounded(v) - // result: (SRA (SignExt32to64 x) y) + // match: (Rsh32x16 [bounded] x y) + // result: (Rsh64x16 [bounded] (SignExt32to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) + v.reset(OpRsh64x16) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh32x16 x y) - // cond: !shiftIsBounded(v) - // result: (SRA (SignExt32to64 x) (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] (ZeroExt16to64 y)))) - for { - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) - v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) - v0.AddArg(x) - v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type) - v1.AuxInt = opToAuxInt(OpARM64LessThanU) - v2 := b.NewValue0(v.Pos, OpConst64, y.Type) - v2.AuxInt = int64ToAuxInt(63) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v4 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v4.AddArg(y) - v3.AddArg(v4) - v1.AddArg3(y, v2, v3) - v.AddArg2(v0, v1) - return true - } - return false } func rewriteValueARM64_OpRsh32x32(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh32x32 x y) - // cond: shiftIsBounded(v) - // result: (SRA (SignExt32to64 x) y) + // match: (Rsh32x32 [bounded] x y) + // result: (Rsh64x32 [bounded] (SignExt32to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) + v.reset(OpRsh64x32) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh32x32 x y) - // cond: !shiftIsBounded(v) - // result: (SRA (SignExt32to64 x) (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] (ZeroExt32to64 y)))) - for { - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) - v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) - v0.AddArg(x) - v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type) - v1.AuxInt = opToAuxInt(OpARM64LessThanU) - v2 := b.NewValue0(v.Pos, OpConst64, y.Type) - v2.AuxInt = int64ToAuxInt(63) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v4 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) - v4.AddArg(y) - v3.AddArg(v4) - v1.AddArg3(y, v2, v3) - v.AddArg2(v0, v1) - return true - } - return false } func rewriteValueARM64_OpRsh32x64(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh32x64 x y) - // cond: shiftIsBounded(v) - // result: (SRA (SignExt32to64 x) y) + // match: (Rsh32x64 [bounded] x y) + // result: (Rsh64x64 [bounded] (SignExt32to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) + v.reset(OpRsh64x64) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh32x64 x y) - // cond: !shiftIsBounded(v) - // result: (SRA (SignExt32to64 x) (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] y))) - for { - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) - v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) - v0.AddArg(x) - v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type) - v1.AuxInt = opToAuxInt(OpARM64LessThanU) - v2 := b.NewValue0(v.Pos, OpConst64, y.Type) - v2.AuxInt = int64ToAuxInt(63) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v3.AddArg(y) - v1.AddArg3(y, v2, v3) - v.AddArg2(v0, v1) - return true - } - return false } func rewriteValueARM64_OpRsh32x8(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh32x8 x y) - // cond: shiftIsBounded(v) - // result: (SRA (SignExt32to64 x) y) + // match: (Rsh32x8 [bounded] x y) + // result: (Rsh64x8 [bounded] (SignExt32to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) + v.reset(OpRsh64x8) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh32x8 x y) - // cond: !shiftIsBounded(v) - // result: (SRA (SignExt32to64 x) (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] (ZeroExt8to64 y)))) - for { - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) - v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) - v0.AddArg(x) - v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type) - v1.AuxInt = opToAuxInt(OpARM64LessThanU) - v2 := b.NewValue0(v.Pos, OpConst64, y.Type) - v2.AuxInt = int64ToAuxInt(63) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v4 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v4.AddArg(y) - v3.AddArg(v4) - v1.AddArg3(y, v2, v3) - v.AddArg2(v0, v1) - return true - } - return false } func rewriteValueARM64_OpRsh64Ux16(v *Value) bool { v_1 := v.Args[1] @@ -21219,28 +20277,23 @@ func rewriteValueARM64_OpRsh64Ux16(v *Value) bool { v.AddArg2(x, y) return true } - // match: (Rsh64Ux16 x y) + // match: (Rsh64Ux16 [bounded] x y) // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SRL x y) (Const64 [0]) (CMPconst [64] (ZeroExt16to64 y))) + // result: (Rsh64Ux32 [bounded] x (ZeroExt16to32 y)) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 if !(!shiftIsBounded(v)) { break } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SRL, t) - v0.AddArg2(x, y) - v1 := b.NewValue0(v.Pos, OpConst64, t) - v1.AuxInt = int64ToAuxInt(0) - v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v2.AuxInt = int64ToAuxInt(64) - v3 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v3.AddArg(y) - v2.AddArg(v3) - v.AddArg3(v0, v1, v2) + v.reset(OpRsh64Ux32) + v.Type = t + v.AuxInt = boolToAuxInt(bounded) + v0 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32) + v0.AddArg(y) + v.AddArg2(x, v0) return true } return false @@ -21249,7 +20302,6 @@ func rewriteValueARM64_OpRsh64Ux32(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block - typ := &b.Func.Config.Types // match: (Rsh64Ux32 x y) // cond: shiftIsBounded(v) // result: (SRL x y) @@ -21267,7 +20319,7 @@ func rewriteValueARM64_OpRsh64Ux32(v *Value) bool { } // match: (Rsh64Ux32 x y) // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SRL x y) (Const64 [0]) (CMPconst [64] (ZeroExt32to64 y))) + // result: (CSEL [OpARM64LessThanU] (SRL x y) (Const64 [0]) (CMPWconst [64] y)) for { t := v.Type x := v_0 @@ -21281,11 +20333,9 @@ func rewriteValueARM64_OpRsh64Ux32(v *Value) bool { v0.AddArg2(x, y) v1 := b.NewValue0(v.Pos, OpConst64, t) v1.AuxInt = int64ToAuxInt(0) - v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v2.AuxInt = int64ToAuxInt(64) - v3 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) - v3.AddArg(y) - v2.AddArg(v3) + v2 := b.NewValue0(v.Pos, OpARM64CMPWconst, types.TypeFlags) + v2.AuxInt = int32ToAuxInt(64) + v2.AddArg(y) v.AddArg3(v0, v1, v2) return true } @@ -21354,28 +20404,23 @@ func rewriteValueARM64_OpRsh64Ux8(v *Value) bool { v.AddArg2(x, y) return true } - // match: (Rsh64Ux8 x y) + // match: (Rsh64Ux8 [bounded] x y) // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SRL x y) (Const64 [0]) (CMPconst [64] (ZeroExt8to64 y))) + // result: (Rsh64Ux32 [bounded] x (ZeroExt8to32 y)) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 if !(!shiftIsBounded(v)) { break } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SRL, t) - v0.AddArg2(x, y) - v1 := b.NewValue0(v.Pos, OpConst64, t) - v1.AuxInt = int64ToAuxInt(0) - v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v2.AuxInt = int64ToAuxInt(64) - v3 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v3.AddArg(y) - v2.AddArg(v3) - v.AddArg3(v0, v1, v2) + v.reset(OpRsh64Ux32) + v.Type = t + v.AuxInt = boolToAuxInt(bounded) + v0 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32) + v0.AddArg(y) + v.AddArg2(x, v0) return true } return false @@ -21400,26 +20445,22 @@ func rewriteValueARM64_OpRsh64x16(v *Value) bool { v.AddArg2(x, y) return true } - // match: (Rsh64x16 x y) + // match: (Rsh64x16 [bounded] x y) // cond: !shiftIsBounded(v) - // result: (SRA x (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] (ZeroExt16to64 y)))) + // result: (Rsh64x32 [bounded] x (ZeroExt16to32 y)) for { + t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 if !(!shiftIsBounded(v)) { break } - v.reset(OpARM64SRA) - v0 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type) - v0.AuxInt = opToAuxInt(OpARM64LessThanU) - v1 := b.NewValue0(v.Pos, OpConst64, y.Type) - v1.AuxInt = int64ToAuxInt(63) - v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v2.AuxInt = int64ToAuxInt(64) - v3 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v3.AddArg(y) - v2.AddArg(v3) - v0.AddArg3(y, v1, v2) + v.reset(OpRsh64x32) + v.Type = t + v.AuxInt = boolToAuxInt(bounded) + v0 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32) + v0.AddArg(y) v.AddArg2(x, v0) return true } @@ -21429,7 +20470,6 @@ func rewriteValueARM64_OpRsh64x32(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block - typ := &b.Func.Config.Types // match: (Rsh64x32 x y) // cond: shiftIsBounded(v) // result: (SRA x y) @@ -21445,9 +20485,9 @@ func rewriteValueARM64_OpRsh64x32(v *Value) bool { v.AddArg2(x, y) return true } - // match: (Rsh64x32 x y) + // match: (Rsh64x32 x y) // cond: !shiftIsBounded(v) - // result: (SRA x (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] (ZeroExt32to64 y)))) + // result: (SRA x (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] y))) for { x := v_0 y := v_1 @@ -21461,9 +20501,7 @@ func rewriteValueARM64_OpRsh64x32(v *Value) bool { v1.AuxInt = int64ToAuxInt(63) v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) v2.AuxInt = int64ToAuxInt(64) - v3 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) - v3.AddArg(y) - v2.AddArg(v3) + v2.AddArg(y) v0.AddArg3(y, v1, v2) v.AddArg2(x, v0) return true @@ -21489,7 +20527,7 @@ func rewriteValueARM64_OpRsh64x64(v *Value) bool { v.AddArg2(x, y) return true } - // match: (Rsh64x64 x y) + // match: (Rsh64x64 x y) // cond: !shiftIsBounded(v) // result: (SRA x (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] y))) for { @@ -21532,26 +20570,22 @@ func rewriteValueARM64_OpRsh64x8(v *Value) bool { v.AddArg2(x, y) return true } - // match: (Rsh64x8 x y) + // match: (Rsh64x8 [bounded] x y) // cond: !shiftIsBounded(v) - // result: (SRA x (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] (ZeroExt8to64 y)))) + // result: (Rsh64x32 [bounded] x (ZeroExt8to32 y)) for { + t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 if !(!shiftIsBounded(v)) { break } - v.reset(OpARM64SRA) - v0 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type) - v0.AuxInt = opToAuxInt(OpARM64LessThanU) - v1 := b.NewValue0(v.Pos, OpConst64, y.Type) - v1.AuxInt = int64ToAuxInt(63) - v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v2.AuxInt = int64ToAuxInt(64) - v3 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v3.AddArg(y) - v2.AddArg(v3) - v0.AddArg3(y, v1, v2) + v.reset(OpRsh64x32) + v.Type = t + v.AuxInt = boolToAuxInt(bounded) + v0 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32) + v0.AddArg(y) v.AddArg2(x, v0) return true } @@ -21562,392 +20596,168 @@ func rewriteValueARM64_OpRsh8Ux16(v *Value) bool { v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh8Ux16 x y) - // cond: shiftIsBounded(v) - // result: (SRL (ZeroExt8to64 x) y) + // match: (Rsh8Ux16 [bounded] x y) + // result: (Rsh64Ux16 [bounded] (ZeroExt8to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRL) + v.reset(OpRsh64Ux16) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh8Ux16 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SRL (ZeroExt8to64 x) y) (Const64 [0]) (CMPconst [64] (ZeroExt16to64 y))) - for { - t := v.Type - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SRL, t) - v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v1.AddArg(x) - v0.AddArg2(v1, y) - v2 := b.NewValue0(v.Pos, OpConst64, t) - v2.AuxInt = int64ToAuxInt(0) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v4 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v4.AddArg(y) - v3.AddArg(v4) - v.AddArg3(v0, v2, v3) - return true - } - return false } func rewriteValueARM64_OpRsh8Ux32(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh8Ux32 x y) - // cond: shiftIsBounded(v) - // result: (SRL (ZeroExt8to64 x) y) + // match: (Rsh8Ux32 [bounded] x y) + // result: (Rsh64Ux32 [bounded] (ZeroExt8to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRL) + v.reset(OpRsh64Ux32) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh8Ux32 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SRL (ZeroExt8to64 x) y) (Const64 [0]) (CMPconst [64] (ZeroExt32to64 y))) - for { - t := v.Type - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SRL, t) - v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v1.AddArg(x) - v0.AddArg2(v1, y) - v2 := b.NewValue0(v.Pos, OpConst64, t) - v2.AuxInt = int64ToAuxInt(0) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v4 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) - v4.AddArg(y) - v3.AddArg(v4) - v.AddArg3(v0, v2, v3) - return true - } - return false } func rewriteValueARM64_OpRsh8Ux64(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh8Ux64 x y) - // cond: shiftIsBounded(v) - // result: (SRL (ZeroExt8to64 x) y) + // match: (Rsh8Ux64 [bounded] x y) + // result: (Rsh64Ux64 [bounded] (ZeroExt8to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRL) + v.reset(OpRsh64Ux64) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh8Ux64 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SRL (ZeroExt8to64 x) y) (Const64 [0]) (CMPconst [64] y)) - for { - t := v.Type - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SRL, t) - v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v1.AddArg(x) - v0.AddArg2(v1, y) - v2 := b.NewValue0(v.Pos, OpConst64, t) - v2.AuxInt = int64ToAuxInt(0) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v3.AddArg(y) - v.AddArg3(v0, v2, v3) - return true - } - return false } func rewriteValueARM64_OpRsh8Ux8(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh8Ux8 x y) - // cond: shiftIsBounded(v) - // result: (SRL (ZeroExt8to64 x) y) + // match: (Rsh8Ux8 [bounded] x y) + // result: (Rsh64Ux8 [bounded] (ZeroExt8to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRL) + v.reset(OpRsh64Ux8) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh8Ux8 x y) - // cond: !shiftIsBounded(v) - // result: (CSEL [OpARM64LessThanU] (SRL (ZeroExt8to64 x) y) (Const64 [0]) (CMPconst [64] (ZeroExt8to64 y))) - for { - t := v.Type - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64CSEL) - v.AuxInt = opToAuxInt(OpARM64LessThanU) - v0 := b.NewValue0(v.Pos, OpARM64SRL, t) - v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v1.AddArg(x) - v0.AddArg2(v1, y) - v2 := b.NewValue0(v.Pos, OpConst64, t) - v2.AuxInt = int64ToAuxInt(0) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v4 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v4.AddArg(y) - v3.AddArg(v4) - v.AddArg3(v0, v2, v3) - return true - } - return false } func rewriteValueARM64_OpRsh8x16(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh8x16 x y) - // cond: shiftIsBounded(v) - // result: (SRA (SignExt8to64 x) y) + // match: (Rsh8x16 [bounded] x y) + // result: (Rsh64x16 [bounded] (SignExt8to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) + v.reset(OpRsh64x16) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh8x16 x y) - // cond: !shiftIsBounded(v) - // result: (SRA (SignExt8to64 x) (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] (ZeroExt16to64 y)))) - for { - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) - v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) - v0.AddArg(x) - v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type) - v1.AuxInt = opToAuxInt(OpARM64LessThanU) - v2 := b.NewValue0(v.Pos, OpConst64, y.Type) - v2.AuxInt = int64ToAuxInt(63) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v4 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) - v4.AddArg(y) - v3.AddArg(v4) - v1.AddArg3(y, v2, v3) - v.AddArg2(v0, v1) - return true - } - return false } func rewriteValueARM64_OpRsh8x32(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh8x32 x y) - // cond: shiftIsBounded(v) - // result: (SRA (SignExt8to64 x) y) + // match: (Rsh8x32 [bounded] x y) + // result: (Rsh64x32 [bounded] (SignExt8to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) + v.reset(OpRsh64x32) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh8x32 x y) - // cond: !shiftIsBounded(v) - // result: (SRA (SignExt8to64 x) (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] (ZeroExt32to64 y)))) - for { - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) - v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) - v0.AddArg(x) - v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type) - v1.AuxInt = opToAuxInt(OpARM64LessThanU) - v2 := b.NewValue0(v.Pos, OpConst64, y.Type) - v2.AuxInt = int64ToAuxInt(63) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v4 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) - v4.AddArg(y) - v3.AddArg(v4) - v1.AddArg3(y, v2, v3) - v.AddArg2(v0, v1) - return true - } - return false } func rewriteValueARM64_OpRsh8x64(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh8x64 x y) - // cond: shiftIsBounded(v) - // result: (SRA (SignExt8to64 x) y) + // match: (Rsh8x64 [bounded] x y) + // result: (Rsh64x64 [bounded] (SignExt8to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) + v.reset(OpRsh64x64) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh8x64 x y) - // cond: !shiftIsBounded(v) - // result: (SRA (SignExt8to64 x) (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] y))) - for { - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) - v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) - v0.AddArg(x) - v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type) - v1.AuxInt = opToAuxInt(OpARM64LessThanU) - v2 := b.NewValue0(v.Pos, OpConst64, y.Type) - v2.AuxInt = int64ToAuxInt(63) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v3.AddArg(y) - v1.AddArg3(y, v2, v3) - v.AddArg2(v0, v1) - return true - } - return false } func rewriteValueARM64_OpRsh8x8(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] b := v.Block typ := &b.Func.Config.Types - // match: (Rsh8x8 x y) - // cond: shiftIsBounded(v) - // result: (SRA (SignExt8to64 x) y) + // match: (Rsh8x8 [bounded] x y) + // result: (Rsh64x8 [bounded] (SignExt8to64 x) y) for { t := v.Type + bounded := auxIntToBool(v.AuxInt) x := v_0 y := v_1 - if !(shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) + v.reset(OpRsh64x8) v.Type = t + v.AuxInt = boolToAuxInt(bounded) v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) v0.AddArg(x) v.AddArg2(v0, y) return true } - // match: (Rsh8x8 x y) - // cond: !shiftIsBounded(v) - // result: (SRA (SignExt8to64 x) (CSEL [OpARM64LessThanU] y (Const64 [63]) (CMPconst [64] (ZeroExt8to64 y)))) - for { - x := v_0 - y := v_1 - if !(!shiftIsBounded(v)) { - break - } - v.reset(OpARM64SRA) - v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) - v0.AddArg(x) - v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type) - v1.AuxInt = opToAuxInt(OpARM64LessThanU) - v2 := b.NewValue0(v.Pos, OpConst64, y.Type) - v2.AuxInt = int64ToAuxInt(63) - v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v3.AuxInt = int64ToAuxInt(64) - v4 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) - v4.AddArg(y) - v3.AddArg(v4) - v1.AddArg3(y, v2, v3) - v.AddArg2(v0, v1) - return true - } - return false } func rewriteValueARM64_OpSelect0(v *Value) bool { v_0 := v.Args[0] From 4e06ed21ac41552468e47b4f99823f18365041d7 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Wed, 4 Mar 2026 10:11:05 +0100 Subject: [PATCH 2/3] runtime: throw if a timespec64 can't be converted to a timespec32 Firstly; As far as I know we do not ever have a value inside a timespec that does not fit into a timespec32, we only ever use it for time durations which will continue to fit in timespec32 after Y2038 since it is relative. In the case that assumption is wrong I would like to be told about it. Secondly; Assuming this is false and we are storing datetimes in theses timespecs, I do not know what to do if we are trying to convert it to a 32bits timespec. Since the correct thing we are doing is to always use the 64bits codepath when it is available, thus if we try to convert such too big timespec to 32bits means the host Linux doesn't support the 64bits codepaths. Then I think it's a there is no good solution situation, and I think crashing is better than continuing with a corrupted (due to truncation) timespec32. Change-Id: I4456ff9d96d85eb3da38a938d699a6e5e99f3844 Reviewed-on: https://go-review.googlesource.com/c/go/+/751342 Auto-Submit: Jorropo Reviewed-by: David Chase Reviewed-by: Dmitri Shuralyov LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com --- src/runtime/os_linux32.go | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/runtime/os_linux32.go b/src/runtime/os_linux32.go index 1ee1cdcaf90051..3bc6183276180a 100644 --- a/src/runtime/os_linux32.go +++ b/src/runtime/os_linux32.go @@ -27,11 +27,11 @@ func futex(addr unsafe.Pointer, op int32, val uint32, ts *timespec, addr2 unsafe if use64bitsTimeOn32bits { return futex_time64(addr, op, val, ts, addr2, val3) } - // Downgrade ts. + var ts32 timespec32 var pts32 *timespec32 if ts != nil { - ts32.setNsec(ts.tv_sec*1e9 + int64(ts.tv_nsec)) + ts32 = ts.mustDowncastToTimespec32() pts32 = &ts32 } return futex_time32(addr, op, val, pts32, addr2, val3) @@ -53,16 +53,29 @@ func timer_settime(timerid int32, flags int32, new, old *itimerspec) int32 { var new32, old32 *itimerspec32 if new != nil { - newts.it_interval.setNsec(new.it_interval.tv_sec*1e9 + int64(new.it_interval.tv_nsec)) - newts.it_value.setNsec(new.it_value.tv_sec*1e9 + int64(new.it_value.tv_nsec)) + newts.it_interval = new.it_interval.mustDowncastToTimespec32() + newts.it_value = new.it_value.mustDowncastToTimespec32() new32 = &newts } if old != nil { - oldts.it_interval.setNsec(old.it_interval.tv_sec*1e9 + int64(old.it_interval.tv_nsec)) - oldts.it_value.setNsec(old.it_value.tv_sec*1e9 + int64(old.it_value.tv_nsec)) + oldts.it_interval = old.it_interval.mustDowncastToTimespec32() + oldts.it_value = old.it_value.mustDowncastToTimespec32() old32 = &oldts } return timer_settime32(timerid, flags, new32, old32) } + +// mustDowncastToTimespec32 converts a 64-bit timespec to a 32-bit +// timespec and throws if the value cannot be represented in 32 bits. +// +//go:nosplit +func (ts timespec) mustDowncastToTimespec32() (r timespec32) { + r.tv_sec = int32(ts.tv_sec) + if ts.tv_sec != int64(r.tv_sec) { + throw("timespec64 value cannot be represented in timespec32") + } + r.tv_nsec = ts.tv_nsec + return +} From 9df04115d6798a7272112804eefaae1b6b1bb03f Mon Sep 17 00:00:00 2001 From: kovan Date: Sat, 7 Mar 2026 10:12:25 +0100 Subject: [PATCH 3/3] log/slog: document context.Background use in non-Context methods Document that Debug, Info, Warn, Error (both Logger methods and package-level functions) use context.Background internally, and point users to their *Context variants. Updates #44143 Change-Id: I1bfb7bc1b0d050dfa6a665233f3df9ee70510153 Reviewed-on: https://go-review.googlesource.com/c/go/+/752620 Reviewed-by: Jonathan Amsterdam Reviewed-by: Sean Liao LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com Reviewed-by: Dmitri Shuralyov Auto-Submit: Sean Liao --- src/log/slog/logger.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/log/slog/logger.go b/src/log/slog/logger.go index 69e1cf9f152860..bda5070cef3dbd 100644 --- a/src/log/slog/logger.go +++ b/src/log/slog/logger.go @@ -195,6 +195,8 @@ func (l *Logger) LogAttrs(ctx context.Context, level Level, msg string, attrs .. } // Debug logs at [LevelDebug]. +// It uses [context.Background] internally; to specify the context, use +// [Logger.DebugContext]. func (l *Logger) Debug(msg string, args ...any) { l.log(context.Background(), LevelDebug, msg, args...) } @@ -205,6 +207,8 @@ func (l *Logger) DebugContext(ctx context.Context, msg string, args ...any) { } // Info logs at [LevelInfo]. +// It uses [context.Background] internally; to specify the context, use +// [Logger.InfoContext]. func (l *Logger) Info(msg string, args ...any) { l.log(context.Background(), LevelInfo, msg, args...) } @@ -215,6 +219,8 @@ func (l *Logger) InfoContext(ctx context.Context, msg string, args ...any) { } // Warn logs at [LevelWarn]. +// It uses [context.Background] internally; to specify the context, use +// [Logger.WarnContext]. func (l *Logger) Warn(msg string, args ...any) { l.log(context.Background(), LevelWarn, msg, args...) } @@ -225,6 +231,8 @@ func (l *Logger) WarnContext(ctx context.Context, msg string, args ...any) { } // Error logs at [LevelError]. +// It uses [context.Background] internally; to specify the context, use +// [Logger.ErrorContext]. func (l *Logger) Error(msg string, args ...any) { l.log(context.Background(), LevelError, msg, args...) } @@ -277,6 +285,8 @@ func (l *Logger) logAttrs(ctx context.Context, level Level, msg string, attrs .. } // Debug calls [Logger.Debug] on the default logger. +// It uses [context.Background] internally; to specify the context, use +// [DebugContext]. func Debug(msg string, args ...any) { Default().log(context.Background(), LevelDebug, msg, args...) } @@ -287,6 +297,8 @@ func DebugContext(ctx context.Context, msg string, args ...any) { } // Info calls [Logger.Info] on the default logger. +// It uses [context.Background] internally; to specify the context, use +// [InfoContext]. func Info(msg string, args ...any) { Default().log(context.Background(), LevelInfo, msg, args...) } @@ -297,6 +309,8 @@ func InfoContext(ctx context.Context, msg string, args ...any) { } // Warn calls [Logger.Warn] on the default logger. +// It uses [context.Background] internally; to specify the context, use +// [WarnContext]. func Warn(msg string, args ...any) { Default().log(context.Background(), LevelWarn, msg, args...) } @@ -307,6 +321,8 @@ func WarnContext(ctx context.Context, msg string, args ...any) { } // Error calls [Logger.Error] on the default logger. +// It uses [context.Background] internally; to specify the context, use +// [ErrorContext]. func Error(msg string, args ...any) { Default().log(context.Background(), LevelError, msg, args...) }