1
0
mirror of https://github.com/golang/go synced 2024-11-23 01:40:03 -07:00

cmd/compile: use ANDCC, ORCC, XORCC to avoid CMP on ppc64x

This change makes use of the cc versions of the AND, OR, XOR
instructions, omitting the need for a CMP instruction.

In many test programs and in the go binary, this reduces the
size of 20-30 functions by at least 1 instruction, many in
runtime.

Testcase added to test/codegen/comparisons.go

Change-Id: I6cc1ca8b80b065d7390749c625bc9784b0039adb
Reviewed-on: https://go-review.googlesource.com/c/143059
Reviewed-by: Carlos Eduardo Seo <cseo@linux.vnet.ibm.com>
Reviewed-by: Michael Munday <mike.munday@ibm.com>
Run-TryBot: Lynn Boger <laboger@linux.vnet.ibm.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Lynn Boger 2018-10-10 13:47:18 -04:00
parent 410d63dbe9
commit 4ae49b5921
6 changed files with 932 additions and 19 deletions

View File

@ -569,7 +569,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
ssa.OpPPC64ROTL, ssa.OpPPC64ROTLW,
ssa.OpPPC64MULHD, ssa.OpPPC64MULHW, ssa.OpPPC64MULHDU, ssa.OpPPC64MULHWU,
ssa.OpPPC64FMUL, ssa.OpPPC64FMULS, ssa.OpPPC64FDIV, ssa.OpPPC64FDIVS, ssa.OpPPC64FCPSGN,
ssa.OpPPC64AND, ssa.OpPPC64OR, ssa.OpPPC64ANDN, ssa.OpPPC64ORN, ssa.OpPPC64NOR, ssa.OpPPC64XOR, ssa.OpPPC64EQV:
ssa.OpPPC64AND, ssa.OpPPC64ANDCC, ssa.OpPPC64OR, ssa.OpPPC64ORCC, ssa.OpPPC64ANDN, ssa.OpPPC64ORN, ssa.OpPPC64NOR, ssa.OpPPC64XOR, ssa.OpPPC64XORCC, ssa.OpPPC64EQV:
r := v.Reg()
r1 := v.Args[0].Reg()
r2 := v.Args[1].Reg()

View File

@ -518,6 +518,13 @@
(LessEqual (InvertFlags x)) -> (GreaterEqual x)
(GreaterEqual (InvertFlags x)) -> (LessEqual x)
// Elide compares of bit tests // TODO need to make both CC and result of ANDCC available.
((EQ|NE|LT|LE|GT|GE) (CMPconst [0] (ANDconst [c] x)) yes no) -> ((EQ|NE|LT|LE|GT|GE) (ANDCCconst [c] x) yes no)
((EQ|NE|LT|LE|GT|GE) (CMPWconst [0] (ANDconst [c] x)) yes no) -> ((EQ|NE|LT|LE|GT|GE) (ANDCCconst [c] x) yes no)
((EQ|NE|LT|LE|GT|GE) (CMPconst [0] z:(AND x y)) yes no) && z.Uses == 1 -> ((EQ|NE|LT|LE|GT|GE) (ANDCC x y) yes no)
((EQ|NE|LT|LE|GT|GE) (CMPconst [0] z:(OR x y)) yes no) && z.Uses == 1 -> ((EQ|NE|LT|LE|GT|GE) (ORCC x y) yes no)
((EQ|NE|LT|LE|GT|GE) (CMPconst [0] z:(XOR x y)) yes no) && z.Uses == 1 -> ((EQ|NE|LT|LE|GT|GE) (XORCC x y) yes no)
// Lowering loads
(Load <t> ptr mem) && (is64BitInt(t) || isPtr(t)) -> (MOVDload ptr mem)
(Load <t> ptr mem) && is32BitInt(t) && isSigned(t) -> (MOVWload ptr mem)

View File

@ -241,24 +241,27 @@ func init() {
{name: "MFVSRD", argLength: 1, reg: fpgp, asm: "MFVSRD", typ: "Int64"}, // move 64 bits of F register into G register
{name: "MTVSRD", argLength: 1, reg: gpfp, asm: "MTVSRD", typ: "Float64"}, // move 64 bits of G register into F register
{name: "AND", argLength: 2, reg: gp21, asm: "AND", commutative: true}, // arg0&arg1
{name: "ANDN", argLength: 2, reg: gp21, asm: "ANDN"}, // arg0&^arg1
{name: "OR", argLength: 2, reg: gp21, asm: "OR", commutative: true}, // arg0|arg1
{name: "ORN", argLength: 2, reg: gp21, asm: "ORN"}, // arg0|^arg1
{name: "NOR", argLength: 2, reg: gp21, asm: "NOR", commutative: true}, // ^(arg0|arg1)
{name: "XOR", argLength: 2, reg: gp21, asm: "XOR", typ: "Int64", commutative: true}, // arg0^arg1
{name: "EQV", argLength: 2, reg: gp21, asm: "EQV", typ: "Int64", commutative: true}, // arg0^^arg1
{name: "NEG", argLength: 1, reg: gp11, asm: "NEG"}, // -arg0 (integer)
{name: "FNEG", argLength: 1, reg: fp11, asm: "FNEG"}, // -arg0 (floating point)
{name: "FSQRT", argLength: 1, reg: fp11, asm: "FSQRT"}, // sqrt(arg0) (floating point)
{name: "FSQRTS", argLength: 1, reg: fp11, asm: "FSQRTS"}, // sqrt(arg0) (floating point, single precision)
{name: "FFLOOR", argLength: 1, reg: fp11, asm: "FRIM"}, // floor(arg0), float64
{name: "FCEIL", argLength: 1, reg: fp11, asm: "FRIP"}, // ceil(arg0), float64
{name: "FTRUNC", argLength: 1, reg: fp11, asm: "FRIZ"}, // trunc(arg0), float64
{name: "FROUND", argLength: 1, reg: fp11, asm: "FRIN"}, // round(arg0), float64
{name: "FABS", argLength: 1, reg: fp11, asm: "FABS"}, // abs(arg0), float64
{name: "FNABS", argLength: 1, reg: fp11, asm: "FNABS"}, // -abs(arg0), float64
{name: "FCPSGN", argLength: 2, reg: fp21, asm: "FCPSGN"}, // copysign arg0 -> arg1, float64
{name: "AND", argLength: 2, reg: gp21, asm: "AND", commutative: true}, // arg0&arg1
{name: "ANDN", argLength: 2, reg: gp21, asm: "ANDN"}, // arg0&^arg1
{name: "ANDCC", argLength: 2, reg: gp21, asm: "ANDCC", commutative: true, typ: "Flags"}, // arg0&arg1 sets CC
{name: "OR", argLength: 2, reg: gp21, asm: "OR", commutative: true}, // arg0|arg1
{name: "ORN", argLength: 2, reg: gp21, asm: "ORN"}, // arg0|^arg1
{name: "ORCC", argLength: 2, reg: gp21, asm: "ORCC", commutative: true, typ: "Flags"}, // arg0|arg1 sets CC
{name: "NOR", argLength: 2, reg: gp21, asm: "NOR", commutative: true}, // ^(arg0|arg1)
{name: "XOR", argLength: 2, reg: gp21, asm: "XOR", typ: "Int64", commutative: true}, // arg0^arg1
{name: "XORCC", argLength: 2, reg: gp21, asm: "XORCC", commutative: true, typ: "Flags"}, // arg0^arg1 sets CC
{name: "EQV", argLength: 2, reg: gp21, asm: "EQV", typ: "Int64", commutative: true}, // arg0^^arg1
{name: "NEG", argLength: 1, reg: gp11, asm: "NEG"}, // -arg0 (integer)
{name: "FNEG", argLength: 1, reg: fp11, asm: "FNEG"}, // -arg0 (floating point)
{name: "FSQRT", argLength: 1, reg: fp11, asm: "FSQRT"}, // sqrt(arg0) (floating point)
{name: "FSQRTS", argLength: 1, reg: fp11, asm: "FSQRTS"}, // sqrt(arg0) (floating point, single precision)
{name: "FFLOOR", argLength: 1, reg: fp11, asm: "FRIM"}, // floor(arg0), float64
{name: "FCEIL", argLength: 1, reg: fp11, asm: "FRIP"}, // ceil(arg0), float64
{name: "FTRUNC", argLength: 1, reg: fp11, asm: "FRIZ"}, // trunc(arg0), float64
{name: "FROUND", argLength: 1, reg: fp11, asm: "FRIN"}, // round(arg0), float64
{name: "FABS", argLength: 1, reg: fp11, asm: "FABS"}, // abs(arg0), float64
{name: "FNABS", argLength: 1, reg: fp11, asm: "FNABS"}, // -abs(arg0), float64
{name: "FCPSGN", argLength: 2, reg: fp21, asm: "FCPSGN"}, // copysign arg0 -> arg1, float64
{name: "ORconst", argLength: 1, reg: gp11, asm: "OR", aux: "Int64"}, // arg0|aux
{name: "XORconst", argLength: 1, reg: gp11, asm: "XOR", aux: "Int64"}, // arg0^aux

View File

@ -1663,10 +1663,13 @@ const (
OpPPC64MTVSRD
OpPPC64AND
OpPPC64ANDN
OpPPC64ANDCC
OpPPC64OR
OpPPC64ORN
OpPPC64ORCC
OpPPC64NOR
OpPPC64XOR
OpPPC64XORCC
OpPPC64EQV
OpPPC64NEG
OpPPC64FNEG
@ -22202,6 +22205,21 @@ var opcodeTable = [...]opInfo{
},
},
},
{
name: "ANDCC",
argLen: 2,
commutative: true,
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
{1, 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
},
outputs: []outputInfo{
{0, 1073733624}, // 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: "OR",
argLen: 2,
@ -22231,6 +22249,21 @@ var opcodeTable = [...]opInfo{
},
},
},
{
name: "ORCC",
argLen: 2,
commutative: true,
asm: ppc64.AORCC,
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
{1, 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
},
outputs: []outputInfo{
{0, 1073733624}, // 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: "NOR",
argLen: 2,
@ -22261,6 +22294,21 @@ var opcodeTable = [...]opInfo{
},
},
},
{
name: "XORCC",
argLen: 2,
commutative: true,
asm: ppc64.AXORCC,
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
{1, 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
},
outputs: []outputInfo{
{0, 1073733624}, // 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: "EQV",
argLen: 2,

View File

@ -30996,6 +30996,143 @@ func rewriteBlockPPC64(b *Block) bool {
b.Aux = nil
return true
}
// 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]
b.Kind = BlockPPC64EQ
v0 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.TypeFlags)
v0.AuxInt = c
v0.AddArg(x)
b.SetControl(v0)
b.Aux = nil
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]
b.Kind = BlockPPC64EQ
v0 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.TypeFlags)
v0.AuxInt = c
v0.AddArg(x)
b.SetControl(v0)
b.Aux = nil
return true
}
// match: (EQ (CMPconst [0] z:(AND x y)) yes no)
// cond: z.Uses == 1
// result: (EQ (ANDCC x y) yes no)
for {
v := b.Control
if v.Op != OpPPC64CMPconst {
break
}
if v.AuxInt != 0 {
break
}
z := v.Args[0]
if z.Op != OpPPC64AND {
break
}
_ = z.Args[1]
x := z.Args[0]
y := z.Args[1]
if !(z.Uses == 1) {
break
}
b.Kind = BlockPPC64EQ
v0 := b.NewValue0(v.Pos, OpPPC64ANDCC, types.TypeFlags)
v0.AddArg(x)
v0.AddArg(y)
b.SetControl(v0)
b.Aux = nil
return true
}
// match: (EQ (CMPconst [0] z:(OR x y)) yes no)
// cond: z.Uses == 1
// result: (EQ (ORCC x y) yes no)
for {
v := b.Control
if v.Op != OpPPC64CMPconst {
break
}
if v.AuxInt != 0 {
break
}
z := v.Args[0]
if z.Op != OpPPC64OR {
break
}
_ = z.Args[1]
x := z.Args[0]
y := z.Args[1]
if !(z.Uses == 1) {
break
}
b.Kind = BlockPPC64EQ
v0 := b.NewValue0(v.Pos, OpPPC64ORCC, types.TypeFlags)
v0.AddArg(x)
v0.AddArg(y)
b.SetControl(v0)
b.Aux = nil
return true
}
// match: (EQ (CMPconst [0] z:(XOR x y)) yes no)
// cond: z.Uses == 1
// result: (EQ (XORCC x y) yes no)
for {
v := b.Control
if v.Op != OpPPC64CMPconst {
break
}
if v.AuxInt != 0 {
break
}
z := v.Args[0]
if z.Op != OpPPC64XOR {
break
}
_ = z.Args[1]
x := z.Args[0]
y := z.Args[1]
if !(z.Uses == 1) {
break
}
b.Kind = BlockPPC64EQ
v0 := b.NewValue0(v.Pos, OpPPC64XORCC, types.TypeFlags)
v0.AddArg(x)
v0.AddArg(y)
b.SetControl(v0)
b.Aux = nil
return true
}
case BlockPPC64GE:
// match: (GE (FlagEQ) yes no)
// cond:
@ -31051,6 +31188,143 @@ func rewriteBlockPPC64(b *Block) bool {
b.Aux = nil
return true
}
// match: (GE (CMPconst [0] (ANDconst [c] x)) yes no)
// cond:
// result: (GE (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]
b.Kind = BlockPPC64GE
v0 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.TypeFlags)
v0.AuxInt = c
v0.AddArg(x)
b.SetControl(v0)
b.Aux = nil
return true
}
// match: (GE (CMPWconst [0] (ANDconst [c] x)) yes no)
// cond:
// result: (GE (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]
b.Kind = BlockPPC64GE
v0 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.TypeFlags)
v0.AuxInt = c
v0.AddArg(x)
b.SetControl(v0)
b.Aux = nil
return true
}
// match: (GE (CMPconst [0] z:(AND x y)) yes no)
// cond: z.Uses == 1
// result: (GE (ANDCC x y) yes no)
for {
v := b.Control
if v.Op != OpPPC64CMPconst {
break
}
if v.AuxInt != 0 {
break
}
z := v.Args[0]
if z.Op != OpPPC64AND {
break
}
_ = z.Args[1]
x := z.Args[0]
y := z.Args[1]
if !(z.Uses == 1) {
break
}
b.Kind = BlockPPC64GE
v0 := b.NewValue0(v.Pos, OpPPC64ANDCC, types.TypeFlags)
v0.AddArg(x)
v0.AddArg(y)
b.SetControl(v0)
b.Aux = nil
return true
}
// match: (GE (CMPconst [0] z:(OR x y)) yes no)
// cond: z.Uses == 1
// result: (GE (ORCC x y) yes no)
for {
v := b.Control
if v.Op != OpPPC64CMPconst {
break
}
if v.AuxInt != 0 {
break
}
z := v.Args[0]
if z.Op != OpPPC64OR {
break
}
_ = z.Args[1]
x := z.Args[0]
y := z.Args[1]
if !(z.Uses == 1) {
break
}
b.Kind = BlockPPC64GE
v0 := b.NewValue0(v.Pos, OpPPC64ORCC, types.TypeFlags)
v0.AddArg(x)
v0.AddArg(y)
b.SetControl(v0)
b.Aux = nil
return true
}
// match: (GE (CMPconst [0] z:(XOR x y)) yes no)
// cond: z.Uses == 1
// result: (GE (XORCC x y) yes no)
for {
v := b.Control
if v.Op != OpPPC64CMPconst {
break
}
if v.AuxInt != 0 {
break
}
z := v.Args[0]
if z.Op != OpPPC64XOR {
break
}
_ = z.Args[1]
x := z.Args[0]
y := z.Args[1]
if !(z.Uses == 1) {
break
}
b.Kind = BlockPPC64GE
v0 := b.NewValue0(v.Pos, OpPPC64XORCC, types.TypeFlags)
v0.AddArg(x)
v0.AddArg(y)
b.SetControl(v0)
b.Aux = nil
return true
}
case BlockPPC64GT:
// match: (GT (FlagEQ) yes no)
// cond:
@ -31107,6 +31381,143 @@ func rewriteBlockPPC64(b *Block) bool {
b.Aux = nil
return true
}
// match: (GT (CMPconst [0] (ANDconst [c] x)) yes no)
// cond:
// result: (GT (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]
b.Kind = BlockPPC64GT
v0 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.TypeFlags)
v0.AuxInt = c
v0.AddArg(x)
b.SetControl(v0)
b.Aux = nil
return true
}
// match: (GT (CMPWconst [0] (ANDconst [c] x)) yes no)
// cond:
// result: (GT (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]
b.Kind = BlockPPC64GT
v0 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.TypeFlags)
v0.AuxInt = c
v0.AddArg(x)
b.SetControl(v0)
b.Aux = nil
return true
}
// match: (GT (CMPconst [0] z:(AND x y)) yes no)
// cond: z.Uses == 1
// result: (GT (ANDCC x y) yes no)
for {
v := b.Control
if v.Op != OpPPC64CMPconst {
break
}
if v.AuxInt != 0 {
break
}
z := v.Args[0]
if z.Op != OpPPC64AND {
break
}
_ = z.Args[1]
x := z.Args[0]
y := z.Args[1]
if !(z.Uses == 1) {
break
}
b.Kind = BlockPPC64GT
v0 := b.NewValue0(v.Pos, OpPPC64ANDCC, types.TypeFlags)
v0.AddArg(x)
v0.AddArg(y)
b.SetControl(v0)
b.Aux = nil
return true
}
// match: (GT (CMPconst [0] z:(OR x y)) yes no)
// cond: z.Uses == 1
// result: (GT (ORCC x y) yes no)
for {
v := b.Control
if v.Op != OpPPC64CMPconst {
break
}
if v.AuxInt != 0 {
break
}
z := v.Args[0]
if z.Op != OpPPC64OR {
break
}
_ = z.Args[1]
x := z.Args[0]
y := z.Args[1]
if !(z.Uses == 1) {
break
}
b.Kind = BlockPPC64GT
v0 := b.NewValue0(v.Pos, OpPPC64ORCC, types.TypeFlags)
v0.AddArg(x)
v0.AddArg(y)
b.SetControl(v0)
b.Aux = nil
return true
}
// match: (GT (CMPconst [0] z:(XOR x y)) yes no)
// cond: z.Uses == 1
// result: (GT (XORCC x y) yes no)
for {
v := b.Control
if v.Op != OpPPC64CMPconst {
break
}
if v.AuxInt != 0 {
break
}
z := v.Args[0]
if z.Op != OpPPC64XOR {
break
}
_ = z.Args[1]
x := z.Args[0]
y := z.Args[1]
if !(z.Uses == 1) {
break
}
b.Kind = BlockPPC64GT
v0 := b.NewValue0(v.Pos, OpPPC64XORCC, types.TypeFlags)
v0.AddArg(x)
v0.AddArg(y)
b.SetControl(v0)
b.Aux = nil
return true
}
case BlockIf:
// match: (If (Equal cc) yes no)
// cond:
@ -31318,6 +31729,143 @@ func rewriteBlockPPC64(b *Block) bool {
b.Aux = nil
return true
}
// match: (LE (CMPconst [0] (ANDconst [c] x)) yes no)
// cond:
// result: (LE (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]
b.Kind = BlockPPC64LE
v0 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.TypeFlags)
v0.AuxInt = c
v0.AddArg(x)
b.SetControl(v0)
b.Aux = nil
return true
}
// match: (LE (CMPWconst [0] (ANDconst [c] x)) yes no)
// cond:
// result: (LE (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]
b.Kind = BlockPPC64LE
v0 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.TypeFlags)
v0.AuxInt = c
v0.AddArg(x)
b.SetControl(v0)
b.Aux = nil
return true
}
// match: (LE (CMPconst [0] z:(AND x y)) yes no)
// cond: z.Uses == 1
// result: (LE (ANDCC x y) yes no)
for {
v := b.Control
if v.Op != OpPPC64CMPconst {
break
}
if v.AuxInt != 0 {
break
}
z := v.Args[0]
if z.Op != OpPPC64AND {
break
}
_ = z.Args[1]
x := z.Args[0]
y := z.Args[1]
if !(z.Uses == 1) {
break
}
b.Kind = BlockPPC64LE
v0 := b.NewValue0(v.Pos, OpPPC64ANDCC, types.TypeFlags)
v0.AddArg(x)
v0.AddArg(y)
b.SetControl(v0)
b.Aux = nil
return true
}
// match: (LE (CMPconst [0] z:(OR x y)) yes no)
// cond: z.Uses == 1
// result: (LE (ORCC x y) yes no)
for {
v := b.Control
if v.Op != OpPPC64CMPconst {
break
}
if v.AuxInt != 0 {
break
}
z := v.Args[0]
if z.Op != OpPPC64OR {
break
}
_ = z.Args[1]
x := z.Args[0]
y := z.Args[1]
if !(z.Uses == 1) {
break
}
b.Kind = BlockPPC64LE
v0 := b.NewValue0(v.Pos, OpPPC64ORCC, types.TypeFlags)
v0.AddArg(x)
v0.AddArg(y)
b.SetControl(v0)
b.Aux = nil
return true
}
// match: (LE (CMPconst [0] z:(XOR x y)) yes no)
// cond: z.Uses == 1
// result: (LE (XORCC x y) yes no)
for {
v := b.Control
if v.Op != OpPPC64CMPconst {
break
}
if v.AuxInt != 0 {
break
}
z := v.Args[0]
if z.Op != OpPPC64XOR {
break
}
_ = z.Args[1]
x := z.Args[0]
y := z.Args[1]
if !(z.Uses == 1) {
break
}
b.Kind = BlockPPC64LE
v0 := b.NewValue0(v.Pos, OpPPC64XORCC, types.TypeFlags)
v0.AddArg(x)
v0.AddArg(y)
b.SetControl(v0)
b.Aux = nil
return true
}
case BlockPPC64LT:
// match: (LT (FlagEQ) yes no)
// cond:
@ -31374,6 +31922,143 @@ func rewriteBlockPPC64(b *Block) bool {
b.Aux = nil
return true
}
// match: (LT (CMPconst [0] (ANDconst [c] x)) yes no)
// cond:
// result: (LT (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]
b.Kind = BlockPPC64LT
v0 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.TypeFlags)
v0.AuxInt = c
v0.AddArg(x)
b.SetControl(v0)
b.Aux = nil
return true
}
// match: (LT (CMPWconst [0] (ANDconst [c] x)) yes no)
// cond:
// result: (LT (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]
b.Kind = BlockPPC64LT
v0 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.TypeFlags)
v0.AuxInt = c
v0.AddArg(x)
b.SetControl(v0)
b.Aux = nil
return true
}
// match: (LT (CMPconst [0] z:(AND x y)) yes no)
// cond: z.Uses == 1
// result: (LT (ANDCC x y) yes no)
for {
v := b.Control
if v.Op != OpPPC64CMPconst {
break
}
if v.AuxInt != 0 {
break
}
z := v.Args[0]
if z.Op != OpPPC64AND {
break
}
_ = z.Args[1]
x := z.Args[0]
y := z.Args[1]
if !(z.Uses == 1) {
break
}
b.Kind = BlockPPC64LT
v0 := b.NewValue0(v.Pos, OpPPC64ANDCC, types.TypeFlags)
v0.AddArg(x)
v0.AddArg(y)
b.SetControl(v0)
b.Aux = nil
return true
}
// match: (LT (CMPconst [0] z:(OR x y)) yes no)
// cond: z.Uses == 1
// result: (LT (ORCC x y) yes no)
for {
v := b.Control
if v.Op != OpPPC64CMPconst {
break
}
if v.AuxInt != 0 {
break
}
z := v.Args[0]
if z.Op != OpPPC64OR {
break
}
_ = z.Args[1]
x := z.Args[0]
y := z.Args[1]
if !(z.Uses == 1) {
break
}
b.Kind = BlockPPC64LT
v0 := b.NewValue0(v.Pos, OpPPC64ORCC, types.TypeFlags)
v0.AddArg(x)
v0.AddArg(y)
b.SetControl(v0)
b.Aux = nil
return true
}
// match: (LT (CMPconst [0] z:(XOR x y)) yes no)
// cond: z.Uses == 1
// result: (LT (XORCC x y) yes no)
for {
v := b.Control
if v.Op != OpPPC64CMPconst {
break
}
if v.AuxInt != 0 {
break
}
z := v.Args[0]
if z.Op != OpPPC64XOR {
break
}
_ = z.Args[1]
x := z.Args[0]
y := z.Args[1]
if !(z.Uses == 1) {
break
}
b.Kind = BlockPPC64LT
v0 := b.NewValue0(v.Pos, OpPPC64XORCC, types.TypeFlags)
v0.AddArg(x)
v0.AddArg(y)
b.SetControl(v0)
b.Aux = nil
return true
}
case BlockPPC64NE:
// match: (NE (CMPWconst [0] (Equal cc)) yes no)
// cond:
@ -31689,6 +32374,143 @@ func rewriteBlockPPC64(b *Block) bool {
b.Aux = nil
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]
b.Kind = BlockPPC64NE
v0 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.TypeFlags)
v0.AuxInt = c
v0.AddArg(x)
b.SetControl(v0)
b.Aux = nil
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]
b.Kind = BlockPPC64NE
v0 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.TypeFlags)
v0.AuxInt = c
v0.AddArg(x)
b.SetControl(v0)
b.Aux = nil
return true
}
// match: (NE (CMPconst [0] z:(AND x y)) yes no)
// cond: z.Uses == 1
// result: (NE (ANDCC x y) yes no)
for {
v := b.Control
if v.Op != OpPPC64CMPconst {
break
}
if v.AuxInt != 0 {
break
}
z := v.Args[0]
if z.Op != OpPPC64AND {
break
}
_ = z.Args[1]
x := z.Args[0]
y := z.Args[1]
if !(z.Uses == 1) {
break
}
b.Kind = BlockPPC64NE
v0 := b.NewValue0(v.Pos, OpPPC64ANDCC, types.TypeFlags)
v0.AddArg(x)
v0.AddArg(y)
b.SetControl(v0)
b.Aux = nil
return true
}
// match: (NE (CMPconst [0] z:(OR x y)) yes no)
// cond: z.Uses == 1
// result: (NE (ORCC x y) yes no)
for {
v := b.Control
if v.Op != OpPPC64CMPconst {
break
}
if v.AuxInt != 0 {
break
}
z := v.Args[0]
if z.Op != OpPPC64OR {
break
}
_ = z.Args[1]
x := z.Args[0]
y := z.Args[1]
if !(z.Uses == 1) {
break
}
b.Kind = BlockPPC64NE
v0 := b.NewValue0(v.Pos, OpPPC64ORCC, types.TypeFlags)
v0.AddArg(x)
v0.AddArg(y)
b.SetControl(v0)
b.Aux = nil
return true
}
// match: (NE (CMPconst [0] z:(XOR x y)) yes no)
// cond: z.Uses == 1
// result: (NE (XORCC x y) yes no)
for {
v := b.Control
if v.Op != OpPPC64CMPconst {
break
}
if v.AuxInt != 0 {
break
}
z := v.Args[0]
if z.Op != OpPPC64XOR {
break
}
_ = z.Args[1]
x := z.Args[0]
y := z.Args[1]
if !(z.Uses == 1) {
break
}
b.Kind = BlockPPC64NE
v0 := b.NewValue0(v.Pos, OpPPC64XORCC, types.TypeFlags)
v0.AddArg(x)
v0.AddArg(y)
b.SetControl(v0)
b.Aux = nil
return true
}
}
return false
}

View File

@ -210,3 +210,36 @@ func CmpToZero(a, b, d int32, e, f int64) int32 {
return 0
}
}
func CmpLogicalToZero(a, b, c uint32, d, e uint64) uint64 {
// ppc64:"ANDCC",-"CMPW"
// ppc64le:"ANDCC",-"CMPW"
if a & 63 == 0 {
return 1
}
// ppc64:"ANDCC",-"CMP"
// ppc64le:"ANDCC",-"CMP"
if d & 255 == 0 {
return 1
}
// ppc64:"ANDCC",-"CMP"
// ppc64le:"ANDCC",-"CMP"
if d & e == 0 {
return 1
}
// ppc64:"ORCC",-"CMP"
// ppc64le:"ORCC",-"CMP"
if d | e == 0 {
return 1
}
// ppc64:"XORCC",-"CMP"
// ppc64le:"XORCC",-"CMP"
if e ^ d == 0 {
return 1
}
return 0
}