diff options
Diffstat (limited to '')
-rw-r--r-- | go-patches/0013-cmd-compile-do-not-assume-TST-and-TEQ-set-V-on-arm.patch | 1275 |
1 files changed, 1275 insertions, 0 deletions
diff --git a/go-patches/0013-cmd-compile-do-not-assume-TST-and-TEQ-set-V-on-arm.patch b/go-patches/0013-cmd-compile-do-not-assume-TST-and-TEQ-set-V-on-arm.patch new file mode 100644 index 00000000..296ca4a2 --- /dev/null +++ b/go-patches/0013-cmd-compile-do-not-assume-TST-and-TEQ-set-V-on-arm.patch @@ -0,0 +1,1275 @@ +From 58e426bb8175959d7bf32ea7c87e51f4706b309b Mon Sep 17 00:00:00 2001 +From: "Jason A. Donenfeld" <Jason@zx2c4.com> +Date: Mon, 30 Nov 2020 10:41:46 +0100 +Subject: [PATCH 13/13] cmd/compile: do not assume TST and TEQ set V on arm + +These replacement rules assume that TST and TEQ set V. But TST and +TEQ do not set V. This is a problem because instructions like LT are +actually checking for N!=V. But with TST and TEQ not setting V, LT +doesn't do anything meaningful. It's possible to construct trivial +miscompilations from this, such as: + + package main + + var x = [4]int32{-0x7fffffff, 0x7fffffff, 2, 4} + + func main() { + if x[0] > x[1] { + panic("fail 1") + } + if x[2]&x[3] < 0 { + panic("fail 2") // Fails here + } + } + +That first comparison sets V, via the CMP that subtracts the values +causing the overflow. Then the second comparison operation thinks that +it uses the result of TST, when it actually uses the V from CMP. + +Before this fix: + + TST R0, R1 + BLT loc_6C164 + +After this fix: + + TST R0, R1 + BMI loc_6C164 + +The BMI instruction checks the N flag, which TST sets. This commit +fixes the issue by using [LG][TE]noov instead of vanilla [LG][TE], and +also adds a test case for the direct issue. + +Fixes #42876. + +Change-Id: I13c62c88d18574247ad002b671b38d2d0b0fc6fa +Reviewed-on: https://go-review.googlesource.com/c/go/+/274026 +Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com> +TryBot-Result: Go Bot <gobot@golang.org> +Reviewed-by: Cherry Zhang <cherryyz@google.com> +Trust: Jason A. Donenfeld <Jason@zx2c4.com> +--- + src/cmd/compile/internal/ssa/gen/ARM.rules | 128 ++++----- + src/cmd/compile/internal/ssa/rewriteARM.go | 306 ++++++++++----------- + test/fixedbugs/issue42876.go | 18 ++ + 3 files changed, 235 insertions(+), 217 deletions(-) + create mode 100644 test/fixedbugs/issue42876.go + +diff --git a/src/cmd/compile/internal/ssa/gen/ARM.rules b/src/cmd/compile/internal/ssa/gen/ARM.rules +index ab8bd0e81e..c69084a701 100644 +--- a/src/cmd/compile/internal/ssa/gen/ARM.rules ++++ b/src/cmd/compile/internal/ssa/gen/ARM.rules +@@ -1369,38 +1369,38 @@ + (LE (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 -> (LEnoov (CMNshiftLLreg x y z) yes no) + (LE (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 -> (LEnoov (CMNshiftRLreg x y z) yes no) + (LE (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 -> (LEnoov (CMNshiftRAreg x y z) yes no) +-(LT (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 -> (LT (TST x y) yes no) +-(LT (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 -> (LT (TSTconst [c] x) yes no) +-(LT (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 -> (LT (TSTshiftLL x y [c]) yes no) +-(LT (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 -> (LT (TSTshiftRL x y [c]) yes no) +-(LT (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 -> (LT (TSTshiftRA x y [c]) yes no) +-(LT (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 -> (LT (TSTshiftLLreg x y z) yes no) +-(LT (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 -> (LT (TSTshiftRLreg x y z) yes no) +-(LT (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 -> (LT (TSTshiftRAreg x y z) yes no) +-(LE (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 -> (LE (TST x y) yes no) +-(LE (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 -> (LE (TSTconst [c] x) yes no) +-(LE (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 -> (LE (TSTshiftLL x y [c]) yes no) +-(LE (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 -> (LE (TSTshiftRL x y [c]) yes no) +-(LE (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 -> (LE (TSTshiftRA x y [c]) yes no) +-(LE (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 -> (LE (TSTshiftLLreg x y z) yes no) +-(LE (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 -> (LE (TSTshiftRLreg x y z) yes no) +-(LE (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 -> (LE (TSTshiftRAreg x y z) yes no) +-(LT (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 -> (LT (TEQ x y) yes no) +-(LT (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 -> (LT (TEQconst [c] x) yes no) +-(LT (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 -> (LT (TEQshiftLL x y [c]) yes no) +-(LT (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 -> (LT (TEQshiftRL x y [c]) yes no) +-(LT (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 -> (LT (TEQshiftRA x y [c]) yes no) +-(LT (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 -> (LT (TEQshiftLLreg x y z) yes no) +-(LT (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 -> (LT (TEQshiftRLreg x y z) yes no) +-(LT (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 -> (LT (TEQshiftRAreg x y z) yes no) +-(LE (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 -> (LE (TEQ x y) yes no) +-(LE (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 -> (LE (TEQconst [c] x) yes no) +-(LE (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 -> (LE (TEQshiftLL x y [c]) yes no) +-(LE (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 -> (LE (TEQshiftRL x y [c]) yes no) +-(LE (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 -> (LE (TEQshiftRA x y [c]) yes no) +-(LE (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 -> (LE (TEQshiftLLreg x y z) yes no) +-(LE (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 -> (LE (TEQshiftRLreg x y z) yes no) +-(LE (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 -> (LE (TEQshiftRAreg x y z) yes no) ++(LT (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 -> (LTnoov (TST x y) yes no) ++(LT (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 -> (LTnoov (TSTconst [c] x) yes no) ++(LT (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 -> (LTnoov (TSTshiftLL x y [c]) yes no) ++(LT (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 -> (LTnoov (TSTshiftRL x y [c]) yes no) ++(LT (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 -> (LTnoov (TSTshiftRA x y [c]) yes no) ++(LT (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 -> (LTnoov (TSTshiftLLreg x y z) yes no) ++(LT (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 -> (LTnoov (TSTshiftRLreg x y z) yes no) ++(LT (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 -> (LTnoov (TSTshiftRAreg x y z) yes no) ++(LE (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 -> (LEnoov (TST x y) yes no) ++(LE (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 -> (LEnoov (TSTconst [c] x) yes no) ++(LE (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 -> (LEnoov (TSTshiftLL x y [c]) yes no) ++(LE (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 -> (LEnoov (TSTshiftRL x y [c]) yes no) ++(LE (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 -> (LEnoov (TSTshiftRA x y [c]) yes no) ++(LE (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 -> (LEnoov (TSTshiftLLreg x y z) yes no) ++(LE (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 -> (LEnoov (TSTshiftRLreg x y z) yes no) ++(LE (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 -> (LEnoov (TSTshiftRAreg x y z) yes no) ++(LT (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 -> (LTnoov (TEQ x y) yes no) ++(LT (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 -> (LTnoov (TEQconst [c] x) yes no) ++(LT (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 -> (LTnoov (TEQshiftLL x y [c]) yes no) ++(LT (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 -> (LTnoov (TEQshiftRL x y [c]) yes no) ++(LT (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 -> (LTnoov (TEQshiftRA x y [c]) yes no) ++(LT (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 -> (LTnoov (TEQshiftLLreg x y z) yes no) ++(LT (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 -> (LTnoov (TEQshiftRLreg x y z) yes no) ++(LT (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 -> (LTnoov (TEQshiftRAreg x y z) yes no) ++(LE (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 -> (LEnoov (TEQ x y) yes no) ++(LE (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 -> (LEnoov (TEQconst [c] x) yes no) ++(LE (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 -> (LEnoov (TEQshiftLL x y [c]) yes no) ++(LE (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 -> (LEnoov (TEQshiftRL x y [c]) yes no) ++(LE (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 -> (LEnoov (TEQshiftRA x y [c]) yes no) ++(LE (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 -> (LEnoov (TEQshiftLLreg x y z) yes no) ++(LE (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 -> (LEnoov (TEQshiftRLreg x y z) yes no) ++(LE (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 -> (LEnoov (TEQshiftRAreg x y z) yes no) + (GT (CMPconst [0] l:(SUB x y)) yes no) && l.Uses==1 -> (GTnoov (CMP x y) yes no) + (GT (CMPconst [0] l:(MULS x y a)) yes no) && l.Uses==1 -> (GTnoov (CMP a (MUL <x.Type> x y)) yes no) + (GT (CMPconst [0] l:(SUBconst [c] x)) yes no) && l.Uses==1 -> (GTnoov (CMPconst [c] x) yes no) +@@ -1436,39 +1436,39 @@ + (GE (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 -> (GEnoov (CMNshiftLLreg x y z) yes no) + (GE (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 -> (GEnoov (CMNshiftRLreg x y z) yes no) + (GE (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 -> (GEnoov (CMNshiftRAreg x y z) yes no) +-(GT (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 -> (GT (TST x y) yes no) + (GT (CMPconst [0] l:(MULA x y a)) yes no) && l.Uses==1 -> (GTnoov (CMN a (MUL <x.Type> x y)) yes no) +-(GT (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 -> (GT (TSTconst [c] x) yes no) +-(GT (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 -> (GT (TSTshiftLL x y [c]) yes no) +-(GT (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 -> (GT (TSTshiftRL x y [c]) yes no) +-(GT (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 -> (GT (TSTshiftRA x y [c]) yes no) +-(GT (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 -> (GT (TSTshiftLLreg x y z) yes no) +-(GT (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 -> (GT (TSTshiftRLreg x y z) yes no) +-(GT (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 -> (GT (TSTshiftRAreg x y z) yes no) +-(GE (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 -> (GE (TST x y) yes no) +-(GE (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 -> (GE (TSTconst [c] x) yes no) +-(GE (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 -> (GE (TSTshiftLL x y [c]) yes no) +-(GE (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 -> (GE (TSTshiftRL x y [c]) yes no) +-(GE (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 -> (GE (TSTshiftRA x y [c]) yes no) +-(GE (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 -> (GE (TSTshiftLLreg x y z) yes no) +-(GE (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 -> (GE (TSTshiftRLreg x y z) yes no) +-(GE (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 -> (GE (TSTshiftRAreg x y z) yes no) +-(GT (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 -> (GT (TEQ x y) yes no) +-(GT (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 -> (GT (TEQconst [c] x) yes no) +-(GT (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 -> (GT (TEQshiftLL x y [c]) yes no) +-(GT (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 -> (GT (TEQshiftRL x y [c]) yes no) +-(GT (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 -> (GT (TEQshiftRA x y [c]) yes no) +-(GT (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 -> (GT (TEQshiftLLreg x y z) yes no) +-(GT (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 -> (GT (TEQshiftRLreg x y z) yes no) +-(GT (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 -> (GT (TEQshiftRAreg x y z) yes no) +-(GE (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 -> (GE (TEQ x y) yes no) +-(GE (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 -> (GE (TEQconst [c] x) yes no) +-(GE (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 -> (GE (TEQshiftLL x y [c]) yes no) +-(GE (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 -> (GE (TEQshiftRL x y [c]) yes no) +-(GE (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 -> (GE (TEQshiftRA x y [c]) yes no) +-(GE (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 -> (GE (TEQshiftLLreg x y z) yes no) +-(GE (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 -> (GE (TEQshiftRLreg x y z) yes no) +-(GE (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 -> (GE (TEQshiftRAreg x y z) yes no) ++(GT (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 -> (GTnoov (TST x y) yes no) ++(GT (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 -> (GTnoov (TSTconst [c] x) yes no) ++(GT (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 -> (GTnoov (TSTshiftLL x y [c]) yes no) ++(GT (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 -> (GTnoov (TSTshiftRL x y [c]) yes no) ++(GT (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 -> (GTnoov (TSTshiftRA x y [c]) yes no) ++(GT (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 -> (GTnoov (TSTshiftLLreg x y z) yes no) ++(GT (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 -> (GTnoov (TSTshiftRLreg x y z) yes no) ++(GT (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 -> (GTnoov (TSTshiftRAreg x y z) yes no) ++(GE (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 -> (GEnoov (TST x y) yes no) ++(GE (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 -> (GEnoov (TSTconst [c] x) yes no) ++(GE (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 -> (GEnoov (TSTshiftLL x y [c]) yes no) ++(GE (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 -> (GEnoov (TSTshiftRL x y [c]) yes no) ++(GE (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 -> (GEnoov (TSTshiftRA x y [c]) yes no) ++(GE (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 -> (GEnoov (TSTshiftLLreg x y z) yes no) ++(GE (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 -> (GEnoov (TSTshiftRLreg x y z) yes no) ++(GE (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 -> (GEnoov (TSTshiftRAreg x y z) yes no) ++(GT (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 -> (GTnoov (TEQ x y) yes no) ++(GT (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 -> (GTnoov (TEQconst [c] x) yes no) ++(GT (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 -> (GTnoov (TEQshiftLL x y [c]) yes no) ++(GT (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 -> (GTnoov (TEQshiftRL x y [c]) yes no) ++(GT (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 -> (GTnoov (TEQshiftRA x y [c]) yes no) ++(GT (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 -> (GTnoov (TEQshiftLLreg x y z) yes no) ++(GT (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 -> (GTnoov (TEQshiftRLreg x y z) yes no) ++(GT (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 -> (GTnoov (TEQshiftRAreg x y z) yes no) ++(GE (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 -> (GEnoov (TEQ x y) yes no) ++(GE (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 -> (GEnoov (TEQconst [c] x) yes no) ++(GE (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 -> (GEnoov (TEQshiftLL x y [c]) yes no) ++(GE (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 -> (GEnoov (TEQshiftRL x y [c]) yes no) ++(GE (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 -> (GEnoov (TEQshiftRA x y [c]) yes no) ++(GE (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 -> (GEnoov (TEQshiftLLreg x y z) yes no) ++(GE (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 -> (GEnoov (TEQshiftRLreg x y z) yes no) ++(GE (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 -> (GEnoov (TEQshiftRAreg x y z) yes no) + + (MOVBUload [off] {sym} (SB) _) && symIsRO(sym) -> (MOVWconst [int64(read8(sym, off))]) + (MOVHUload [off] {sym} (SB) _) && symIsRO(sym) -> (MOVWconst [int64(read16(sym, off, config.ctxt.Arch.ByteOrder))]) +diff --git a/src/cmd/compile/internal/ssa/rewriteARM.go b/src/cmd/compile/internal/ssa/rewriteARM.go +index f55e542505..07653b78f8 100644 +--- a/src/cmd/compile/internal/ssa/rewriteARM.go ++++ b/src/cmd/compile/internal/ssa/rewriteARM.go +@@ -17278,7 +17278,7 @@ func rewriteBlockARM(b *Block) bool { + } + // match: (GE (CMPconst [0] l:(AND x y)) yes no) + // cond: l.Uses==1 +- // result: (GE (TST x y) yes no) ++ // result: (GEnoov (TST x y) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -17299,14 +17299,14 @@ func rewriteBlockARM(b *Block) bool { + } + v0 := b.NewValue0(v_0.Pos, OpARMTST, types.TypeFlags) + v0.AddArg2(x, y) +- b.resetWithControl(BlockARMGE, v0) ++ b.resetWithControl(BlockARMGEnoov, v0) + return true + } + break + } + // match: (GE (CMPconst [0] l:(ANDconst [c] x)) yes no) + // cond: l.Uses==1 +- // result: (GE (TSTconst [c] x) yes no) ++ // result: (GEnoov (TSTconst [c] x) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -17324,12 +17324,12 @@ func rewriteBlockARM(b *Block) bool { + v0 := b.NewValue0(v_0.Pos, OpARMTSTconst, types.TypeFlags) + v0.AuxInt = c + v0.AddArg(x) +- b.resetWithControl(BlockARMGE, v0) ++ b.resetWithControl(BlockARMGEnoov, v0) + return true + } + // match: (GE (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) + // cond: l.Uses==1 +- // result: (GE (TSTshiftLL x y [c]) yes no) ++ // result: (GEnoov (TSTshiftLL x y [c]) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -17348,12 +17348,12 @@ func rewriteBlockARM(b *Block) bool { + v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftLL, types.TypeFlags) + v0.AuxInt = c + v0.AddArg2(x, y) +- b.resetWithControl(BlockARMGE, v0) ++ b.resetWithControl(BlockARMGEnoov, v0) + return true + } + // match: (GE (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) + // cond: l.Uses==1 +- // result: (GE (TSTshiftRL x y [c]) yes no) ++ // result: (GEnoov (TSTshiftRL x y [c]) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -17372,12 +17372,12 @@ func rewriteBlockARM(b *Block) bool { + v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRL, types.TypeFlags) + v0.AuxInt = c + v0.AddArg2(x, y) +- b.resetWithControl(BlockARMGE, v0) ++ b.resetWithControl(BlockARMGEnoov, v0) + return true + } + // match: (GE (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) + // cond: l.Uses==1 +- // result: (GE (TSTshiftRA x y [c]) yes no) ++ // result: (GEnoov (TSTshiftRA x y [c]) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -17396,12 +17396,12 @@ func rewriteBlockARM(b *Block) bool { + v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRA, types.TypeFlags) + v0.AuxInt = c + v0.AddArg2(x, y) +- b.resetWithControl(BlockARMGE, v0) ++ b.resetWithControl(BlockARMGEnoov, v0) + return true + } + // match: (GE (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) + // cond: l.Uses==1 +- // result: (GE (TSTshiftLLreg x y z) yes no) ++ // result: (GEnoov (TSTshiftLLreg x y z) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -17419,12 +17419,12 @@ func rewriteBlockARM(b *Block) bool { + } + v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftLLreg, types.TypeFlags) + v0.AddArg3(x, y, z) +- b.resetWithControl(BlockARMGE, v0) ++ b.resetWithControl(BlockARMGEnoov, v0) + return true + } + // match: (GE (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) + // cond: l.Uses==1 +- // result: (GE (TSTshiftRLreg x y z) yes no) ++ // result: (GEnoov (TSTshiftRLreg x y z) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -17442,12 +17442,12 @@ func rewriteBlockARM(b *Block) bool { + } + v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRLreg, types.TypeFlags) + v0.AddArg3(x, y, z) +- b.resetWithControl(BlockARMGE, v0) ++ b.resetWithControl(BlockARMGEnoov, v0) + return true + } + // match: (GE (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) + // cond: l.Uses==1 +- // result: (GE (TSTshiftRAreg x y z) yes no) ++ // result: (GEnoov (TSTshiftRAreg x y z) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -17465,12 +17465,12 @@ func rewriteBlockARM(b *Block) bool { + } + v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRAreg, types.TypeFlags) + v0.AddArg3(x, y, z) +- b.resetWithControl(BlockARMGE, v0) ++ b.resetWithControl(BlockARMGEnoov, v0) + return true + } + // match: (GE (CMPconst [0] l:(XOR x y)) yes no) + // cond: l.Uses==1 +- // result: (GE (TEQ x y) yes no) ++ // result: (GEnoov (TEQ x y) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -17491,14 +17491,14 @@ func rewriteBlockARM(b *Block) bool { + } + v0 := b.NewValue0(v_0.Pos, OpARMTEQ, types.TypeFlags) + v0.AddArg2(x, y) +- b.resetWithControl(BlockARMGE, v0) ++ b.resetWithControl(BlockARMGEnoov, v0) + return true + } + break + } + // match: (GE (CMPconst [0] l:(XORconst [c] x)) yes no) + // cond: l.Uses==1 +- // result: (GE (TEQconst [c] x) yes no) ++ // result: (GEnoov (TEQconst [c] x) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -17516,12 +17516,12 @@ func rewriteBlockARM(b *Block) bool { + v0 := b.NewValue0(v_0.Pos, OpARMTEQconst, types.TypeFlags) + v0.AuxInt = c + v0.AddArg(x) +- b.resetWithControl(BlockARMGE, v0) ++ b.resetWithControl(BlockARMGEnoov, v0) + return true + } + // match: (GE (CMPconst [0] l:(XORshiftLL x y [c])) yes no) + // cond: l.Uses==1 +- // result: (GE (TEQshiftLL x y [c]) yes no) ++ // result: (GEnoov (TEQshiftLL x y [c]) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -17540,12 +17540,12 @@ func rewriteBlockARM(b *Block) bool { + v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftLL, types.TypeFlags) + v0.AuxInt = c + v0.AddArg2(x, y) +- b.resetWithControl(BlockARMGE, v0) ++ b.resetWithControl(BlockARMGEnoov, v0) + return true + } + // match: (GE (CMPconst [0] l:(XORshiftRL x y [c])) yes no) + // cond: l.Uses==1 +- // result: (GE (TEQshiftRL x y [c]) yes no) ++ // result: (GEnoov (TEQshiftRL x y [c]) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -17564,12 +17564,12 @@ func rewriteBlockARM(b *Block) bool { + v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRL, types.TypeFlags) + v0.AuxInt = c + v0.AddArg2(x, y) +- b.resetWithControl(BlockARMGE, v0) ++ b.resetWithControl(BlockARMGEnoov, v0) + return true + } + // match: (GE (CMPconst [0] l:(XORshiftRA x y [c])) yes no) + // cond: l.Uses==1 +- // result: (GE (TEQshiftRA x y [c]) yes no) ++ // result: (GEnoov (TEQshiftRA x y [c]) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -17588,12 +17588,12 @@ func rewriteBlockARM(b *Block) bool { + v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRA, types.TypeFlags) + v0.AuxInt = c + v0.AddArg2(x, y) +- b.resetWithControl(BlockARMGE, v0) ++ b.resetWithControl(BlockARMGEnoov, v0) + return true + } + // match: (GE (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) + // cond: l.Uses==1 +- // result: (GE (TEQshiftLLreg x y z) yes no) ++ // result: (GEnoov (TEQshiftLLreg x y z) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -17611,12 +17611,12 @@ func rewriteBlockARM(b *Block) bool { + } + v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftLLreg, types.TypeFlags) + v0.AddArg3(x, y, z) +- b.resetWithControl(BlockARMGE, v0) ++ b.resetWithControl(BlockARMGEnoov, v0) + return true + } + // match: (GE (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) + // cond: l.Uses==1 +- // result: (GE (TEQshiftRLreg x y z) yes no) ++ // result: (GEnoov (TEQshiftRLreg x y z) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -17634,12 +17634,12 @@ func rewriteBlockARM(b *Block) bool { + } + v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRLreg, types.TypeFlags) + v0.AddArg3(x, y, z) +- b.resetWithControl(BlockARMGE, v0) ++ b.resetWithControl(BlockARMGEnoov, v0) + return true + } + // match: (GE (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) + // cond: l.Uses==1 +- // result: (GE (TEQshiftRAreg x y z) yes no) ++ // result: (GEnoov (TEQshiftRAreg x y z) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -17657,7 +17657,7 @@ func rewriteBlockARM(b *Block) bool { + } + v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRAreg, types.TypeFlags) + v0.AddArg3(x, y, z) +- b.resetWithControl(BlockARMGE, v0) ++ b.resetWithControl(BlockARMGEnoov, v0) + return true + } + case BlockARMGEnoov: +@@ -18131,9 +18131,34 @@ func rewriteBlockARM(b *Block) bool { + b.resetWithControl(BlockARMGTnoov, v0) + return true + } ++ // match: (GT (CMPconst [0] l:(MULA x y a)) yes no) ++ // cond: l.Uses==1 ++ // result: (GTnoov (CMN a (MUL <x.Type> x y)) yes no) ++ for b.Controls[0].Op == OpARMCMPconst { ++ v_0 := b.Controls[0] ++ if v_0.AuxInt != 0 { ++ break ++ } ++ l := v_0.Args[0] ++ if l.Op != OpARMMULA { ++ break ++ } ++ a := l.Args[2] ++ x := l.Args[0] ++ y := l.Args[1] ++ if !(l.Uses == 1) { ++ break ++ } ++ v0 := b.NewValue0(v_0.Pos, OpARMCMN, types.TypeFlags) ++ v1 := b.NewValue0(v_0.Pos, OpARMMUL, x.Type) ++ v1.AddArg2(x, y) ++ v0.AddArg2(a, v1) ++ b.resetWithControl(BlockARMGTnoov, v0) ++ return true ++ } + // match: (GT (CMPconst [0] l:(AND x y)) yes no) + // cond: l.Uses==1 +- // result: (GT (TST x y) yes no) ++ // result: (GTnoov (TST x y) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -18154,39 +18179,14 @@ func rewriteBlockARM(b *Block) bool { + } + v0 := b.NewValue0(v_0.Pos, OpARMTST, types.TypeFlags) + v0.AddArg2(x, y) +- b.resetWithControl(BlockARMGT, v0) ++ b.resetWithControl(BlockARMGTnoov, v0) + return true + } + break + } +- // match: (GT (CMPconst [0] l:(MULA x y a)) yes no) +- // cond: l.Uses==1 +- // result: (GTnoov (CMN a (MUL <x.Type> x y)) yes no) +- for b.Controls[0].Op == OpARMCMPconst { +- v_0 := b.Controls[0] +- if v_0.AuxInt != 0 { +- break +- } +- l := v_0.Args[0] +- if l.Op != OpARMMULA { +- break +- } +- a := l.Args[2] +- x := l.Args[0] +- y := l.Args[1] +- if !(l.Uses == 1) { +- break +- } +- v0 := b.NewValue0(v_0.Pos, OpARMCMN, types.TypeFlags) +- v1 := b.NewValue0(v_0.Pos, OpARMMUL, x.Type) +- v1.AddArg2(x, y) +- v0.AddArg2(a, v1) +- b.resetWithControl(BlockARMGTnoov, v0) +- return true +- } + // match: (GT (CMPconst [0] l:(ANDconst [c] x)) yes no) + // cond: l.Uses==1 +- // result: (GT (TSTconst [c] x) yes no) ++ // result: (GTnoov (TSTconst [c] x) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -18204,12 +18204,12 @@ func rewriteBlockARM(b *Block) bool { + v0 := b.NewValue0(v_0.Pos, OpARMTSTconst, types.TypeFlags) + v0.AuxInt = c + v0.AddArg(x) +- b.resetWithControl(BlockARMGT, v0) ++ b.resetWithControl(BlockARMGTnoov, v0) + return true + } + // match: (GT (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) + // cond: l.Uses==1 +- // result: (GT (TSTshiftLL x y [c]) yes no) ++ // result: (GTnoov (TSTshiftLL x y [c]) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -18228,12 +18228,12 @@ func rewriteBlockARM(b *Block) bool { + v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftLL, types.TypeFlags) + v0.AuxInt = c + v0.AddArg2(x, y) +- b.resetWithControl(BlockARMGT, v0) ++ b.resetWithControl(BlockARMGTnoov, v0) + return true + } + // match: (GT (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) + // cond: l.Uses==1 +- // result: (GT (TSTshiftRL x y [c]) yes no) ++ // result: (GTnoov (TSTshiftRL x y [c]) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -18252,12 +18252,12 @@ func rewriteBlockARM(b *Block) bool { + v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRL, types.TypeFlags) + v0.AuxInt = c + v0.AddArg2(x, y) +- b.resetWithControl(BlockARMGT, v0) ++ b.resetWithControl(BlockARMGTnoov, v0) + return true + } + // match: (GT (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) + // cond: l.Uses==1 +- // result: (GT (TSTshiftRA x y [c]) yes no) ++ // result: (GTnoov (TSTshiftRA x y [c]) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -18276,12 +18276,12 @@ func rewriteBlockARM(b *Block) bool { + v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRA, types.TypeFlags) + v0.AuxInt = c + v0.AddArg2(x, y) +- b.resetWithControl(BlockARMGT, v0) ++ b.resetWithControl(BlockARMGTnoov, v0) + return true + } + // match: (GT (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) + // cond: l.Uses==1 +- // result: (GT (TSTshiftLLreg x y z) yes no) ++ // result: (GTnoov (TSTshiftLLreg x y z) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -18299,12 +18299,12 @@ func rewriteBlockARM(b *Block) bool { + } + v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftLLreg, types.TypeFlags) + v0.AddArg3(x, y, z) +- b.resetWithControl(BlockARMGT, v0) ++ b.resetWithControl(BlockARMGTnoov, v0) + return true + } + // match: (GT (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) + // cond: l.Uses==1 +- // result: (GT (TSTshiftRLreg x y z) yes no) ++ // result: (GTnoov (TSTshiftRLreg x y z) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -18322,12 +18322,12 @@ func rewriteBlockARM(b *Block) bool { + } + v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRLreg, types.TypeFlags) + v0.AddArg3(x, y, z) +- b.resetWithControl(BlockARMGT, v0) ++ b.resetWithControl(BlockARMGTnoov, v0) + return true + } + // match: (GT (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) + // cond: l.Uses==1 +- // result: (GT (TSTshiftRAreg x y z) yes no) ++ // result: (GTnoov (TSTshiftRAreg x y z) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -18345,12 +18345,12 @@ func rewriteBlockARM(b *Block) bool { + } + v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRAreg, types.TypeFlags) + v0.AddArg3(x, y, z) +- b.resetWithControl(BlockARMGT, v0) ++ b.resetWithControl(BlockARMGTnoov, v0) + return true + } + // match: (GT (CMPconst [0] l:(XOR x y)) yes no) + // cond: l.Uses==1 +- // result: (GT (TEQ x y) yes no) ++ // result: (GTnoov (TEQ x y) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -18371,14 +18371,14 @@ func rewriteBlockARM(b *Block) bool { + } + v0 := b.NewValue0(v_0.Pos, OpARMTEQ, types.TypeFlags) + v0.AddArg2(x, y) +- b.resetWithControl(BlockARMGT, v0) ++ b.resetWithControl(BlockARMGTnoov, v0) + return true + } + break + } + // match: (GT (CMPconst [0] l:(XORconst [c] x)) yes no) + // cond: l.Uses==1 +- // result: (GT (TEQconst [c] x) yes no) ++ // result: (GTnoov (TEQconst [c] x) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -18396,12 +18396,12 @@ func rewriteBlockARM(b *Block) bool { + v0 := b.NewValue0(v_0.Pos, OpARMTEQconst, types.TypeFlags) + v0.AuxInt = c + v0.AddArg(x) +- b.resetWithControl(BlockARMGT, v0) ++ b.resetWithControl(BlockARMGTnoov, v0) + return true + } + // match: (GT (CMPconst [0] l:(XORshiftLL x y [c])) yes no) + // cond: l.Uses==1 +- // result: (GT (TEQshiftLL x y [c]) yes no) ++ // result: (GTnoov (TEQshiftLL x y [c]) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -18420,12 +18420,12 @@ func rewriteBlockARM(b *Block) bool { + v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftLL, types.TypeFlags) + v0.AuxInt = c + v0.AddArg2(x, y) +- b.resetWithControl(BlockARMGT, v0) ++ b.resetWithControl(BlockARMGTnoov, v0) + return true + } + // match: (GT (CMPconst [0] l:(XORshiftRL x y [c])) yes no) + // cond: l.Uses==1 +- // result: (GT (TEQshiftRL x y [c]) yes no) ++ // result: (GTnoov (TEQshiftRL x y [c]) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -18444,12 +18444,12 @@ func rewriteBlockARM(b *Block) bool { + v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRL, types.TypeFlags) + v0.AuxInt = c + v0.AddArg2(x, y) +- b.resetWithControl(BlockARMGT, v0) ++ b.resetWithControl(BlockARMGTnoov, v0) + return true + } + // match: (GT (CMPconst [0] l:(XORshiftRA x y [c])) yes no) + // cond: l.Uses==1 +- // result: (GT (TEQshiftRA x y [c]) yes no) ++ // result: (GTnoov (TEQshiftRA x y [c]) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -18468,12 +18468,12 @@ func rewriteBlockARM(b *Block) bool { + v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRA, types.TypeFlags) + v0.AuxInt = c + v0.AddArg2(x, y) +- b.resetWithControl(BlockARMGT, v0) ++ b.resetWithControl(BlockARMGTnoov, v0) + return true + } + // match: (GT (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) + // cond: l.Uses==1 +- // result: (GT (TEQshiftLLreg x y z) yes no) ++ // result: (GTnoov (TEQshiftLLreg x y z) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -18491,12 +18491,12 @@ func rewriteBlockARM(b *Block) bool { + } + v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftLLreg, types.TypeFlags) + v0.AddArg3(x, y, z) +- b.resetWithControl(BlockARMGT, v0) ++ b.resetWithControl(BlockARMGTnoov, v0) + return true + } + // match: (GT (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) + // cond: l.Uses==1 +- // result: (GT (TEQshiftRLreg x y z) yes no) ++ // result: (GTnoov (TEQshiftRLreg x y z) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -18514,12 +18514,12 @@ func rewriteBlockARM(b *Block) bool { + } + v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRLreg, types.TypeFlags) + v0.AddArg3(x, y, z) +- b.resetWithControl(BlockARMGT, v0) ++ b.resetWithControl(BlockARMGTnoov, v0) + return true + } + // match: (GT (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) + // cond: l.Uses==1 +- // result: (GT (TEQshiftRAreg x y z) yes no) ++ // result: (GTnoov (TEQshiftRAreg x y z) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -18537,7 +18537,7 @@ func rewriteBlockARM(b *Block) bool { + } + v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRAreg, types.TypeFlags) + v0.AddArg3(x, y, z) +- b.resetWithControl(BlockARMGT, v0) ++ b.resetWithControl(BlockARMGTnoov, v0) + return true + } + case BlockARMGTnoov: +@@ -19129,7 +19129,7 @@ func rewriteBlockARM(b *Block) bool { + } + // match: (LE (CMPconst [0] l:(AND x y)) yes no) + // cond: l.Uses==1 +- // result: (LE (TST x y) yes no) ++ // result: (LEnoov (TST x y) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -19150,14 +19150,14 @@ func rewriteBlockARM(b *Block) bool { + } + v0 := b.NewValue0(v_0.Pos, OpARMTST, types.TypeFlags) + v0.AddArg2(x, y) +- b.resetWithControl(BlockARMLE, v0) ++ b.resetWithControl(BlockARMLEnoov, v0) + return true + } + break + } + // match: (LE (CMPconst [0] l:(ANDconst [c] x)) yes no) + // cond: l.Uses==1 +- // result: (LE (TSTconst [c] x) yes no) ++ // result: (LEnoov (TSTconst [c] x) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -19175,12 +19175,12 @@ func rewriteBlockARM(b *Block) bool { + v0 := b.NewValue0(v_0.Pos, OpARMTSTconst, types.TypeFlags) + v0.AuxInt = c + v0.AddArg(x) +- b.resetWithControl(BlockARMLE, v0) ++ b.resetWithControl(BlockARMLEnoov, v0) + return true + } + // match: (LE (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) + // cond: l.Uses==1 +- // result: (LE (TSTshiftLL x y [c]) yes no) ++ // result: (LEnoov (TSTshiftLL x y [c]) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -19199,12 +19199,12 @@ func rewriteBlockARM(b *Block) bool { + v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftLL, types.TypeFlags) + v0.AuxInt = c + v0.AddArg2(x, y) +- b.resetWithControl(BlockARMLE, v0) ++ b.resetWithControl(BlockARMLEnoov, v0) + return true + } + // match: (LE (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) + // cond: l.Uses==1 +- // result: (LE (TSTshiftRL x y [c]) yes no) ++ // result: (LEnoov (TSTshiftRL x y [c]) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -19223,12 +19223,12 @@ func rewriteBlockARM(b *Block) bool { + v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRL, types.TypeFlags) + v0.AuxInt = c + v0.AddArg2(x, y) +- b.resetWithControl(BlockARMLE, v0) ++ b.resetWithControl(BlockARMLEnoov, v0) + return true + } + // match: (LE (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) + // cond: l.Uses==1 +- // result: (LE (TSTshiftRA x y [c]) yes no) ++ // result: (LEnoov (TSTshiftRA x y [c]) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -19247,12 +19247,12 @@ func rewriteBlockARM(b *Block) bool { + v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRA, types.TypeFlags) + v0.AuxInt = c + v0.AddArg2(x, y) +- b.resetWithControl(BlockARMLE, v0) ++ b.resetWithControl(BlockARMLEnoov, v0) + return true + } + // match: (LE (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) + // cond: l.Uses==1 +- // result: (LE (TSTshiftLLreg x y z) yes no) ++ // result: (LEnoov (TSTshiftLLreg x y z) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -19270,12 +19270,12 @@ func rewriteBlockARM(b *Block) bool { + } + v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftLLreg, types.TypeFlags) + v0.AddArg3(x, y, z) +- b.resetWithControl(BlockARMLE, v0) ++ b.resetWithControl(BlockARMLEnoov, v0) + return true + } + // match: (LE (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) + // cond: l.Uses==1 +- // result: (LE (TSTshiftRLreg x y z) yes no) ++ // result: (LEnoov (TSTshiftRLreg x y z) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -19293,12 +19293,12 @@ func rewriteBlockARM(b *Block) bool { + } + v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRLreg, types.TypeFlags) + v0.AddArg3(x, y, z) +- b.resetWithControl(BlockARMLE, v0) ++ b.resetWithControl(BlockARMLEnoov, v0) + return true + } + // match: (LE (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) + // cond: l.Uses==1 +- // result: (LE (TSTshiftRAreg x y z) yes no) ++ // result: (LEnoov (TSTshiftRAreg x y z) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -19316,12 +19316,12 @@ func rewriteBlockARM(b *Block) bool { + } + v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRAreg, types.TypeFlags) + v0.AddArg3(x, y, z) +- b.resetWithControl(BlockARMLE, v0) ++ b.resetWithControl(BlockARMLEnoov, v0) + return true + } + // match: (LE (CMPconst [0] l:(XOR x y)) yes no) + // cond: l.Uses==1 +- // result: (LE (TEQ x y) yes no) ++ // result: (LEnoov (TEQ x y) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -19342,14 +19342,14 @@ func rewriteBlockARM(b *Block) bool { + } + v0 := b.NewValue0(v_0.Pos, OpARMTEQ, types.TypeFlags) + v0.AddArg2(x, y) +- b.resetWithControl(BlockARMLE, v0) ++ b.resetWithControl(BlockARMLEnoov, v0) + return true + } + break + } + // match: (LE (CMPconst [0] l:(XORconst [c] x)) yes no) + // cond: l.Uses==1 +- // result: (LE (TEQconst [c] x) yes no) ++ // result: (LEnoov (TEQconst [c] x) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -19367,12 +19367,12 @@ func rewriteBlockARM(b *Block) bool { + v0 := b.NewValue0(v_0.Pos, OpARMTEQconst, types.TypeFlags) + v0.AuxInt = c + v0.AddArg(x) +- b.resetWithControl(BlockARMLE, v0) ++ b.resetWithControl(BlockARMLEnoov, v0) + return true + } + // match: (LE (CMPconst [0] l:(XORshiftLL x y [c])) yes no) + // cond: l.Uses==1 +- // result: (LE (TEQshiftLL x y [c]) yes no) ++ // result: (LEnoov (TEQshiftLL x y [c]) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -19391,12 +19391,12 @@ func rewriteBlockARM(b *Block) bool { + v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftLL, types.TypeFlags) + v0.AuxInt = c + v0.AddArg2(x, y) +- b.resetWithControl(BlockARMLE, v0) ++ b.resetWithControl(BlockARMLEnoov, v0) + return true + } + // match: (LE (CMPconst [0] l:(XORshiftRL x y [c])) yes no) + // cond: l.Uses==1 +- // result: (LE (TEQshiftRL x y [c]) yes no) ++ // result: (LEnoov (TEQshiftRL x y [c]) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -19415,12 +19415,12 @@ func rewriteBlockARM(b *Block) bool { + v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRL, types.TypeFlags) + v0.AuxInt = c + v0.AddArg2(x, y) +- b.resetWithControl(BlockARMLE, v0) ++ b.resetWithControl(BlockARMLEnoov, v0) + return true + } + // match: (LE (CMPconst [0] l:(XORshiftRA x y [c])) yes no) + // cond: l.Uses==1 +- // result: (LE (TEQshiftRA x y [c]) yes no) ++ // result: (LEnoov (TEQshiftRA x y [c]) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -19439,12 +19439,12 @@ func rewriteBlockARM(b *Block) bool { + v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRA, types.TypeFlags) + v0.AuxInt = c + v0.AddArg2(x, y) +- b.resetWithControl(BlockARMLE, v0) ++ b.resetWithControl(BlockARMLEnoov, v0) + return true + } + // match: (LE (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) + // cond: l.Uses==1 +- // result: (LE (TEQshiftLLreg x y z) yes no) ++ // result: (LEnoov (TEQshiftLLreg x y z) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -19462,12 +19462,12 @@ func rewriteBlockARM(b *Block) bool { + } + v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftLLreg, types.TypeFlags) + v0.AddArg3(x, y, z) +- b.resetWithControl(BlockARMLE, v0) ++ b.resetWithControl(BlockARMLEnoov, v0) + return true + } + // match: (LE (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) + // cond: l.Uses==1 +- // result: (LE (TEQshiftRLreg x y z) yes no) ++ // result: (LEnoov (TEQshiftRLreg x y z) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -19485,12 +19485,12 @@ func rewriteBlockARM(b *Block) bool { + } + v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRLreg, types.TypeFlags) + v0.AddArg3(x, y, z) +- b.resetWithControl(BlockARMLE, v0) ++ b.resetWithControl(BlockARMLEnoov, v0) + return true + } + // match: (LE (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) + // cond: l.Uses==1 +- // result: (LE (TEQshiftRAreg x y z) yes no) ++ // result: (LEnoov (TEQshiftRAreg x y z) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -19508,7 +19508,7 @@ func rewriteBlockARM(b *Block) bool { + } + v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRAreg, types.TypeFlags) + v0.AddArg3(x, y, z) +- b.resetWithControl(BlockARMLE, v0) ++ b.resetWithControl(BlockARMLEnoov, v0) + return true + } + case BlockARMLEnoov: +@@ -20009,7 +20009,7 @@ func rewriteBlockARM(b *Block) bool { + } + // match: (LT (CMPconst [0] l:(AND x y)) yes no) + // cond: l.Uses==1 +- // result: (LT (TST x y) yes no) ++ // result: (LTnoov (TST x y) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -20030,14 +20030,14 @@ func rewriteBlockARM(b *Block) bool { + } + v0 := b.NewValue0(v_0.Pos, OpARMTST, types.TypeFlags) + v0.AddArg2(x, y) +- b.resetWithControl(BlockARMLT, v0) ++ b.resetWithControl(BlockARMLTnoov, v0) + return true + } + break + } + // match: (LT (CMPconst [0] l:(ANDconst [c] x)) yes no) + // cond: l.Uses==1 +- // result: (LT (TSTconst [c] x) yes no) ++ // result: (LTnoov (TSTconst [c] x) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -20055,12 +20055,12 @@ func rewriteBlockARM(b *Block) bool { + v0 := b.NewValue0(v_0.Pos, OpARMTSTconst, types.TypeFlags) + v0.AuxInt = c + v0.AddArg(x) +- b.resetWithControl(BlockARMLT, v0) ++ b.resetWithControl(BlockARMLTnoov, v0) + return true + } + // match: (LT (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) + // cond: l.Uses==1 +- // result: (LT (TSTshiftLL x y [c]) yes no) ++ // result: (LTnoov (TSTshiftLL x y [c]) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -20079,12 +20079,12 @@ func rewriteBlockARM(b *Block) bool { + v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftLL, types.TypeFlags) + v0.AuxInt = c + v0.AddArg2(x, y) +- b.resetWithControl(BlockARMLT, v0) ++ b.resetWithControl(BlockARMLTnoov, v0) + return true + } + // match: (LT (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) + // cond: l.Uses==1 +- // result: (LT (TSTshiftRL x y [c]) yes no) ++ // result: (LTnoov (TSTshiftRL x y [c]) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -20103,12 +20103,12 @@ func rewriteBlockARM(b *Block) bool { + v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRL, types.TypeFlags) + v0.AuxInt = c + v0.AddArg2(x, y) +- b.resetWithControl(BlockARMLT, v0) ++ b.resetWithControl(BlockARMLTnoov, v0) + return true + } + // match: (LT (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) + // cond: l.Uses==1 +- // result: (LT (TSTshiftRA x y [c]) yes no) ++ // result: (LTnoov (TSTshiftRA x y [c]) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -20127,12 +20127,12 @@ func rewriteBlockARM(b *Block) bool { + v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRA, types.TypeFlags) + v0.AuxInt = c + v0.AddArg2(x, y) +- b.resetWithControl(BlockARMLT, v0) ++ b.resetWithControl(BlockARMLTnoov, v0) + return true + } + // match: (LT (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) + // cond: l.Uses==1 +- // result: (LT (TSTshiftLLreg x y z) yes no) ++ // result: (LTnoov (TSTshiftLLreg x y z) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -20150,12 +20150,12 @@ func rewriteBlockARM(b *Block) bool { + } + v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftLLreg, types.TypeFlags) + v0.AddArg3(x, y, z) +- b.resetWithControl(BlockARMLT, v0) ++ b.resetWithControl(BlockARMLTnoov, v0) + return true + } + // match: (LT (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) + // cond: l.Uses==1 +- // result: (LT (TSTshiftRLreg x y z) yes no) ++ // result: (LTnoov (TSTshiftRLreg x y z) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -20173,12 +20173,12 @@ func rewriteBlockARM(b *Block) bool { + } + v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRLreg, types.TypeFlags) + v0.AddArg3(x, y, z) +- b.resetWithControl(BlockARMLT, v0) ++ b.resetWithControl(BlockARMLTnoov, v0) + return true + } + // match: (LT (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) + // cond: l.Uses==1 +- // result: (LT (TSTshiftRAreg x y z) yes no) ++ // result: (LTnoov (TSTshiftRAreg x y z) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -20196,12 +20196,12 @@ func rewriteBlockARM(b *Block) bool { + } + v0 := b.NewValue0(v_0.Pos, OpARMTSTshiftRAreg, types.TypeFlags) + v0.AddArg3(x, y, z) +- b.resetWithControl(BlockARMLT, v0) ++ b.resetWithControl(BlockARMLTnoov, v0) + return true + } + // match: (LT (CMPconst [0] l:(XOR x y)) yes no) + // cond: l.Uses==1 +- // result: (LT (TEQ x y) yes no) ++ // result: (LTnoov (TEQ x y) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -20222,14 +20222,14 @@ func rewriteBlockARM(b *Block) bool { + } + v0 := b.NewValue0(v_0.Pos, OpARMTEQ, types.TypeFlags) + v0.AddArg2(x, y) +- b.resetWithControl(BlockARMLT, v0) ++ b.resetWithControl(BlockARMLTnoov, v0) + return true + } + break + } + // match: (LT (CMPconst [0] l:(XORconst [c] x)) yes no) + // cond: l.Uses==1 +- // result: (LT (TEQconst [c] x) yes no) ++ // result: (LTnoov (TEQconst [c] x) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -20247,12 +20247,12 @@ func rewriteBlockARM(b *Block) bool { + v0 := b.NewValue0(v_0.Pos, OpARMTEQconst, types.TypeFlags) + v0.AuxInt = c + v0.AddArg(x) +- b.resetWithControl(BlockARMLT, v0) ++ b.resetWithControl(BlockARMLTnoov, v0) + return true + } + // match: (LT (CMPconst [0] l:(XORshiftLL x y [c])) yes no) + // cond: l.Uses==1 +- // result: (LT (TEQshiftLL x y [c]) yes no) ++ // result: (LTnoov (TEQshiftLL x y [c]) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -20271,12 +20271,12 @@ func rewriteBlockARM(b *Block) bool { + v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftLL, types.TypeFlags) + v0.AuxInt = c + v0.AddArg2(x, y) +- b.resetWithControl(BlockARMLT, v0) ++ b.resetWithControl(BlockARMLTnoov, v0) + return true + } + // match: (LT (CMPconst [0] l:(XORshiftRL x y [c])) yes no) + // cond: l.Uses==1 +- // result: (LT (TEQshiftRL x y [c]) yes no) ++ // result: (LTnoov (TEQshiftRL x y [c]) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -20295,12 +20295,12 @@ func rewriteBlockARM(b *Block) bool { + v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRL, types.TypeFlags) + v0.AuxInt = c + v0.AddArg2(x, y) +- b.resetWithControl(BlockARMLT, v0) ++ b.resetWithControl(BlockARMLTnoov, v0) + return true + } + // match: (LT (CMPconst [0] l:(XORshiftRA x y [c])) yes no) + // cond: l.Uses==1 +- // result: (LT (TEQshiftRA x y [c]) yes no) ++ // result: (LTnoov (TEQshiftRA x y [c]) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -20319,12 +20319,12 @@ func rewriteBlockARM(b *Block) bool { + v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRA, types.TypeFlags) + v0.AuxInt = c + v0.AddArg2(x, y) +- b.resetWithControl(BlockARMLT, v0) ++ b.resetWithControl(BlockARMLTnoov, v0) + return true + } + // match: (LT (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) + // cond: l.Uses==1 +- // result: (LT (TEQshiftLLreg x y z) yes no) ++ // result: (LTnoov (TEQshiftLLreg x y z) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -20342,12 +20342,12 @@ func rewriteBlockARM(b *Block) bool { + } + v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftLLreg, types.TypeFlags) + v0.AddArg3(x, y, z) +- b.resetWithControl(BlockARMLT, v0) ++ b.resetWithControl(BlockARMLTnoov, v0) + return true + } + // match: (LT (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) + // cond: l.Uses==1 +- // result: (LT (TEQshiftRLreg x y z) yes no) ++ // result: (LTnoov (TEQshiftRLreg x y z) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -20365,12 +20365,12 @@ func rewriteBlockARM(b *Block) bool { + } + v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRLreg, types.TypeFlags) + v0.AddArg3(x, y, z) +- b.resetWithControl(BlockARMLT, v0) ++ b.resetWithControl(BlockARMLTnoov, v0) + return true + } + // match: (LT (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) + // cond: l.Uses==1 +- // result: (LT (TEQshiftRAreg x y z) yes no) ++ // result: (LTnoov (TEQshiftRAreg x y z) yes no) + for b.Controls[0].Op == OpARMCMPconst { + v_0 := b.Controls[0] + if v_0.AuxInt != 0 { +@@ -20388,7 +20388,7 @@ func rewriteBlockARM(b *Block) bool { + } + v0 := b.NewValue0(v_0.Pos, OpARMTEQshiftRAreg, types.TypeFlags) + v0.AddArg3(x, y, z) +- b.resetWithControl(BlockARMLT, v0) ++ b.resetWithControl(BlockARMLTnoov, v0) + return true + } + case BlockARMLTnoov: +diff --git a/test/fixedbugs/issue42876.go b/test/fixedbugs/issue42876.go +new file mode 100644 +index 0000000000..67cf4919ac +--- /dev/null ++++ b/test/fixedbugs/issue42876.go +@@ -0,0 +1,18 @@ ++// run ++ ++// Copyright 2020 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++package main ++ ++var x = [4]int32{-0x7fffffff, 0x7fffffff, 2, 4} ++ ++func main() { ++ if x[0] > x[1] { ++ panic("fail 1") ++ } ++ if x[2]&x[3] < 0 { ++ panic("fail 2") // Fails here ++ } ++} +-- +2.29.2 + |