]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: improve absorb shifts optimization for arm64
authorChad Rosier <mrosier.qdt@qualcommdatacenter.com>
Thu, 15 Feb 2018 19:49:03 +0000 (14:49 -0500)
committerCherry Zhang <cherryyz@google.com>
Thu, 15 Feb 2018 20:54:50 +0000 (20:54 +0000)
Current absorb shifts optimization can generate dead Value nodes which increase
use count of other live nodes. It will impact other optimizations (such as
combined loads) which are enabled based on specific use count. This patch fixes
the issue by decreasing the use count of nodes referenced by dead Value nodes
generated by absorb shifts optimization.

Performance impacts on go1 benchmarks (data collected on A57@2GHzx8):

name                     old time/op    new time/op    delta
BinaryTree17-8              6.28s ± 2%     6.24s ± 1%     ~     (p=0.065 n=10+9)
Fannkuch11-8                6.32s ± 0%     6.33s ± 0%   +0.17%  (p=0.000 n=10+10)
FmtFprintfEmpty-8          98.9ns ± 0%    99.2ns ± 0%   +0.34%  (p=0.000 n=9+7)
FmtFprintfString-8          183ns ± 1%     182ns ± 1%   -1.01%  (p=0.005 n=9+10)
FmtFprintfInt-8             199ns ± 1%     202ns ± 1%   +1.41%  (p=0.000 n=10+9)
FmtFprintfIntInt-8          272ns ± 1%     276ns ± 3%   +1.36%  (p=0.015 n=10+10)
FmtFprintfPrefixedInt-8     367ns ± 1%     369ns ± 1%   +0.68%  (p=0.042 n=10+10)
FmtFprintfFloat-8           491ns ± 1%     493ns ± 1%     ~     (p=0.064 n=10+10)
FmtManyArgs-8              1.31µs ± 1%    1.32µs ± 1%   +0.39%  (p=0.042 n=8+9)
GobDecode-8                17.0ms ± 2%    16.2ms ± 2%   -4.74%  (p=0.000 n=10+10)
GobEncode-8                13.7ms ± 2%    13.4ms ± 1%   -2.40%  (p=0.000 n=10+9)
Gzip-8                      844ms ± 0%     737ms ± 0%  -12.70%  (p=0.000 n=10+10)
Gunzip-8                   84.4ms ± 1%    83.9ms ± 0%   -0.55%  (p=0.000 n=10+8)
HTTPClientServer-8          122µs ± 1%     124µs ± 1%   +1.75%  (p=0.000 n=10+9)
JSONEncode-8               34.9ms ± 1%    32.4ms ± 0%   -7.11%  (p=0.000 n=10+9)
JSONDecode-8                150ms ± 0%     146ms ± 1%   -2.84%  (p=0.000 n=7+10)
Mandelbrot200-8            10.0ms ± 0%    10.0ms ± 0%     ~     (p=0.529 n=10+10)
GoParse-8                  8.18ms ± 1%    8.03ms ± 0%   -1.93%  (p=0.000 n=10+10)
RegexpMatchEasy0_32-8       209ns ± 0%     209ns ± 0%     ~     (p=0.248 n=10+9)
RegexpMatchEasy0_1K-8       789ns ± 1%     790ns ± 0%     ~     (p=0.361 n=10+10)
RegexpMatchEasy1_32-8       202ns ± 0%     202ns ± 1%     ~     (p=0.137 n=8+10)
RegexpMatchEasy1_1K-8      1.12µs ± 2%    1.12µs ± 1%     ~     (p=0.810 n=10+10)
RegexpMatchMedium_32-8      298ns ± 0%     298ns ± 0%     ~     (p=0.443 n=10+9)
RegexpMatchMedium_1K-8     83.0µs ± 5%    78.6µs ± 0%   -5.37%  (p=0.000 n=10+10)
RegexpMatchHard_32-8       4.32µs ± 0%    4.26µs ± 0%   -1.47%  (p=0.000 n=10+10)
RegexpMatchHard_1K-8        132µs ± 4%     126µs ± 0%   -4.41%  (p=0.000 n=10+9)
Revcomp-8                   1.11s ± 0%     1.11s ± 0%   +0.14%  (p=0.017 n=10+9)
Template-8                  155ms ± 1%     155ms ± 1%     ~     (p=0.796 n=10+10)
TimeParse-8                 774ns ± 1%     785ns ± 1%   +1.41%  (p=0.001 n=10+10)
TimeFormat-8                788ns ± 1%     806ns ± 1%   +2.24%  (p=0.000 n=10+9)

name                     old speed      new speed      delta
GobDecode-8              45.2MB/s ± 2%  47.5MB/s ± 2%   +4.96%  (p=0.000 n=10+10)
GobEncode-8              56.0MB/s ± 2%  57.4MB/s ± 1%   +2.44%  (p=0.000 n=10+9)
Gzip-8                   23.0MB/s ± 0%  26.3MB/s ± 0%  +14.55%  (p=0.000 n=10+10)
Gunzip-8                  230MB/s ± 1%   231MB/s ± 0%   +0.55%  (p=0.000 n=10+8)
JSONEncode-8             55.6MB/s ± 1%  59.9MB/s ± 0%   +7.65%  (p=0.000 n=10+9)
JSONDecode-8             12.9MB/s ± 0%  13.3MB/s ± 1%   +2.94%  (p=0.000 n=7+10)
GoParse-8                7.08MB/s ± 1%  7.22MB/s ± 0%   +1.95%  (p=0.000 n=10+10)
RegexpMatchEasy0_32-8     153MB/s ± 0%   153MB/s ± 0%   -0.16%  (p=0.023 n=10+10)
RegexpMatchEasy0_1K-8    1.30GB/s ± 1%  1.30GB/s ± 0%     ~     (p=0.393 n=10+10)
RegexpMatchEasy1_32-8     158MB/s ± 0%   158MB/s ± 0%     ~     (p=0.684 n=10+10)
RegexpMatchEasy1_1K-8     915MB/s ± 2%   918MB/s ± 1%     ~     (p=0.796 n=10+10)
RegexpMatchMedium_32-8   3.35MB/s ± 0%  3.35MB/s ± 0%     ~     (p=1.000 n=10+9)
RegexpMatchMedium_1K-8   12.3MB/s ± 5%  13.0MB/s ± 0%   +5.56%  (p=0.000 n=10+10)
RegexpMatchHard_32-8     7.40MB/s ± 0%  7.51MB/s ± 0%   +1.50%  (p=0.000 n=10+10)
RegexpMatchHard_1K-8     7.75MB/s ± 4%  8.10MB/s ± 0%   +4.52%  (p=0.000 n=10+8)
Revcomp-8                 229MB/s ± 0%   228MB/s ± 0%   -0.14%  (p=0.017 n=10+9)
Template-8               12.5MB/s ± 1%  12.5MB/s ± 1%     ~     (p=0.780 n=10+10)

Change-Id: I103389f168eac79f6af44e8fef93acc2a7a4ac96
Reviewed-on: https://go-review.googlesource.com/88415
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
src/cmd/compile/internal/gc/asm_test.go
src/cmd/compile/internal/ssa/gen/ARM64.rules
src/cmd/compile/internal/ssa/rewrite.go
src/cmd/compile/internal/ssa/rewriteARM64.go

index 9b62d9f6b172f26b87986089ba1dc68102edfde4..f1ab3f5a8df1b86aecf52655a267e690e27bc5de 100644 (file)
@@ -248,7 +248,7 @@ var allAsmTests = []*asmTests{
        {
                arch:    "arm64",
                os:      "linux",
-               imports: []string{"math/bits"},
+               imports: []string{"encoding/binary", "math/bits"},
                tests:   linuxARM64Tests,
        },
        {
@@ -2751,6 +2751,80 @@ var linuxARM64Tests = []*asmTest{
                `,
                pos: []string{"TBZ"},
        },
+       // Load-combining tests.
+       {
+               fn: `
+               func $(b []byte) uint64 {
+                       return binary.LittleEndian.Uint64(b)
+               }
+               `,
+               pos: []string{"\tMOVD\t\\(R[0-9]+\\)"},
+       },
+       {
+               fn: `
+               func $(b []byte, i int) uint64 {
+                       return binary.LittleEndian.Uint64(b[i:])
+               }
+               `,
+               pos: []string{"\tMOVD\t\\(R[0-9]+\\)"},
+       },
+       {
+               fn: `
+               func $(b []byte) uint32 {
+                       return binary.LittleEndian.Uint32(b)
+               }
+               `,
+               pos: []string{"\tMOVWU\t\\(R[0-9]+\\)"},
+       },
+       {
+               fn: `
+               func $(b []byte, i int) uint32 {
+                       return binary.LittleEndian.Uint32(b[i:])
+               }
+               `,
+               pos: []string{"\tMOVWU\t\\(R[0-9]+\\)"},
+       },
+       {
+               fn: `
+               func $(b []byte) uint64 {
+                       return binary.BigEndian.Uint64(b)
+               }
+               `,
+               pos: []string{"\tREV\t"},
+       },
+       {
+               fn: `
+               func $(b []byte, i int) uint64 {
+                       return binary.BigEndian.Uint64(b[i:])
+               }
+               `,
+               pos: []string{"\tREV\t"},
+       },
+       {
+               fn: `
+               func $(b []byte) uint32 {
+                       return binary.BigEndian.Uint32(b)
+               }
+               `,
+               pos: []string{"\tREVW\t"},
+       },
+       {
+               fn: `
+               func $(b []byte, i int) uint32 {
+                       return binary.BigEndian.Uint32(b[i:])
+               }
+               `,
+               pos: []string{"\tREVW\t"},
+       },
+       {
+               fn: `
+               func $(s []byte) uint16 {
+                       return uint16(s[0]) | uint16(s[1]) << 8
+               }
+               `,
+               pos: []string{"\tMOVHU\t\\(R[0-9]+\\)"},
+               neg: []string{"ORR\tR[0-9]+<<8\t"},
+       },
 }
 
 var linuxMIPSTests = []*asmTest{
index 48ca634438ff8e3fb5115a5faaf59b5941f03b64..f9af4c6da87f78d3943588d77deec114172ede4f 100644 (file)
 (CSELULT0 _ (FlagGT_UGT)) -> (MOVDconst [0])
 
 // absorb shifts into ops
-(ADD x (SLLconst [c] y)) -> (ADDshiftLL x y [c])
-(ADD x (SRLconst [c] y)) -> (ADDshiftRL x y [c])
-(ADD x (SRAconst [c] y)) -> (ADDshiftRA x y [c])
-(SUB x (SLLconst [c] y)) -> (SUBshiftLL x y [c])
-(SUB x (SRLconst [c] y)) -> (SUBshiftRL x y [c])
-(SUB x (SRAconst [c] y)) -> (SUBshiftRA x y [c])
-(AND x (SLLconst [c] y)) -> (ANDshiftLL x y [c])
-(AND x (SRLconst [c] y)) -> (ANDshiftRL x y [c])
-(AND x (SRAconst [c] y)) -> (ANDshiftRA x y [c])
-(OR  x (SLLconst [c] y)) -> (ORshiftLL  x y [c]) // useful for combined load
-(OR  x (SRLconst [c] y)) -> (ORshiftRL  x y [c])
-(OR  x (SRAconst [c] y)) -> (ORshiftRA  x y [c])
-(XOR x (SLLconst [c] y)) -> (XORshiftLL x y [c])
-(XOR x (SRLconst [c] y)) -> (XORshiftRL x y [c])
-(XOR x (SRAconst [c] y)) -> (XORshiftRA x y [c])
-(BIC x (SLLconst [c] y)) -> (BICshiftLL x y [c])
-(BIC x (SRLconst [c] y)) -> (BICshiftRL x y [c])
-(BIC x (SRAconst [c] y)) -> (BICshiftRA x y [c])
-(CMP x (SLLconst [c] y)) -> (CMPshiftLL x y [c])
-(CMP (SLLconst [c] y) x) -> (InvertFlags (CMPshiftLL x y [c]))
-(CMP x (SRLconst [c] y)) -> (CMPshiftRL x y [c])
-(CMP (SRLconst [c] y) x) -> (InvertFlags (CMPshiftRL x y [c]))
-(CMP x (SRAconst [c] y)) -> (CMPshiftRA x y [c])
-(CMP (SRAconst [c] y) x) -> (InvertFlags (CMPshiftRA x y [c]))
+(ADD x0 x1:(SLLconst [c] y)) && clobberIfDead(x1) -> (ADDshiftLL x0 y [c])
+(ADD x0 x1:(SRLconst [c] y)) && clobberIfDead(x1) -> (ADDshiftRL x0 y [c])
+(ADD x0 x1:(SRAconst [c] y)) && clobberIfDead(x1) -> (ADDshiftRA x0 y [c])
+(SUB x0 x1:(SLLconst [c] y)) && clobberIfDead(x1) -> (SUBshiftLL x0 y [c])
+(SUB x0 x1:(SRLconst [c] y)) && clobberIfDead(x1) -> (SUBshiftRL x0 y [c])
+(SUB x0 x1:(SRAconst [c] y)) && clobberIfDead(x1) -> (SUBshiftRA x0 y [c])
+(AND x0 x1:(SLLconst [c] y)) && clobberIfDead(x1) -> (ANDshiftLL x0 y [c])
+(AND x0 x1:(SRLconst [c] y)) && clobberIfDead(x1) -> (ANDshiftRL x0 y [c])
+(AND x0 x1:(SRAconst [c] y)) && clobberIfDead(x1) -> (ANDshiftRA x0 y [c])
+(OR  x0 x1:(SLLconst [c] y)) && clobberIfDead(x1) -> (ORshiftLL  x0 y [c]) // useful for combined load
+(OR  x0 x1:(SRLconst [c] y)) && clobberIfDead(x1) -> (ORshiftRL  x0 y [c])
+(OR  x0 x1:(SRAconst [c] y)) && clobberIfDead(x1) -> (ORshiftRA  x0 y [c])
+(XOR x0 x1:(SLLconst [c] y)) && clobberIfDead(x1) -> (XORshiftLL x0 y [c])
+(XOR x0 x1:(SRLconst [c] y)) && clobberIfDead(x1) -> (XORshiftRL x0 y [c])
+(XOR x0 x1:(SRAconst [c] y)) && clobberIfDead(x1) -> (XORshiftRA x0 y [c])
+(BIC x0 x1:(SLLconst [c] y)) && clobberIfDead(x1) -> (BICshiftLL x0 y [c])
+(BIC x0 x1:(SRLconst [c] y)) && clobberIfDead(x1) -> (BICshiftRL x0 y [c])
+(BIC x0 x1:(SRAconst [c] y)) && clobberIfDead(x1) -> (BICshiftRA x0 y [c])
+(CMP x0 x1:(SLLconst [c] y)) && clobberIfDead(x1) -> (CMPshiftLL x0 y [c])
+(CMP x0:(SLLconst [c] y) x1) && clobberIfDead(x0) -> (InvertFlags (CMPshiftLL x1 y [c]))
+(CMP x0 x1:(SRLconst [c] y)) && clobberIfDead(x1) -> (CMPshiftRL x0 y [c])
+(CMP x0:(SRLconst [c] y) x1) && clobberIfDead(x0) -> (InvertFlags (CMPshiftRL x1 y [c]))
+(CMP x0 x1:(SRAconst [c] y)) && clobberIfDead(x1) -> (CMPshiftRA x0 y [c])
+(CMP x0:(SRAconst [c] y) x1) && clobberIfDead(x0) -> (InvertFlags (CMPshiftRA x1 y [c]))
 
 // prefer *const ops to *shift ops
 (ADDshiftLL (MOVDconst [c]) x [d]) -> (ADDconst [c] (SLLconst <x.Type> x [d]))
index c617841ee881646fb8bb124f34f298b39c783b48..e595962f74bc0d50ea951caf7484da91f728bbd3 100644 (file)
@@ -505,6 +505,17 @@ func clobber(v *Value) bool {
        return true
 }
 
+// clobberIfDead resets v when use count is 1. Returns true.
+// clobberIfDead is used by rewrite rules to decrement
+// use counts of v's args when v is dead and never used.
+func clobberIfDead(v *Value) bool {
+       if v.Uses == 1 {
+               v.reset(OpInvalid)
+       }
+       // Note: leave v.Block intact.  The Block field is used after clobberIfDead.
+       return true
+}
+
 // noteRule is an easy way to track if a rule is matched when writing
 // new ones.  Make the rule of interest also conditional on
 //     noteRule("note to self: rule of interest matched")
index 4e91217517473851baa6b8a5ca01f349ae75b46a..953e06e06ef1374570e953382656db2a51a01e06 100644 (file)
@@ -805,111 +805,129 @@ func rewriteValueARM64_OpARM64ADD_0(v *Value) bool {
                v.AddArg(y)
                return true
        }
-       // match: (ADD x (SLLconst [c] y))
-       // cond:
-       // result: (ADDshiftLL x y [c])
+       // match: (ADD x0 x1:(SLLconst [c] y))
+       // cond: clobberIfDead(x1)
+       // result: (ADDshiftLL x0 y [c])
        for {
                _ = v.Args[1]
-               x := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARM64SLLconst {
+               x0 := v.Args[0]
+               x1 := v.Args[1]
+               if x1.Op != OpARM64SLLconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               if !(clobberIfDead(x1)) {
                        break
                }
-               c := v_1.AuxInt
-               y := v_1.Args[0]
                v.reset(OpARM64ADDshiftLL)
                v.AuxInt = c
-               v.AddArg(x)
+               v.AddArg(x0)
                v.AddArg(y)
                return true
        }
-       // match: (ADD (SLLconst [c] y) x)
-       // cond:
-       // result: (ADDshiftLL x y [c])
+       // match: (ADD x1:(SLLconst [c] y) x0)
+       // cond: clobberIfDead(x1)
+       // result: (ADDshiftLL x0 y [c])
        for {
                _ = v.Args[1]
-               v_0 := v.Args[0]
-               if v_0.Op != OpARM64SLLconst {
+               x1 := v.Args[0]
+               if x1.Op != OpARM64SLLconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               x0 := v.Args[1]
+               if !(clobberIfDead(x1)) {
                        break
                }
-               c := v_0.AuxInt
-               y := v_0.Args[0]
-               x := v.Args[1]
                v.reset(OpARM64ADDshiftLL)
                v.AuxInt = c
-               v.AddArg(x)
+               v.AddArg(x0)
                v.AddArg(y)
                return true
        }
-       // match: (ADD x (SRLconst [c] y))
-       // cond:
-       // result: (ADDshiftRL x y [c])
+       // match: (ADD x0 x1:(SRLconst [c] y))
+       // cond: clobberIfDead(x1)
+       // result: (ADDshiftRL x0 y [c])
        for {
                _ = v.Args[1]
-               x := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARM64SRLconst {
+               x0 := v.Args[0]
+               x1 := v.Args[1]
+               if x1.Op != OpARM64SRLconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               if !(clobberIfDead(x1)) {
                        break
                }
-               c := v_1.AuxInt
-               y := v_1.Args[0]
                v.reset(OpARM64ADDshiftRL)
                v.AuxInt = c
-               v.AddArg(x)
+               v.AddArg(x0)
                v.AddArg(y)
                return true
        }
-       // match: (ADD (SRLconst [c] y) x)
-       // cond:
-       // result: (ADDshiftRL x y [c])
+       // match: (ADD x1:(SRLconst [c] y) x0)
+       // cond: clobberIfDead(x1)
+       // result: (ADDshiftRL x0 y [c])
        for {
                _ = v.Args[1]
-               v_0 := v.Args[0]
-               if v_0.Op != OpARM64SRLconst {
+               x1 := v.Args[0]
+               if x1.Op != OpARM64SRLconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               x0 := v.Args[1]
+               if !(clobberIfDead(x1)) {
                        break
                }
-               c := v_0.AuxInt
-               y := v_0.Args[0]
-               x := v.Args[1]
                v.reset(OpARM64ADDshiftRL)
                v.AuxInt = c
-               v.AddArg(x)
+               v.AddArg(x0)
                v.AddArg(y)
                return true
        }
-       // match: (ADD x (SRAconst [c] y))
-       // cond:
-       // result: (ADDshiftRA x y [c])
+       // match: (ADD x0 x1:(SRAconst [c] y))
+       // cond: clobberIfDead(x1)
+       // result: (ADDshiftRA x0 y [c])
        for {
                _ = v.Args[1]
-               x := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARM64SRAconst {
+               x0 := v.Args[0]
+               x1 := v.Args[1]
+               if x1.Op != OpARM64SRAconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               if !(clobberIfDead(x1)) {
                        break
                }
-               c := v_1.AuxInt
-               y := v_1.Args[0]
                v.reset(OpARM64ADDshiftRA)
                v.AuxInt = c
-               v.AddArg(x)
+               v.AddArg(x0)
                v.AddArg(y)
                return true
        }
-       // match: (ADD (SRAconst [c] y) x)
-       // cond:
-       // result: (ADDshiftRA x y [c])
+       // match: (ADD x1:(SRAconst [c] y) x0)
+       // cond: clobberIfDead(x1)
+       // result: (ADDshiftRA x0 y [c])
        for {
                _ = v.Args[1]
-               v_0 := v.Args[0]
-               if v_0.Op != OpARM64SRAconst {
+               x1 := v.Args[0]
+               if x1.Op != OpARM64SRAconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               x0 := v.Args[1]
+               if !(clobberIfDead(x1)) {
                        break
                }
-               c := v_0.AuxInt
-               y := v_0.Args[0]
-               x := v.Args[1]
                v.reset(OpARM64ADDshiftRA)
                v.AuxInt = c
-               v.AddArg(x)
+               v.AddArg(x0)
                v.AddArg(y)
                return true
        }
@@ -1304,114 +1322,132 @@ func rewriteValueARM64_OpARM64AND_0(v *Value) bool {
                v.AddArg(y)
                return true
        }
-       // match: (AND x (SLLconst [c] y))
-       // cond:
-       // result: (ANDshiftLL x y [c])
+       // match: (AND x0 x1:(SLLconst [c] y))
+       // cond: clobberIfDead(x1)
+       // result: (ANDshiftLL x0 y [c])
        for {
                _ = v.Args[1]
-               x := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARM64SLLconst {
+               x0 := v.Args[0]
+               x1 := v.Args[1]
+               if x1.Op != OpARM64SLLconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               if !(clobberIfDead(x1)) {
                        break
                }
-               c := v_1.AuxInt
-               y := v_1.Args[0]
                v.reset(OpARM64ANDshiftLL)
                v.AuxInt = c
-               v.AddArg(x)
+               v.AddArg(x0)
                v.AddArg(y)
                return true
        }
-       // match: (AND (SLLconst [c] y) x)
-       // cond:
-       // result: (ANDshiftLL x y [c])
+       // match: (AND x1:(SLLconst [c] y) x0)
+       // cond: clobberIfDead(x1)
+       // result: (ANDshiftLL x0 y [c])
        for {
                _ = v.Args[1]
-               v_0 := v.Args[0]
-               if v_0.Op != OpARM64SLLconst {
+               x1 := v.Args[0]
+               if x1.Op != OpARM64SLLconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               x0 := v.Args[1]
+               if !(clobberIfDead(x1)) {
                        break
                }
-               c := v_0.AuxInt
-               y := v_0.Args[0]
-               x := v.Args[1]
                v.reset(OpARM64ANDshiftLL)
                v.AuxInt = c
-               v.AddArg(x)
+               v.AddArg(x0)
                v.AddArg(y)
                return true
        }
-       // match: (AND x (SRLconst [c] y))
-       // cond:
-       // result: (ANDshiftRL x y [c])
+       // match: (AND x0 x1:(SRLconst [c] y))
+       // cond: clobberIfDead(x1)
+       // result: (ANDshiftRL x0 y [c])
        for {
                _ = v.Args[1]
-               x := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARM64SRLconst {
+               x0 := v.Args[0]
+               x1 := v.Args[1]
+               if x1.Op != OpARM64SRLconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               if !(clobberIfDead(x1)) {
                        break
                }
-               c := v_1.AuxInt
-               y := v_1.Args[0]
                v.reset(OpARM64ANDshiftRL)
                v.AuxInt = c
-               v.AddArg(x)
+               v.AddArg(x0)
                v.AddArg(y)
                return true
        }
-       // match: (AND (SRLconst [c] y) x)
-       // cond:
-       // result: (ANDshiftRL x y [c])
+       // match: (AND x1:(SRLconst [c] y) x0)
+       // cond: clobberIfDead(x1)
+       // result: (ANDshiftRL x0 y [c])
        for {
                _ = v.Args[1]
-               v_0 := v.Args[0]
-               if v_0.Op != OpARM64SRLconst {
+               x1 := v.Args[0]
+               if x1.Op != OpARM64SRLconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               x0 := v.Args[1]
+               if !(clobberIfDead(x1)) {
                        break
                }
-               c := v_0.AuxInt
-               y := v_0.Args[0]
-               x := v.Args[1]
                v.reset(OpARM64ANDshiftRL)
                v.AuxInt = c
-               v.AddArg(x)
+               v.AddArg(x0)
                v.AddArg(y)
                return true
        }
-       // match: (AND x (SRAconst [c] y))
-       // cond:
-       // result: (ANDshiftRA x y [c])
+       // match: (AND x0 x1:(SRAconst [c] y))
+       // cond: clobberIfDead(x1)
+       // result: (ANDshiftRA x0 y [c])
        for {
                _ = v.Args[1]
-               x := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARM64SRAconst {
+               x0 := v.Args[0]
+               x1 := v.Args[1]
+               if x1.Op != OpARM64SRAconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               if !(clobberIfDead(x1)) {
                        break
                }
-               c := v_1.AuxInt
-               y := v_1.Args[0]
                v.reset(OpARM64ANDshiftRA)
                v.AuxInt = c
-               v.AddArg(x)
+               v.AddArg(x0)
                v.AddArg(y)
                return true
        }
        return false
 }
 func rewriteValueARM64_OpARM64AND_10(v *Value) bool {
-       // match: (AND (SRAconst [c] y) x)
-       // cond:
-       // result: (ANDshiftRA x y [c])
+       // match: (AND x1:(SRAconst [c] y) x0)
+       // cond: clobberIfDead(x1)
+       // result: (ANDshiftRA x0 y [c])
        for {
                _ = v.Args[1]
-               v_0 := v.Args[0]
-               if v_0.Op != OpARM64SRAconst {
+               x1 := v.Args[0]
+               if x1.Op != OpARM64SRAconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               x0 := v.Args[1]
+               if !(clobberIfDead(x1)) {
                        break
                }
-               c := v_0.AuxInt
-               y := v_0.Args[0]
-               x := v.Args[1]
                v.reset(OpARM64ANDshiftRA)
                v.AuxInt = c
-               v.AddArg(x)
+               v.AddArg(x0)
                v.AddArg(y)
                return true
        }
@@ -1699,57 +1735,66 @@ func rewriteValueARM64_OpARM64BIC_0(v *Value) bool {
                v.AuxInt = 0
                return true
        }
-       // match: (BIC x (SLLconst [c] y))
-       // cond:
-       // result: (BICshiftLL x y [c])
+       // match: (BIC x0 x1:(SLLconst [c] y))
+       // cond: clobberIfDead(x1)
+       // result: (BICshiftLL x0 y [c])
        for {
                _ = v.Args[1]
-               x := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARM64SLLconst {
+               x0 := v.Args[0]
+               x1 := v.Args[1]
+               if x1.Op != OpARM64SLLconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               if !(clobberIfDead(x1)) {
                        break
                }
-               c := v_1.AuxInt
-               y := v_1.Args[0]
                v.reset(OpARM64BICshiftLL)
                v.AuxInt = c
-               v.AddArg(x)
+               v.AddArg(x0)
                v.AddArg(y)
                return true
        }
-       // match: (BIC x (SRLconst [c] y))
-       // cond:
-       // result: (BICshiftRL x y [c])
+       // match: (BIC x0 x1:(SRLconst [c] y))
+       // cond: clobberIfDead(x1)
+       // result: (BICshiftRL x0 y [c])
        for {
                _ = v.Args[1]
-               x := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARM64SRLconst {
+               x0 := v.Args[0]
+               x1 := v.Args[1]
+               if x1.Op != OpARM64SRLconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               if !(clobberIfDead(x1)) {
                        break
                }
-               c := v_1.AuxInt
-               y := v_1.Args[0]
                v.reset(OpARM64BICshiftRL)
                v.AuxInt = c
-               v.AddArg(x)
+               v.AddArg(x0)
                v.AddArg(y)
                return true
        }
-       // match: (BIC x (SRAconst [c] y))
-       // cond:
-       // result: (BICshiftRA x y [c])
+       // match: (BIC x0 x1:(SRAconst [c] y))
+       // cond: clobberIfDead(x1)
+       // result: (BICshiftRA x0 y [c])
        for {
                _ = v.Args[1]
-               x := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARM64SRAconst {
+               x0 := v.Args[0]
+               x1 := v.Args[1]
+               if x1.Op != OpARM64SRAconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               if !(clobberIfDead(x1)) {
                        break
                }
-               c := v_1.AuxInt
-               y := v_1.Args[0]
                v.reset(OpARM64BICshiftRA)
                v.AuxInt = c
-               v.AddArg(x)
+               v.AddArg(x0)
                v.AddArg(y)
                return true
        }
@@ -1959,116 +2004,134 @@ func rewriteValueARM64_OpARM64CMP_0(v *Value) bool {
                v.AddArg(v0)
                return true
        }
-       // match: (CMP x (SLLconst [c] y))
-       // cond:
-       // result: (CMPshiftLL x y [c])
+       // match: (CMP x0 x1:(SLLconst [c] y))
+       // cond: clobberIfDead(x1)
+       // result: (CMPshiftLL x0 y [c])
        for {
                _ = v.Args[1]
-               x := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARM64SLLconst {
+               x0 := v.Args[0]
+               x1 := v.Args[1]
+               if x1.Op != OpARM64SLLconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               if !(clobberIfDead(x1)) {
                        break
                }
-               c := v_1.AuxInt
-               y := v_1.Args[0]
                v.reset(OpARM64CMPshiftLL)
                v.AuxInt = c
-               v.AddArg(x)
+               v.AddArg(x0)
                v.AddArg(y)
                return true
        }
-       // match: (CMP (SLLconst [c] y) x)
-       // cond:
-       // result: (InvertFlags (CMPshiftLL x y [c]))
+       // match: (CMP x0:(SLLconst [c] y) x1)
+       // cond: clobberIfDead(x0)
+       // result: (InvertFlags (CMPshiftLL x1 y [c]))
        for {
                _ = v.Args[1]
-               v_0 := v.Args[0]
-               if v_0.Op != OpARM64SLLconst {
+               x0 := v.Args[0]
+               if x0.Op != OpARM64SLLconst {
+                       break
+               }
+               c := x0.AuxInt
+               y := x0.Args[0]
+               x1 := v.Args[1]
+               if !(clobberIfDead(x0)) {
                        break
                }
-               c := v_0.AuxInt
-               y := v_0.Args[0]
-               x := v.Args[1]
                v.reset(OpARM64InvertFlags)
                v0 := b.NewValue0(v.Pos, OpARM64CMPshiftLL, types.TypeFlags)
                v0.AuxInt = c
-               v0.AddArg(x)
+               v0.AddArg(x1)
                v0.AddArg(y)
                v.AddArg(v0)
                return true
        }
-       // match: (CMP x (SRLconst [c] y))
-       // cond:
-       // result: (CMPshiftRL x y [c])
+       // match: (CMP x0 x1:(SRLconst [c] y))
+       // cond: clobberIfDead(x1)
+       // result: (CMPshiftRL x0 y [c])
        for {
                _ = v.Args[1]
-               x := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARM64SRLconst {
+               x0 := v.Args[0]
+               x1 := v.Args[1]
+               if x1.Op != OpARM64SRLconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               if !(clobberIfDead(x1)) {
                        break
                }
-               c := v_1.AuxInt
-               y := v_1.Args[0]
                v.reset(OpARM64CMPshiftRL)
                v.AuxInt = c
-               v.AddArg(x)
+               v.AddArg(x0)
                v.AddArg(y)
                return true
        }
-       // match: (CMP (SRLconst [c] y) x)
-       // cond:
-       // result: (InvertFlags (CMPshiftRL x y [c]))
+       // match: (CMP x0:(SRLconst [c] y) x1)
+       // cond: clobberIfDead(x0)
+       // result: (InvertFlags (CMPshiftRL x1 y [c]))
        for {
                _ = v.Args[1]
-               v_0 := v.Args[0]
-               if v_0.Op != OpARM64SRLconst {
+               x0 := v.Args[0]
+               if x0.Op != OpARM64SRLconst {
+                       break
+               }
+               c := x0.AuxInt
+               y := x0.Args[0]
+               x1 := v.Args[1]
+               if !(clobberIfDead(x0)) {
                        break
                }
-               c := v_0.AuxInt
-               y := v_0.Args[0]
-               x := v.Args[1]
                v.reset(OpARM64InvertFlags)
                v0 := b.NewValue0(v.Pos, OpARM64CMPshiftRL, types.TypeFlags)
                v0.AuxInt = c
-               v0.AddArg(x)
+               v0.AddArg(x1)
                v0.AddArg(y)
                v.AddArg(v0)
                return true
        }
-       // match: (CMP x (SRAconst [c] y))
-       // cond:
-       // result: (CMPshiftRA x y [c])
+       // match: (CMP x0 x1:(SRAconst [c] y))
+       // cond: clobberIfDead(x1)
+       // result: (CMPshiftRA x0 y [c])
        for {
                _ = v.Args[1]
-               x := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARM64SRAconst {
+               x0 := v.Args[0]
+               x1 := v.Args[1]
+               if x1.Op != OpARM64SRAconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               if !(clobberIfDead(x1)) {
                        break
                }
-               c := v_1.AuxInt
-               y := v_1.Args[0]
                v.reset(OpARM64CMPshiftRA)
                v.AuxInt = c
-               v.AddArg(x)
+               v.AddArg(x0)
                v.AddArg(y)
                return true
        }
-       // match: (CMP (SRAconst [c] y) x)
-       // cond:
-       // result: (InvertFlags (CMPshiftRA x y [c]))
+       // match: (CMP x0:(SRAconst [c] y) x1)
+       // cond: clobberIfDead(x0)
+       // result: (InvertFlags (CMPshiftRA x1 y [c]))
        for {
                _ = v.Args[1]
-               v_0 := v.Args[0]
-               if v_0.Op != OpARM64SRAconst {
+               x0 := v.Args[0]
+               if x0.Op != OpARM64SRAconst {
+                       break
+               }
+               c := x0.AuxInt
+               y := x0.Args[0]
+               x1 := v.Args[1]
+               if !(clobberIfDead(x0)) {
                        break
                }
-               c := v_0.AuxInt
-               y := v_0.Args[0]
-               x := v.Args[1]
                v.reset(OpARM64InvertFlags)
                v0 := b.NewValue0(v.Pos, OpARM64CMPshiftRA, types.TypeFlags)
                v0.AuxInt = c
-               v0.AddArg(x)
+               v0.AddArg(x1)
                v0.AddArg(y)
                v.AddArg(v0)
                return true
@@ -6930,111 +6993,129 @@ func rewriteValueARM64_OpARM64OR_0(v *Value) bool {
                v.AddArg(x)
                return true
        }
-       // match: (OR x (SLLconst [c] y))
-       // cond:
-       // result: (ORshiftLL  x y [c])
+       // match: (OR x0 x1:(SLLconst [c] y))
+       // cond: clobberIfDead(x1)
+       // result: (ORshiftLL  x0 y [c])
        for {
                _ = v.Args[1]
-               x := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARM64SLLconst {
+               x0 := v.Args[0]
+               x1 := v.Args[1]
+               if x1.Op != OpARM64SLLconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               if !(clobberIfDead(x1)) {
                        break
                }
-               c := v_1.AuxInt
-               y := v_1.Args[0]
                v.reset(OpARM64ORshiftLL)
                v.AuxInt = c
-               v.AddArg(x)
+               v.AddArg(x0)
                v.AddArg(y)
                return true
        }
-       // match: (OR (SLLconst [c] y) x)
-       // cond:
-       // result: (ORshiftLL  x y [c])
+       // match: (OR x1:(SLLconst [c] y) x0)
+       // cond: clobberIfDead(x1)
+       // result: (ORshiftLL  x0 y [c])
        for {
                _ = v.Args[1]
-               v_0 := v.Args[0]
-               if v_0.Op != OpARM64SLLconst {
+               x1 := v.Args[0]
+               if x1.Op != OpARM64SLLconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               x0 := v.Args[1]
+               if !(clobberIfDead(x1)) {
                        break
                }
-               c := v_0.AuxInt
-               y := v_0.Args[0]
-               x := v.Args[1]
                v.reset(OpARM64ORshiftLL)
                v.AuxInt = c
-               v.AddArg(x)
+               v.AddArg(x0)
                v.AddArg(y)
                return true
        }
-       // match: (OR x (SRLconst [c] y))
-       // cond:
-       // result: (ORshiftRL  x y [c])
+       // match: (OR x0 x1:(SRLconst [c] y))
+       // cond: clobberIfDead(x1)
+       // result: (ORshiftRL  x0 y [c])
        for {
                _ = v.Args[1]
-               x := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARM64SRLconst {
+               x0 := v.Args[0]
+               x1 := v.Args[1]
+               if x1.Op != OpARM64SRLconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               if !(clobberIfDead(x1)) {
                        break
                }
-               c := v_1.AuxInt
-               y := v_1.Args[0]
                v.reset(OpARM64ORshiftRL)
                v.AuxInt = c
-               v.AddArg(x)
+               v.AddArg(x0)
                v.AddArg(y)
                return true
        }
-       // match: (OR (SRLconst [c] y) x)
-       // cond:
-       // result: (ORshiftRL  x y [c])
+       // match: (OR x1:(SRLconst [c] y) x0)
+       // cond: clobberIfDead(x1)
+       // result: (ORshiftRL  x0 y [c])
        for {
                _ = v.Args[1]
-               v_0 := v.Args[0]
-               if v_0.Op != OpARM64SRLconst {
+               x1 := v.Args[0]
+               if x1.Op != OpARM64SRLconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               x0 := v.Args[1]
+               if !(clobberIfDead(x1)) {
                        break
                }
-               c := v_0.AuxInt
-               y := v_0.Args[0]
-               x := v.Args[1]
                v.reset(OpARM64ORshiftRL)
                v.AuxInt = c
-               v.AddArg(x)
+               v.AddArg(x0)
                v.AddArg(y)
                return true
        }
-       // match: (OR x (SRAconst [c] y))
-       // cond:
-       // result: (ORshiftRA  x y [c])
+       // match: (OR x0 x1:(SRAconst [c] y))
+       // cond: clobberIfDead(x1)
+       // result: (ORshiftRA  x0 y [c])
        for {
                _ = v.Args[1]
-               x := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARM64SRAconst {
+               x0 := v.Args[0]
+               x1 := v.Args[1]
+               if x1.Op != OpARM64SRAconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               if !(clobberIfDead(x1)) {
                        break
                }
-               c := v_1.AuxInt
-               y := v_1.Args[0]
                v.reset(OpARM64ORshiftRA)
                v.AuxInt = c
-               v.AddArg(x)
+               v.AddArg(x0)
                v.AddArg(y)
                return true
        }
-       // match: (OR (SRAconst [c] y) x)
-       // cond:
-       // result: (ORshiftRA  x y [c])
+       // match: (OR x1:(SRAconst [c] y) x0)
+       // cond: clobberIfDead(x1)
+       // result: (ORshiftRA  x0 y [c])
        for {
                _ = v.Args[1]
-               v_0 := v.Args[0]
-               if v_0.Op != OpARM64SRAconst {
+               x1 := v.Args[0]
+               if x1.Op != OpARM64SRAconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               x0 := v.Args[1]
+               if !(clobberIfDead(x1)) {
                        break
                }
-               c := v_0.AuxInt
-               y := v_0.Args[0]
-               x := v.Args[1]
                v.reset(OpARM64ORshiftRA)
                v.AuxInt = c
-               v.AddArg(x)
+               v.AddArg(x0)
                v.AddArg(y)
                return true
        }
@@ -9628,57 +9709,66 @@ func rewriteValueARM64_OpARM64SUB_0(v *Value) bool {
                v.AddArg(v0)
                return true
        }
-       // match: (SUB x (SLLconst [c] y))
-       // cond:
-       // result: (SUBshiftLL x y [c])
+       // match: (SUB x0 x1:(SLLconst [c] y))
+       // cond: clobberIfDead(x1)
+       // result: (SUBshiftLL x0 y [c])
        for {
                _ = v.Args[1]
-               x := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARM64SLLconst {
+               x0 := v.Args[0]
+               x1 := v.Args[1]
+               if x1.Op != OpARM64SLLconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               if !(clobberIfDead(x1)) {
                        break
                }
-               c := v_1.AuxInt
-               y := v_1.Args[0]
                v.reset(OpARM64SUBshiftLL)
                v.AuxInt = c
-               v.AddArg(x)
+               v.AddArg(x0)
                v.AddArg(y)
                return true
        }
-       // match: (SUB x (SRLconst [c] y))
-       // cond:
-       // result: (SUBshiftRL x y [c])
+       // match: (SUB x0 x1:(SRLconst [c] y))
+       // cond: clobberIfDead(x1)
+       // result: (SUBshiftRL x0 y [c])
        for {
                _ = v.Args[1]
-               x := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARM64SRLconst {
+               x0 := v.Args[0]
+               x1 := v.Args[1]
+               if x1.Op != OpARM64SRLconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               if !(clobberIfDead(x1)) {
                        break
                }
-               c := v_1.AuxInt
-               y := v_1.Args[0]
                v.reset(OpARM64SUBshiftRL)
                v.AuxInt = c
-               v.AddArg(x)
+               v.AddArg(x0)
                v.AddArg(y)
                return true
        }
-       // match: (SUB x (SRAconst [c] y))
-       // cond:
-       // result: (SUBshiftRA x y [c])
+       // match: (SUB x0 x1:(SRAconst [c] y))
+       // cond: clobberIfDead(x1)
+       // result: (SUBshiftRA x0 y [c])
        for {
                _ = v.Args[1]
-               x := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARM64SRAconst {
+               x0 := v.Args[0]
+               x1 := v.Args[1]
+               if x1.Op != OpARM64SRAconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               if !(clobberIfDead(x1)) {
                        break
                }
-               c := v_1.AuxInt
-               y := v_1.Args[0]
                v.reset(OpARM64SUBshiftRA)
                v.AuxInt = c
-               v.AddArg(x)
+               v.AddArg(x0)
                v.AddArg(y)
                return true
        }
@@ -10152,111 +10242,129 @@ func rewriteValueARM64_OpARM64XOR_0(v *Value) bool {
                v.AuxInt = 0
                return true
        }
-       // match: (XOR x (SLLconst [c] y))
-       // cond:
-       // result: (XORshiftLL x y [c])
+       // match: (XOR x0 x1:(SLLconst [c] y))
+       // cond: clobberIfDead(x1)
+       // result: (XORshiftLL x0 y [c])
        for {
                _ = v.Args[1]
-               x := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARM64SLLconst {
+               x0 := v.Args[0]
+               x1 := v.Args[1]
+               if x1.Op != OpARM64SLLconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               if !(clobberIfDead(x1)) {
                        break
                }
-               c := v_1.AuxInt
-               y := v_1.Args[0]
                v.reset(OpARM64XORshiftLL)
                v.AuxInt = c
-               v.AddArg(x)
+               v.AddArg(x0)
                v.AddArg(y)
                return true
        }
-       // match: (XOR (SLLconst [c] y) x)
-       // cond:
-       // result: (XORshiftLL x y [c])
+       // match: (XOR x1:(SLLconst [c] y) x0)
+       // cond: clobberIfDead(x1)
+       // result: (XORshiftLL x0 y [c])
        for {
                _ = v.Args[1]
-               v_0 := v.Args[0]
-               if v_0.Op != OpARM64SLLconst {
+               x1 := v.Args[0]
+               if x1.Op != OpARM64SLLconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               x0 := v.Args[1]
+               if !(clobberIfDead(x1)) {
                        break
                }
-               c := v_0.AuxInt
-               y := v_0.Args[0]
-               x := v.Args[1]
                v.reset(OpARM64XORshiftLL)
                v.AuxInt = c
-               v.AddArg(x)
+               v.AddArg(x0)
                v.AddArg(y)
                return true
        }
-       // match: (XOR x (SRLconst [c] y))
-       // cond:
-       // result: (XORshiftRL x y [c])
+       // match: (XOR x0 x1:(SRLconst [c] y))
+       // cond: clobberIfDead(x1)
+       // result: (XORshiftRL x0 y [c])
        for {
                _ = v.Args[1]
-               x := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARM64SRLconst {
+               x0 := v.Args[0]
+               x1 := v.Args[1]
+               if x1.Op != OpARM64SRLconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               if !(clobberIfDead(x1)) {
                        break
                }
-               c := v_1.AuxInt
-               y := v_1.Args[0]
                v.reset(OpARM64XORshiftRL)
                v.AuxInt = c
-               v.AddArg(x)
+               v.AddArg(x0)
                v.AddArg(y)
                return true
        }
-       // match: (XOR (SRLconst [c] y) x)
-       // cond:
-       // result: (XORshiftRL x y [c])
+       // match: (XOR x1:(SRLconst [c] y) x0)
+       // cond: clobberIfDead(x1)
+       // result: (XORshiftRL x0 y [c])
        for {
                _ = v.Args[1]
-               v_0 := v.Args[0]
-               if v_0.Op != OpARM64SRLconst {
+               x1 := v.Args[0]
+               if x1.Op != OpARM64SRLconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               x0 := v.Args[1]
+               if !(clobberIfDead(x1)) {
                        break
                }
-               c := v_0.AuxInt
-               y := v_0.Args[0]
-               x := v.Args[1]
                v.reset(OpARM64XORshiftRL)
                v.AuxInt = c
-               v.AddArg(x)
+               v.AddArg(x0)
                v.AddArg(y)
                return true
        }
-       // match: (XOR x (SRAconst [c] y))
-       // cond:
-       // result: (XORshiftRA x y [c])
+       // match: (XOR x0 x1:(SRAconst [c] y))
+       // cond: clobberIfDead(x1)
+       // result: (XORshiftRA x0 y [c])
        for {
                _ = v.Args[1]
-               x := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARM64SRAconst {
+               x0 := v.Args[0]
+               x1 := v.Args[1]
+               if x1.Op != OpARM64SRAconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               if !(clobberIfDead(x1)) {
                        break
                }
-               c := v_1.AuxInt
-               y := v_1.Args[0]
                v.reset(OpARM64XORshiftRA)
                v.AuxInt = c
-               v.AddArg(x)
+               v.AddArg(x0)
                v.AddArg(y)
                return true
        }
-       // match: (XOR (SRAconst [c] y) x)
-       // cond:
-       // result: (XORshiftRA x y [c])
+       // match: (XOR x1:(SRAconst [c] y) x0)
+       // cond: clobberIfDead(x1)
+       // result: (XORshiftRA x0 y [c])
        for {
                _ = v.Args[1]
-               v_0 := v.Args[0]
-               if v_0.Op != OpARM64SRAconst {
+               x1 := v.Args[0]
+               if x1.Op != OpARM64SRAconst {
+                       break
+               }
+               c := x1.AuxInt
+               y := x1.Args[0]
+               x0 := v.Args[1]
+               if !(clobberIfDead(x1)) {
                        break
                }
-               c := v_0.AuxInt
-               y := v_0.Args[0]
-               x := v.Args[1]
                v.reset(OpARM64XORshiftRA)
                v.AuxInt = c
-               v.AddArg(x)
+               v.AddArg(x0)
                v.AddArg(y)
                return true
        }