From 6211a024b491f3df6bf3eab11dd50259525b8713 Mon Sep 17 00:00:00 2001 From: "Paul E. Murphy" Date: Tue, 11 Jul 2023 09:07:43 -0500 Subject: [release-branch.go1.20] cmd/compile: on PPC64, fix sign/zero extension when masking (ANDCCconst [y] (MOV.*reg x)) should only be merged when zero extending. Otherwise, sign bits are lost on negative values. (ANDCCconst [0xFF] (MOVBreg x)) should be simplified to a zero extension of x. Likewise for the MOVHreg variant. Fixes #61320 Change-Id: I04e4fd7dc6a826e870681f37506620d48393698b Reviewed-on: https://go-review.googlesource.com/c/go/+/508775 TryBot-Result: Gopher Robot Run-TryBot: Paul Murphy Reviewed-by: Bryan Mills Reviewed-by: Cherry Mui Reviewed-on: https://go-review.googlesource.com/c/go/+/509195 Auto-Submit: Heschi Kreinick --- src/cmd/compile/internal/ssa/_gen/PPC64.rules | 10 ++-- src/cmd/compile/internal/ssa/rewritePPC64.go | 77 +++++---------------------- test/codegen/bits.go | 24 +++++++++ 3 files changed, 41 insertions(+), 70 deletions(-) diff --git a/src/cmd/compile/internal/ssa/_gen/PPC64.rules b/src/cmd/compile/internal/ssa/_gen/PPC64.rules index 5a68de0ca4..3aea9abd90 100644 --- a/src/cmd/compile/internal/ssa/_gen/PPC64.rules +++ b/src/cmd/compile/internal/ssa/_gen/PPC64.rules @@ -581,16 +581,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 bc593128da..b6aed2389a 100644 --- a/src/cmd/compile/internal/ssa/rewritePPC64.go +++ b/src/cmd/compile/internal/ssa/rewritePPC64.go @@ -15554,17 +15554,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 _))) @@ -15582,36 +15584,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))) @@ -15633,25 +15618,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 { @@ -15671,25 +15637,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 4f70627c25..cd413924fe 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 + +} -- cgit v1.2.3-54-g00ecf