mirror of https://github.com/golang/go.git
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 #61297 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>
This commit is contained in:
parent
af8f94e3c5
commit
5e4000ad7f
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue