diff --git a/src/cmd/compile/internal/ssa/_gen/PPC64.rules b/src/cmd/compile/internal/ssa/_gen/PPC64.rules index cbce468ad516ae..97e592fd7e1722 100644 --- a/src/cmd/compile/internal/ssa/_gen/PPC64.rules +++ b/src/cmd/compile/internal/ssa/_gen/PPC64.rules @@ -588,16 +588,16 @@ // 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 a380b4aeaf8708..d1c0c2b07f666e 100644 --- a/src/cmd/compile/internal/ssa/rewritePPC64.go +++ b/src/cmd/compile/internal/ssa/rewritePPC64.go @@ -14410,17 +14410,19 @@ func rewriteValuePPC64_OpSelect0(v *Value) bool { 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 _))) @@ -14438,36 +14440,19 @@ func rewriteValuePPC64_OpSelect0(v *Value) bool { 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))) @@ -14489,25 +14474,6 @@ func rewriteValuePPC64_OpSelect0(v *Value) bool { 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 { @@ -14527,25 +14493,6 @@ func rewriteValuePPC64_OpSelect0(v *Value) bool { 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 - } // match: (Select0 (ANDCCconst [c] (MOVWZreg x))) // result: (Select0 (ANDCCconst [c&0xFFFFFFFF] x)) for { diff --git a/test/codegen/bits.go b/test/codegen/bits.go index 4f70627c258ced..018f5b909e6d64 100644 --- a/test/codegen/bits.go +++ b/test/codegen/bits.go @@ -374,3 +374,23 @@ 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) { + // ppc64x: "MOVB", "ANDCC\t[$]1015," + s = uint64(a) & 0x3F7 + // ppc64x: -"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) { + // ppc64x: -"MOVB\t", -"ANDCC", "MOVBZ" + x = uint64(a) & 0xFF + // ppc64x: -"MOVH\t", -"ANDCC", "MOVHZ" + y = uint64(b) & 0xFFFF + return + +}