]> Cypherpunks.ru repositories - gostls13.git/commitdiff
cmd/compile: on PPC64, fix sign/zero extension when masking
authorPaul E. Murphy <murp@ibm.com>
Tue, 11 Jul 2023 14:07:43 +0000 (09:07 -0500)
committerPaul Murphy <murp@ibm.com>
Wed, 12 Jul 2023 16:34:02 +0000 (16:34 +0000)
(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>
src/cmd/compile/internal/ssa/_gen/PPC64.rules
src/cmd/compile/internal/ssa/rewritePPC64.go
test/codegen/bits.go

index cbce468ad516ae85c5a5333a3bd1707f0fc2e743..97e592fd7e17225a47154d2774aa68f343bc10e6 100644 (file)
 
 // 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))
index a380b4aeaf8708903d691d5f92e270b99dd2fbcc..d1c0c2b07f666eadd94e54012bf3b92bbed2a67a 100644 (file)
@@ -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 {
index 4f70627c258cedb31a5441d03f3eb8d5341e21f8..018f5b909e6d64942c07821d451545114510765d 100644 (file)
@@ -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
+
+}