]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: optimize arm's comparison
authorBen Shi <powerman1st@163.com>
Tue, 10 Jul 2018 01:48:55 +0000 (01:48 +0000)
committerCherry Zhang <cherryyz@google.com>
Mon, 27 Aug 2018 15:49:46 +0000 (15:49 +0000)
The CMP/CMN/TST/TEQ perform similar to SUB/ADD/AND/XOR except
the result is abondoned, and only NZCV flags are affected.

This CL implements further optimization with them.

1. A micro benchmark test gets more than 9% improvment.
TSTTEQ-4                   6.99ms ± 0%    6.35ms ± 0%  -9.15%  (p=0.000 n=33+36)
(https://github.com/benshi001/ugo1/blob/master/tstteq2_test.go)

2. The go1 benckmark shows no regression, excluding noise.
name                     old time/op    new time/op    delta
BinaryTree17-4              25.7s ± 1%     25.7s ± 1%    ~     (p=0.830 n=40+40)
Fannkuch11-4                13.3s ± 0%     13.2s ± 0%  -0.65%  (p=0.000 n=40+34)
FmtFprintfEmpty-4           394ns ± 0%     394ns ± 0%    ~     (p=0.819 n=40+40)
FmtFprintfString-4          677ns ± 0%     677ns ± 0%  +0.06%  (p=0.039 n=39+40)
FmtFprintfInt-4             707ns ± 0%     706ns ± 0%  -0.14%  (p=0.000 n=40+39)
FmtFprintfIntInt-4         1.04µs ± 0%    1.04µs ± 0%  +0.10%  (p=0.000 n=29+31)
FmtFprintfPrefixedInt-4    1.10µs ± 0%    1.11µs ± 0%  +0.65%  (p=0.000 n=39+37)
FmtFprintfFloat-4          2.27µs ± 0%    2.26µs ± 0%  -0.53%  (p=0.000 n=39+40)
FmtManyArgs-4              3.96µs ± 0%    3.96µs ± 0%  +0.10%  (p=0.000 n=39+40)
GobDecode-4                53.4ms ± 1%    52.8ms ± 2%  -1.10%  (p=0.000 n=39+39)
GobEncode-4                50.3ms ± 3%    50.4ms ± 2%    ~     (p=0.089 n=40+39)
Gzip-4                      2.62s ± 0%     2.64s ± 0%  +0.60%  (p=0.000 n=40+39)
Gunzip-4                    312ms ± 0%     312ms ± 0%  +0.02%  (p=0.030 n=40+39)
HTTPClientServer-4         1.01ms ± 7%    0.98ms ± 7%  -2.37%  (p=0.000 n=40+39)
JSONEncode-4                126ms ± 1%     126ms ± 1%  -0.38%  (p=0.004 n=39+39)
JSONDecode-4                423ms ± 0%     426ms ± 2%  +0.72%  (p=0.001 n=39+40)
Mandelbrot200-4            18.4ms ± 0%    18.4ms ± 0%  +0.04%  (p=0.000 n=38+40)
GoParse-4                  22.8ms ± 0%    22.6ms ± 0%  -0.68%  (p=0.000 n=35+40)
RegexpMatchEasy0_32-4       699ns ± 0%     704ns ± 0%  +0.73%  (p=0.000 n=27+40)
RegexpMatchEasy0_1K-4      4.27µs ± 0%    4.26µs ± 0%  -0.09%  (p=0.000 n=35+38)
RegexpMatchEasy1_32-4       741ns ± 0%     735ns ± 0%  -0.85%  (p=0.000 n=40+35)
RegexpMatchEasy1_1K-4      5.53µs ± 0%    5.49µs ± 0%  -0.69%  (p=0.000 n=39+40)
RegexpMatchMedium_32-4     1.07µs ± 0%    1.04µs ± 2%  -2.34%  (p=0.000 n=40+40)
RegexpMatchMedium_1K-4      261µs ± 0%     261µs ± 0%  -0.16%  (p=0.000 n=40+39)
RegexpMatchHard_32-4       14.9µs ± 0%    14.9µs ± 0%  -0.18%  (p=0.000 n=39+40)
RegexpMatchHard_1K-4        445µs ± 0%     446µs ± 0%  +0.09%  (p=0.000 n=36+34)
Revcomp-4                  41.8ms ± 1%    41.8ms ± 1%    ~     (p=0.595 n=39+38)
Template-4                  530ms ± 1%     528ms ± 1%  -0.49%  (p=0.000 n=40+40)
TimeParse-4                3.39µs ± 0%    3.42µs ± 0%  +0.98%  (p=0.000 n=36+38)
TimeFormat-4               6.12µs ± 0%    6.07µs ± 0%  -0.81%  (p=0.000 n=34+38)
[Geo mean]                  384µs          383µs       -0.24%

name                     old speed      new speed      delta
GobDecode-4              14.4MB/s ± 1%  14.5MB/s ± 2%  +1.11%  (p=0.000 n=39+39)
GobEncode-4              15.3MB/s ± 3%  15.2MB/s ± 2%    ~     (p=0.104 n=40+39)
Gzip-4                   7.40MB/s ± 1%  7.36MB/s ± 0%  -0.60%  (p=0.000 n=40+39)
Gunzip-4                 62.2MB/s ± 0%  62.1MB/s ± 0%  -0.02%  (p=0.047 n=40+39)
JSONEncode-4             15.4MB/s ± 1%  15.4MB/s ± 2%  +0.39%  (p=0.002 n=39+39)
JSONDecode-4             4.59MB/s ± 0%  4.56MB/s ± 2%  -0.71%  (p=0.000 n=39+40)
GoParse-4                2.54MB/s ± 0%  2.56MB/s ± 0%  +0.72%  (p=0.000 n=26+40)
RegexpMatchEasy0_32-4    45.8MB/s ± 0%  45.4MB/s ± 0%  -0.75%  (p=0.000 n=38+40)
RegexpMatchEasy0_1K-4     240MB/s ± 0%   240MB/s ± 0%  +0.09%  (p=0.000 n=35+38)
RegexpMatchEasy1_32-4    43.1MB/s ± 0%  43.5MB/s ± 0%  +0.84%  (p=0.000 n=40+39)
RegexpMatchEasy1_1K-4     185MB/s ± 0%   186MB/s ± 0%  +0.69%  (p=0.000 n=39+40)
RegexpMatchMedium_32-4    936kB/s ± 1%   959kB/s ± 2%  +2.38%  (p=0.000 n=40+40)
RegexpMatchMedium_1K-4   3.92MB/s ± 0%  3.93MB/s ± 0%  +0.18%  (p=0.000 n=39+40)
RegexpMatchHard_32-4     2.15MB/s ± 0%  2.15MB/s ± 0%  +0.19%  (p=0.000 n=40+40)
RegexpMatchHard_1K-4     2.30MB/s ± 0%  2.30MB/s ± 0%    ~     (all equal)
Revcomp-4                60.8MB/s ± 1%  60.8MB/s ± 1%    ~     (p=0.600 n=39+38)
Template-4               3.66MB/s ± 1%  3.68MB/s ± 1%  +0.46%  (p=0.000 n=40+40)
[Geo mean]               12.8MB/s       12.8MB/s       +0.27%

Change-Id: I849161169ecf0876a04b7c1d3990fa8d1435215e
Reviewed-on: https://go-review.googlesource.com/122855
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/ssa/gen/ARM.rules
src/cmd/compile/internal/ssa/rewriteARM.go
test/codegen/comparisons.go

index e8a3c27c71beab946f5b041d96a26f63e28104ce..8cea322295bdb7525fcbdaf70c62f45f3e07b083 100644 (file)
 (NE (CMPconst [0] (XORshiftLLreg x y z)) yes no) -> (NE (TEQshiftLLreg x y z) yes no)
 (NE (CMPconst [0] (XORshiftRLreg x y z)) yes no) -> (NE (TEQshiftRLreg x y z) yes no)
 (NE (CMPconst [0] (XORshiftRAreg x y z)) yes no) -> (NE (TEQshiftRAreg x y z) yes no)
+(LT (CMPconst [0] l:(SUB x y)) yes no) -> (LT (CMP x y) yes no)
+(LT (CMPconst [0] (MULS x y a)) yes no) -> (LT (CMP a (MUL <x.Type> x y)) yes no)
+(LT (CMPconst [0] l:(SUBconst [c] x)) yes no) -> (LT (CMPconst [c] x) yes no)
+(LT (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) -> (LT (CMPshiftLL x y [c]) yes no)
+(LT (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) -> (LT (CMPshiftRL x y [c]) yes no)
+(LT (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) -> (LT (CMPshiftRA x y [c]) yes no)
+(LT (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) -> (LT (CMPshiftLLreg x y z) yes no)
+(LT (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) -> (LT (CMPshiftRLreg x y z) yes no)
+(LT (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) -> (LT (CMPshiftRAreg x y z) yes no)
+(LE (CMPconst [0] l:(SUB x y)) yes no) -> (LE (CMP x y) yes no)
+(LE (CMPconst [0] (MULS x y a)) yes no) -> (LE (CMP a (MUL <x.Type> x y)) yes no)
+(LE (CMPconst [0] l:(SUBconst [c] x)) yes no) -> (LE (CMPconst [c] x) yes no)
+(LE (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) -> (LE (CMPshiftLL x y [c]) yes no)
+(LE (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) -> (LE (CMPshiftRL x y [c]) yes no)
+(LE (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) -> (LE (CMPshiftRA x y [c]) yes no)
+(LE (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) -> (LE (CMPshiftLLreg x y z) yes no)
+(LE (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) -> (LE (CMPshiftRLreg x y z) yes no)
+(LE (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) -> (LE (CMPshiftRAreg x y z) yes no)
+(LT (CMPconst [0] l:(ADD x y)) yes no) -> (LT (CMN x y) yes no)
+(LT (CMPconst [0] (MULA x y a)) yes no) -> (LT (CMN a (MUL <x.Type> x y)) yes no)
+(LT (CMPconst [0] l:(ADDconst [c] x)) yes no) -> (LT (CMNconst [c] x) yes no)
+(LT (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) -> (LT (CMNshiftLL x y [c]) yes no)
+(LT (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) -> (LT (CMNshiftRL x y [c]) yes no)
+(LT (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) -> (LT (CMNshiftRA x y [c]) yes no)
+(LT (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) -> (LT (CMNshiftLLreg x y z) yes no)
+(LT (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) -> (LT (CMNshiftRLreg x y z) yes no)
+(LT (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) -> (LT (CMNshiftRAreg x y z) yes no)
+(LE (CMPconst [0] l:(ADD x y)) yes no) -> (LE (CMN x y) yes no)
+(LE (CMPconst [0] (MULA x y a)) yes no) -> (LE (CMN a (MUL <x.Type> x y)) yes no)
+(LE (CMPconst [0] l:(ADDconst [c] x)) yes no) -> (LE (CMNconst [c] x) yes no)
+(LE (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) -> (LE (CMNshiftLL x y [c]) yes no)
+(LE (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) -> (LE (CMNshiftRL x y [c]) yes no)
+(LE (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) -> (LE (CMNshiftRA x y [c]) yes no)
+(LE (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) -> (LE (CMNshiftLLreg x y z) yes no)
+(LE (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) -> (LE (CMNshiftRLreg x y z) yes no)
+(LE (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) -> (LE (CMNshiftRAreg x y z) yes no)
+(LT (CMPconst [0] l:(AND x y)) yes no) -> (LT (TST x y) yes no)
+(LT (CMPconst [0] l:(ANDconst [c] x)) yes no) -> (LT (TSTconst [c] x) yes no)
+(LT (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) -> (LT (TSTshiftLL x y [c]) yes no)
+(LT (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) -> (LT (TSTshiftRL x y [c]) yes no)
+(LT (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) -> (LT (TSTshiftRA x y [c]) yes no)
+(LT (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) -> (LT (TSTshiftLLreg x y z) yes no)
+(LT (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) -> (LT (TSTshiftRLreg x y z) yes no)
+(LT (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) -> (LT (TSTshiftRAreg x y z) yes no)
+(LE (CMPconst [0] l:(AND x y)) yes no) -> (LE (TST x y) yes no)
+(LE (CMPconst [0] l:(ANDconst [c] x)) yes no) -> (LE (TSTconst [c] x) yes no)
+(LE (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) -> (LE (TSTshiftLL x y [c]) yes no)
+(LE (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) -> (LE (TSTshiftRL x y [c]) yes no)
+(LE (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) -> (LE (TSTshiftRA x y [c]) yes no)
+(LE (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) -> (LE (TSTshiftLLreg x y z) yes no)
+(LE (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) -> (LE (TSTshiftRLreg x y z) yes no)
+(LE (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) -> (LE (TSTshiftRAreg x y z) yes no)
+(LT (CMPconst [0] l:(XOR x y)) yes no) -> (LT (TEQ x y) yes no)
+(LT (CMPconst [0] l:(XORconst [c] x)) yes no) -> (LT (TEQconst [c] x) yes no)
+(LT (CMPconst [0] l:(XORshiftLL x y [c])) yes no) -> (LT (TEQshiftLL x y [c]) yes no)
+(LT (CMPconst [0] l:(XORshiftRL x y [c])) yes no) -> (LT (TEQshiftRL x y [c]) yes no)
+(LT (CMPconst [0] l:(XORshiftRA x y [c])) yes no) -> (LT (TEQshiftRA x y [c]) yes no)
+(LT (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) -> (LT (TEQshiftLLreg x y z) yes no)
+(LT (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) -> (LT (TEQshiftRLreg x y z) yes no)
+(LT (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) -> (LT (TEQshiftRAreg x y z) yes no)
+(LE (CMPconst [0] l:(XOR x y)) yes no) -> (LE (TEQ x y) yes no)
+(LE (CMPconst [0] l:(XORconst [c] x)) yes no) -> (LE (TEQconst [c] x) yes no)
+(LE (CMPconst [0] l:(XORshiftLL x y [c])) yes no) -> (LE (TEQshiftLL x y [c]) yes no)
+(LE (CMPconst [0] l:(XORshiftRL x y [c])) yes no) -> (LE (TEQshiftRL x y [c]) yes no)
+(LE (CMPconst [0] l:(XORshiftRA x y [c])) yes no) -> (LE (TEQshiftRA x y [c]) yes no)
+(LE (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) -> (LE (TEQshiftLLreg x y z) yes no)
+(LE (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) -> (LE (TEQshiftRLreg x y z) yes no)
+(LE (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) -> (LE (TEQshiftRAreg x y z) yes no)
+(GT (CMPconst [0] l:(SUB x y)) yes no) -> (GT (CMP x y) yes no)
+(GT (CMPconst [0] (MULS x y a)) yes no) -> (GT (CMP a (MUL <x.Type> x y)) yes no)
+(GT (CMPconst [0] l:(SUBconst [c] x)) yes no) -> (GT (CMPconst [c] x) yes no)
+(GT (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) -> (GT (CMPshiftLL x y [c]) yes no)
+(GT (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) -> (GT (CMPshiftRL x y [c]) yes no)
+(GT (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) -> (GT (CMPshiftRA x y [c]) yes no)
+(GT (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) -> (GT (CMPshiftLLreg x y z) yes no)
+(GT (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) -> (GT (CMPshiftRLreg x y z) yes no)
+(GT (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) -> (GT (CMPshiftRAreg x y z) yes no)
+(GE (CMPconst [0] l:(SUB x y)) yes no) -> (GE (CMP x y) yes no)
+(GE (CMPconst [0] (MULS x y a)) yes no) -> (GE (CMP a (MUL <x.Type> x y)) yes no)
+(GE (CMPconst [0] l:(SUBconst [c] x)) yes no) -> (GE (CMPconst [c] x) yes no)
+(GE (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) -> (GE (CMPshiftLL x y [c]) yes no)
+(GE (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) -> (GE (CMPshiftRL x y [c]) yes no)
+(GE (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) -> (GE (CMPshiftRA x y [c]) yes no)
+(GE (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) -> (GE (CMPshiftLLreg x y z) yes no)
+(GE (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) -> (GE (CMPshiftRLreg x y z) yes no)
+(GE (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) -> (GE (CMPshiftRAreg x y z) yes no)
+(GT (CMPconst [0] l:(ADD x y)) yes no) -> (GT (CMN x y) yes no)
+(GT (CMPconst [0] l:(ADDconst [c] x)) yes no) -> (GT (CMNconst [c] x) yes no)
+(GT (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) -> (GT (CMNshiftLL x y [c]) yes no)
+(GT (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) -> (GT (CMNshiftRL x y [c]) yes no)
+(GT (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) -> (GT (CMNshiftRA x y [c]) yes no)
+(GT (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) -> (GT (CMNshiftLLreg x y z) yes no)
+(GT (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) -> (GT (CMNshiftRLreg x y z) yes no)
+(GT (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) -> (GT (CMNshiftRAreg x y z) yes no)
+(GE (CMPconst [0] l:(ADD x y)) yes no) -> (GE (CMN x y) yes no)
+(GE (CMPconst [0] (MULA x y a)) yes no) -> (GE (CMN a (MUL <x.Type> x y)) yes no)
+(GE (CMPconst [0] l:(ADDconst [c] x)) yes no) -> (GE (CMNconst [c] x) yes no)
+(GE (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) -> (GE (CMNshiftLL x y [c]) yes no)
+(GE (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) -> (GE (CMNshiftRL x y [c]) yes no)
+(GE (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) -> (GE (CMNshiftRA x y [c]) yes no)
+(GE (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) -> (GE (CMNshiftLLreg x y z) yes no)
+(GE (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) -> (GE (CMNshiftRLreg x y z) yes no)
+(GE (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) -> (GE (CMNshiftRAreg x y z) yes no)
+(GT (CMPconst [0] l:(AND x y)) yes no) -> (GT (TST x y) yes no)
+(GT (CMPconst [0] (MULA x y a)) yes no) -> (GT (CMN a (MUL <x.Type> x y)) yes no)
+(GT (CMPconst [0] l:(ANDconst [c] x)) yes no) -> (GT (TSTconst [c] x) yes no)
+(GT (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) -> (GT (TSTshiftLL x y [c]) yes no)
+(GT (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) -> (GT (TSTshiftRL x y [c]) yes no)
+(GT (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) -> (GT (TSTshiftRA x y [c]) yes no)
+(GT (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) -> (GT (TSTshiftLLreg x y z) yes no)
+(GT (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) -> (GT (TSTshiftRLreg x y z) yes no)
+(GT (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) -> (GT (TSTshiftRAreg x y z) yes no)
+(GE (CMPconst [0] l:(AND x y)) yes no) -> (GE (TST x y) yes no)
+(GE (CMPconst [0] l:(ANDconst [c] x)) yes no) -> (GE (TSTconst [c] x) yes no)
+(GE (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) -> (GE (TSTshiftLL x y [c]) yes no)
+(GE (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) -> (GE (TSTshiftRL x y [c]) yes no)
+(GE (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) -> (GE (TSTshiftRA x y [c]) yes no)
+(GE (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) -> (GE (TSTshiftLLreg x y z) yes no)
+(GE (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) -> (GE (TSTshiftRLreg x y z) yes no)
+(GE (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) -> (GE (TSTshiftRAreg x y z) yes no)
+(GT (CMPconst [0] l:(XOR x y)) yes no) -> (GT (TEQ x y) yes no)
+(GT (CMPconst [0] l:(XORconst [c] x)) yes no) -> (GT (TEQconst [c] x) yes no)
+(GT (CMPconst [0] l:(XORshiftLL x y [c])) yes no) -> (GT (TEQshiftLL x y [c]) yes no)
+(GT (CMPconst [0] l:(XORshiftRL x y [c])) yes no) -> (GT (TEQshiftRL x y [c]) yes no)
+(GT (CMPconst [0] l:(XORshiftRA x y [c])) yes no) -> (GT (TEQshiftRA x y [c]) yes no)
+(GT (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) -> (GT (TEQshiftLLreg x y z) yes no)
+(GT (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) -> (GT (TEQshiftRLreg x y z) yes no)
+(GT (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) -> (GT (TEQshiftRAreg x y z) yes no)
+(GE (CMPconst [0] l:(XOR x y)) yes no) -> (GE (TEQ x y) yes no)
+(GE (CMPconst [0] l:(XORconst [c] x)) yes no) -> (GE (TEQconst [c] x) yes no)
+(GE (CMPconst [0] l:(XORshiftLL x y [c])) yes no) -> (GE (TEQshiftLL x y [c]) yes no)
+(GE (CMPconst [0] l:(XORshiftRL x y [c])) yes no) -> (GE (TEQshiftRL x y [c]) yes no)
+(GE (CMPconst [0] l:(XORshiftRA x y [c])) yes no) -> (GE (TEQshiftRA x y [c]) yes no)
+(GE (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) -> (GE (TEQshiftLLreg x y z) yes no)
+(GE (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) -> (GE (TEQshiftRLreg x y z) yes no)
+(GE (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) -> (GE (TEQshiftRAreg x y z) yes no)
index e463511f17361115d4d1a885ebe5df83617ca70c..40d8d7f0b38420831f8a246a921ed95a32698b55 100644 (file)
@@ -23274,6 +23274,942 @@ func rewriteBlockARM(b *Block) bool {
                        b.Aux = nil
                        return true
                }
+               // match: (GE (CMPconst [0] l:(SUB x y)) yes no)
+               // cond:
+               // result: (GE (CMP x y) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMSUB {
+                               break
+                       }
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMGE
+                       v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GE (CMPconst [0] (MULS x y a)) yes no)
+               // cond:
+               // result: (GE (CMP a (MUL <x.Type> x y)) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMMULS {
+                               break
+                       }
+                       _ = v_0.Args[2]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       a := v_0.Args[2]
+                       b.Kind = BlockARMGE
+                       v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
+                       v0.AddArg(a)
+                       v1 := b.NewValue0(v.Pos, OpARMMUL, x.Type)
+                       v1.AddArg(x)
+                       v1.AddArg(y)
+                       v0.AddArg(v1)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GE (CMPconst [0] l:(SUBconst [c] x)) yes no)
+               // cond:
+               // result: (GE (CMPconst [c] x) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMSUBconst {
+                               break
+                       }
+                       c := l.AuxInt
+                       x := l.Args[0]
+                       b.Kind = BlockARMGE
+                       v0 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GE (CMPconst [0] l:(SUBshiftLL x y [c])) yes no)
+               // cond:
+               // result: (GE (CMPshiftLL x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMSUBshiftLL {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMGE
+                       v0 := b.NewValue0(v.Pos, OpARMCMPshiftLL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GE (CMPconst [0] l:(SUBshiftRL x y [c])) yes no)
+               // cond:
+               // result: (GE (CMPshiftRL x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMSUBshiftRL {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMGE
+                       v0 := b.NewValue0(v.Pos, OpARMCMPshiftRL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GE (CMPconst [0] l:(SUBshiftRA x y [c])) yes no)
+               // cond:
+               // result: (GE (CMPshiftRA x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMSUBshiftRA {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMGE
+                       v0 := b.NewValue0(v.Pos, OpARMCMPshiftRA, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GE (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no)
+               // cond:
+               // result: (GE (CMPshiftLLreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMSUBshiftLLreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMGE
+                       v0 := b.NewValue0(v.Pos, OpARMCMPshiftLLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GE (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no)
+               // cond:
+               // result: (GE (CMPshiftRLreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMSUBshiftRLreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMGE
+                       v0 := b.NewValue0(v.Pos, OpARMCMPshiftRLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GE (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no)
+               // cond:
+               // result: (GE (CMPshiftRAreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMSUBshiftRAreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMGE
+                       v0 := b.NewValue0(v.Pos, OpARMCMPshiftRAreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GE (CMPconst [0] l:(ADD x y)) yes no)
+               // cond:
+               // result: (GE (CMN x y) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMADD {
+                               break
+                       }
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMGE
+                       v0 := b.NewValue0(v.Pos, OpARMCMN, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GE (CMPconst [0] (MULA x y a)) yes no)
+               // cond:
+               // result: (GE (CMN a (MUL <x.Type> x y)) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMMULA {
+                               break
+                       }
+                       _ = v_0.Args[2]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       a := v_0.Args[2]
+                       b.Kind = BlockARMGE
+                       v0 := b.NewValue0(v.Pos, OpARMCMN, types.TypeFlags)
+                       v0.AddArg(a)
+                       v1 := b.NewValue0(v.Pos, OpARMMUL, x.Type)
+                       v1.AddArg(x)
+                       v1.AddArg(y)
+                       v0.AddArg(v1)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GE (CMPconst [0] l:(ADDconst [c] x)) yes no)
+               // cond:
+               // result: (GE (CMNconst [c] x) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMADDconst {
+                               break
+                       }
+                       c := l.AuxInt
+                       x := l.Args[0]
+                       b.Kind = BlockARMGE
+                       v0 := b.NewValue0(v.Pos, OpARMCMNconst, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GE (CMPconst [0] l:(ADDshiftLL x y [c])) yes no)
+               // cond:
+               // result: (GE (CMNshiftLL x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMADDshiftLL {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMGE
+                       v0 := b.NewValue0(v.Pos, OpARMCMNshiftLL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GE (CMPconst [0] l:(ADDshiftRL x y [c])) yes no)
+               // cond:
+               // result: (GE (CMNshiftRL x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMADDshiftRL {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMGE
+                       v0 := b.NewValue0(v.Pos, OpARMCMNshiftRL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GE (CMPconst [0] l:(ADDshiftRA x y [c])) yes no)
+               // cond:
+               // result: (GE (CMNshiftRA x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMADDshiftRA {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMGE
+                       v0 := b.NewValue0(v.Pos, OpARMCMNshiftRA, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GE (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no)
+               // cond:
+               // result: (GE (CMNshiftLLreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMADDshiftLLreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMGE
+                       v0 := b.NewValue0(v.Pos, OpARMCMNshiftLLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GE (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no)
+               // cond:
+               // result: (GE (CMNshiftRLreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMADDshiftRLreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMGE
+                       v0 := b.NewValue0(v.Pos, OpARMCMNshiftRLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GE (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no)
+               // cond:
+               // result: (GE (CMNshiftRAreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMADDshiftRAreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMGE
+                       v0 := b.NewValue0(v.Pos, OpARMCMNshiftRAreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GE (CMPconst [0] l:(AND x y)) yes no)
+               // cond:
+               // result: (GE (TST x y) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMAND {
+                               break
+                       }
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMGE
+                       v0 := b.NewValue0(v.Pos, OpARMTST, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GE (CMPconst [0] l:(ANDconst [c] x)) yes no)
+               // cond:
+               // result: (GE (TSTconst [c] x) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMANDconst {
+                               break
+                       }
+                       c := l.AuxInt
+                       x := l.Args[0]
+                       b.Kind = BlockARMGE
+                       v0 := b.NewValue0(v.Pos, OpARMTSTconst, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GE (CMPconst [0] l:(ANDshiftLL x y [c])) yes no)
+               // cond:
+               // result: (GE (TSTshiftLL x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMANDshiftLL {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMGE
+                       v0 := b.NewValue0(v.Pos, OpARMTSTshiftLL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GE (CMPconst [0] l:(ANDshiftRL x y [c])) yes no)
+               // cond:
+               // result: (GE (TSTshiftRL x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMANDshiftRL {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMGE
+                       v0 := b.NewValue0(v.Pos, OpARMTSTshiftRL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GE (CMPconst [0] l:(ANDshiftRA x y [c])) yes no)
+               // cond:
+               // result: (GE (TSTshiftRA x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMANDshiftRA {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMGE
+                       v0 := b.NewValue0(v.Pos, OpARMTSTshiftRA, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GE (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no)
+               // cond:
+               // result: (GE (TSTshiftLLreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMANDshiftLLreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMGE
+                       v0 := b.NewValue0(v.Pos, OpARMTSTshiftLLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GE (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no)
+               // cond:
+               // result: (GE (TSTshiftRLreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMANDshiftRLreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMGE
+                       v0 := b.NewValue0(v.Pos, OpARMTSTshiftRLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GE (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no)
+               // cond:
+               // result: (GE (TSTshiftRAreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMANDshiftRAreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMGE
+                       v0 := b.NewValue0(v.Pos, OpARMTSTshiftRAreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GE (CMPconst [0] l:(XOR x y)) yes no)
+               // cond:
+               // result: (GE (TEQ x y) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMXOR {
+                               break
+                       }
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMGE
+                       v0 := b.NewValue0(v.Pos, OpARMTEQ, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GE (CMPconst [0] l:(XORconst [c] x)) yes no)
+               // cond:
+               // result: (GE (TEQconst [c] x) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMXORconst {
+                               break
+                       }
+                       c := l.AuxInt
+                       x := l.Args[0]
+                       b.Kind = BlockARMGE
+                       v0 := b.NewValue0(v.Pos, OpARMTEQconst, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GE (CMPconst [0] l:(XORshiftLL x y [c])) yes no)
+               // cond:
+               // result: (GE (TEQshiftLL x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMXORshiftLL {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMGE
+                       v0 := b.NewValue0(v.Pos, OpARMTEQshiftLL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GE (CMPconst [0] l:(XORshiftRL x y [c])) yes no)
+               // cond:
+               // result: (GE (TEQshiftRL x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMXORshiftRL {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMGE
+                       v0 := b.NewValue0(v.Pos, OpARMTEQshiftRL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GE (CMPconst [0] l:(XORshiftRA x y [c])) yes no)
+               // cond:
+               // result: (GE (TEQshiftRA x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMXORshiftRA {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMGE
+                       v0 := b.NewValue0(v.Pos, OpARMTEQshiftRA, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GE (CMPconst [0] l:(XORshiftLLreg x y z)) yes no)
+               // cond:
+               // result: (GE (TEQshiftLLreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMXORshiftLLreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMGE
+                       v0 := b.NewValue0(v.Pos, OpARMTEQshiftLLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GE (CMPconst [0] l:(XORshiftRLreg x y z)) yes no)
+               // cond:
+               // result: (GE (TEQshiftRLreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMXORshiftRLreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMGE
+                       v0 := b.NewValue0(v.Pos, OpARMTEQshiftRLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GE (CMPconst [0] l:(XORshiftRAreg x y z)) yes no)
+               // cond:
+               // result: (GE (TEQshiftRAreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMXORshiftRAreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMGE
+                       v0 := b.NewValue0(v.Pos, OpARMTEQshiftRAreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
        case BlockARMGT:
                // match: (GT (FlagEQ) yes no)
                // cond:
@@ -23283,398 +24219,3206 @@ func rewriteBlockARM(b *Block) bool {
                        if v.Op != OpARMFlagEQ {
                                break
                        }
-                       b.Kind = BlockFirst
-                       b.SetControl(nil)
+                       b.Kind = BlockFirst
+                       b.SetControl(nil)
+                       b.Aux = nil
+                       b.swapSuccessors()
+                       return true
+               }
+               // match: (GT (FlagLT_ULT) yes no)
+               // cond:
+               // result: (First nil no yes)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMFlagLT_ULT {
+                               break
+                       }
+                       b.Kind = BlockFirst
+                       b.SetControl(nil)
+                       b.Aux = nil
+                       b.swapSuccessors()
+                       return true
+               }
+               // match: (GT (FlagLT_UGT) yes no)
+               // cond:
+               // result: (First nil no yes)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMFlagLT_UGT {
+                               break
+                       }
+                       b.Kind = BlockFirst
+                       b.SetControl(nil)
+                       b.Aux = nil
+                       b.swapSuccessors()
+                       return true
+               }
+               // match: (GT (FlagGT_ULT) yes no)
+               // cond:
+               // result: (First nil yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMFlagGT_ULT {
+                               break
+                       }
+                       b.Kind = BlockFirst
+                       b.SetControl(nil)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GT (FlagGT_UGT) yes no)
+               // cond:
+               // result: (First nil yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMFlagGT_UGT {
+                               break
+                       }
+                       b.Kind = BlockFirst
+                       b.SetControl(nil)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GT (InvertFlags cmp) yes no)
+               // cond:
+               // result: (LT cmp yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMInvertFlags {
+                               break
+                       }
+                       cmp := v.Args[0]
+                       b.Kind = BlockARMLT
+                       b.SetControl(cmp)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GT (CMPconst [0] l:(SUB x y)) yes no)
+               // cond:
+               // result: (GT (CMP x y) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMSUB {
+                               break
+                       }
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMGT
+                       v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GT (CMPconst [0] (MULS x y a)) yes no)
+               // cond:
+               // result: (GT (CMP a (MUL <x.Type> x y)) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMMULS {
+                               break
+                       }
+                       _ = v_0.Args[2]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       a := v_0.Args[2]
+                       b.Kind = BlockARMGT
+                       v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
+                       v0.AddArg(a)
+                       v1 := b.NewValue0(v.Pos, OpARMMUL, x.Type)
+                       v1.AddArg(x)
+                       v1.AddArg(y)
+                       v0.AddArg(v1)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GT (CMPconst [0] l:(SUBconst [c] x)) yes no)
+               // cond:
+               // result: (GT (CMPconst [c] x) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMSUBconst {
+                               break
+                       }
+                       c := l.AuxInt
+                       x := l.Args[0]
+                       b.Kind = BlockARMGT
+                       v0 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GT (CMPconst [0] l:(SUBshiftLL x y [c])) yes no)
+               // cond:
+               // result: (GT (CMPshiftLL x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMSUBshiftLL {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMGT
+                       v0 := b.NewValue0(v.Pos, OpARMCMPshiftLL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GT (CMPconst [0] l:(SUBshiftRL x y [c])) yes no)
+               // cond:
+               // result: (GT (CMPshiftRL x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMSUBshiftRL {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMGT
+                       v0 := b.NewValue0(v.Pos, OpARMCMPshiftRL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GT (CMPconst [0] l:(SUBshiftRA x y [c])) yes no)
+               // cond:
+               // result: (GT (CMPshiftRA x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMSUBshiftRA {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMGT
+                       v0 := b.NewValue0(v.Pos, OpARMCMPshiftRA, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GT (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no)
+               // cond:
+               // result: (GT (CMPshiftLLreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMSUBshiftLLreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMGT
+                       v0 := b.NewValue0(v.Pos, OpARMCMPshiftLLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GT (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no)
+               // cond:
+               // result: (GT (CMPshiftRLreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMSUBshiftRLreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMGT
+                       v0 := b.NewValue0(v.Pos, OpARMCMPshiftRLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GT (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no)
+               // cond:
+               // result: (GT (CMPshiftRAreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMSUBshiftRAreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMGT
+                       v0 := b.NewValue0(v.Pos, OpARMCMPshiftRAreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GT (CMPconst [0] l:(ADD x y)) yes no)
+               // cond:
+               // result: (GT (CMN x y) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMADD {
+                               break
+                       }
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMGT
+                       v0 := b.NewValue0(v.Pos, OpARMCMN, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GT (CMPconst [0] l:(ADDconst [c] x)) yes no)
+               // cond:
+               // result: (GT (CMNconst [c] x) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMADDconst {
+                               break
+                       }
+                       c := l.AuxInt
+                       x := l.Args[0]
+                       b.Kind = BlockARMGT
+                       v0 := b.NewValue0(v.Pos, OpARMCMNconst, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GT (CMPconst [0] l:(ADDshiftLL x y [c])) yes no)
+               // cond:
+               // result: (GT (CMNshiftLL x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMADDshiftLL {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMGT
+                       v0 := b.NewValue0(v.Pos, OpARMCMNshiftLL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GT (CMPconst [0] l:(ADDshiftRL x y [c])) yes no)
+               // cond:
+               // result: (GT (CMNshiftRL x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMADDshiftRL {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMGT
+                       v0 := b.NewValue0(v.Pos, OpARMCMNshiftRL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GT (CMPconst [0] l:(ADDshiftRA x y [c])) yes no)
+               // cond:
+               // result: (GT (CMNshiftRA x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMADDshiftRA {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMGT
+                       v0 := b.NewValue0(v.Pos, OpARMCMNshiftRA, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GT (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no)
+               // cond:
+               // result: (GT (CMNshiftLLreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMADDshiftLLreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMGT
+                       v0 := b.NewValue0(v.Pos, OpARMCMNshiftLLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GT (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no)
+               // cond:
+               // result: (GT (CMNshiftRLreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMADDshiftRLreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMGT
+                       v0 := b.NewValue0(v.Pos, OpARMCMNshiftRLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GT (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no)
+               // cond:
+               // result: (GT (CMNshiftRAreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMADDshiftRAreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMGT
+                       v0 := b.NewValue0(v.Pos, OpARMCMNshiftRAreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GT (CMPconst [0] l:(AND x y)) yes no)
+               // cond:
+               // result: (GT (TST x y) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMAND {
+                               break
+                       }
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMGT
+                       v0 := b.NewValue0(v.Pos, OpARMTST, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GT (CMPconst [0] (MULA x y a)) yes no)
+               // cond:
+               // result: (GT (CMN a (MUL <x.Type> x y)) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMMULA {
+                               break
+                       }
+                       _ = v_0.Args[2]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       a := v_0.Args[2]
+                       b.Kind = BlockARMGT
+                       v0 := b.NewValue0(v.Pos, OpARMCMN, types.TypeFlags)
+                       v0.AddArg(a)
+                       v1 := b.NewValue0(v.Pos, OpARMMUL, x.Type)
+                       v1.AddArg(x)
+                       v1.AddArg(y)
+                       v0.AddArg(v1)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GT (CMPconst [0] l:(ANDconst [c] x)) yes no)
+               // cond:
+               // result: (GT (TSTconst [c] x) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMANDconst {
+                               break
+                       }
+                       c := l.AuxInt
+                       x := l.Args[0]
+                       b.Kind = BlockARMGT
+                       v0 := b.NewValue0(v.Pos, OpARMTSTconst, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GT (CMPconst [0] l:(ANDshiftLL x y [c])) yes no)
+               // cond:
+               // result: (GT (TSTshiftLL x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMANDshiftLL {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMGT
+                       v0 := b.NewValue0(v.Pos, OpARMTSTshiftLL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GT (CMPconst [0] l:(ANDshiftRL x y [c])) yes no)
+               // cond:
+               // result: (GT (TSTshiftRL x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMANDshiftRL {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMGT
+                       v0 := b.NewValue0(v.Pos, OpARMTSTshiftRL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GT (CMPconst [0] l:(ANDshiftRA x y [c])) yes no)
+               // cond:
+               // result: (GT (TSTshiftRA x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMANDshiftRA {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMGT
+                       v0 := b.NewValue0(v.Pos, OpARMTSTshiftRA, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GT (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no)
+               // cond:
+               // result: (GT (TSTshiftLLreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMANDshiftLLreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMGT
+                       v0 := b.NewValue0(v.Pos, OpARMTSTshiftLLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GT (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no)
+               // cond:
+               // result: (GT (TSTshiftRLreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMANDshiftRLreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMGT
+                       v0 := b.NewValue0(v.Pos, OpARMTSTshiftRLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GT (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no)
+               // cond:
+               // result: (GT (TSTshiftRAreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMANDshiftRAreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMGT
+                       v0 := b.NewValue0(v.Pos, OpARMTSTshiftRAreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GT (CMPconst [0] l:(XOR x y)) yes no)
+               // cond:
+               // result: (GT (TEQ x y) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMXOR {
+                               break
+                       }
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMGT
+                       v0 := b.NewValue0(v.Pos, OpARMTEQ, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GT (CMPconst [0] l:(XORconst [c] x)) yes no)
+               // cond:
+               // result: (GT (TEQconst [c] x) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMXORconst {
+                               break
+                       }
+                       c := l.AuxInt
+                       x := l.Args[0]
+                       b.Kind = BlockARMGT
+                       v0 := b.NewValue0(v.Pos, OpARMTEQconst, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GT (CMPconst [0] l:(XORshiftLL x y [c])) yes no)
+               // cond:
+               // result: (GT (TEQshiftLL x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMXORshiftLL {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMGT
+                       v0 := b.NewValue0(v.Pos, OpARMTEQshiftLL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GT (CMPconst [0] l:(XORshiftRL x y [c])) yes no)
+               // cond:
+               // result: (GT (TEQshiftRL x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMXORshiftRL {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMGT
+                       v0 := b.NewValue0(v.Pos, OpARMTEQshiftRL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GT (CMPconst [0] l:(XORshiftRA x y [c])) yes no)
+               // cond:
+               // result: (GT (TEQshiftRA x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMXORshiftRA {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMGT
+                       v0 := b.NewValue0(v.Pos, OpARMTEQshiftRA, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GT (CMPconst [0] l:(XORshiftLLreg x y z)) yes no)
+               // cond:
+               // result: (GT (TEQshiftLLreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMXORshiftLLreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMGT
+                       v0 := b.NewValue0(v.Pos, OpARMTEQshiftLLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GT (CMPconst [0] l:(XORshiftRLreg x y z)) yes no)
+               // cond:
+               // result: (GT (TEQshiftRLreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMXORshiftRLreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMGT
+                       v0 := b.NewValue0(v.Pos, OpARMTEQshiftRLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (GT (CMPconst [0] l:(XORshiftRAreg x y z)) yes no)
+               // cond:
+               // result: (GT (TEQshiftRAreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMXORshiftRAreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMGT
+                       v0 := b.NewValue0(v.Pos, OpARMTEQshiftRAreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+       case BlockIf:
+               // match: (If (Equal cc) yes no)
+               // cond:
+               // result: (EQ cc yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMEqual {
+                               break
+                       }
+                       cc := v.Args[0]
+                       b.Kind = BlockARMEQ
+                       b.SetControl(cc)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (If (NotEqual cc) yes no)
+               // cond:
+               // result: (NE cc yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMNotEqual {
+                               break
+                       }
+                       cc := v.Args[0]
+                       b.Kind = BlockARMNE
+                       b.SetControl(cc)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (If (LessThan cc) yes no)
+               // cond:
+               // result: (LT cc yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMLessThan {
+                               break
+                       }
+                       cc := v.Args[0]
+                       b.Kind = BlockARMLT
+                       b.SetControl(cc)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (If (LessThanU cc) yes no)
+               // cond:
+               // result: (ULT cc yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMLessThanU {
+                               break
+                       }
+                       cc := v.Args[0]
+                       b.Kind = BlockARMULT
+                       b.SetControl(cc)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (If (LessEqual cc) yes no)
+               // cond:
+               // result: (LE cc yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMLessEqual {
+                               break
+                       }
+                       cc := v.Args[0]
+                       b.Kind = BlockARMLE
+                       b.SetControl(cc)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (If (LessEqualU cc) yes no)
+               // cond:
+               // result: (ULE cc yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMLessEqualU {
+                               break
+                       }
+                       cc := v.Args[0]
+                       b.Kind = BlockARMULE
+                       b.SetControl(cc)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (If (GreaterThan cc) yes no)
+               // cond:
+               // result: (GT cc yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMGreaterThan {
+                               break
+                       }
+                       cc := v.Args[0]
+                       b.Kind = BlockARMGT
+                       b.SetControl(cc)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (If (GreaterThanU cc) yes no)
+               // cond:
+               // result: (UGT cc yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMGreaterThanU {
+                               break
+                       }
+                       cc := v.Args[0]
+                       b.Kind = BlockARMUGT
+                       b.SetControl(cc)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (If (GreaterEqual cc) yes no)
+               // cond:
+               // result: (GE cc yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMGreaterEqual {
+                               break
+                       }
+                       cc := v.Args[0]
+                       b.Kind = BlockARMGE
+                       b.SetControl(cc)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (If (GreaterEqualU cc) yes no)
+               // cond:
+               // result: (UGE cc yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMGreaterEqualU {
+                               break
+                       }
+                       cc := v.Args[0]
+                       b.Kind = BlockARMUGE
+                       b.SetControl(cc)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (If cond yes no)
+               // cond:
+               // result: (NE (CMPconst [0] cond) yes no)
+               for {
+                       v := b.Control
+                       _ = v
+                       cond := b.Control
+                       b.Kind = BlockARMNE
+                       v0 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
+                       v0.AuxInt = 0
+                       v0.AddArg(cond)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+       case BlockARMLE:
+               // match: (LE (FlagEQ) yes no)
+               // cond:
+               // result: (First nil yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMFlagEQ {
+                               break
+                       }
+                       b.Kind = BlockFirst
+                       b.SetControl(nil)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LE (FlagLT_ULT) yes no)
+               // cond:
+               // result: (First nil yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMFlagLT_ULT {
+                               break
+                       }
+                       b.Kind = BlockFirst
+                       b.SetControl(nil)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LE (FlagLT_UGT) yes no)
+               // cond:
+               // result: (First nil yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMFlagLT_UGT {
+                               break
+                       }
+                       b.Kind = BlockFirst
+                       b.SetControl(nil)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LE (FlagGT_ULT) yes no)
+               // cond:
+               // result: (First nil no yes)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMFlagGT_ULT {
+                               break
+                       }
+                       b.Kind = BlockFirst
+                       b.SetControl(nil)
+                       b.Aux = nil
+                       b.swapSuccessors()
+                       return true
+               }
+               // match: (LE (FlagGT_UGT) yes no)
+               // cond:
+               // result: (First nil no yes)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMFlagGT_UGT {
+                               break
+                       }
+                       b.Kind = BlockFirst
+                       b.SetControl(nil)
+                       b.Aux = nil
+                       b.swapSuccessors()
+                       return true
+               }
+               // match: (LE (InvertFlags cmp) yes no)
+               // cond:
+               // result: (GE cmp yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMInvertFlags {
+                               break
+                       }
+                       cmp := v.Args[0]
+                       b.Kind = BlockARMGE
+                       b.SetControl(cmp)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LE (CMPconst [0] l:(SUB x y)) yes no)
+               // cond:
+               // result: (LE (CMP x y) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMSUB {
+                               break
+                       }
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMLE
+                       v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LE (CMPconst [0] (MULS x y a)) yes no)
+               // cond:
+               // result: (LE (CMP a (MUL <x.Type> x y)) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMMULS {
+                               break
+                       }
+                       _ = v_0.Args[2]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       a := v_0.Args[2]
+                       b.Kind = BlockARMLE
+                       v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
+                       v0.AddArg(a)
+                       v1 := b.NewValue0(v.Pos, OpARMMUL, x.Type)
+                       v1.AddArg(x)
+                       v1.AddArg(y)
+                       v0.AddArg(v1)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LE (CMPconst [0] l:(SUBconst [c] x)) yes no)
+               // cond:
+               // result: (LE (CMPconst [c] x) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMSUBconst {
+                               break
+                       }
+                       c := l.AuxInt
+                       x := l.Args[0]
+                       b.Kind = BlockARMLE
+                       v0 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LE (CMPconst [0] l:(SUBshiftLL x y [c])) yes no)
+               // cond:
+               // result: (LE (CMPshiftLL x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMSUBshiftLL {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMLE
+                       v0 := b.NewValue0(v.Pos, OpARMCMPshiftLL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LE (CMPconst [0] l:(SUBshiftRL x y [c])) yes no)
+               // cond:
+               // result: (LE (CMPshiftRL x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMSUBshiftRL {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMLE
+                       v0 := b.NewValue0(v.Pos, OpARMCMPshiftRL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LE (CMPconst [0] l:(SUBshiftRA x y [c])) yes no)
+               // cond:
+               // result: (LE (CMPshiftRA x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMSUBshiftRA {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMLE
+                       v0 := b.NewValue0(v.Pos, OpARMCMPshiftRA, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LE (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no)
+               // cond:
+               // result: (LE (CMPshiftLLreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMSUBshiftLLreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMLE
+                       v0 := b.NewValue0(v.Pos, OpARMCMPshiftLLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LE (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no)
+               // cond:
+               // result: (LE (CMPshiftRLreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMSUBshiftRLreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMLE
+                       v0 := b.NewValue0(v.Pos, OpARMCMPshiftRLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LE (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no)
+               // cond:
+               // result: (LE (CMPshiftRAreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMSUBshiftRAreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMLE
+                       v0 := b.NewValue0(v.Pos, OpARMCMPshiftRAreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LE (CMPconst [0] l:(ADD x y)) yes no)
+               // cond:
+               // result: (LE (CMN x y) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMADD {
+                               break
+                       }
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMLE
+                       v0 := b.NewValue0(v.Pos, OpARMCMN, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LE (CMPconst [0] (MULA x y a)) yes no)
+               // cond:
+               // result: (LE (CMN a (MUL <x.Type> x y)) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMMULA {
+                               break
+                       }
+                       _ = v_0.Args[2]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       a := v_0.Args[2]
+                       b.Kind = BlockARMLE
+                       v0 := b.NewValue0(v.Pos, OpARMCMN, types.TypeFlags)
+                       v0.AddArg(a)
+                       v1 := b.NewValue0(v.Pos, OpARMMUL, x.Type)
+                       v1.AddArg(x)
+                       v1.AddArg(y)
+                       v0.AddArg(v1)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LE (CMPconst [0] l:(ADDconst [c] x)) yes no)
+               // cond:
+               // result: (LE (CMNconst [c] x) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMADDconst {
+                               break
+                       }
+                       c := l.AuxInt
+                       x := l.Args[0]
+                       b.Kind = BlockARMLE
+                       v0 := b.NewValue0(v.Pos, OpARMCMNconst, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LE (CMPconst [0] l:(ADDshiftLL x y [c])) yes no)
+               // cond:
+               // result: (LE (CMNshiftLL x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMADDshiftLL {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMLE
+                       v0 := b.NewValue0(v.Pos, OpARMCMNshiftLL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LE (CMPconst [0] l:(ADDshiftRL x y [c])) yes no)
+               // cond:
+               // result: (LE (CMNshiftRL x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMADDshiftRL {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMLE
+                       v0 := b.NewValue0(v.Pos, OpARMCMNshiftRL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LE (CMPconst [0] l:(ADDshiftRA x y [c])) yes no)
+               // cond:
+               // result: (LE (CMNshiftRA x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMADDshiftRA {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMLE
+                       v0 := b.NewValue0(v.Pos, OpARMCMNshiftRA, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LE (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no)
+               // cond:
+               // result: (LE (CMNshiftLLreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMADDshiftLLreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMLE
+                       v0 := b.NewValue0(v.Pos, OpARMCMNshiftLLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LE (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no)
+               // cond:
+               // result: (LE (CMNshiftRLreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMADDshiftRLreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMLE
+                       v0 := b.NewValue0(v.Pos, OpARMCMNshiftRLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LE (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no)
+               // cond:
+               // result: (LE (CMNshiftRAreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMADDshiftRAreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMLE
+                       v0 := b.NewValue0(v.Pos, OpARMCMNshiftRAreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LE (CMPconst [0] l:(AND x y)) yes no)
+               // cond:
+               // result: (LE (TST x y) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMAND {
+                               break
+                       }
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMLE
+                       v0 := b.NewValue0(v.Pos, OpARMTST, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LE (CMPconst [0] l:(ANDconst [c] x)) yes no)
+               // cond:
+               // result: (LE (TSTconst [c] x) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMANDconst {
+                               break
+                       }
+                       c := l.AuxInt
+                       x := l.Args[0]
+                       b.Kind = BlockARMLE
+                       v0 := b.NewValue0(v.Pos, OpARMTSTconst, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LE (CMPconst [0] l:(ANDshiftLL x y [c])) yes no)
+               // cond:
+               // result: (LE (TSTshiftLL x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMANDshiftLL {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMLE
+                       v0 := b.NewValue0(v.Pos, OpARMTSTshiftLL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LE (CMPconst [0] l:(ANDshiftRL x y [c])) yes no)
+               // cond:
+               // result: (LE (TSTshiftRL x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMANDshiftRL {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMLE
+                       v0 := b.NewValue0(v.Pos, OpARMTSTshiftRL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LE (CMPconst [0] l:(ANDshiftRA x y [c])) yes no)
+               // cond:
+               // result: (LE (TSTshiftRA x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMANDshiftRA {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMLE
+                       v0 := b.NewValue0(v.Pos, OpARMTSTshiftRA, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LE (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no)
+               // cond:
+               // result: (LE (TSTshiftLLreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMANDshiftLLreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMLE
+                       v0 := b.NewValue0(v.Pos, OpARMTSTshiftLLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LE (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no)
+               // cond:
+               // result: (LE (TSTshiftRLreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMANDshiftRLreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMLE
+                       v0 := b.NewValue0(v.Pos, OpARMTSTshiftRLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LE (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no)
+               // cond:
+               // result: (LE (TSTshiftRAreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMANDshiftRAreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMLE
+                       v0 := b.NewValue0(v.Pos, OpARMTSTshiftRAreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LE (CMPconst [0] l:(XOR x y)) yes no)
+               // cond:
+               // result: (LE (TEQ x y) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMXOR {
+                               break
+                       }
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMLE
+                       v0 := b.NewValue0(v.Pos, OpARMTEQ, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LE (CMPconst [0] l:(XORconst [c] x)) yes no)
+               // cond:
+               // result: (LE (TEQconst [c] x) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMXORconst {
+                               break
+                       }
+                       c := l.AuxInt
+                       x := l.Args[0]
+                       b.Kind = BlockARMLE
+                       v0 := b.NewValue0(v.Pos, OpARMTEQconst, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LE (CMPconst [0] l:(XORshiftLL x y [c])) yes no)
+               // cond:
+               // result: (LE (TEQshiftLL x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMXORshiftLL {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMLE
+                       v0 := b.NewValue0(v.Pos, OpARMTEQshiftLL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LE (CMPconst [0] l:(XORshiftRL x y [c])) yes no)
+               // cond:
+               // result: (LE (TEQshiftRL x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMXORshiftRL {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMLE
+                       v0 := b.NewValue0(v.Pos, OpARMTEQshiftRL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LE (CMPconst [0] l:(XORshiftRA x y [c])) yes no)
+               // cond:
+               // result: (LE (TEQshiftRA x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMXORshiftRA {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMLE
+                       v0 := b.NewValue0(v.Pos, OpARMTEQshiftRA, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LE (CMPconst [0] l:(XORshiftLLreg x y z)) yes no)
+               // cond:
+               // result: (LE (TEQshiftLLreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMXORshiftLLreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMLE
+                       v0 := b.NewValue0(v.Pos, OpARMTEQshiftLLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LE (CMPconst [0] l:(XORshiftRLreg x y z)) yes no)
+               // cond:
+               // result: (LE (TEQshiftRLreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMXORshiftRLreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMLE
+                       v0 := b.NewValue0(v.Pos, OpARMTEQshiftRLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LE (CMPconst [0] l:(XORshiftRAreg x y z)) yes no)
+               // cond:
+               // result: (LE (TEQshiftRAreg x y z) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMXORshiftRAreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMLE
+                       v0 := b.NewValue0(v.Pos, OpARMTEQshiftRAreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+       case BlockARMLT:
+               // match: (LT (FlagEQ) yes no)
+               // cond:
+               // result: (First nil no yes)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMFlagEQ {
+                               break
+                       }
+                       b.Kind = BlockFirst
+                       b.SetControl(nil)
+                       b.Aux = nil
+                       b.swapSuccessors()
+                       return true
+               }
+               // match: (LT (FlagLT_ULT) yes no)
+               // cond:
+               // result: (First nil yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMFlagLT_ULT {
+                               break
+                       }
+                       b.Kind = BlockFirst
+                       b.SetControl(nil)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LT (FlagLT_UGT) yes no)
+               // cond:
+               // result: (First nil yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMFlagLT_UGT {
+                               break
+                       }
+                       b.Kind = BlockFirst
+                       b.SetControl(nil)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LT (FlagGT_ULT) yes no)
+               // cond:
+               // result: (First nil no yes)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMFlagGT_ULT {
+                               break
+                       }
+                       b.Kind = BlockFirst
+                       b.SetControl(nil)
+                       b.Aux = nil
+                       b.swapSuccessors()
+                       return true
+               }
+               // match: (LT (FlagGT_UGT) yes no)
+               // cond:
+               // result: (First nil no yes)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMFlagGT_UGT {
+                               break
+                       }
+                       b.Kind = BlockFirst
+                       b.SetControl(nil)
+                       b.Aux = nil
+                       b.swapSuccessors()
+                       return true
+               }
+               // match: (LT (InvertFlags cmp) yes no)
+               // cond:
+               // result: (GT cmp yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMInvertFlags {
+                               break
+                       }
+                       cmp := v.Args[0]
+                       b.Kind = BlockARMGT
+                       b.SetControl(cmp)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LT (CMPconst [0] l:(SUB x y)) yes no)
+               // cond:
+               // result: (LT (CMP x y) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMSUB {
+                               break
+                       }
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMLT
+                       v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LT (CMPconst [0] (MULS x y a)) yes no)
+               // cond:
+               // result: (LT (CMP a (MUL <x.Type> x y)) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMMULS {
+                               break
+                       }
+                       _ = v_0.Args[2]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       a := v_0.Args[2]
+                       b.Kind = BlockARMLT
+                       v0 := b.NewValue0(v.Pos, OpARMCMP, types.TypeFlags)
+                       v0.AddArg(a)
+                       v1 := b.NewValue0(v.Pos, OpARMMUL, x.Type)
+                       v1.AddArg(x)
+                       v1.AddArg(y)
+                       v0.AddArg(v1)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LT (CMPconst [0] l:(SUBconst [c] x)) yes no)
+               // cond:
+               // result: (LT (CMPconst [c] x) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMSUBconst {
+                               break
+                       }
+                       c := l.AuxInt
+                       x := l.Args[0]
+                       b.Kind = BlockARMLT
+                       v0 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LT (CMPconst [0] l:(SUBshiftLL x y [c])) yes no)
+               // cond:
+               // result: (LT (CMPshiftLL x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMSUBshiftLL {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMLT
+                       v0 := b.NewValue0(v.Pos, OpARMCMPshiftLL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LT (CMPconst [0] l:(SUBshiftRL x y [c])) yes no)
+               // cond:
+               // result: (LT (CMPshiftRL x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMSUBshiftRL {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMLT
+                       v0 := b.NewValue0(v.Pos, OpARMCMPshiftRL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
+                       b.Aux = nil
+                       return true
+               }
+               // match: (LT (CMPconst [0] l:(SUBshiftRA x y [c])) yes no)
+               // cond:
+               // result: (LT (CMPshiftRA x y [c]) yes no)
+               for {
+                       v := b.Control
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMSUBshiftRA {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMLT
+                       v0 := b.NewValue0(v.Pos, OpARMCMPshiftRA, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
                        b.Aux = nil
-                       b.swapSuccessors()
                        return true
                }
-               // match: (GT (FlagLT_ULT) yes no)
+               // match: (LT (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no)
                // cond:
-               // result: (First nil no yes)
+               // result: (LT (CMPshiftLLreg x y z) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMFlagLT_ULT {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       b.Kind = BlockFirst
-                       b.SetControl(nil)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMSUBshiftLLreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMLT
+                       v0 := b.NewValue0(v.Pos, OpARMCMPshiftLLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
                        b.Aux = nil
-                       b.swapSuccessors()
                        return true
                }
-               // match: (GT (FlagLT_UGT) yes no)
+               // match: (LT (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no)
                // cond:
-               // result: (First nil no yes)
+               // result: (LT (CMPshiftRLreg x y z) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMFlagLT_UGT {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       b.Kind = BlockFirst
-                       b.SetControl(nil)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMSUBshiftRLreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMLT
+                       v0 := b.NewValue0(v.Pos, OpARMCMPshiftRLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
                        b.Aux = nil
-                       b.swapSuccessors()
                        return true
                }
-               // match: (GT (FlagGT_ULT) yes no)
+               // match: (LT (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no)
                // cond:
-               // result: (First nil yes no)
+               // result: (LT (CMPshiftRAreg x y z) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMFlagGT_ULT {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       b.Kind = BlockFirst
-                       b.SetControl(nil)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMSUBshiftRAreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMLT
+                       v0 := b.NewValue0(v.Pos, OpARMCMPshiftRAreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-               // match: (GT (FlagGT_UGT) yes no)
+               // match: (LT (CMPconst [0] l:(ADD x y)) yes no)
                // cond:
-               // result: (First nil yes no)
+               // result: (LT (CMN x y) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMFlagGT_UGT {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       b.Kind = BlockFirst
-                       b.SetControl(nil)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMADD {
+                               break
+                       }
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMLT
+                       v0 := b.NewValue0(v.Pos, OpARMCMN, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-               // match: (GT (InvertFlags cmp) yes no)
+               // match: (LT (CMPconst [0] (MULA x y a)) yes no)
                // cond:
-               // result: (LT cmp yes no)
+               // result: (LT (CMN a (MUL <x.Type> x y)) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMInvertFlags {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       cmp := v.Args[0]
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       v_0 := v.Args[0]
+                       if v_0.Op != OpARMMULA {
+                               break
+                       }
+                       _ = v_0.Args[2]
+                       x := v_0.Args[0]
+                       y := v_0.Args[1]
+                       a := v_0.Args[2]
                        b.Kind = BlockARMLT
-                       b.SetControl(cmp)
+                       v0 := b.NewValue0(v.Pos, OpARMCMN, types.TypeFlags)
+                       v0.AddArg(a)
+                       v1 := b.NewValue0(v.Pos, OpARMMUL, x.Type)
+                       v1.AddArg(x)
+                       v1.AddArg(y)
+                       v0.AddArg(v1)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-       case BlockIf:
-               // match: (If (Equal cc) yes no)
+               // match: (LT (CMPconst [0] l:(ADDconst [c] x)) yes no)
                // cond:
-               // result: (EQ cc yes no)
+               // result: (LT (CMNconst [c] x) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMEqual {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       cc := v.Args[0]
-                       b.Kind = BlockARMEQ
-                       b.SetControl(cc)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMADDconst {
+                               break
+                       }
+                       c := l.AuxInt
+                       x := l.Args[0]
+                       b.Kind = BlockARMLT
+                       v0 := b.NewValue0(v.Pos, OpARMCMNconst, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-               // match: (If (NotEqual cc) yes no)
+               // match: (LT (CMPconst [0] l:(ADDshiftLL x y [c])) yes no)
                // cond:
-               // result: (NE cc yes no)
+               // result: (LT (CMNshiftLL x y [c]) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMNotEqual {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       cc := v.Args[0]
-                       b.Kind = BlockARMNE
-                       b.SetControl(cc)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMADDshiftLL {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMLT
+                       v0 := b.NewValue0(v.Pos, OpARMCMNshiftLL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-               // match: (If (LessThan cc) yes no)
+               // match: (LT (CMPconst [0] l:(ADDshiftRL x y [c])) yes no)
                // cond:
-               // result: (LT cc yes no)
+               // result: (LT (CMNshiftRL x y [c]) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMLessThan {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       cc := v.Args[0]
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMADDshiftRL {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
                        b.Kind = BlockARMLT
-                       b.SetControl(cc)
+                       v0 := b.NewValue0(v.Pos, OpARMCMNshiftRL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-               // match: (If (LessThanU cc) yes no)
+               // match: (LT (CMPconst [0] l:(ADDshiftRA x y [c])) yes no)
                // cond:
-               // result: (ULT cc yes no)
+               // result: (LT (CMNshiftRA x y [c]) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMLessThanU {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       cc := v.Args[0]
-                       b.Kind = BlockARMULT
-                       b.SetControl(cc)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMADDshiftRA {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMLT
+                       v0 := b.NewValue0(v.Pos, OpARMCMNshiftRA, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-               // match: (If (LessEqual cc) yes no)
+               // match: (LT (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no)
                // cond:
-               // result: (LE cc yes no)
+               // result: (LT (CMNshiftLLreg x y z) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMLessEqual {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       cc := v.Args[0]
-                       b.Kind = BlockARMLE
-                       b.SetControl(cc)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMADDshiftLLreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMLT
+                       v0 := b.NewValue0(v.Pos, OpARMCMNshiftLLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-               // match: (If (LessEqualU cc) yes no)
+               // match: (LT (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no)
                // cond:
-               // result: (ULE cc yes no)
+               // result: (LT (CMNshiftRLreg x y z) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMLessEqualU {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       cc := v.Args[0]
-                       b.Kind = BlockARMULE
-                       b.SetControl(cc)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMADDshiftRLreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMLT
+                       v0 := b.NewValue0(v.Pos, OpARMCMNshiftRLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-               // match: (If (GreaterThan cc) yes no)
+               // match: (LT (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no)
                // cond:
-               // result: (GT cc yes no)
+               // result: (LT (CMNshiftRAreg x y z) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMGreaterThan {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       cc := v.Args[0]
-                       b.Kind = BlockARMGT
-                       b.SetControl(cc)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMADDshiftRAreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMLT
+                       v0 := b.NewValue0(v.Pos, OpARMCMNshiftRAreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-               // match: (If (GreaterThanU cc) yes no)
+               // match: (LT (CMPconst [0] l:(AND x y)) yes no)
                // cond:
-               // result: (UGT cc yes no)
+               // result: (LT (TST x y) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMGreaterThanU {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       cc := v.Args[0]
-                       b.Kind = BlockARMUGT
-                       b.SetControl(cc)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMAND {
+                               break
+                       }
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMLT
+                       v0 := b.NewValue0(v.Pos, OpARMTST, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-               // match: (If (GreaterEqual cc) yes no)
+               // match: (LT (CMPconst [0] l:(ANDconst [c] x)) yes no)
                // cond:
-               // result: (GE cc yes no)
+               // result: (LT (TSTconst [c] x) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMGreaterEqual {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       cc := v.Args[0]
-                       b.Kind = BlockARMGE
-                       b.SetControl(cc)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMANDconst {
+                               break
+                       }
+                       c := l.AuxInt
+                       x := l.Args[0]
+                       b.Kind = BlockARMLT
+                       v0 := b.NewValue0(v.Pos, OpARMTSTconst, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-               // match: (If (GreaterEqualU cc) yes no)
+               // match: (LT (CMPconst [0] l:(ANDshiftLL x y [c])) yes no)
                // cond:
-               // result: (UGE cc yes no)
+               // result: (LT (TSTshiftLL x y [c]) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMGreaterEqualU {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       cc := v.Args[0]
-                       b.Kind = BlockARMUGE
-                       b.SetControl(cc)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMANDshiftLL {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMLT
+                       v0 := b.NewValue0(v.Pos, OpARMTSTshiftLL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-               // match: (If cond yes no)
+               // match: (LT (CMPconst [0] l:(ANDshiftRL x y [c])) yes no)
                // cond:
-               // result: (NE (CMPconst [0] cond) yes no)
+               // result: (LT (TSTshiftRL x y [c]) yes no)
                for {
                        v := b.Control
-                       _ = v
-                       cond := b.Control
-                       b.Kind = BlockARMNE
-                       v0 := b.NewValue0(v.Pos, OpARMCMPconst, types.TypeFlags)
-                       v0.AuxInt = 0
-                       v0.AddArg(cond)
+                       if v.Op != OpARMCMPconst {
+                               break
+                       }
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMANDshiftRL {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMLT
+                       v0 := b.NewValue0(v.Pos, OpARMTSTshiftRL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
                        b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-       case BlockARMLE:
-               // match: (LE (FlagEQ) yes no)
+               // match: (LT (CMPconst [0] l:(ANDshiftRA x y [c])) yes no)
                // cond:
-               // result: (First nil yes no)
+               // result: (LT (TSTshiftRA x y [c]) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMFlagEQ {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       b.Kind = BlockFirst
-                       b.SetControl(nil)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMANDshiftRA {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMLT
+                       v0 := b.NewValue0(v.Pos, OpARMTSTshiftRA, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-               // match: (LE (FlagLT_ULT) yes no)
+               // match: (LT (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no)
                // cond:
-               // result: (First nil yes no)
+               // result: (LT (TSTshiftLLreg x y z) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMFlagLT_ULT {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       b.Kind = BlockFirst
-                       b.SetControl(nil)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMANDshiftLLreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMLT
+                       v0 := b.NewValue0(v.Pos, OpARMTSTshiftLLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-               // match: (LE (FlagLT_UGT) yes no)
+               // match: (LT (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no)
                // cond:
-               // result: (First nil yes no)
+               // result: (LT (TSTshiftRLreg x y z) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMFlagLT_UGT {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       b.Kind = BlockFirst
-                       b.SetControl(nil)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMANDshiftRLreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMLT
+                       v0 := b.NewValue0(v.Pos, OpARMTSTshiftRLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-               // match: (LE (FlagGT_ULT) yes no)
+               // match: (LT (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no)
                // cond:
-               // result: (First nil no yes)
+               // result: (LT (TSTshiftRAreg x y z) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMFlagGT_ULT {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       b.Kind = BlockFirst
-                       b.SetControl(nil)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMANDshiftRAreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMLT
+                       v0 := b.NewValue0(v.Pos, OpARMTSTshiftRAreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
                        b.Aux = nil
-                       b.swapSuccessors()
                        return true
                }
-               // match: (LE (FlagGT_UGT) yes no)
+               // match: (LT (CMPconst [0] l:(XOR x y)) yes no)
                // cond:
-               // result: (First nil no yes)
+               // result: (LT (TEQ x y) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMFlagGT_UGT {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       b.Kind = BlockFirst
-                       b.SetControl(nil)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMXOR {
+                               break
+                       }
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMLT
+                       v0 := b.NewValue0(v.Pos, OpARMTEQ, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
                        b.Aux = nil
-                       b.swapSuccessors()
                        return true
                }
-               // match: (LE (InvertFlags cmp) yes no)
+               // match: (LT (CMPconst [0] l:(XORconst [c] x)) yes no)
                // cond:
-               // result: (GE cmp yes no)
+               // result: (LT (TEQconst [c] x) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMInvertFlags {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       cmp := v.Args[0]
-                       b.Kind = BlockARMGE
-                       b.SetControl(cmp)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMXORconst {
+                               break
+                       }
+                       c := l.AuxInt
+                       x := l.Args[0]
+                       b.Kind = BlockARMLT
+                       v0 := b.NewValue0(v.Pos, OpARMTEQconst, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-       case BlockARMLT:
-               // match: (LT (FlagEQ) yes no)
+               // match: (LT (CMPconst [0] l:(XORshiftLL x y [c])) yes no)
                // cond:
-               // result: (First nil no yes)
+               // result: (LT (TEQshiftLL x y [c]) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMFlagEQ {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       b.Kind = BlockFirst
-                       b.SetControl(nil)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMXORshiftLL {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMLT
+                       v0 := b.NewValue0(v.Pos, OpARMTEQshiftLL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
                        b.Aux = nil
-                       b.swapSuccessors()
                        return true
                }
-               // match: (LT (FlagLT_ULT) yes no)
+               // match: (LT (CMPconst [0] l:(XORshiftRL x y [c])) yes no)
                // cond:
-               // result: (First nil yes no)
+               // result: (LT (TEQshiftRL x y [c]) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMFlagLT_ULT {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       b.Kind = BlockFirst
-                       b.SetControl(nil)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMXORshiftRL {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMLT
+                       v0 := b.NewValue0(v.Pos, OpARMTEQshiftRL, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-               // match: (LT (FlagLT_UGT) yes no)
+               // match: (LT (CMPconst [0] l:(XORshiftRA x y [c])) yes no)
                // cond:
-               // result: (First nil yes no)
+               // result: (LT (TEQshiftRA x y [c]) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMFlagLT_UGT {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       b.Kind = BlockFirst
-                       b.SetControl(nil)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMXORshiftRA {
+                               break
+                       }
+                       c := l.AuxInt
+                       _ = l.Args[1]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       b.Kind = BlockARMLT
+                       v0 := b.NewValue0(v.Pos, OpARMTEQshiftRA, types.TypeFlags)
+                       v0.AuxInt = c
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
-               // match: (LT (FlagGT_ULT) yes no)
+               // match: (LT (CMPconst [0] l:(XORshiftLLreg x y z)) yes no)
                // cond:
-               // result: (First nil no yes)
+               // result: (LT (TEQshiftLLreg x y z) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMFlagGT_ULT {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       b.Kind = BlockFirst
-                       b.SetControl(nil)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMXORshiftLLreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMLT
+                       v0 := b.NewValue0(v.Pos, OpARMTEQshiftLLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
                        b.Aux = nil
-                       b.swapSuccessors()
                        return true
                }
-               // match: (LT (FlagGT_UGT) yes no)
+               // match: (LT (CMPconst [0] l:(XORshiftRLreg x y z)) yes no)
                // cond:
-               // result: (First nil no yes)
+               // result: (LT (TEQshiftRLreg x y z) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMFlagGT_UGT {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       b.Kind = BlockFirst
-                       b.SetControl(nil)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMXORshiftRLreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMLT
+                       v0 := b.NewValue0(v.Pos, OpARMTEQshiftRLreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
                        b.Aux = nil
-                       b.swapSuccessors()
                        return true
                }
-               // match: (LT (InvertFlags cmp) yes no)
+               // match: (LT (CMPconst [0] l:(XORshiftRAreg x y z)) yes no)
                // cond:
-               // result: (GT cmp yes no)
+               // result: (LT (TEQshiftRAreg x y z) yes no)
                for {
                        v := b.Control
-                       if v.Op != OpARMInvertFlags {
+                       if v.Op != OpARMCMPconst {
                                break
                        }
-                       cmp := v.Args[0]
-                       b.Kind = BlockARMGT
-                       b.SetControl(cmp)
+                       if v.AuxInt != 0 {
+                               break
+                       }
+                       l := v.Args[0]
+                       if l.Op != OpARMXORshiftRAreg {
+                               break
+                       }
+                       _ = l.Args[2]
+                       x := l.Args[0]
+                       y := l.Args[1]
+                       z := l.Args[2]
+                       b.Kind = BlockARMLT
+                       v0 := b.NewValue0(v.Pos, OpARMTEQshiftRAreg, types.TypeFlags)
+                       v0.AddArg(x)
+                       v0.AddArg(y)
+                       v0.AddArg(z)
+                       b.SetControl(v0)
                        b.Aux = nil
                        return true
                }
index ebd75d85d9178960d4f364ef8bcb55370d48c101..22d06363ba182325819077a8971891eb2f6a0219 100644 (file)
@@ -157,3 +157,15 @@ func CmpZero4(a int64, ptr *int) {
                *ptr = 0
        }
 }
+
+func CmpToZero(a, b int32) int32 {
+       if a&b < 0 { // arm:`TST`,-`AND`
+               return 1
+       } else if a+b < 0 { // arm:`CMN`,-`ADD`
+               return 2
+       } else if a^b < 0 { // arm:`TEQ`,-`XOR`
+               return 3
+       } else {
+               return 0
+       }
+}