From: David Chase Date: Wed, 5 Oct 2016 20:21:09 +0000 (-0700) Subject: cmd/compile: PPC64, elide unnecessary sign extension X-Git-Tag: go1.8beta1~961 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=2f0b8f88df33ca48494a90eea705ad092322a1ca;p=gostls13.git cmd/compile: PPC64, elide unnecessary sign extension Inputs to store[BHW] and cmpW(U) need not be correct in more bits than are used by the instruction. Added a pattern tailored to what appears to be cgo boilerplate. Added a pattern (also seen in cgo boilerplate and hashing) to replace {EQ,NE}-CMP-ANDconst with {EQ-NE}-ANDCCconst. Added a pattern to clean up ANDconst shift distance inputs (this was seen in hashing). Simplify repeated and,or,xor. Fixes #17109. Change-Id: I68eac83e3e614d69ffe473a08953048c8b066d88 Reviewed-on: https://go-review.googlesource.com/30455 Run-TryBot: David Chase TryBot-Result: Gobot Gobot Reviewed-by: Keith Randall --- diff --git a/src/cmd/compile/internal/ppc64/ssa.go b/src/cmd/compile/internal/ppc64/ssa.go index 966ee39118..8387692f86 100644 --- a/src/cmd/compile/internal/ppc64/ssa.go +++ b/src/cmd/compile/internal/ppc64/ssa.go @@ -352,6 +352,21 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { p.To.Type = obj.TYPE_REG p.To.Reg = v.Reg() + case ssa.OpPPC64ANDCCconst: + p := gc.Prog(v.Op.Asm()) + p.Reg = v.Args[0].Reg() + + if v.Aux != nil { + p.From.Type = obj.TYPE_CONST + p.From.Offset = gc.AuxOffset(v) + } else { + p.From.Type = obj.TYPE_CONST + p.From.Offset = v.AuxInt + } + + p.To.Type = obj.TYPE_REG + p.To.Reg = ppc64.REGTMP // discard result + case ssa.OpPPC64MOVDaddr: p := gc.Prog(ppc64.AMOVD) p.From.Type = obj.TYPE_ADDR diff --git a/src/cmd/compile/internal/ssa/gen/PPC64.rules b/src/cmd/compile/internal/ssa/gen/PPC64.rules index 87e9fd0ce4..1df8b3ca0e 100644 --- a/src/cmd/compile/internal/ssa/gen/PPC64.rules +++ b/src/cmd/compile/internal/ssa/gen/PPC64.rules @@ -221,6 +221,10 @@ (Rsh8Ux8 x y) -> (SRW (ZeroExt8to32 x) (ORN y (MaskIfNotCarry (ADDconstForCarry [-8] (ZeroExt8to64 y))))) (Lsh8x8 x y) -> (SLW x (ORN y (MaskIfNotCarry (ADDconstForCarry [-8] (ZeroExt8to64 y))))) +// Cleaning up shift ops when input is masked +(MaskIfNotCarry (ADDconstForCarry [c] (ANDconst [d] _))) && c < 0 && d > 0 && c + d < 0 -> (MOVDconst [-1]) +(ORN x (MOVDconst [-1])) -> x + // Potentially useful optimizing rewrites. // (ADDconstForCarry [k] c), k < 0 && (c < 0 || k+c >= 0) -> CarrySet // (ADDconstForCarry [k] c), K < 0 && (c >= 0 && k+c < 0) -> CarryClear @@ -362,6 +366,12 @@ // (NE (CMPWconst [0] (FGreaterThan cc)) yes no) -> (FGT cc yes no) // (NE (CMPWconst [0] (FGreaterEqual cc)) yes no) -> (FGE cc yes no) +// Elide compares of bit tests // TODO need to make both CC and result of ANDCC available. +(EQ (CMPconst [0] (ANDconst [c] x)) yes no) -> (EQ (ANDCCconst [c] x) yes no) +(NE (CMPconst [0] (ANDconst [c] x)) yes no) -> (NE (ANDCCconst [c] x) yes no) +(EQ (CMPWconst [0] (ANDconst [c] x)) yes no) -> (EQ (ANDCCconst [c] x) yes no) +(NE (CMPWconst [0] (ANDconst [c] x)) yes no) -> (NE (ANDCCconst [c] x) yes no) + // absorb flag constants into branches (EQ (FlagEQ) yes no) -> (First nil yes no) (EQ (FlagLT) yes no) -> (First nil no yes) @@ -588,20 +598,94 @@ (NilCheck ptr mem) -> (LoweredNilCheck ptr mem) // Optimizations +// Note that PPC "logical" immediates come in 0:15 and 16:31 unsigned immediate forms, +// so ORconst, XORconst easily expand into a pair. + +// Include very-large constants in the const-const case. +(AND (MOVDconst [c]) (MOVDconst [d])) -> (MOVDconst [c&d]) +(OR (MOVDconst [c]) (MOVDconst [d])) -> (MOVDconst [c|d]) +(XOR (MOVDconst [c]) (MOVDconst [d])) -> (MOVDconst [c^d]) + +// Discover consts +(AND x (MOVDconst [c])) && isU16Bit(c) -> (ANDconst [c] x) +(XOR x (MOVDconst [c])) && isU32Bit(c) -> (XORconst [c] x) +(OR x (MOVDconst [c])) && isU32Bit(c) -> (ORconst [c] x) +(AND (MOVDconst [c]) x) && isU16Bit(c) -> (ANDconst [c] x) +(XOR (MOVDconst [c]) x) && isU32Bit(c) -> (XORconst [c] x) +(OR (MOVDconst [c]) x) && isU32Bit(c) -> (ORconst [c] x) + +// Simplify consts +(ANDconst [c] (ANDconst [d] x)) -> (ANDconst [c&d] x) +(ORconst [c] (ORconst [d] x)) -> (ORconst [c|d] x) +(XORconst [c] (XORconst [d] x)) -> (XORconst [c^d] x) +(ANDconst [-1] x) -> x +(ANDconst [0] _) -> (MOVDconst [0]) +(XORconst [0] x) -> x +(ORconst [-1] _) -> (MOVDconst [-1]) +(ORconst [0] x) -> x + +// zero-extend of small and -> small and +(MOVBZreg y:(ANDconst [c] _)) && uint64(c) <= 0xFF -> y +(MOVHZreg y:(ANDconst [c] _)) && uint64(c) <= 0xFFFF -> y +(MOVWZreg y:(ANDconst [c] _)) && uint64(c) <= 0xFFFFFFFF -> y +(MOVWZreg y:(AND (MOVDconst [c]) _)) && uint64(c) <= 0xFFFFFFFF -> y + +// sign extend of small-positive and -> small-positive-and +(MOVBreg y:(ANDconst [c] _)) && uint64(c) <= 0x7F -> y +(MOVHreg y:(ANDconst [c] _)) && uint64(c) <= 0x7FFF -> y +(MOVWreg y:(ANDconst [c] _)) && uint64(c) <= 0xFFFF -> y // 0xFFFF is largest immediate constant, when regarded as 32-bit is > 0 +(MOVWreg y:(AND (MOVDconst [c]) _)) && uint64(c) <= 0x7FFFFFFF -> y + +// small and of zero-extend -> either zero-extend or small and + // degenerate-and +(ANDconst [c] y:(MOVBZreg _)) && c&0xFF == 0xFF -> y +(ANDconst [c] y:(MOVHZreg _)) && c&0xFFFF == 0xFFFF -> y +(ANDconst [c] y:(MOVWZreg _)) && c&0xFFFFFFFF == 0xFFFFFFFF -> y + // normal case +(ANDconst [c] (MOVBZreg x)) -> (ANDconst [c&0xFF] x) +(ANDconst [c] (MOVHZreg x)) -> (ANDconst [c&0xFFFF] x) +(ANDconst [c] (MOVWZreg x)) -> (ANDconst [c&0xFFFFFFFF] x) + +// Various redundant zero/sign extension combinations. +(MOVBZreg y:(MOVBZreg _)) -> y // repeat +(MOVBreg y:(MOVBreg _)) -> y // repeat +(MOVBreg (MOVBZreg x)) -> (MOVBreg x) +(MOVBZreg (MOVBreg x)) -> (MOVBZreg x) + +// H - there are more combinations than these + +(MOVHZreg y:(MOVHZreg _)) -> y // repeat +(MOVHZreg y:(MOVBZreg _)) -> y // wide of narrow + +(MOVHreg y:(MOVHreg _)) -> y // repeat +(MOVHreg y:(MOVBreg _)) -> y // wide of narrow + +(MOVHreg y:(MOVHZreg x)) -> (MOVHreg x) +(MOVHZreg y:(MOVHreg x)) -> (MOVHZreg x) + +// W - there are more combinations than these + +(MOVWZreg y:(MOVWZreg _)) -> y // repeat +(MOVWZreg y:(MOVHZreg _)) -> y // wide of narrow +(MOVWZreg y:(MOVBZreg _)) -> y // wide of narrow + +(MOVWreg y:(MOVWreg _)) -> y // repeat +(MOVWreg y:(MOVHreg _)) -> y // wide of narrow +(MOVWreg y:(MOVBreg _)) -> y // wide of narrow + +(MOVWreg y:(MOVWZreg x)) -> (MOVWreg x) +(MOVWZreg y:(MOVWreg x)) -> (MOVWZreg x) + +// Arithmetic constant ops (ADD (MOVDconst [c]) x) && is32Bit(c) -> (ADDconst [c] x) (ADD x (MOVDconst [c])) && is32Bit(c) -> (ADDconst [c] x) (ADDconst [c] (ADDconst [d] x)) && is32Bit(c+d) -> (ADDconst [c+d] x) -(ADDconst [c] (MOVDaddr [d] {sym} x)) -> (MOVDaddr [c+d] {sym} x) (ADDconst [0] x) -> x -(ANDconst [-1] x) -> x -(ANDconst [0] _) -> (MOVDconst [0]) -(XORconst [0] x) -> x +(SUB x (MOVDconst [c])) && is32Bit(-c) -> (ADDconst [-c] x) +// TODO deal with subtract-from-const -(XOR (MOVDconst [0]) x) -> x -(XOR x (MOVDconst [0])) -> x -(ADD (MOVDconst [0]) x) -> x -(ADD x (MOVDconst [0])) -> x +(ADDconst [c] (MOVDaddr [d] {sym} x)) -> (MOVDaddr [c+d] {sym} x) // Fold offsets for stores. (MOVDstore [off1] {sym} (ADDconst [off2] x) val mem) && is16Bit(off1+off2) -> (MOVDstore [off1+off2] {sym} x val mem) @@ -714,10 +798,19 @@ (MOVHZreg (MOVDconst [c])) -> (MOVDconst [int64(uint16(c))]) (MOVHreg (MOVDconst [c])) -> (MOVDconst [int64(int16(c))]) +// Lose widening ops fed to to stores (MOVBstore [off] {sym} ptr (MOVBreg x) mem) -> (MOVBstore [off] {sym} ptr x mem) (MOVBstore [off] {sym} ptr (MOVBZreg x) mem) -> (MOVBstore [off] {sym} ptr x mem) (MOVHstore [off] {sym} ptr (MOVHreg x) mem) -> (MOVHstore [off] {sym} ptr x mem) (MOVHstore [off] {sym} ptr (MOVHZreg x) mem) -> (MOVHstore [off] {sym} ptr x mem) +(MOVWstore [off] {sym} ptr (MOVWreg x) mem) -> (MOVWstore [off] {sym} ptr x mem) +(MOVWstore [off] {sym} ptr (MOVWZreg x) mem) -> (MOVWstore [off] {sym} ptr x mem) + +// Lose W-widening ops fed to compare-W +(CMPW x (MOVWreg y)) -> (CMPW x y) +(CMPW (MOVWreg x) y) -> (CMPW x y) +(CMPWU x (MOVWZreg y)) -> (CMPWU x y) +(CMPWU (MOVWZreg x) y) -> (CMPWU x y) (CMP x (MOVDconst [c])) && is16Bit(c) -> (CMPconst x [c]) (CMP (MOVDconst [c]) y) && is16Bit(c) -> (InvertFlags (CMPconst y [c])) @@ -728,3 +821,7 @@ (CMPU (MOVDconst [c]) y) && isU16Bit(c) -> (InvertFlags (CMPUconst y [c])) (CMPWU x (MOVDconst [c])) && isU16Bit(c) -> (CMPWUconst x [c]) (CMPWU (MOVDconst [c]) y) && isU16Bit(c) -> (InvertFlags (CMPWUconst y [c])) + +// A particular pattern seen in cgo code: +(AND (MOVDconst [c]) x:(MOVBZload _ _)) -> (ANDconst [c&0xFF] x) +(AND x:(MOVBZload _ _) (MOVDconst [c])) -> (ANDconst [c&0xFF] x) diff --git a/src/cmd/compile/internal/ssa/gen/PPC64Ops.go b/src/cmd/compile/internal/ssa/gen/PPC64Ops.go index a3233912c0..4b4f799668 100644 --- a/src/cmd/compile/internal/ssa/gen/PPC64Ops.go +++ b/src/cmd/compile/internal/ssa/gen/PPC64Ops.go @@ -226,6 +226,7 @@ func init() { {name: "ORconst", argLength: 1, reg: gp11, asm: "OR", aux: "Int64"}, // arg0|aux {name: "XORconst", argLength: 1, reg: gp11, asm: "XOR", aux: "Int64"}, // arg0^aux {name: "ANDconst", argLength: 1, reg: regInfo{inputs: []regMask{gp | sp | sb}, outputs: []regMask{gp}}, asm: "ANDCC", aux: "Int64", clobberFlags: true}, // arg0&aux // and-immediate sets CC on PPC, always. + {name: "ANDCCconst", argLength: 1, reg: regInfo{inputs: []regMask{gp | sp | sb}}, asm: "ANDCC", aux: "Int64", typ: "Flags"}, // arg0&aux == 0 // and-immediate sets CC on PPC, always. {name: "MOVBreg", argLength: 1, reg: gp11, asm: "MOVB", typ: "Int64"}, // sign extend int8 to int64 {name: "MOVBZreg", argLength: 1, reg: gp11, asm: "MOVBZ", typ: "Int64"}, // zero extend uint8 to uint64 @@ -256,9 +257,9 @@ func init() { {name: "MOVDaddr", argLength: 1, reg: regInfo{inputs: []regMask{sp | sb}, outputs: []regMask{gp}}, aux: "SymOff", asm: "MOVD", rematerializeable: true}, // arg0 + auxInt + aux.(*gc.Sym), arg0=SP/SB - {name: "MOVDconst", argLength: 0, reg: gp01, aux: "Int64", asm: "MOVD", rematerializeable: true}, // - {name: "FMOVDconst", argLength: 0, reg: fp01, aux: "Float64", asm: "FMOVD", rematerializeable: true}, // - {name: "FMOVSconst", argLength: 0, reg: fp01, aux: "Float32", asm: "FMOVS", rematerializeable: true}, // + {name: "MOVDconst", argLength: 0, reg: gp01, aux: "Int64", asm: "MOVD", typ: "Int64", rematerializeable: true}, // + {name: "FMOVDconst", argLength: 0, reg: fp01, aux: "Float64", asm: "FMOVD", rematerializeable: true}, // + {name: "FMOVSconst", argLength: 0, reg: fp01, aux: "Float32", asm: "FMOVS", rematerializeable: true}, // {name: "FCMPU", argLength: 2, reg: fp2cr, asm: "FCMPU", typ: "Flags"}, {name: "CMP", argLength: 2, reg: gp2cr, asm: "CMP", typ: "Flags"}, // arg0 compare to arg1 diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go index 42f7071a8a..cd897198d4 100644 --- a/src/cmd/compile/internal/ssa/opGen.go +++ b/src/cmd/compile/internal/ssa/opGen.go @@ -1176,6 +1176,7 @@ const ( OpPPC64ORconst OpPPC64XORconst OpPPC64ANDconst + OpPPC64ANDCCconst OpPPC64MOVBreg OpPPC64MOVBZreg OpPPC64MOVHreg @@ -14652,6 +14653,17 @@ var opcodeTable = [...]opInfo{ }, }, }, + { + name: "ANDCCconst", + auxType: auxInt64, + argLen: 1, + asm: ppc64.AANDCC, + reg: regInfo{ + inputs: []inputInfo{ + {0, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29 + }, + }, + }, { name: "MOVBreg", argLen: 1, diff --git a/src/cmd/compile/internal/ssa/rewrite.go b/src/cmd/compile/internal/ssa/rewrite.go index 0a419f6e4e..b3555c1fed 100644 --- a/src/cmd/compile/internal/ssa/rewrite.go +++ b/src/cmd/compile/internal/ssa/rewrite.go @@ -229,11 +229,16 @@ func is16Bit(n int64) bool { return n == int64(int16(n)) } -// is16Bit reports whether n can be represented as an unsigned 16 bit integer. +// isU16Bit reports whether n can be represented as an unsigned 16 bit integer. func isU16Bit(n int64) bool { return n == int64(uint16(n)) } +// isU32Bit reports whether n can be represented as an unsigned 32 bit integer. +func isU32Bit(n int64) bool { + return n == int64(uint32(n)) +} + // is20Bit reports whether n can be represented as a signed 20 bit integer. func is20Bit(n int64) bool { return -(1<<19) <= n && n < (1<<19) diff --git a/src/cmd/compile/internal/ssa/rewritePPC64.go b/src/cmd/compile/internal/ssa/rewritePPC64.go index d898568f02..defda0aa63 100644 --- a/src/cmd/compile/internal/ssa/rewritePPC64.go +++ b/src/cmd/compile/internal/ssa/rewritePPC64.go @@ -342,6 +342,8 @@ func rewriteValuePPC64(v *Value, config *Config) bool { return rewriteValuePPC64_OpPPC64ADD(v, config) case OpPPC64ADDconst: return rewriteValuePPC64_OpPPC64ADDconst(v, config) + case OpPPC64AND: + return rewriteValuePPC64_OpPPC64AND(v, config) case OpPPC64ANDconst: return rewriteValuePPC64_OpPPC64ANDconst(v, config) case OpPPC64CMP: @@ -408,14 +410,28 @@ func rewriteValuePPC64(v *Value, config *Config) bool { return rewriteValuePPC64_OpPPC64MOVHstorezero(v, config) case OpPPC64MOVWZload: return rewriteValuePPC64_OpPPC64MOVWZload(v, config) + case OpPPC64MOVWZreg: + return rewriteValuePPC64_OpPPC64MOVWZreg(v, config) case OpPPC64MOVWload: return rewriteValuePPC64_OpPPC64MOVWload(v, config) + case OpPPC64MOVWreg: + return rewriteValuePPC64_OpPPC64MOVWreg(v, config) case OpPPC64MOVWstore: return rewriteValuePPC64_OpPPC64MOVWstore(v, config) case OpPPC64MOVWstorezero: return rewriteValuePPC64_OpPPC64MOVWstorezero(v, config) + case OpPPC64MaskIfNotCarry: + return rewriteValuePPC64_OpPPC64MaskIfNotCarry(v, config) case OpPPC64NotEqual: return rewriteValuePPC64_OpPPC64NotEqual(v, config) + case OpPPC64OR: + return rewriteValuePPC64_OpPPC64OR(v, config) + case OpPPC64ORN: + return rewriteValuePPC64_OpPPC64ORN(v, config) + case OpPPC64ORconst: + return rewriteValuePPC64_OpPPC64ORconst(v, config) + case OpPPC64SUB: + return rewriteValuePPC64_OpPPC64SUB(v, config) case OpPPC64XOR: return rewriteValuePPC64_OpPPC64XOR(v, config) case OpPPC64XORconst: @@ -4395,40 +4411,6 @@ func rewriteValuePPC64_OpPPC64ADD(v *Value, config *Config) bool { v.AddArg(x) return true } - // match: (ADD (MOVDconst [0]) x) - // cond: - // result: x - for { - v_0 := v.Args[0] - if v_0.Op != OpPPC64MOVDconst { - break - } - if v_0.AuxInt != 0 { - break - } - x := v.Args[1] - v.reset(OpCopy) - v.Type = x.Type - v.AddArg(x) - return true - } - // match: (ADD x (MOVDconst [0])) - // cond: - // result: x - for { - x := v.Args[0] - v_1 := v.Args[1] - if v_1.Op != OpPPC64MOVDconst { - break - } - if v_1.AuxInt != 0 { - break - } - v.reset(OpCopy) - v.Type = x.Type - v.AddArg(x) - return true - } return false } func rewriteValuePPC64_OpPPC64ADDconst(v *Value, config *Config) bool { @@ -4453,6 +4435,19 @@ func rewriteValuePPC64_OpPPC64ADDconst(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: (ADDconst [0] x) + // cond: + // result: x + for { + if v.AuxInt != 0 { + break + } + x := v.Args[0] + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } // match: (ADDconst [c] (MOVDaddr [d] {sym} x)) // cond: // result: (MOVDaddr [c+d] {sym} x) @@ -4471,16 +4466,98 @@ func rewriteValuePPC64_OpPPC64ADDconst(v *Value, config *Config) bool { v.AddArg(x) return true } - // match: (ADDconst [0] x) + return false +} +func rewriteValuePPC64_OpPPC64AND(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (AND (MOVDconst [c]) (MOVDconst [d])) // cond: - // result: x + // result: (MOVDconst [c&d]) for { - if v.AuxInt != 0 { + v_0 := v.Args[0] + if v_0.Op != OpPPC64MOVDconst { + break + } + c := v_0.AuxInt + v_1 := v.Args[1] + if v_1.Op != OpPPC64MOVDconst { break } + d := v_1.AuxInt + v.reset(OpPPC64MOVDconst) + v.AuxInt = c & d + return true + } + // match: (AND x (MOVDconst [c])) + // cond: isU16Bit(c) + // result: (ANDconst [c] x) + for { x := v.Args[0] - v.reset(OpCopy) - v.Type = x.Type + v_1 := v.Args[1] + if v_1.Op != OpPPC64MOVDconst { + break + } + c := v_1.AuxInt + if !(isU16Bit(c)) { + break + } + v.reset(OpPPC64ANDconst) + v.AuxInt = c + v.AddArg(x) + return true + } + // match: (AND (MOVDconst [c]) x) + // cond: isU16Bit(c) + // result: (ANDconst [c] x) + for { + v_0 := v.Args[0] + if v_0.Op != OpPPC64MOVDconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + if !(isU16Bit(c)) { + break + } + v.reset(OpPPC64ANDconst) + v.AuxInt = c + v.AddArg(x) + return true + } + // match: (AND (MOVDconst [c]) x:(MOVBZload _ _)) + // cond: + // result: (ANDconst [c&0xFF] x) + for { + v_0 := v.Args[0] + if v_0.Op != OpPPC64MOVDconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + if x.Op != OpPPC64MOVBZload { + break + } + v.reset(OpPPC64ANDconst) + v.AuxInt = c & 0xFF + v.AddArg(x) + return true + } + // match: (AND x:(MOVBZload _ _) (MOVDconst [c])) + // cond: + // result: (ANDconst [c&0xFF] x) + for { + x := v.Args[0] + if x.Op != OpPPC64MOVBZload { + break + } + v_1 := v.Args[1] + if v_1.Op != OpPPC64MOVDconst { + break + } + c := v_1.AuxInt + v.reset(OpPPC64ANDconst) + v.AuxInt = c & 0xFF v.AddArg(x) return true } @@ -4489,6 +4566,22 @@ func rewriteValuePPC64_OpPPC64ADDconst(v *Value, config *Config) bool { func rewriteValuePPC64_OpPPC64ANDconst(v *Value, config *Config) bool { b := v.Block _ = b + // match: (ANDconst [c] (ANDconst [d] x)) + // cond: + // result: (ANDconst [c&d] x) + for { + c := v.AuxInt + v_0 := v.Args[0] + if v_0.Op != OpPPC64ANDconst { + break + } + d := v_0.AuxInt + x := v_0.Args[0] + v.reset(OpPPC64ANDconst) + v.AuxInt = c & d + v.AddArg(x) + return true + } // match: (ANDconst [-1] x) // cond: // result: x @@ -4513,6 +4606,102 @@ func rewriteValuePPC64_OpPPC64ANDconst(v *Value, config *Config) bool { v.AuxInt = 0 return true } + // match: (ANDconst [c] y:(MOVBZreg _)) + // cond: c&0xFF == 0xFF + // result: y + for { + c := v.AuxInt + y := v.Args[0] + if y.Op != OpPPC64MOVBZreg { + break + } + if !(c&0xFF == 0xFF) { + break + } + v.reset(OpCopy) + v.Type = y.Type + v.AddArg(y) + return true + } + // match: (ANDconst [c] y:(MOVHZreg _)) + // cond: c&0xFFFF == 0xFFFF + // result: y + for { + c := v.AuxInt + y := v.Args[0] + if y.Op != OpPPC64MOVHZreg { + break + } + if !(c&0xFFFF == 0xFFFF) { + break + } + v.reset(OpCopy) + v.Type = y.Type + v.AddArg(y) + return true + } + // match: (ANDconst [c] y:(MOVWZreg _)) + // cond: c&0xFFFFFFFF == 0xFFFFFFFF + // result: y + for { + c := v.AuxInt + y := v.Args[0] + if y.Op != OpPPC64MOVWZreg { + break + } + if !(c&0xFFFFFFFF == 0xFFFFFFFF) { + break + } + v.reset(OpCopy) + v.Type = y.Type + v.AddArg(y) + return true + } + // match: (ANDconst [c] (MOVBZreg x)) + // cond: + // result: (ANDconst [c&0xFF] x) + for { + c := v.AuxInt + v_0 := v.Args[0] + if v_0.Op != OpPPC64MOVBZreg { + break + } + x := v_0.Args[0] + v.reset(OpPPC64ANDconst) + v.AuxInt = c & 0xFF + v.AddArg(x) + return true + } + // match: (ANDconst [c] (MOVHZreg x)) + // cond: + // result: (ANDconst [c&0xFFFF] x) + for { + c := v.AuxInt + v_0 := v.Args[0] + if v_0.Op != OpPPC64MOVHZreg { + break + } + x := v_0.Args[0] + v.reset(OpPPC64ANDconst) + v.AuxInt = c & 0xFFFF + v.AddArg(x) + return true + } + // match: (ANDconst [c] (MOVWZreg x)) + // cond: + // result: (ANDconst [c&0xFFFFFFFF] x) + for { + c := v.AuxInt + v_0 := v.Args[0] + if v_0.Op != OpPPC64MOVWZreg { + break + } + x := v_0.Args[0] + v.reset(OpPPC64ANDconst) + v.AuxInt = c & 0xFFFFFFFF + v.AddArg(x) + return true + } return false } func rewriteValuePPC64_OpPPC64CMP(v *Value, config *Config) bool { @@ -4657,6 +4846,36 @@ func rewriteValuePPC64_OpPPC64CMPUconst(v *Value, config *Config) bool { func rewriteValuePPC64_OpPPC64CMPW(v *Value, config *Config) bool { b := v.Block _ = b + // match: (CMPW x (MOVWreg y)) + // cond: + // result: (CMPW x y) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpPPC64MOVWreg { + break + } + y := v_1.Args[0] + v.reset(OpPPC64CMPW) + v.AddArg(x) + v.AddArg(y) + return true + } + // match: (CMPW (MOVWreg x) y) + // cond: + // result: (CMPW x y) + for { + v_0 := v.Args[0] + if v_0.Op != OpPPC64MOVWreg { + break + } + x := v_0.Args[0] + y := v.Args[1] + v.reset(OpPPC64CMPW) + v.AddArg(x) + v.AddArg(y) + return true + } // match: (CMPW x (MOVDconst [c])) // cond: is16Bit(c) // result: (CMPWconst x [c]) @@ -4700,6 +4919,36 @@ func rewriteValuePPC64_OpPPC64CMPW(v *Value, config *Config) bool { func rewriteValuePPC64_OpPPC64CMPWU(v *Value, config *Config) bool { b := v.Block _ = b + // match: (CMPWU x (MOVWZreg y)) + // cond: + // result: (CMPWU x y) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpPPC64MOVWZreg { + break + } + y := v_1.Args[0] + v.reset(OpPPC64CMPWU) + v.AddArg(x) + v.AddArg(y) + return true + } + // match: (CMPWU (MOVWZreg x) y) + // cond: + // result: (CMPWU x y) + for { + v_0 := v.Args[0] + if v_0.Op != OpPPC64MOVWZreg { + break + } + x := v_0.Args[0] + y := v.Args[1] + v.reset(OpPPC64CMPWU) + v.AddArg(x) + v.AddArg(y) + return true + } // match: (CMPWU x (MOVDconst [c])) // cond: isU16Bit(c) // result: (CMPWUconst x [c]) @@ -5440,30 +5689,73 @@ func rewriteValuePPC64_OpPPC64MOVBZload(v *Value, config *Config) bool { func rewriteValuePPC64_OpPPC64MOVBZreg(v *Value, config *Config) bool { b := v.Block _ = b - // match: (MOVBZreg x:(MOVBZload _ _)) - // cond: - // result: x + // match: (MOVBZreg y:(ANDconst [c] _)) + // cond: uint64(c) <= 0xFF + // result: y for { - x := v.Args[0] - if x.Op != OpPPC64MOVBZload { + y := v.Args[0] + if y.Op != OpPPC64ANDconst { + break + } + c := y.AuxInt + if !(uint64(c) <= 0xFF) { break } v.reset(OpCopy) - v.Type = x.Type - v.AddArg(x) + v.Type = y.Type + v.AddArg(y) return true } - // match: (MOVBZreg (MOVDconst [c])) + // match: (MOVBZreg y:(MOVBZreg _)) // cond: - // result: (MOVDconst [int64(uint8(c))]) + // result: y for { - v_0 := v.Args[0] - if v_0.Op != OpPPC64MOVDconst { + y := v.Args[0] + if y.Op != OpPPC64MOVBZreg { break } - c := v_0.AuxInt - v.reset(OpPPC64MOVDconst) - v.AuxInt = int64(uint8(c)) + v.reset(OpCopy) + v.Type = y.Type + v.AddArg(y) + return true + } + // match: (MOVBZreg (MOVBreg x)) + // cond: + // result: (MOVBZreg x) + for { + v_0 := v.Args[0] + if v_0.Op != OpPPC64MOVBreg { + break + } + x := v_0.Args[0] + v.reset(OpPPC64MOVBZreg) + v.AddArg(x) + return true + } + // match: (MOVBZreg x:(MOVBZload _ _)) + // cond: + // result: x + for { + x := v.Args[0] + if x.Op != OpPPC64MOVBZload { + break + } + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } + // match: (MOVBZreg (MOVDconst [c])) + // cond: + // result: (MOVDconst [int64(uint8(c))]) + for { + v_0 := v.Args[0] + if v_0.Op != OpPPC64MOVDconst { + break + } + c := v_0.AuxInt + v.reset(OpPPC64MOVDconst) + v.AuxInt = int64(uint8(c)) return true } return false @@ -5471,6 +5763,49 @@ func rewriteValuePPC64_OpPPC64MOVBZreg(v *Value, config *Config) bool { func rewriteValuePPC64_OpPPC64MOVBreg(v *Value, config *Config) bool { b := v.Block _ = b + // match: (MOVBreg y:(ANDconst [c] _)) + // cond: uint64(c) <= 0x7F + // result: y + for { + y := v.Args[0] + if y.Op != OpPPC64ANDconst { + break + } + c := y.AuxInt + if !(uint64(c) <= 0x7F) { + break + } + v.reset(OpCopy) + v.Type = y.Type + v.AddArg(y) + return true + } + // match: (MOVBreg y:(MOVBreg _)) + // cond: + // result: y + for { + y := v.Args[0] + if y.Op != OpPPC64MOVBreg { + break + } + v.reset(OpCopy) + v.Type = y.Type + v.AddArg(y) + return true + } + // match: (MOVBreg (MOVBZreg x)) + // cond: + // result: (MOVBreg x) + for { + v_0 := v.Args[0] + if v_0.Op != OpPPC64MOVBZreg { + break + } + x := v_0.Args[0] + v.reset(OpPPC64MOVBreg) + v.AddArg(x) + return true + } // match: (MOVBreg (MOVDconst [c])) // cond: // result: (MOVDconst [int64(int8(c))]) @@ -5897,6 +6232,62 @@ func rewriteValuePPC64_OpPPC64MOVHZload(v *Value, config *Config) bool { func rewriteValuePPC64_OpPPC64MOVHZreg(v *Value, config *Config) bool { b := v.Block _ = b + // match: (MOVHZreg y:(ANDconst [c] _)) + // cond: uint64(c) <= 0xFFFF + // result: y + for { + y := v.Args[0] + if y.Op != OpPPC64ANDconst { + break + } + c := y.AuxInt + if !(uint64(c) <= 0xFFFF) { + break + } + v.reset(OpCopy) + v.Type = y.Type + v.AddArg(y) + return true + } + // match: (MOVHZreg y:(MOVHZreg _)) + // cond: + // result: y + for { + y := v.Args[0] + if y.Op != OpPPC64MOVHZreg { + break + } + v.reset(OpCopy) + v.Type = y.Type + v.AddArg(y) + return true + } + // match: (MOVHZreg y:(MOVBZreg _)) + // cond: + // result: y + for { + y := v.Args[0] + if y.Op != OpPPC64MOVBZreg { + break + } + v.reset(OpCopy) + v.Type = y.Type + v.AddArg(y) + return true + } + // match: (MOVHZreg y:(MOVHreg x)) + // cond: + // result: (MOVHZreg x) + for { + y := v.Args[0] + if y.Op != OpPPC64MOVHreg { + break + } + x := y.Args[0] + v.reset(OpPPC64MOVHZreg) + v.AddArg(x) + return true + } // match: (MOVHZreg x:(MOVHZload _ _)) // cond: // result: x @@ -5980,6 +6371,62 @@ func rewriteValuePPC64_OpPPC64MOVHload(v *Value, config *Config) bool { func rewriteValuePPC64_OpPPC64MOVHreg(v *Value, config *Config) bool { b := v.Block _ = b + // match: (MOVHreg y:(ANDconst [c] _)) + // cond: uint64(c) <= 0x7FFF + // result: y + for { + y := v.Args[0] + if y.Op != OpPPC64ANDconst { + break + } + c := y.AuxInt + if !(uint64(c) <= 0x7FFF) { + break + } + v.reset(OpCopy) + v.Type = y.Type + v.AddArg(y) + return true + } + // match: (MOVHreg y:(MOVHreg _)) + // cond: + // result: y + for { + y := v.Args[0] + if y.Op != OpPPC64MOVHreg { + break + } + v.reset(OpCopy) + v.Type = y.Type + v.AddArg(y) + return true + } + // match: (MOVHreg y:(MOVBreg _)) + // cond: + // result: y + for { + y := v.Args[0] + if y.Op != OpPPC64MOVBreg { + break + } + v.reset(OpCopy) + v.Type = y.Type + v.AddArg(y) + return true + } + // match: (MOVHreg y:(MOVHZreg x)) + // cond: + // result: (MOVHreg x) + for { + y := v.Args[0] + if y.Op != OpPPC64MOVHZreg { + break + } + x := y.Args[0] + v.reset(OpPPC64MOVHreg) + v.AddArg(x) + return true + } // match: (MOVHreg x:(MOVHload _ _)) // cond: // result: x @@ -6233,6 +6680,101 @@ func rewriteValuePPC64_OpPPC64MOVWZload(v *Value, config *Config) bool { } return false } +func rewriteValuePPC64_OpPPC64MOVWZreg(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (MOVWZreg y:(ANDconst [c] _)) + // cond: uint64(c) <= 0xFFFFFFFF + // result: y + for { + y := v.Args[0] + if y.Op != OpPPC64ANDconst { + break + } + c := y.AuxInt + if !(uint64(c) <= 0xFFFFFFFF) { + break + } + v.reset(OpCopy) + v.Type = y.Type + v.AddArg(y) + return true + } + // match: (MOVWZreg y:(AND (MOVDconst [c]) _)) + // cond: uint64(c) <= 0xFFFFFFFF + // result: y + for { + y := v.Args[0] + if y.Op != OpPPC64AND { + break + } + y_0 := y.Args[0] + if y_0.Op != OpPPC64MOVDconst { + break + } + c := y_0.AuxInt + if !(uint64(c) <= 0xFFFFFFFF) { + break + } + v.reset(OpCopy) + v.Type = y.Type + v.AddArg(y) + return true + } + // match: (MOVWZreg y:(MOVWZreg _)) + // cond: + // result: y + for { + y := v.Args[0] + if y.Op != OpPPC64MOVWZreg { + break + } + v.reset(OpCopy) + v.Type = y.Type + v.AddArg(y) + return true + } + // match: (MOVWZreg y:(MOVHZreg _)) + // cond: + // result: y + for { + y := v.Args[0] + if y.Op != OpPPC64MOVHZreg { + break + } + v.reset(OpCopy) + v.Type = y.Type + v.AddArg(y) + return true + } + // match: (MOVWZreg y:(MOVBZreg _)) + // cond: + // result: y + for { + y := v.Args[0] + if y.Op != OpPPC64MOVBZreg { + break + } + v.reset(OpCopy) + v.Type = y.Type + v.AddArg(y) + return true + } + // match: (MOVWZreg y:(MOVWreg x)) + // cond: + // result: (MOVWZreg x) + for { + y := v.Args[0] + if y.Op != OpPPC64MOVWreg { + break + } + x := y.Args[0] + v.reset(OpPPC64MOVWZreg) + v.AddArg(x) + return true + } + return false +} func rewriteValuePPC64_OpPPC64MOVWload(v *Value, config *Config) bool { b := v.Block _ = b @@ -6285,6 +6827,101 @@ func rewriteValuePPC64_OpPPC64MOVWload(v *Value, config *Config) bool { } return false } +func rewriteValuePPC64_OpPPC64MOVWreg(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (MOVWreg y:(ANDconst [c] _)) + // cond: uint64(c) <= 0xFFFF + // result: y + for { + y := v.Args[0] + if y.Op != OpPPC64ANDconst { + break + } + c := y.AuxInt + if !(uint64(c) <= 0xFFFF) { + break + } + v.reset(OpCopy) + v.Type = y.Type + v.AddArg(y) + return true + } + // match: (MOVWreg y:(AND (MOVDconst [c]) _)) + // cond: uint64(c) <= 0x7FFFFFFF + // result: y + for { + y := v.Args[0] + if y.Op != OpPPC64AND { + break + } + y_0 := y.Args[0] + if y_0.Op != OpPPC64MOVDconst { + break + } + c := y_0.AuxInt + if !(uint64(c) <= 0x7FFFFFFF) { + break + } + v.reset(OpCopy) + v.Type = y.Type + v.AddArg(y) + return true + } + // match: (MOVWreg y:(MOVWreg _)) + // cond: + // result: y + for { + y := v.Args[0] + if y.Op != OpPPC64MOVWreg { + break + } + v.reset(OpCopy) + v.Type = y.Type + v.AddArg(y) + return true + } + // match: (MOVWreg y:(MOVHreg _)) + // cond: + // result: y + for { + y := v.Args[0] + if y.Op != OpPPC64MOVHreg { + break + } + v.reset(OpCopy) + v.Type = y.Type + v.AddArg(y) + return true + } + // match: (MOVWreg y:(MOVBreg _)) + // cond: + // result: y + for { + y := v.Args[0] + if y.Op != OpPPC64MOVBreg { + break + } + v.reset(OpCopy) + v.Type = y.Type + v.AddArg(y) + return true + } + // match: (MOVWreg y:(MOVWZreg x)) + // cond: + // result: (MOVWreg x) + for { + y := v.Args[0] + if y.Op != OpPPC64MOVWZreg { + break + } + x := y.Args[0] + v.reset(OpPPC64MOVWreg) + v.AddArg(x) + return true + } + return false +} func rewriteValuePPC64_OpPPC64MOVWstore(v *Value, config *Config) bool { b := v.Block _ = b @@ -6339,26 +6976,68 @@ func rewriteValuePPC64_OpPPC64MOVWstore(v *Value, config *Config) bool { v.AddArg(mem) return true } - // match: (MOVWstore [off] {sym} ptr (MOVDconst [c]) mem) - // cond: c == 0 - // result: (MOVWstorezero [off] {sym} ptr mem) + // match: (MOVWstore [off] {sym} ptr (MOVDconst [c]) mem) + // cond: c == 0 + // result: (MOVWstorezero [off] {sym} ptr mem) + for { + off := v.AuxInt + sym := v.Aux + ptr := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpPPC64MOVDconst { + break + } + c := v_1.AuxInt + mem := v.Args[2] + if !(c == 0) { + break + } + v.reset(OpPPC64MOVWstorezero) + v.AuxInt = off + v.Aux = sym + v.AddArg(ptr) + v.AddArg(mem) + return true + } + // match: (MOVWstore [off] {sym} ptr (MOVWreg x) mem) + // cond: + // result: (MOVWstore [off] {sym} ptr x mem) + for { + off := v.AuxInt + sym := v.Aux + ptr := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpPPC64MOVWreg { + break + } + x := v_1.Args[0] + mem := v.Args[2] + v.reset(OpPPC64MOVWstore) + v.AuxInt = off + v.Aux = sym + v.AddArg(ptr) + v.AddArg(x) + v.AddArg(mem) + return true + } + // match: (MOVWstore [off] {sym} ptr (MOVWZreg x) mem) + // cond: + // result: (MOVWstore [off] {sym} ptr x mem) for { off := v.AuxInt sym := v.Aux ptr := v.Args[0] v_1 := v.Args[1] - if v_1.Op != OpPPC64MOVDconst { + if v_1.Op != OpPPC64MOVWZreg { break } - c := v_1.AuxInt + x := v_1.Args[0] mem := v.Args[2] - if !(c == 0) { - break - } - v.reset(OpPPC64MOVWstorezero) + v.reset(OpPPC64MOVWstore) v.AuxInt = off v.Aux = sym v.AddArg(ptr) + v.AddArg(x) v.AddArg(mem) return true } @@ -6416,6 +7095,32 @@ func rewriteValuePPC64_OpPPC64MOVWstorezero(v *Value, config *Config) bool { } return false } +func rewriteValuePPC64_OpPPC64MaskIfNotCarry(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (MaskIfNotCarry (ADDconstForCarry [c] (ANDconst [d] _))) + // cond: c < 0 && d > 0 && c + d < 0 + // result: (MOVDconst [-1]) + for { + v_0 := v.Args[0] + if v_0.Op != OpPPC64ADDconstForCarry { + break + } + c := v_0.AuxInt + v_0_0 := v_0.Args[0] + if v_0_0.Op != OpPPC64ANDconst { + break + } + d := v_0_0.AuxInt + if !(c < 0 && d > 0 && c+d < 0) { + break + } + v.reset(OpPPC64MOVDconst) + v.AuxInt = -1 + return true + } + return false +} func rewriteValuePPC64_OpPPC64NotEqual(v *Value, config *Config) bool { b := v.Block _ = b @@ -6470,27 +7175,69 @@ func rewriteValuePPC64_OpPPC64NotEqual(v *Value, config *Config) bool { } return false } -func rewriteValuePPC64_OpPPC64XOR(v *Value, config *Config) bool { +func rewriteValuePPC64_OpPPC64OR(v *Value, config *Config) bool { b := v.Block _ = b - // match: (XOR (MOVDconst [0]) x) + // match: (OR (MOVDconst [c]) (MOVDconst [d])) // cond: - // result: x + // result: (MOVDconst [c|d]) for { v_0 := v.Args[0] if v_0.Op != OpPPC64MOVDconst { break } - if v_0.AuxInt != 0 { + c := v_0.AuxInt + v_1 := v.Args[1] + if v_1.Op != OpPPC64MOVDconst { + break + } + d := v_1.AuxInt + v.reset(OpPPC64MOVDconst) + v.AuxInt = c | d + return true + } + // match: (OR x (MOVDconst [c])) + // cond: isU32Bit(c) + // result: (ORconst [c] x) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpPPC64MOVDconst { + break + } + c := v_1.AuxInt + if !(isU32Bit(c)) { + break + } + v.reset(OpPPC64ORconst) + v.AuxInt = c + v.AddArg(x) + return true + } + // match: (OR (MOVDconst [c]) x) + // cond: isU32Bit(c) + // result: (ORconst [c] x) + for { + v_0 := v.Args[0] + if v_0.Op != OpPPC64MOVDconst { break } + c := v_0.AuxInt x := v.Args[1] - v.reset(OpCopy) - v.Type = x.Type + if !(isU32Bit(c)) { + break + } + v.reset(OpPPC64ORconst) + v.AuxInt = c v.AddArg(x) return true } - // match: (XOR x (MOVDconst [0])) + return false +} +func rewriteValuePPC64_OpPPC64ORN(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (ORN x (MOVDconst [-1])) // cond: // result: x for { @@ -6499,9 +7246,54 @@ func rewriteValuePPC64_OpPPC64XOR(v *Value, config *Config) bool { if v_1.Op != OpPPC64MOVDconst { break } - if v_1.AuxInt != 0 { + if v_1.AuxInt != -1 { + break + } + v.reset(OpCopy) + v.Type = x.Type + v.AddArg(x) + return true + } + return false +} +func rewriteValuePPC64_OpPPC64ORconst(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (ORconst [c] (ORconst [d] x)) + // cond: + // result: (ORconst [c|d] x) + for { + c := v.AuxInt + v_0 := v.Args[0] + if v_0.Op != OpPPC64ORconst { + break + } + d := v_0.AuxInt + x := v_0.Args[0] + v.reset(OpPPC64ORconst) + v.AuxInt = c | d + v.AddArg(x) + return true + } + // match: (ORconst [-1] _) + // cond: + // result: (MOVDconst [-1]) + for { + if v.AuxInt != -1 { + break + } + v.reset(OpPPC64MOVDconst) + v.AuxInt = -1 + return true + } + // match: (ORconst [0] x) + // cond: + // result: x + for { + if v.AuxInt != 0 { break } + x := v.Args[0] v.reset(OpCopy) v.Type = x.Type v.AddArg(x) @@ -6509,9 +7301,107 @@ func rewriteValuePPC64_OpPPC64XOR(v *Value, config *Config) bool { } return false } +func rewriteValuePPC64_OpPPC64SUB(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (SUB x (MOVDconst [c])) + // cond: is32Bit(-c) + // result: (ADDconst [-c] x) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpPPC64MOVDconst { + break + } + c := v_1.AuxInt + if !(is32Bit(-c)) { + break + } + v.reset(OpPPC64ADDconst) + v.AuxInt = -c + v.AddArg(x) + return true + } + return false +} +func rewriteValuePPC64_OpPPC64XOR(v *Value, config *Config) bool { + b := v.Block + _ = b + // match: (XOR (MOVDconst [c]) (MOVDconst [d])) + // cond: + // result: (MOVDconst [c^d]) + for { + v_0 := v.Args[0] + if v_0.Op != OpPPC64MOVDconst { + break + } + c := v_0.AuxInt + v_1 := v.Args[1] + if v_1.Op != OpPPC64MOVDconst { + break + } + d := v_1.AuxInt + v.reset(OpPPC64MOVDconst) + v.AuxInt = c ^ d + return true + } + // match: (XOR x (MOVDconst [c])) + // cond: isU32Bit(c) + // result: (XORconst [c] x) + for { + x := v.Args[0] + v_1 := v.Args[1] + if v_1.Op != OpPPC64MOVDconst { + break + } + c := v_1.AuxInt + if !(isU32Bit(c)) { + break + } + v.reset(OpPPC64XORconst) + v.AuxInt = c + v.AddArg(x) + return true + } + // match: (XOR (MOVDconst [c]) x) + // cond: isU32Bit(c) + // result: (XORconst [c] x) + for { + v_0 := v.Args[0] + if v_0.Op != OpPPC64MOVDconst { + break + } + c := v_0.AuxInt + x := v.Args[1] + if !(isU32Bit(c)) { + break + } + v.reset(OpPPC64XORconst) + v.AuxInt = c + v.AddArg(x) + return true + } + return false +} func rewriteValuePPC64_OpPPC64XORconst(v *Value, config *Config) bool { b := v.Block _ = b + // match: (XORconst [c] (XORconst [d] x)) + // cond: + // result: (XORconst [c^d] x) + for { + c := v.AuxInt + v_0 := v.Args[0] + if v_0.Op != OpPPC64XORconst { + break + } + d := v_0.AuxInt + x := v_0.Args[0] + v.reset(OpPPC64XORconst) + v.AuxInt = c ^ d + v.AddArg(x) + return true + } // match: (XORconst [0] x) // cond: // result: x @@ -8967,6 +9857,62 @@ func rewriteValuePPC64_OpZeroExt8to64(v *Value, config *Config) bool { func rewriteBlockPPC64(b *Block, config *Config) bool { switch b.Kind { case BlockPPC64EQ: + // match: (EQ (CMPconst [0] (ANDconst [c] x)) yes no) + // cond: + // result: (EQ (ANDCCconst [c] x) yes no) + for { + v := b.Control + if v.Op != OpPPC64CMPconst { + break + } + if v.AuxInt != 0 { + break + } + v_0 := v.Args[0] + if v_0.Op != OpPPC64ANDconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + yes := b.Succs[0] + no := b.Succs[1] + b.Kind = BlockPPC64EQ + v0 := b.NewValue0(v.Line, OpPPC64ANDCCconst, TypeFlags) + v0.AuxInt = c + v0.AddArg(x) + b.SetControl(v0) + _ = yes + _ = no + return true + } + // match: (EQ (CMPWconst [0] (ANDconst [c] x)) yes no) + // cond: + // result: (EQ (ANDCCconst [c] x) yes no) + for { + v := b.Control + if v.Op != OpPPC64CMPWconst { + break + } + if v.AuxInt != 0 { + break + } + v_0 := v.Args[0] + if v_0.Op != OpPPC64ANDconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + yes := b.Succs[0] + no := b.Succs[1] + b.Kind = BlockPPC64EQ + v0 := b.NewValue0(v.Line, OpPPC64ANDCCconst, TypeFlags) + v0.AuxInt = c + v0.AddArg(x) + b.SetControl(v0) + _ = yes + _ = no + return true + } // match: (EQ (FlagEQ) yes no) // cond: // result: (First nil yes no) @@ -9638,6 +10584,62 @@ func rewriteBlockPPC64(b *Block, config *Config) bool { _ = no return true } + // match: (NE (CMPconst [0] (ANDconst [c] x)) yes no) + // cond: + // result: (NE (ANDCCconst [c] x) yes no) + for { + v := b.Control + if v.Op != OpPPC64CMPconst { + break + } + if v.AuxInt != 0 { + break + } + v_0 := v.Args[0] + if v_0.Op != OpPPC64ANDconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + yes := b.Succs[0] + no := b.Succs[1] + b.Kind = BlockPPC64NE + v0 := b.NewValue0(v.Line, OpPPC64ANDCCconst, TypeFlags) + v0.AuxInt = c + v0.AddArg(x) + b.SetControl(v0) + _ = yes + _ = no + return true + } + // match: (NE (CMPWconst [0] (ANDconst [c] x)) yes no) + // cond: + // result: (NE (ANDCCconst [c] x) yes no) + for { + v := b.Control + if v.Op != OpPPC64CMPWconst { + break + } + if v.AuxInt != 0 { + break + } + v_0 := v.Args[0] + if v_0.Op != OpPPC64ANDconst { + break + } + c := v_0.AuxInt + x := v_0.Args[0] + yes := b.Succs[0] + no := b.Succs[1] + b.Kind = BlockPPC64NE + v0 := b.NewValue0(v.Line, OpPPC64ANDCCconst, TypeFlags) + v0.AuxInt = c + v0.AddArg(x) + b.SetControl(v0) + _ = yes + _ = no + return true + } // match: (NE (FlagEQ) yes no) // cond: // result: (First nil no yes)