src/cmd/compile/internal/ssa/_gen/PPC64.rules | 10 +++++----- src/cmd/compile/internal/ssa/rewritePPC64.go | 77 +++++++++-------------------------------------------- test/codegen/bits.go | 24 ++++++++++++++++++++++++ diff --git a/src/cmd/compile/internal/ssa/_gen/PPC64.rules b/src/cmd/compile/internal/ssa/_gen/PPC64.rules index 5a68de0ca4dadff18c19b4c37b09094998b9ecee..3aea9abd9062b5534095a1701792e46b34889a05 100644 --- a/src/cmd/compile/internal/ssa/_gen/PPC64.rules +++ b/src/cmd/compile/internal/ssa/_gen/PPC64.rules @@ -581,16 +581,16 @@ (MOVWreg y:(AND (MOVDconst [c]) _)) && uint64(c) <= 0x7FFFFFFF => y // small and of zero-extend => either zero-extend or small and (Select0 (ANDCCconst [c] y:(MOVBZreg _))) && c&0xFF == 0xFF => y -(Select0 (ANDCCconst [0xFF] y:(MOVBreg _))) => y +(Select0 (ANDCCconst [0xFF] (MOVBreg x))) => (MOVBZreg x) (Select0 (ANDCCconst [c] y:(MOVHZreg _))) && c&0xFFFF == 0xFFFF => y -(Select0 (ANDCCconst [0xFFFF] y:(MOVHreg _))) => y +(Select0 (ANDCCconst [0xFFFF] (MOVHreg x))) => (MOVHZreg x) (AND (MOVDconst [c]) y:(MOVWZreg _)) && c&0xFFFFFFFF == 0xFFFFFFFF => y (AND (MOVDconst [0xFFFFFFFF]) y:(MOVWreg x)) => (MOVWZreg x) // normal case -(Select0 (ANDCCconst [c] (MOV(B|BZ)reg x))) => (Select0 (ANDCCconst [c&0xFF] x)) -(Select0 (ANDCCconst [c] (MOV(H|HZ)reg x))) => (Select0 (ANDCCconst [c&0xFFFF] x)) -(Select0 (ANDCCconst [c] (MOV(W|WZ)reg x))) => (Select0 (ANDCCconst [c&0xFFFFFFFF] x)) +(Select0 (ANDCCconst [c] (MOVBZreg x))) => (Select0 (ANDCCconst [c&0xFF] x)) +(Select0 (ANDCCconst [c] (MOVHZreg x))) => (Select0 (ANDCCconst [c&0xFFFF] x)) +(Select0 (ANDCCconst [c] (MOVWZreg x))) => (Select0 (ANDCCconst [c&0xFFFFFFFF] x)) // Eliminate unnecessary sign/zero extend following right shift (MOV(B|H|W)Zreg (SRWconst [c] (MOVBZreg x))) => (SRWconst [c] (MOVBZreg x)) diff --git a/src/cmd/compile/internal/ssa/rewritePPC64.go b/src/cmd/compile/internal/ssa/rewritePPC64.go index bc593128daf4ca6d1149f2700a2e952427e79895..b6aed2389a09636818aa5acf0c739414d60e1490 100644 --- a/src/cmd/compile/internal/ssa/rewritePPC64.go +++ b/src/cmd/compile/internal/ssa/rewritePPC64.go @@ -15554,17 +15554,19 @@ } v.copyOf(y) return true } - // match: (Select0 (ANDCCconst [0xFF] y:(MOVBreg _))) - // result: y + // match: (Select0 (ANDCCconst [0xFF] (MOVBreg x))) + // result: (MOVBZreg x) for { if v_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0.AuxInt) != 0xFF { break } - y := v_0.Args[0] - if y.Op != OpPPC64MOVBreg { + v_0_0 := v_0.Args[0] + if v_0_0.Op != OpPPC64MOVBreg { break } - v.copyOf(y) + x := v_0_0.Args[0] + v.reset(OpPPC64MOVBZreg) + v.AddArg(x) return true } // match: (Select0 (ANDCCconst [c] y:(MOVHZreg _))) @@ -15582,36 +15584,19 @@ } v.copyOf(y) return true } - // match: (Select0 (ANDCCconst [0xFFFF] y:(MOVHreg _))) - // result: y + // match: (Select0 (ANDCCconst [0xFFFF] (MOVHreg x))) + // result: (MOVHZreg x) for { if v_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0.AuxInt) != 0xFFFF { break } - y := v_0.Args[0] - if y.Op != OpPPC64MOVHreg { - break - } - v.copyOf(y) - return true - } - // match: (Select0 (ANDCCconst [c] (MOVBreg x))) - // result: (Select0 (ANDCCconst [c&0xFF] x)) - for { - if v_0.Op != OpPPC64ANDCCconst { - break - } - c := auxIntToInt64(v_0.AuxInt) v_0_0 := v_0.Args[0] - if v_0_0.Op != OpPPC64MOVBreg { + if v_0_0.Op != OpPPC64MOVHreg { break } x := v_0_0.Args[0] - v.reset(OpSelect0) - v0 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags)) - v0.AuxInt = int64ToAuxInt(c & 0xFF) - v0.AddArg(x) - v.AddArg(v0) + v.reset(OpPPC64MOVHZreg) + v.AddArg(x) return true } // match: (Select0 (ANDCCconst [c] (MOVBZreg x))) @@ -15633,25 +15618,6 @@ v0.AddArg(x) v.AddArg(v0) return true } - // match: (Select0 (ANDCCconst [c] (MOVHreg x))) - // result: (Select0 (ANDCCconst [c&0xFFFF] x)) - for { - if v_0.Op != OpPPC64ANDCCconst { - break - } - c := auxIntToInt64(v_0.AuxInt) - v_0_0 := v_0.Args[0] - if v_0_0.Op != OpPPC64MOVHreg { - break - } - x := v_0_0.Args[0] - v.reset(OpSelect0) - v0 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags)) - v0.AuxInt = int64ToAuxInt(c & 0xFFFF) - v0.AddArg(x) - v.AddArg(v0) - return true - } // match: (Select0 (ANDCCconst [c] (MOVHZreg x))) // result: (Select0 (ANDCCconst [c&0xFFFF] x)) for { @@ -15667,25 +15633,6 @@ x := v_0_0.Args[0] v.reset(OpSelect0) v0 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags)) v0.AuxInt = int64ToAuxInt(c & 0xFFFF) - v0.AddArg(x) - v.AddArg(v0) - return true - } - // match: (Select0 (ANDCCconst [c] (MOVWreg x))) - // result: (Select0 (ANDCCconst [c&0xFFFFFFFF] x)) - for { - if v_0.Op != OpPPC64ANDCCconst { - break - } - c := auxIntToInt64(v_0.AuxInt) - v_0_0 := v_0.Args[0] - if v_0_0.Op != OpPPC64MOVWreg { - break - } - x := v_0_0.Args[0] - v.reset(OpSelect0) - v0 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags)) - v0.AuxInt = int64ToAuxInt(c & 0xFFFFFFFF) v0.AddArg(x) v.AddArg(v0) return true diff --git a/test/codegen/bits.go b/test/codegen/bits.go index 4f70627c258cedb31a5441d03f3eb8d5341e21f8..cd413924feba765068a2a2211ac01f01604c15ad 100644 --- a/test/codegen/bits.go +++ b/test/codegen/bits.go @@ -374,3 +374,27 @@ func foldConstOutOfRange(a uint64) uint64 { // arm64: "MOVD\t[$]19088744",-"ADD\t[$]19088744" return a + 0x1234568 } + +// Verify sign-extended values are not zero-extended under a bit mask (#61297) +func signextendAndMask8to64(a int8) (s, z uint64) { + // ppc64: "MOVB", "ANDCC\t[$]1015," + // ppc64le: "MOVB", "ANDCC\t[$]1015," + s = uint64(a) & 0x3F7 + // ppc64: -"MOVB", "ANDCC\t[$]247," + // ppc64le: -"MOVB", "ANDCC\t[$]247," + z = uint64(uint8(a)) & 0x3F7 + return + +} + +// Verify zero-extended values are not sign-extended under a bit mask (#61297) +func zeroextendAndMask8to64(a int8, b int16) (x, y uint64) { + // ppc64: -"MOVB\t", -"ANDCC", "MOVBZ" + // ppc64le: -"MOVB\t", -"ANDCC", "MOVBZ" + x = uint64(a) & 0xFF + // ppc64: -"MOVH\t", -"ANDCC", "MOVHZ" + // ppc64le: -"MOVH\t", -"ANDCC", "MOVHZ" + y = uint64(b) & 0xFFFF + return + +}