From d11e41728515aea6f7def4a279a3a2591fb18650 Mon Sep 17 00:00:00 2001 From: "Paul E. Murphy" Date: Thu, 2 May 2024 15:05:27 -0500 Subject: [PATCH] cmd/compile/internal/ssa: cleanup ANDCCconst rewrite rules on PPC64 Avoid creating duplicate usages of ANDCCconst. This is preparation for a patch to reintroduce ANDconst to simplify the lower pass while treating ANDCCconst like other *CC* ssa opcodes. Also, move many of the similar rules wich retarget ANDCCconst users to the flag result to a common rule for all compares against zero. Change-Id: Ida86efe17ff413cb82c349d8ef69d2899361f4c0 Reviewed-on: https://go-review.googlesource.com/c/go/+/585400 Reviewed-by: Cherry Mui Reviewed-by: Lynn Boger LUCI-TryBot-Result: Go LUCI Reviewed-by: Dmitri Shuralyov --- src/cmd/compile/internal/ssa/_gen/PPC64.rules | 18 +- src/cmd/compile/internal/ssa/rewritePPC64.go | 512 +++++------------- test/codegen/arithmetic.go | 4 +- 3 files changed, 140 insertions(+), 394 deletions(-) diff --git a/src/cmd/compile/internal/ssa/_gen/PPC64.rules b/src/cmd/compile/internal/ssa/_gen/PPC64.rules index 6e07aa2ec7..49d4f460e5 100644 --- a/src/cmd/compile/internal/ssa/_gen/PPC64.rules +++ b/src/cmd/compile/internal/ssa/_gen/PPC64.rules @@ -322,11 +322,11 @@ (If (FGreaterThan cc) yes no) => (FGT cc yes no) (If (FGreaterEqual cc) yes no) => (FGE cc yes no) -(If cond yes no) => (NE (CMPWconst [0] (Select0 (ANDCCconst [1] cond))) yes no) +(If cond yes no) => (NE (Select1 (ANDCCconst [1] cond)) yes no) // Absorb boolean tests into block -(NE (CMPWconst [0] (Select0 (ANDCCconst [1] ((Equal|NotEqual|LessThan|LessEqual|GreaterThan|GreaterEqual) cc)))) yes no) => ((EQ|NE|LT|LE|GT|GE) cc yes no) -(NE (CMPWconst [0] (Select0 (ANDCCconst [1] ((FLessThan|FLessEqual|FGreaterThan|FGreaterEqual) cc)))) yes no) => ((FLT|FLE|FGT|FGE) cc yes no) +(NE (Select1 (ANDCCconst [1] ((Equal|NotEqual|LessThan|LessEqual|GreaterThan|GreaterEqual) cc))) yes no) => ((EQ|NE|LT|LE|GT|GE) cc yes no) +(NE (Select1 (ANDCCconst [1] ((FLessThan|FLessEqual|FGreaterThan|FGreaterEqual) cc))) yes no) => ((FLT|FLE|FGT|FGE) cc yes no) // absorb flag constants into branches (EQ (FlagEQ) yes no) => (First yes no) @@ -894,6 +894,9 @@ // Canonicalize the order of arguments to comparisons - helps with CSE. ((CMP|CMPW|CMPU|CMPWU) x y) && canonLessThan(x,y) => (InvertFlags ((CMP|CMPW|CMPU|CMPWU) y x)) +// n is always a zero-extended uint16 value, so n & z is always a non-negative 32 or 64 bit value. Use the flag result of ANDCCconst. +((CMP|CMPW|CMPU|CMPWU)const [0] (Select0 a:(ANDCCconst [n] z))) => (Select1 a) + // SETBC auxInt values 0=LT 1=GT 2=EQ Crbit==1 ? 1 : 0 // SETBCR auxInt values 0=LT 1=GT 2=EQ Crbit==1 ? 0 : 1 (Equal cmp) => (SETBC [2] cmp) @@ -950,8 +953,6 @@ (ISEL [4] x _ (Flag(EQ|GT))) => x (ISEL [4] _ y (FlagLT)) => y -(ISEL [2] x y ((CMP|CMPW)const [0] (Select0 (ANDCCconst [n] z)))) => (ISEL [2] x y (Select1 (ANDCCconst [n] z ))) -(ISEL [6] x y ((CMP|CMPW)const [0] (Select0 (ANDCCconst [n] z)))) => (ISEL [6] x y (Select1 (ANDCCconst [n] z ))) (SETBC [n] (InvertFlags bool)) => (SETBCR [n] bool) (SETBCR [n] (InvertFlags bool)) => (SETBC [n] bool) @@ -961,11 +962,8 @@ (XORconst [1] (SETBCR [n] cmp)) => (SETBC [n] cmp) (XORconst [1] (SETBC [n] cmp)) => (SETBCR [n] cmp) -(SETBC [2] ((CMP|CMPW)const [0] (Select0 (ANDCCconst [1] z)))) => (XORconst [1] (Select0 (ANDCCconst [1] z ))) -(SETBCR [2] ((CMP|CMPW)const [0] (Select0 (ANDCCconst [1] z)))) => (Select0 (ANDCCconst [1] z )) - -(SETBC [2] (CMPWconst [0] (Select0 (ANDCCconst [n] z)))) => (SETBC [2] (Select1 (ANDCCconst [n] z ))) -(SETBCR [2] (CMPWconst [0] (Select0 (ANDCCconst [n] z)))) => (SETBCR [2] (Select1 (ANDCCconst [n] z ))) +(SETBC [2] (Select1 a:(ANDCCconst [1] _))) => (XORconst [1] (Select0 a)) +(SETBCR [2] (Select1 a:(ANDCCconst [1] _))) => (Select0 a) // Only CMPconst for these in case AND|OR|XOR result is > 32 bits (SETBC [2] (CMPconst [0] a:(AND y z))) && a.Uses == 1 => (SETBC [2] (Select1 (ANDCC y z ))) diff --git a/src/cmd/compile/internal/ssa/rewritePPC64.go b/src/cmd/compile/internal/ssa/rewritePPC64.go index cef2f21e50..6e39ee5576 100644 --- a/src/cmd/compile/internal/ssa/rewritePPC64.go +++ b/src/cmd/compile/internal/ssa/rewritePPC64.go @@ -4849,6 +4849,21 @@ func rewriteValuePPC64_OpPPC64CMPUconst(v *Value) bool { v.reset(OpPPC64FlagGT) return true } + // match: (CMPUconst [0] (Select0 a:(ANDCCconst [n] z))) + // result: (Select1 a) + for { + if auxIntToInt64(v.AuxInt) != 0 || v_0.Op != OpSelect0 { + break + } + a := v_0.Args[0] + if a.Op != OpPPC64ANDCCconst { + break + } + v.reset(OpSelect1) + v.Type = types.TypeFlags + v.AddArg(a) + return true + } return false } func rewriteValuePPC64_OpPPC64CMPW(v *Value) bool { @@ -5079,6 +5094,21 @@ func rewriteValuePPC64_OpPPC64CMPWUconst(v *Value) bool { v.reset(OpPPC64FlagGT) return true } + // match: (CMPWUconst [0] (Select0 a:(ANDCCconst [n] z))) + // result: (Select1 a) + for { + if auxIntToInt32(v.AuxInt) != 0 || v_0.Op != OpSelect0 { + break + } + a := v_0.Args[0] + if a.Op != OpPPC64ANDCCconst { + break + } + v.reset(OpSelect1) + v.Type = types.TypeFlags + v.AddArg(a) + return true + } return false } func rewriteValuePPC64_OpPPC64CMPWconst(v *Value) bool { @@ -5128,6 +5158,21 @@ func rewriteValuePPC64_OpPPC64CMPWconst(v *Value) bool { v.reset(OpPPC64FlagGT) return true } + // match: (CMPWconst [0] (Select0 a:(ANDCCconst [n] z))) + // result: (Select1 a) + for { + if auxIntToInt32(v.AuxInt) != 0 || v_0.Op != OpSelect0 { + break + } + a := v_0.Args[0] + if a.Op != OpPPC64ANDCCconst { + break + } + v.reset(OpSelect1) + v.Type = types.TypeFlags + v.AddArg(a) + return true + } return false } func rewriteValuePPC64_OpPPC64CMPconst(v *Value) bool { @@ -5177,6 +5222,21 @@ func rewriteValuePPC64_OpPPC64CMPconst(v *Value) bool { v.reset(OpPPC64FlagGT) return true } + // match: (CMPconst [0] (Select0 a:(ANDCCconst [n] z))) + // result: (Select1 a) + for { + if auxIntToInt64(v.AuxInt) != 0 || v_0.Op != OpSelect0 { + break + } + a := v_0.Args[0] + if a.Op != OpPPC64ANDCCconst { + break + } + v.reset(OpSelect1) + v.Type = types.TypeFlags + v.AddArg(a) + return true + } return false } func rewriteValuePPC64_OpPPC64Equal(v *Value) bool { @@ -5861,8 +5921,6 @@ func rewriteValuePPC64_OpPPC64ISEL(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: (ISEL [6] x y (Select1 (ANDCCconst [1] (SETBC [c] cmp)))) // result: (ISEL [c] x y cmp) for { @@ -6211,130 +6269,6 @@ func rewriteValuePPC64_OpPPC64ISEL(v *Value) bool { v.copyOf(y) return true } - // match: (ISEL [2] x y (CMPconst [0] (Select0 (ANDCCconst [n] z)))) - // result: (ISEL [2] x y (Select1 (ANDCCconst [n] z ))) - for { - if auxIntToInt32(v.AuxInt) != 2 { - break - } - x := v_0 - y := v_1 - if v_2.Op != OpPPC64CMPconst || auxIntToInt64(v_2.AuxInt) != 0 { - break - } - v_2_0 := v_2.Args[0] - if v_2_0.Op != OpSelect0 { - break - } - v_2_0_0 := v_2_0.Args[0] - if v_2_0_0.Op != OpPPC64ANDCCconst { - break - } - n := auxIntToInt64(v_2_0_0.AuxInt) - z := v_2_0_0.Args[0] - v.reset(OpPPC64ISEL) - v.AuxInt = int32ToAuxInt(2) - v0 := b.NewValue0(v.Pos, OpSelect1, types.TypeFlags) - v1 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags)) - v1.AuxInt = int64ToAuxInt(n) - v1.AddArg(z) - v0.AddArg(v1) - v.AddArg3(x, y, v0) - return true - } - // match: (ISEL [2] x y (CMPWconst [0] (Select0 (ANDCCconst [n] z)))) - // result: (ISEL [2] x y (Select1 (ANDCCconst [n] z ))) - for { - if auxIntToInt32(v.AuxInt) != 2 { - break - } - x := v_0 - y := v_1 - if v_2.Op != OpPPC64CMPWconst || auxIntToInt32(v_2.AuxInt) != 0 { - break - } - v_2_0 := v_2.Args[0] - if v_2_0.Op != OpSelect0 { - break - } - v_2_0_0 := v_2_0.Args[0] - if v_2_0_0.Op != OpPPC64ANDCCconst { - break - } - n := auxIntToInt64(v_2_0_0.AuxInt) - z := v_2_0_0.Args[0] - v.reset(OpPPC64ISEL) - v.AuxInt = int32ToAuxInt(2) - v0 := b.NewValue0(v.Pos, OpSelect1, types.TypeFlags) - v1 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags)) - v1.AuxInt = int64ToAuxInt(n) - v1.AddArg(z) - v0.AddArg(v1) - v.AddArg3(x, y, v0) - return true - } - // match: (ISEL [6] x y (CMPconst [0] (Select0 (ANDCCconst [n] z)))) - // result: (ISEL [6] x y (Select1 (ANDCCconst [n] z ))) - for { - if auxIntToInt32(v.AuxInt) != 6 { - break - } - x := v_0 - y := v_1 - if v_2.Op != OpPPC64CMPconst || auxIntToInt64(v_2.AuxInt) != 0 { - break - } - v_2_0 := v_2.Args[0] - if v_2_0.Op != OpSelect0 { - break - } - v_2_0_0 := v_2_0.Args[0] - if v_2_0_0.Op != OpPPC64ANDCCconst { - break - } - n := auxIntToInt64(v_2_0_0.AuxInt) - z := v_2_0_0.Args[0] - v.reset(OpPPC64ISEL) - v.AuxInt = int32ToAuxInt(6) - v0 := b.NewValue0(v.Pos, OpSelect1, types.TypeFlags) - v1 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags)) - v1.AuxInt = int64ToAuxInt(n) - v1.AddArg(z) - v0.AddArg(v1) - v.AddArg3(x, y, v0) - return true - } - // match: (ISEL [6] x y (CMPWconst [0] (Select0 (ANDCCconst [n] z)))) - // result: (ISEL [6] x y (Select1 (ANDCCconst [n] z ))) - for { - if auxIntToInt32(v.AuxInt) != 6 { - break - } - x := v_0 - y := v_1 - if v_2.Op != OpPPC64CMPWconst || auxIntToInt32(v_2.AuxInt) != 0 { - break - } - v_2_0 := v_2.Args[0] - if v_2_0.Op != OpSelect0 { - break - } - v_2_0_0 := v_2_0.Args[0] - if v_2_0_0.Op != OpPPC64ANDCCconst { - break - } - n := auxIntToInt64(v_2_0_0.AuxInt) - z := v_2_0_0.Args[0] - v.reset(OpPPC64ISEL) - v.AuxInt = int32ToAuxInt(6) - v0 := b.NewValue0(v.Pos, OpSelect1, types.TypeFlags) - v1 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags)) - v1.AuxInt = int64ToAuxInt(n) - v1.AddArg(z) - v0.AddArg(v1) - v.AddArg3(x, y, v0) - return true - } // match: (ISEL [n] x y (InvertFlags bool)) // cond: n%4 == 0 // result: (ISEL [n+1] x y bool) @@ -11701,79 +11635,24 @@ func rewriteValuePPC64_OpPPC64SETBC(v *Value) bool { v.AddArg(bool) return true } - // match: (SETBC [2] (CMPconst [0] (Select0 (ANDCCconst [1] z)))) - // result: (XORconst [1] (Select0 (ANDCCconst [1] z ))) - for { - if auxIntToInt32(v.AuxInt) != 2 || v_0.Op != OpPPC64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 { - break - } - v_0_0 := v_0.Args[0] - if v_0_0.Op != OpSelect0 { - break - } - v_0_0_0 := v_0_0.Args[0] - if v_0_0_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0_0_0.AuxInt) != 1 { - break - } - z := v_0_0_0.Args[0] - v.reset(OpPPC64XORconst) - v.AuxInt = int64ToAuxInt(1) - v0 := b.NewValue0(v.Pos, OpSelect0, typ.UInt64) - v1 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags)) - v1.AuxInt = int64ToAuxInt(1) - v1.AddArg(z) - v0.AddArg(v1) - v.AddArg(v0) - return true - } - // match: (SETBC [2] (CMPWconst [0] (Select0 (ANDCCconst [1] z)))) - // result: (XORconst [1] (Select0 (ANDCCconst [1] z ))) + // match: (SETBC [2] (Select1 a:(ANDCCconst [1] _))) + // result: (XORconst [1] (Select0 a)) for { - if auxIntToInt32(v.AuxInt) != 2 || v_0.Op != OpPPC64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 { + if auxIntToInt32(v.AuxInt) != 2 || v_0.Op != OpSelect1 { break } - v_0_0 := v_0.Args[0] - if v_0_0.Op != OpSelect0 { + a := v_0.Args[0] + if a.Op != OpPPC64ANDCCconst { break } - v_0_0_0 := v_0_0.Args[0] - if v_0_0_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0_0_0.AuxInt) != 1 { + t := a.Type + if auxIntToInt64(a.AuxInt) != 1 { break } - z := v_0_0_0.Args[0] v.reset(OpPPC64XORconst) v.AuxInt = int64ToAuxInt(1) - v0 := b.NewValue0(v.Pos, OpSelect0, typ.UInt64) - v1 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags)) - v1.AuxInt = int64ToAuxInt(1) - v1.AddArg(z) - v0.AddArg(v1) - v.AddArg(v0) - return true - } - // match: (SETBC [2] (CMPWconst [0] (Select0 (ANDCCconst [n] z)))) - // result: (SETBC [2] (Select1 (ANDCCconst [n] z ))) - for { - if auxIntToInt32(v.AuxInt) != 2 || v_0.Op != OpPPC64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 { - break - } - v_0_0 := v_0.Args[0] - if v_0_0.Op != OpSelect0 { - break - } - v_0_0_0 := v_0_0.Args[0] - if v_0_0_0.Op != OpPPC64ANDCCconst { - break - } - n := auxIntToInt64(v_0_0_0.AuxInt) - z := v_0_0_0.Args[0] - v.reset(OpPPC64SETBC) - v.AuxInt = int32ToAuxInt(2) - v0 := b.NewValue0(v.Pos, OpSelect1, types.TypeFlags) - v1 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags)) - v1.AuxInt = int64ToAuxInt(n) - v1.AddArg(z) - v0.AddArg(v1) + v0 := b.NewValue0(v.Pos, OpSelect0, t.FieldType(0)) + v0.AddArg(a) v.AddArg(v0) return true } @@ -11997,76 +11876,18 @@ func rewriteValuePPC64_OpPPC64SETBCR(v *Value) bool { v.AddArg(bool) return true } - // match: (SETBCR [2] (CMPconst [0] (Select0 (ANDCCconst [1] z)))) - // result: (Select0 (ANDCCconst [1] z )) + // match: (SETBCR [2] (Select1 a:(ANDCCconst [1] _))) + // result: (Select0 a) for { - if auxIntToInt32(v.AuxInt) != 2 || v_0.Op != OpPPC64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 { - break - } - v_0_0 := v_0.Args[0] - if v_0_0.Op != OpSelect0 { + if auxIntToInt32(v.AuxInt) != 2 || v_0.Op != OpSelect1 { break } - v_0_0_0 := v_0_0.Args[0] - if v_0_0_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0_0_0.AuxInt) != 1 { - break - } - z := v_0_0_0.Args[0] - v.reset(OpSelect0) - v.Type = typ.UInt64 - v0 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags)) - v0.AuxInt = int64ToAuxInt(1) - v0.AddArg(z) - v.AddArg(v0) - return true - } - // match: (SETBCR [2] (CMPWconst [0] (Select0 (ANDCCconst [1] z)))) - // result: (Select0 (ANDCCconst [1] z )) - for { - if auxIntToInt32(v.AuxInt) != 2 || v_0.Op != OpPPC64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 { - break - } - v_0_0 := v_0.Args[0] - if v_0_0.Op != OpSelect0 { - break - } - v_0_0_0 := v_0_0.Args[0] - if v_0_0_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0_0_0.AuxInt) != 1 { + a := v_0.Args[0] + if a.Op != OpPPC64ANDCCconst || auxIntToInt64(a.AuxInt) != 1 { break } - z := v_0_0_0.Args[0] v.reset(OpSelect0) - v.Type = typ.UInt64 - v0 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags)) - v0.AuxInt = int64ToAuxInt(1) - v0.AddArg(z) - v.AddArg(v0) - return true - } - // match: (SETBCR [2] (CMPWconst [0] (Select0 (ANDCCconst [n] z)))) - // result: (SETBCR [2] (Select1 (ANDCCconst [n] z ))) - for { - if auxIntToInt32(v.AuxInt) != 2 || v_0.Op != OpPPC64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 { - break - } - v_0_0 := v_0.Args[0] - if v_0_0.Op != OpSelect0 { - break - } - v_0_0_0 := v_0_0.Args[0] - if v_0_0_0.Op != OpPPC64ANDCCconst { - break - } - n := auxIntToInt64(v_0_0_0.AuxInt) - z := v_0_0_0.Args[0] - v.reset(OpPPC64SETBCR) - v.AuxInt = int32ToAuxInt(2) - v0 := b.NewValue0(v.Pos, OpSelect1, types.TypeFlags) - v1 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags)) - v1.AuxInt = int64ToAuxInt(n) - v1.AddArg(z) - v0.AddArg(v1) - v.AddArg(v0) + v.AddArg(a) return true } // match: (SETBCR [2] (CMPconst [0] a:(AND y z))) @@ -16129,16 +15950,13 @@ func rewriteBlockPPC64(b *Block) bool { return true } // match: (If cond yes no) - // result: (NE (CMPWconst [0] (Select0 (ANDCCconst [1] cond))) yes no) + // result: (NE (Select1 (ANDCCconst [1] cond)) yes no) for { cond := b.Controls[0] - v0 := b.NewValue0(cond.Pos, OpPPC64CMPWconst, types.TypeFlags) - v0.AuxInt = int32ToAuxInt(0) - v1 := b.NewValue0(cond.Pos, OpSelect0, typ.UInt32) - v2 := b.NewValue0(cond.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags)) - v2.AuxInt = int64ToAuxInt(1) - v2.AddArg(cond) - v1.AddArg(v2) + v0 := b.NewValue0(cond.Pos, OpSelect1, types.TypeFlags) + v1 := b.NewValue0(cond.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags)) + v1.AuxInt = int64ToAuxInt(1) + v1.AddArg(cond) v0.AddArg(v1) b.resetWithControl(BlockPPC64NE, v0) return true @@ -16461,233 +16279,163 @@ func rewriteBlockPPC64(b *Block) bool { break } case BlockPPC64NE: - // match: (NE (CMPWconst [0] (Select0 (ANDCCconst [1] (Equal cc)))) yes no) + // match: (NE (Select1 (ANDCCconst [1] (Equal cc))) yes no) // result: (EQ cc yes no) - for b.Controls[0].Op == OpPPC64CMPWconst { + for b.Controls[0].Op == OpSelect1 { v_0 := b.Controls[0] - if auxIntToInt32(v_0.AuxInt) != 0 { - break - } v_0_0 := v_0.Args[0] - if v_0_0.Op != OpSelect0 { + if v_0_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0_0.AuxInt) != 1 { break } v_0_0_0 := v_0_0.Args[0] - if v_0_0_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0_0_0.AuxInt) != 1 { - break - } - v_0_0_0_0 := v_0_0_0.Args[0] - if v_0_0_0_0.Op != OpPPC64Equal { + if v_0_0_0.Op != OpPPC64Equal { break } - cc := v_0_0_0_0.Args[0] + cc := v_0_0_0.Args[0] b.resetWithControl(BlockPPC64EQ, cc) return true } - // match: (NE (CMPWconst [0] (Select0 (ANDCCconst [1] (NotEqual cc)))) yes no) + // match: (NE (Select1 (ANDCCconst [1] (NotEqual cc))) yes no) // result: (NE cc yes no) - for b.Controls[0].Op == OpPPC64CMPWconst { + for b.Controls[0].Op == OpSelect1 { v_0 := b.Controls[0] - if auxIntToInt32(v_0.AuxInt) != 0 { - break - } v_0_0 := v_0.Args[0] - if v_0_0.Op != OpSelect0 { + if v_0_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0_0.AuxInt) != 1 { break } v_0_0_0 := v_0_0.Args[0] - if v_0_0_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0_0_0.AuxInt) != 1 { - break - } - v_0_0_0_0 := v_0_0_0.Args[0] - if v_0_0_0_0.Op != OpPPC64NotEqual { + if v_0_0_0.Op != OpPPC64NotEqual { break } - cc := v_0_0_0_0.Args[0] + cc := v_0_0_0.Args[0] b.resetWithControl(BlockPPC64NE, cc) return true } - // match: (NE (CMPWconst [0] (Select0 (ANDCCconst [1] (LessThan cc)))) yes no) + // match: (NE (Select1 (ANDCCconst [1] (LessThan cc))) yes no) // result: (LT cc yes no) - for b.Controls[0].Op == OpPPC64CMPWconst { + for b.Controls[0].Op == OpSelect1 { v_0 := b.Controls[0] - if auxIntToInt32(v_0.AuxInt) != 0 { - break - } v_0_0 := v_0.Args[0] - if v_0_0.Op != OpSelect0 { + if v_0_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0_0.AuxInt) != 1 { break } v_0_0_0 := v_0_0.Args[0] - if v_0_0_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0_0_0.AuxInt) != 1 { + if v_0_0_0.Op != OpPPC64LessThan { break } - v_0_0_0_0 := v_0_0_0.Args[0] - if v_0_0_0_0.Op != OpPPC64LessThan { - break - } - cc := v_0_0_0_0.Args[0] + cc := v_0_0_0.Args[0] b.resetWithControl(BlockPPC64LT, cc) return true } - // match: (NE (CMPWconst [0] (Select0 (ANDCCconst [1] (LessEqual cc)))) yes no) + // match: (NE (Select1 (ANDCCconst [1] (LessEqual cc))) yes no) // result: (LE cc yes no) - for b.Controls[0].Op == OpPPC64CMPWconst { + for b.Controls[0].Op == OpSelect1 { v_0 := b.Controls[0] - if auxIntToInt32(v_0.AuxInt) != 0 { - break - } v_0_0 := v_0.Args[0] - if v_0_0.Op != OpSelect0 { + if v_0_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0_0.AuxInt) != 1 { break } v_0_0_0 := v_0_0.Args[0] - if v_0_0_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0_0_0.AuxInt) != 1 { - break - } - v_0_0_0_0 := v_0_0_0.Args[0] - if v_0_0_0_0.Op != OpPPC64LessEqual { + if v_0_0_0.Op != OpPPC64LessEqual { break } - cc := v_0_0_0_0.Args[0] + cc := v_0_0_0.Args[0] b.resetWithControl(BlockPPC64LE, cc) return true } - // match: (NE (CMPWconst [0] (Select0 (ANDCCconst [1] (GreaterThan cc)))) yes no) + // match: (NE (Select1 (ANDCCconst [1] (GreaterThan cc))) yes no) // result: (GT cc yes no) - for b.Controls[0].Op == OpPPC64CMPWconst { + for b.Controls[0].Op == OpSelect1 { v_0 := b.Controls[0] - if auxIntToInt32(v_0.AuxInt) != 0 { - break - } v_0_0 := v_0.Args[0] - if v_0_0.Op != OpSelect0 { + if v_0_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0_0.AuxInt) != 1 { break } v_0_0_0 := v_0_0.Args[0] - if v_0_0_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0_0_0.AuxInt) != 1 { - break - } - v_0_0_0_0 := v_0_0_0.Args[0] - if v_0_0_0_0.Op != OpPPC64GreaterThan { + if v_0_0_0.Op != OpPPC64GreaterThan { break } - cc := v_0_0_0_0.Args[0] + cc := v_0_0_0.Args[0] b.resetWithControl(BlockPPC64GT, cc) return true } - // match: (NE (CMPWconst [0] (Select0 (ANDCCconst [1] (GreaterEqual cc)))) yes no) + // match: (NE (Select1 (ANDCCconst [1] (GreaterEqual cc))) yes no) // result: (GE cc yes no) - for b.Controls[0].Op == OpPPC64CMPWconst { + for b.Controls[0].Op == OpSelect1 { v_0 := b.Controls[0] - if auxIntToInt32(v_0.AuxInt) != 0 { - break - } v_0_0 := v_0.Args[0] - if v_0_0.Op != OpSelect0 { + if v_0_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0_0.AuxInt) != 1 { break } v_0_0_0 := v_0_0.Args[0] - if v_0_0_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0_0_0.AuxInt) != 1 { + if v_0_0_0.Op != OpPPC64GreaterEqual { break } - v_0_0_0_0 := v_0_0_0.Args[0] - if v_0_0_0_0.Op != OpPPC64GreaterEqual { - break - } - cc := v_0_0_0_0.Args[0] + cc := v_0_0_0.Args[0] b.resetWithControl(BlockPPC64GE, cc) return true } - // match: (NE (CMPWconst [0] (Select0 (ANDCCconst [1] (FLessThan cc)))) yes no) + // match: (NE (Select1 (ANDCCconst [1] (FLessThan cc))) yes no) // result: (FLT cc yes no) - for b.Controls[0].Op == OpPPC64CMPWconst { + for b.Controls[0].Op == OpSelect1 { v_0 := b.Controls[0] - if auxIntToInt32(v_0.AuxInt) != 0 { - break - } v_0_0 := v_0.Args[0] - if v_0_0.Op != OpSelect0 { + if v_0_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0_0.AuxInt) != 1 { break } v_0_0_0 := v_0_0.Args[0] - if v_0_0_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0_0_0.AuxInt) != 1 { - break - } - v_0_0_0_0 := v_0_0_0.Args[0] - if v_0_0_0_0.Op != OpPPC64FLessThan { + if v_0_0_0.Op != OpPPC64FLessThan { break } - cc := v_0_0_0_0.Args[0] + cc := v_0_0_0.Args[0] b.resetWithControl(BlockPPC64FLT, cc) return true } - // match: (NE (CMPWconst [0] (Select0 (ANDCCconst [1] (FLessEqual cc)))) yes no) + // match: (NE (Select1 (ANDCCconst [1] (FLessEqual cc))) yes no) // result: (FLE cc yes no) - for b.Controls[0].Op == OpPPC64CMPWconst { + for b.Controls[0].Op == OpSelect1 { v_0 := b.Controls[0] - if auxIntToInt32(v_0.AuxInt) != 0 { - break - } v_0_0 := v_0.Args[0] - if v_0_0.Op != OpSelect0 { + if v_0_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0_0.AuxInt) != 1 { break } v_0_0_0 := v_0_0.Args[0] - if v_0_0_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0_0_0.AuxInt) != 1 { - break - } - v_0_0_0_0 := v_0_0_0.Args[0] - if v_0_0_0_0.Op != OpPPC64FLessEqual { + if v_0_0_0.Op != OpPPC64FLessEqual { break } - cc := v_0_0_0_0.Args[0] + cc := v_0_0_0.Args[0] b.resetWithControl(BlockPPC64FLE, cc) return true } - // match: (NE (CMPWconst [0] (Select0 (ANDCCconst [1] (FGreaterThan cc)))) yes no) + // match: (NE (Select1 (ANDCCconst [1] (FGreaterThan cc))) yes no) // result: (FGT cc yes no) - for b.Controls[0].Op == OpPPC64CMPWconst { + for b.Controls[0].Op == OpSelect1 { v_0 := b.Controls[0] - if auxIntToInt32(v_0.AuxInt) != 0 { - break - } v_0_0 := v_0.Args[0] - if v_0_0.Op != OpSelect0 { + if v_0_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0_0.AuxInt) != 1 { break } v_0_0_0 := v_0_0.Args[0] - if v_0_0_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0_0_0.AuxInt) != 1 { + if v_0_0_0.Op != OpPPC64FGreaterThan { break } - v_0_0_0_0 := v_0_0_0.Args[0] - if v_0_0_0_0.Op != OpPPC64FGreaterThan { - break - } - cc := v_0_0_0_0.Args[0] + cc := v_0_0_0.Args[0] b.resetWithControl(BlockPPC64FGT, cc) return true } - // match: (NE (CMPWconst [0] (Select0 (ANDCCconst [1] (FGreaterEqual cc)))) yes no) + // match: (NE (Select1 (ANDCCconst [1] (FGreaterEqual cc))) yes no) // result: (FGE cc yes no) - for b.Controls[0].Op == OpPPC64CMPWconst { + for b.Controls[0].Op == OpSelect1 { v_0 := b.Controls[0] - if auxIntToInt32(v_0.AuxInt) != 0 { - break - } v_0_0 := v_0.Args[0] - if v_0_0.Op != OpSelect0 { + if v_0_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0_0.AuxInt) != 1 { break } v_0_0_0 := v_0_0.Args[0] - if v_0_0_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0_0_0.AuxInt) != 1 { - break - } - v_0_0_0_0 := v_0_0_0.Args[0] - if v_0_0_0_0.Op != OpPPC64FGreaterEqual { + if v_0_0_0.Op != OpPPC64FGreaterEqual { break } - cc := v_0_0_0_0.Args[0] + cc := v_0_0_0.Args[0] b.resetWithControl(BlockPPC64FGE, cc) return true } diff --git a/test/codegen/arithmetic.go b/test/codegen/arithmetic.go index dc3bab7be9..e474a10ba2 100644 --- a/test/codegen/arithmetic.go +++ b/test/codegen/arithmetic.go @@ -320,14 +320,14 @@ func Pow2DivisibleSigned(n1, n2 int) (bool, bool) { // amd64:"TESTQ\t[$]63",-"DIVQ",-"SHRQ" // arm:"AND\t[$]63",-".*udiv",-"SRA" // arm64:"TST\t[$]63",-"UDIV",-"ASR",-"AND" - // ppc64x:"RLDICL",-"SRAD" + // ppc64x:"ANDCC",-"RLDICL",-"SRAD",-"CMP" a := n1%64 == 0 // signed divisible // 386:"TESTL\t[$]63",-"DIVL",-"SHRL" // amd64:"TESTQ\t[$]63",-"DIVQ",-"SHRQ" // arm:"AND\t[$]63",-".*udiv",-"SRA" // arm64:"TST\t[$]63",-"UDIV",-"ASR",-"AND" - // ppc64x:"RLDICL",-"SRAD" + // ppc64x:"ANDCC",-"RLDICL",-"SRAD",-"CMP" b := n2%64 != 0 // signed indivisible return a, b -- 2.48.1