]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: on AMD64, turn x < 128 into x <= 127
authorJakub Ciolek <jakub@ciolek.dev>
Fri, 3 Jan 2025 12:52:11 +0000 (13:52 +0100)
committerKeith Randall <khr@golang.org>
Sun, 16 Feb 2025 15:23:13 +0000 (07:23 -0800)
x < 128 -> x <= 127
x >= 128 -> x > 127

This allows for shorter encoding as 127 fits into
a single-byte immediate.

archive/tar benchmark (Alder Lake 12600K)

name              old time/op    new time/op    delta
/Writer/USTAR-16    1.46µs ± 0%    1.32µs ± 0%  -9.43%  (p=0.008 n=5+5)
/Writer/GNU-16      1.85µs ± 1%    1.79µs ± 1%  -3.47%  (p=0.008 n=5+5)
/Writer/PAX-16      3.21µs ± 0%    3.11µs ± 2%  -2.96%  (p=0.008 n=5+5)
/Reader/USTAR-16    1.38µs ± 1%    1.37µs ± 0%    ~     (p=0.127 n=5+4)
/Reader/GNU-16       798ns ± 1%     800ns ± 2%    ~     (p=0.548 n=5+5)
/Reader/PAX-16      3.07µs ± 1%    3.00µs ± 0%  -2.35%  (p=0.008 n=5+5)
[Geo mean]          1.76µs         1.70µs       -3.15%

compilecmp:

hash/maphash
hash/maphash.(*Hash).Write 517 -> 510  (-1.35%)

runtime
runtime.traceReadCPU 1626 -> 1615  (-0.68%)

runtime [cmd/compile]
runtime.traceReadCPU 1626 -> 1615  (-0.68%)

math/rand/v2
type:.eq.[128]float32 65 -> 59  (-9.23%)

bytes
bytes.trimLeftUnicode 378 -> 373  (-1.32%)
bytes.IndexAny 1189 -> 1157  (-2.69%)
bytes.LastIndexAny 1256 -> 1239  (-1.35%)
bytes.lastIndexFunc 263 -> 261  (-0.76%)

strings
strings.FieldsFuncSeq.func1 411 -> 399  (-2.92%)
strings.EqualFold 625 -> 624  (-0.16%)
strings.trimLeftUnicode 248 -> 231  (-6.85%)

math/rand
type:.eq.[128]float32 65 -> 59  (-9.23%)

bytes [cmd/compile]
bytes.LastIndexAny 1256 -> 1239  (-1.35%)
bytes.lastIndexFunc 263 -> 261  (-0.76%)
bytes.trimLeftUnicode 378 -> 373  (-1.32%)
bytes.IndexAny 1189 -> 1157  (-2.69%)

regexp/syntax
regexp/syntax.(*parser).parseEscape 1113 -> 1102  (-0.99%)

math/rand/v2 [cmd/compile]
type:.eq.[128]float32 65 -> 59  (-9.23%)

strings [cmd/compile]
strings.EqualFold 625 -> 624  (-0.16%)
strings.FieldsFuncSeq.func1 411 -> 399  (-2.92%)
strings.trimLeftUnicode 248 -> 231  (-6.85%)

math/rand [cmd/compile]
type:.eq.[128]float32 65 -> 59  (-9.23%)

regexp
regexp.(*inputString).context 198 -> 197  (-0.51%)
regexp.(*inputBytes).context 221 -> 212  (-4.07%)

image/jpeg
image/jpeg.(*decoder).processDQT 500 -> 491  (-1.80%)

regexp/syntax [cmd/compile]
regexp/syntax.(*parser).parseEscape 1113 -> 1102  (-0.99%)

regexp [cmd/compile]
regexp.(*inputString).context 198 -> 197  (-0.51%)
regexp.(*inputBytes).context 221 -> 212  (-4.07%)

encoding/csv
encoding/csv.(*Writer).fieldNeedsQuotes 269 -> 266  (-1.12%)

cmd/vendor/golang.org/x/sys/unix
type:.eq.[131]struct 855 -> 823  (-3.74%)

vendor/golang.org/x/text/unicode/norm
vendor/golang.org/x/text/unicode/norm.nextDecomposed 4831 -> 4826  (-0.10%)
vendor/golang.org/x/text/unicode/norm.(*Iter).returnSlice 281 -> 275  (-2.14%)

vendor/golang.org/x/text/secure/bidirule
vendor/golang.org/x/text/secure/bidirule.init.0 85 -> 83  (-2.35%)

go/scanner
go/scanner.isDigit 100 -> 98  (-2.00%)
go/scanner.(*Scanner).next 431 -> 422  (-2.09%)
go/scanner.isLetter 142 -> 124  (-12.68%)

encoding/asn1
encoding/asn1.parseTagAndLength 1189 -> 1182  (-0.59%)
encoding/asn1.makeField 3481 -> 3463  (-0.52%)

text/scanner
text/scanner.(*Scanner).next 1242 -> 1236  (-0.48%)

archive/tar
archive/tar.isASCII 133 -> 127  (-4.51%)
archive/tar.(*Writer).writeRawFile 1206 -> 1198  (-0.66%)
archive/tar.(*Reader).readHeader.func1 9 -> 7  (-22.22%)
archive/tar.toASCII 393 -> 383  (-2.54%)
archive/tar.splitUSTARPath 405 -> 396  (-2.22%)
archive/tar.(*Writer).writePAXHeader.func1 627 -> 620  (-1.12%)

text/template
text/template.jsIsSpecial 59 -> 57  (-3.39%)

go/doc
go/doc.assumedPackageName 714 -> 701  (-1.82%)

vendor/golang.org/x/net/http/httpguts
vendor/golang.org/x/net/http/httpguts.headerValueContainsToken 965 -> 952  (-1.35%)
vendor/golang.org/x/net/http/httpguts.tokenEqual 280 -> 269  (-3.93%)
vendor/golang.org/x/net/http/httpguts.IsTokenRune 28 -> 26  (-7.14%)

net/mail
net/mail.isVchar 26 -> 24  (-7.69%)
net/mail.isAtext 106 -> 104  (-1.89%)
net/mail.(*Address).String 1084 -> 1052  (-2.95%)
net/mail.isQtext 39 -> 37  (-5.13%)
net/mail.isMultibyte 9 -> 7  (-22.22%)
net/mail.isDtext 45 -> 43  (-4.44%)
net/mail.(*addrParser).consumeQuotedString 1050 -> 1029  (-2.00%)
net/mail.quoteString 741 -> 714  (-3.64%)

cmd/internal/obj/s390x
cmd/internal/obj/s390x.preprocess 6405 -> 6393  (-0.19%)

cmd/internal/obj/x86
cmd/internal/obj/x86.toDisp8 303 -> 301  (-0.66%)

fmt [cmd/compile]
fmt.Fprintf 4726 -> 4662  (-1.35%)

go/scanner [cmd/compile]
go/scanner.(*Scanner).next 431 -> 422  (-2.09%)
go/scanner.isLetter 142 -> 124  (-12.68%)
go/scanner.isDigit 100 -> 98  (-2.00%)

cmd/compile/internal/syntax
cmd/compile/internal/syntax.(*source).nextch 879 -> 847  (-3.64%)

cmd/vendor/golang.org/x/mod/module
cmd/vendor/golang.org/x/mod/module.checkElem 1253 -> 1235  (-1.44%)
cmd/vendor/golang.org/x/mod/module.escapeString 519 -> 517  (-0.39%)

go/doc [cmd/compile]
go/doc.assumedPackageName 714 -> 701  (-1.82%)

cmd/compile/internal/syntax [cmd/compile]
cmd/compile/internal/syntax.(*scanner).escape 1965 -> 1933  (-1.63%)
cmd/compile/internal/syntax.(*scanner).next 8975 -> 8847  (-1.43%)

cmd/internal/obj/s390x [cmd/compile]
cmd/internal/obj/s390x.preprocess 6405 -> 6393  (-0.19%)

cmd/internal/obj/x86 [cmd/compile]
cmd/internal/obj/x86.toDisp8 303 -> 301  (-0.66%)

cmd/internal/gcprog
cmd/internal/gcprog.(*Writer).Repeat 688 -> 677  (-1.60%)
cmd/internal/gcprog.(*Writer).varint 442 -> 439  (-0.68%)

cmd/compile/internal/ir
cmd/compile/internal/ir.splitPkg 331 -> 325  (-1.81%)

cmd/compile/internal/ir [cmd/compile]
cmd/compile/internal/ir.splitPkg 331 -> 325  (-1.81%)

net/http
net/http.containsDotDot.FieldsFuncSeq.func1 411 -> 399  (-2.92%)
net/http.isNotToken 33 -> 30  (-9.09%)
net/http.containsDotDot 606 -> 588  (-2.97%)
net/http.isCookieNameValid 197 -> 191  (-3.05%)
net/http.parsePattern 4330 -> 4317  (-0.30%)
net/http.ParseCookie 1099 -> 1096  (-0.27%)
net/http.validMethod 197 -> 187  (-5.08%)

cmd/vendor/golang.org/x/text/unicode/norm
cmd/vendor/golang.org/x/text/unicode/norm.(*Iter).returnSlice 281 -> 275  (-2.14%)
cmd/vendor/golang.org/x/text/unicode/norm.nextDecomposed 4831 -> 4826  (-0.10%)

net/http/cookiejar
net/http/cookiejar.encode 1936 -> 1918  (-0.93%)

expvar
expvar.appendJSONQuote 972 -> 965  (-0.72%)

cmd/cgo/internal/test
cmd/cgo/internal/test.stack128 116 -> 114  (-1.72%)

cmd/vendor/rsc.io/markdown
cmd/vendor/rsc.io/markdown.newATXHeading 1637 -> 1628  (-0.55%)
cmd/vendor/rsc.io/markdown.isUnicodePunct 197 -> 179  (-9.14%)

Change-Id: I578bdf42ef229d687d526e378d697ced51e1880c
Reviewed-on: https://go-review.googlesource.com/c/go/+/639935
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Keith Randall <khr@google.com>
src/cmd/compile/internal/ssa/_gen/AMD64.rules
src/cmd/compile/internal/ssa/rewriteAMD64.go
test/codegen/comparisons.go

index 9177067e522206d4594f664eb6aed283d87a8b16..e590b41d5f5a2d7eff0a87ada2954ca8bf022f69 100644 (file)
 // x & 1 == 0 -> (x & 1) ^ 1
 (SETAE (BT(L|Q)const [0] x)) => (XORLconst [1] (ANDLconst <typ.Bool> [1] x))
 
+// Shorten compare by rewriting x < 128 as x <= 127, which can be encoded in a single-byte immediate on x86.
+(SETL c:(CMP(Q|L)const [128] x)) && c.Uses == 1 => (SETLE (CMP(Q|L)const [127] x))
+(SETB c:(CMP(Q|L)const [128] x)) && c.Uses == 1 => (SETBE (CMP(Q|L)const [127] x))
+
+// x >= 128 -> x > 127
+(SETGE c:(CMP(Q|L)const [128] x)) && c.Uses == 1 => (SETG (CMP(Q|L)const [127] x))
+(SETAE c:(CMP(Q|L)const [128] x)) && c.Uses == 1 => (SETA (CMP(Q|L)const [127] x))
+
+(CMOVQLT x y c:(CMP(Q|L)const [128] z)) && c.Uses == 1 => (CMOVQLE x y (CMP(Q|L)const [127] z))
+(CMOVLLT x y c:(CMP(Q|L)const [128] z)) && c.Uses == 1 => (CMOVLLE x y (CMP(Q|L)const [127] z))
+(LT          c:(CMP(Q|L)const [128] z) yes no) && c.Uses == 1 => (LE (CMP(Q|L)const [127] z) yes no)
+(CMOVQGE x y c:(CMP(Q|L)const [128] z)) && c.Uses == 1 => (CMOVQGT x y (CMP(Q|L)const [127] z))
+(CMOVLGE x y c:(CMP(Q|L)const [128] z)) && c.Uses == 1 => (CMOVLGT x y (CMP(Q|L)const [127] z))
+(GE          c:(CMP(Q|L)const [128] z) yes no) && c.Uses == 1 => (GT (CMP(Q|L)const [127] z)  yes no)
+
 // Recognize bit tests: a&(1<<b) != 0 for b suitably bounded
 // Note that BTx instructions use the carry bit, so we need to convert tests for zero flag
 // into tests for carry flags.
index 63376dcb76f2d98668d8e4ad9aa3ac3ff75d08b1..be9b3d9ea98d3804dd2f0e0ce1e804adce13f4d6 100644 (file)
@@ -4246,6 +4246,7 @@ func rewriteValueAMD64_OpAMD64CMOVLGE(v *Value) bool {
        v_2 := v.Args[2]
        v_1 := v.Args[1]
        v_0 := v.Args[0]
+       b := v.Block
        // match: (CMOVLGE x y (InvertFlags cond))
        // result: (CMOVLLE x y cond)
        for {
@@ -4309,6 +4310,48 @@ func rewriteValueAMD64_OpAMD64CMOVLGE(v *Value) bool {
                v.copyOf(y)
                return true
        }
+       // match: (CMOVLGE x y c:(CMPQconst [128] z))
+       // cond: c.Uses == 1
+       // result: (CMOVLGT x y (CMPQconst [127] z))
+       for {
+               x := v_0
+               y := v_1
+               c := v_2
+               if c.Op != OpAMD64CMPQconst || auxIntToInt32(c.AuxInt) != 128 {
+                       break
+               }
+               z := c.Args[0]
+               if !(c.Uses == 1) {
+                       break
+               }
+               v.reset(OpAMD64CMOVLGT)
+               v0 := b.NewValue0(v.Pos, OpAMD64CMPQconst, types.TypeFlags)
+               v0.AuxInt = int32ToAuxInt(127)
+               v0.AddArg(z)
+               v.AddArg3(x, y, v0)
+               return true
+       }
+       // match: (CMOVLGE x y c:(CMPLconst [128] z))
+       // cond: c.Uses == 1
+       // result: (CMOVLGT x y (CMPLconst [127] z))
+       for {
+               x := v_0
+               y := v_1
+               c := v_2
+               if c.Op != OpAMD64CMPLconst || auxIntToInt32(c.AuxInt) != 128 {
+                       break
+               }
+               z := c.Args[0]
+               if !(c.Uses == 1) {
+                       break
+               }
+               v.reset(OpAMD64CMOVLGT)
+               v0 := b.NewValue0(v.Pos, OpAMD64CMPLconst, types.TypeFlags)
+               v0.AuxInt = int32ToAuxInt(127)
+               v0.AddArg(z)
+               v.AddArg3(x, y, v0)
+               return true
+       }
        return false
 }
 func rewriteValueAMD64_OpAMD64CMOVLGT(v *Value) bool {
@@ -4591,6 +4634,7 @@ func rewriteValueAMD64_OpAMD64CMOVLLT(v *Value) bool {
        v_2 := v.Args[2]
        v_1 := v.Args[1]
        v_0 := v.Args[0]
+       b := v.Block
        // match: (CMOVLLT x y (InvertFlags cond))
        // result: (CMOVLGT x y cond)
        for {
@@ -4654,6 +4698,48 @@ func rewriteValueAMD64_OpAMD64CMOVLLT(v *Value) bool {
                v.copyOf(x)
                return true
        }
+       // match: (CMOVLLT x y c:(CMPQconst [128] z))
+       // cond: c.Uses == 1
+       // result: (CMOVLLE x y (CMPQconst [127] z))
+       for {
+               x := v_0
+               y := v_1
+               c := v_2
+               if c.Op != OpAMD64CMPQconst || auxIntToInt32(c.AuxInt) != 128 {
+                       break
+               }
+               z := c.Args[0]
+               if !(c.Uses == 1) {
+                       break
+               }
+               v.reset(OpAMD64CMOVLLE)
+               v0 := b.NewValue0(v.Pos, OpAMD64CMPQconst, types.TypeFlags)
+               v0.AuxInt = int32ToAuxInt(127)
+               v0.AddArg(z)
+               v.AddArg3(x, y, v0)
+               return true
+       }
+       // match: (CMOVLLT x y c:(CMPLconst [128] z))
+       // cond: c.Uses == 1
+       // result: (CMOVLLE x y (CMPLconst [127] z))
+       for {
+               x := v_0
+               y := v_1
+               c := v_2
+               if c.Op != OpAMD64CMPLconst || auxIntToInt32(c.AuxInt) != 128 {
+                       break
+               }
+               z := c.Args[0]
+               if !(c.Uses == 1) {
+                       break
+               }
+               v.reset(OpAMD64CMOVLLE)
+               v0 := b.NewValue0(v.Pos, OpAMD64CMPLconst, types.TypeFlags)
+               v0.AuxInt = int32ToAuxInt(127)
+               v0.AddArg(z)
+               v.AddArg3(x, y, v0)
+               return true
+       }
        return false
 }
 func rewriteValueAMD64_OpAMD64CMOVLNE(v *Value) bool {
@@ -5096,6 +5182,7 @@ func rewriteValueAMD64_OpAMD64CMOVQGE(v *Value) bool {
        v_2 := v.Args[2]
        v_1 := v.Args[1]
        v_0 := v.Args[0]
+       b := v.Block
        // match: (CMOVQGE x y (InvertFlags cond))
        // result: (CMOVQLE x y cond)
        for {
@@ -5159,6 +5246,48 @@ func rewriteValueAMD64_OpAMD64CMOVQGE(v *Value) bool {
                v.copyOf(y)
                return true
        }
+       // match: (CMOVQGE x y c:(CMPQconst [128] z))
+       // cond: c.Uses == 1
+       // result: (CMOVQGT x y (CMPQconst [127] z))
+       for {
+               x := v_0
+               y := v_1
+               c := v_2
+               if c.Op != OpAMD64CMPQconst || auxIntToInt32(c.AuxInt) != 128 {
+                       break
+               }
+               z := c.Args[0]
+               if !(c.Uses == 1) {
+                       break
+               }
+               v.reset(OpAMD64CMOVQGT)
+               v0 := b.NewValue0(v.Pos, OpAMD64CMPQconst, types.TypeFlags)
+               v0.AuxInt = int32ToAuxInt(127)
+               v0.AddArg(z)
+               v.AddArg3(x, y, v0)
+               return true
+       }
+       // match: (CMOVQGE x y c:(CMPLconst [128] z))
+       // cond: c.Uses == 1
+       // result: (CMOVQGT x y (CMPLconst [127] z))
+       for {
+               x := v_0
+               y := v_1
+               c := v_2
+               if c.Op != OpAMD64CMPLconst || auxIntToInt32(c.AuxInt) != 128 {
+                       break
+               }
+               z := c.Args[0]
+               if !(c.Uses == 1) {
+                       break
+               }
+               v.reset(OpAMD64CMOVQGT)
+               v0 := b.NewValue0(v.Pos, OpAMD64CMPLconst, types.TypeFlags)
+               v0.AuxInt = int32ToAuxInt(127)
+               v0.AddArg(z)
+               v.AddArg3(x, y, v0)
+               return true
+       }
        return false
 }
 func rewriteValueAMD64_OpAMD64CMOVQGT(v *Value) bool {
@@ -5441,6 +5570,7 @@ func rewriteValueAMD64_OpAMD64CMOVQLT(v *Value) bool {
        v_2 := v.Args[2]
        v_1 := v.Args[1]
        v_0 := v.Args[0]
+       b := v.Block
        // match: (CMOVQLT x y (InvertFlags cond))
        // result: (CMOVQGT x y cond)
        for {
@@ -5504,6 +5634,48 @@ func rewriteValueAMD64_OpAMD64CMOVQLT(v *Value) bool {
                v.copyOf(x)
                return true
        }
+       // match: (CMOVQLT x y c:(CMPQconst [128] z))
+       // cond: c.Uses == 1
+       // result: (CMOVQLE x y (CMPQconst [127] z))
+       for {
+               x := v_0
+               y := v_1
+               c := v_2
+               if c.Op != OpAMD64CMPQconst || auxIntToInt32(c.AuxInt) != 128 {
+                       break
+               }
+               z := c.Args[0]
+               if !(c.Uses == 1) {
+                       break
+               }
+               v.reset(OpAMD64CMOVQLE)
+               v0 := b.NewValue0(v.Pos, OpAMD64CMPQconst, types.TypeFlags)
+               v0.AuxInt = int32ToAuxInt(127)
+               v0.AddArg(z)
+               v.AddArg3(x, y, v0)
+               return true
+       }
+       // match: (CMOVQLT x y c:(CMPLconst [128] z))
+       // cond: c.Uses == 1
+       // result: (CMOVQLE x y (CMPLconst [127] z))
+       for {
+               x := v_0
+               y := v_1
+               c := v_2
+               if c.Op != OpAMD64CMPLconst || auxIntToInt32(c.AuxInt) != 128 {
+                       break
+               }
+               z := c.Args[0]
+               if !(c.Uses == 1) {
+                       break
+               }
+               v.reset(OpAMD64CMOVQLE)
+               v0 := b.NewValue0(v.Pos, OpAMD64CMPLconst, types.TypeFlags)
+               v0.AuxInt = int32ToAuxInt(127)
+               v0.AddArg(z)
+               v.AddArg3(x, y, v0)
+               return true
+       }
        return false
 }
 func rewriteValueAMD64_OpAMD64CMOVQNE(v *Value) bool {
@@ -16789,6 +16961,44 @@ func rewriteValueAMD64_OpAMD64SETAE(v *Value) bool {
                v.AddArg(v0)
                return true
        }
+       // match: (SETAE c:(CMPQconst [128] x))
+       // cond: c.Uses == 1
+       // result: (SETA (CMPQconst [127] x))
+       for {
+               c := v_0
+               if c.Op != OpAMD64CMPQconst || auxIntToInt32(c.AuxInt) != 128 {
+                       break
+               }
+               x := c.Args[0]
+               if !(c.Uses == 1) {
+                       break
+               }
+               v.reset(OpAMD64SETA)
+               v0 := b.NewValue0(v.Pos, OpAMD64CMPQconst, types.TypeFlags)
+               v0.AuxInt = int32ToAuxInt(127)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (SETAE c:(CMPLconst [128] x))
+       // cond: c.Uses == 1
+       // result: (SETA (CMPLconst [127] x))
+       for {
+               c := v_0
+               if c.Op != OpAMD64CMPLconst || auxIntToInt32(c.AuxInt) != 128 {
+                       break
+               }
+               x := c.Args[0]
+               if !(c.Uses == 1) {
+                       break
+               }
+               v.reset(OpAMD64SETA)
+               v0 := b.NewValue0(v.Pos, OpAMD64CMPLconst, types.TypeFlags)
+               v0.AuxInt = int32ToAuxInt(127)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
        // match: (SETAE (InvertFlags x))
        // result: (SETBE x)
        for {
@@ -17174,6 +17384,7 @@ func rewriteValueAMD64_OpAMD64SETAstore(v *Value) bool {
 }
 func rewriteValueAMD64_OpAMD64SETB(v *Value) bool {
        v_0 := v.Args[0]
+       b := v.Block
        // match: (SETB (TESTQ x x))
        // result: (ConstBool [false])
        for {
@@ -17254,6 +17465,44 @@ func rewriteValueAMD64_OpAMD64SETB(v *Value) bool {
                v.AddArg(x)
                return true
        }
+       // match: (SETB c:(CMPQconst [128] x))
+       // cond: c.Uses == 1
+       // result: (SETBE (CMPQconst [127] x))
+       for {
+               c := v_0
+               if c.Op != OpAMD64CMPQconst || auxIntToInt32(c.AuxInt) != 128 {
+                       break
+               }
+               x := c.Args[0]
+               if !(c.Uses == 1) {
+                       break
+               }
+               v.reset(OpAMD64SETBE)
+               v0 := b.NewValue0(v.Pos, OpAMD64CMPQconst, types.TypeFlags)
+               v0.AuxInt = int32ToAuxInt(127)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (SETB c:(CMPLconst [128] x))
+       // cond: c.Uses == 1
+       // result: (SETBE (CMPLconst [127] x))
+       for {
+               c := v_0
+               if c.Op != OpAMD64CMPLconst || auxIntToInt32(c.AuxInt) != 128 {
+                       break
+               }
+               x := c.Args[0]
+               if !(c.Uses == 1) {
+                       break
+               }
+               v.reset(OpAMD64SETBE)
+               v0 := b.NewValue0(v.Pos, OpAMD64CMPLconst, types.TypeFlags)
+               v0.AuxInt = int32ToAuxInt(127)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
        // match: (SETB (InvertFlags x))
        // result: (SETA x)
        for {
@@ -18813,6 +19062,45 @@ func rewriteValueAMD64_OpAMD64SETG(v *Value) bool {
 }
 func rewriteValueAMD64_OpAMD64SETGE(v *Value) bool {
        v_0 := v.Args[0]
+       b := v.Block
+       // match: (SETGE c:(CMPQconst [128] x))
+       // cond: c.Uses == 1
+       // result: (SETG (CMPQconst [127] x))
+       for {
+               c := v_0
+               if c.Op != OpAMD64CMPQconst || auxIntToInt32(c.AuxInt) != 128 {
+                       break
+               }
+               x := c.Args[0]
+               if !(c.Uses == 1) {
+                       break
+               }
+               v.reset(OpAMD64SETG)
+               v0 := b.NewValue0(v.Pos, OpAMD64CMPQconst, types.TypeFlags)
+               v0.AuxInt = int32ToAuxInt(127)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (SETGE c:(CMPLconst [128] x))
+       // cond: c.Uses == 1
+       // result: (SETG (CMPLconst [127] x))
+       for {
+               c := v_0
+               if c.Op != OpAMD64CMPLconst || auxIntToInt32(c.AuxInt) != 128 {
+                       break
+               }
+               x := c.Args[0]
+               if !(c.Uses == 1) {
+                       break
+               }
+               v.reset(OpAMD64SETG)
+               v0 := b.NewValue0(v.Pos, OpAMD64CMPLconst, types.TypeFlags)
+               v0.AuxInt = int32ToAuxInt(127)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
        // match: (SETGE (InvertFlags x))
        // result: (SETLE x)
        for {
@@ -19198,6 +19486,45 @@ func rewriteValueAMD64_OpAMD64SETGstore(v *Value) bool {
 }
 func rewriteValueAMD64_OpAMD64SETL(v *Value) bool {
        v_0 := v.Args[0]
+       b := v.Block
+       // match: (SETL c:(CMPQconst [128] x))
+       // cond: c.Uses == 1
+       // result: (SETLE (CMPQconst [127] x))
+       for {
+               c := v_0
+               if c.Op != OpAMD64CMPQconst || auxIntToInt32(c.AuxInt) != 128 {
+                       break
+               }
+               x := c.Args[0]
+               if !(c.Uses == 1) {
+                       break
+               }
+               v.reset(OpAMD64SETLE)
+               v0 := b.NewValue0(v.Pos, OpAMD64CMPQconst, types.TypeFlags)
+               v0.AuxInt = int32ToAuxInt(127)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
+       // match: (SETL c:(CMPLconst [128] x))
+       // cond: c.Uses == 1
+       // result: (SETLE (CMPLconst [127] x))
+       for {
+               c := v_0
+               if c.Op != OpAMD64CMPLconst || auxIntToInt32(c.AuxInt) != 128 {
+                       break
+               }
+               x := c.Args[0]
+               if !(c.Uses == 1) {
+                       break
+               }
+               v.reset(OpAMD64SETLE)
+               v0 := b.NewValue0(v.Pos, OpAMD64CMPLconst, types.TypeFlags)
+               v0.AuxInt = int32ToAuxInt(127)
+               v0.AddArg(x)
+               v.AddArg(v0)
+               return true
+       }
        // match: (SETL (InvertFlags x))
        // result: (SETG x)
        for {
@@ -31015,6 +31342,42 @@ func rewriteBlockAMD64(b *Block) bool {
                        break
                }
        case BlockAMD64GE:
+               // match: (GE c:(CMPQconst [128] z) yes no)
+               // cond: c.Uses == 1
+               // result: (GT (CMPQconst [127] z) yes no)
+               for b.Controls[0].Op == OpAMD64CMPQconst {
+                       c := b.Controls[0]
+                       if auxIntToInt32(c.AuxInt) != 128 {
+                               break
+                       }
+                       z := c.Args[0]
+                       if !(c.Uses == 1) {
+                               break
+                       }
+                       v0 := b.NewValue0(c.Pos, OpAMD64CMPQconst, types.TypeFlags)
+                       v0.AuxInt = int32ToAuxInt(127)
+                       v0.AddArg(z)
+                       b.resetWithControl(BlockAMD64GT, v0)
+                       return true
+               }
+               // match: (GE c:(CMPLconst [128] z) yes no)
+               // cond: c.Uses == 1
+               // result: (GT (CMPLconst [127] z) yes no)
+               for b.Controls[0].Op == OpAMD64CMPLconst {
+                       c := b.Controls[0]
+                       if auxIntToInt32(c.AuxInt) != 128 {
+                               break
+                       }
+                       z := c.Args[0]
+                       if !(c.Uses == 1) {
+                               break
+                       }
+                       v0 := b.NewValue0(c.Pos, OpAMD64CMPLconst, types.TypeFlags)
+                       v0.AuxInt = int32ToAuxInt(127)
+                       v0.AddArg(z)
+                       b.resetWithControl(BlockAMD64GT, v0)
+                       return true
+               }
                // match: (GE (InvertFlags cmp) yes no)
                // result: (LE cmp yes no)
                for b.Controls[0].Op == OpAMD64InvertFlags {
@@ -31282,6 +31645,42 @@ func rewriteBlockAMD64(b *Block) bool {
                        return true
                }
        case BlockAMD64LT:
+               // match: (LT c:(CMPQconst [128] z) yes no)
+               // cond: c.Uses == 1
+               // result: (LE (CMPQconst [127] z) yes no)
+               for b.Controls[0].Op == OpAMD64CMPQconst {
+                       c := b.Controls[0]
+                       if auxIntToInt32(c.AuxInt) != 128 {
+                               break
+                       }
+                       z := c.Args[0]
+                       if !(c.Uses == 1) {
+                               break
+                       }
+                       v0 := b.NewValue0(c.Pos, OpAMD64CMPQconst, types.TypeFlags)
+                       v0.AuxInt = int32ToAuxInt(127)
+                       v0.AddArg(z)
+                       b.resetWithControl(BlockAMD64LE, v0)
+                       return true
+               }
+               // match: (LT c:(CMPLconst [128] z) yes no)
+               // cond: c.Uses == 1
+               // result: (LE (CMPLconst [127] z) yes no)
+               for b.Controls[0].Op == OpAMD64CMPLconst {
+                       c := b.Controls[0]
+                       if auxIntToInt32(c.AuxInt) != 128 {
+                               break
+                       }
+                       z := c.Args[0]
+                       if !(c.Uses == 1) {
+                               break
+                       }
+                       v0 := b.NewValue0(c.Pos, OpAMD64CMPLconst, types.TypeFlags)
+                       v0.AuxInt = int32ToAuxInt(127)
+                       v0.AddArg(z)
+                       b.resetWithControl(BlockAMD64LE, v0)
+                       return true
+               }
                // match: (LT (InvertFlags cmp) yes no)
                // result: (GT cmp yes no)
                for b.Controls[0].Op == OpAMD64InvertFlags {
index 5fbb31c00c8cd87b15bff18bbfe76ac44ea02dbe..702ea275cc9b39956141ce72c254412efa868dcf 100644 (file)
@@ -730,6 +730,54 @@ func cmpToCmnLessThan(a, b, c, d int) int {
        return c1 + c2 + c3 + c4
 }
 
+func less128Signed32(x int32) bool {
+       // amd64:`CMPL.*127`
+       // amd64:`SETLE`
+       return x < 128
+}
+
+func less128Signed64(x int64) bool {
+       // amd64:`CMPQ.*127`
+       // amd64:`SETLE`
+       return x < 128
+}
+
+func less128Unsigned32(x uint32) bool {
+       // amd64:`CMPL.*127`
+       // amd64:`SETLS`
+       return x < 128
+}
+
+func less128Unsigned64(x uint64) bool {
+       // amd64:`CMPQ.*127`
+       // amd64:`SETLS`
+       return x < 128
+}
+
+func ge128Unsigned32(x uint32) bool {
+       // amd64:`CMPL.*127`
+       // amd64:`SETHI`
+       return x >= 128
+}
+
+func ge128Unsigned64(x uint64) bool {
+       // amd64:`CMPQ.*127`
+       // amd64:`SETHI`
+       return x >= 128
+}
+
+func ge128Signed32(x int32) bool {
+       // amd64:`CMPL.*127`
+       // amd64:`SETGT`
+       return x >= 128
+}
+
+func ge128Signed64(x int64) bool {
+       // amd64:`CMPQ.*127`
+       // amd64:`SETGT`
+       return x >= 128
+}
+
 func cmpToCmnGreaterThanEqual(a, b, c, d int) int {
        var c1, c2, c3, c4 int
        // arm64:`CMN`,`CSET\tPL`,-`CMP`