aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul E. Murphy <murp@ibm.com>2023-07-11 09:07:43 -0500
committerGopher Robot <gobot@golang.org>2023-07-19 19:10:08 +0000
commit6211a024b491f3df6bf3eab11dd50259525b8713 (patch)
treea563f2be5e7b77dcd72e5f75781f800ee5519802
parent2c358ffe9762ba08c8db0196942395f97775e31b (diff)
downloadgo-6211a024b491f3df6bf3eab11dd50259525b8713.tar.gz
go-6211a024b491f3df6bf3eab11dd50259525b8713.zip
[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 <gobot@golang.org> Run-TryBot: Paul Murphy <murp@ibm.com> Reviewed-by: Bryan Mills <bcmills@google.com> Reviewed-by: Cherry Mui <cherryyz@google.com> Reviewed-on: https://go-review.googlesource.com/c/go/+/509195 Auto-Submit: Heschi Kreinick <heschi@google.com>
-rw-r--r--src/cmd/compile/internal/ssa/_gen/PPC64.rules10
-rw-r--r--src/cmd/compile/internal/ssa/rewritePPC64.go77
-rw-r--r--test/codegen/bits.go24
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
+
+}