Skip to content

Commit dcb479c

Browse files
amusmangopherbot
authored andcommitted
cmd/compile: optimize slice bounds checking with SUB/SUBconst comparisons
Optimize ARM64 code generation for slice bounds checking by recognizing patterns where comparisons to zero involve SUB or SUBconst operations. This change adds SSA opt rules to simplify: (CMPconst [0] (SUB x y)) => (CMP x y) The optimizations apply to EQ, NE, ULE, and UGT comparisons, enabling more efficient bounds checking for slice operations. Code size improvement: compile: .text: 9088004 -> 9065988 (-0.24%) etcd: .text: 10500276 -> 10497092 (-0.03%) Change-Id: I467cb27674351652bcacc52b87e1f19677bd46a8 Reviewed-on: https://go-review.googlesource.com/c/go/+/679915 LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Keith Randall <[email protected]> Reviewed-by: Keith Randall <[email protected]> Reviewed-by: Michael Knyszek <[email protected]> Auto-Submit: Keith Randall <[email protected]>
1 parent f11599b commit dcb479c

File tree

3 files changed

+206
-0
lines changed

3 files changed

+206
-0
lines changed

src/cmd/compile/internal/ssa/_gen/ARM64.rules

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,14 @@
683683
((EQ|NE) (CMPconst [0] x) yes no) => ((Z|NZ) x yes no)
684684
((EQ|NE) (CMPWconst [0] x) yes no) => ((ZW|NZW) x yes no)
685685

686+
((ULE|UGT) (CMPconst [0] x)) => ((EQ|NE) (CMPconst [0] x))
687+
((ULE|UGT) (CMPWconst [0] x)) => ((EQ|NE) (CMPWconst [0] x))
688+
689+
((Z|NZ) sub:(SUB x y)) && sub.Uses == 1 => ((EQ|NE) (CMP x y))
690+
((ZW|NZW) sub:(SUB x y)) && sub.Uses == 1 => ((EQ|NE) (CMPW x y))
691+
((Z|NZ) sub:(SUBconst [c] y)) && sub.Uses == 1 => ((EQ|NE) (CMPconst [c] y))
692+
((ZW|NZW) sub:(SUBconst [c] y)) && sub.Uses == 1 => ((EQ|NE) (CMPWconst [int32(c)] y))
693+
686694
((EQ|NE|LT|LE|GT|GE) (CMPconst [0] z:(MADD a x y)) yes no) && z.Uses==1 => ((EQ|NE|LTnoov|LEnoov|GTnoov|GEnoov) (CMN a (MUL <x.Type> x y)) yes no)
687695
((EQ|NE|LT|LE|GT|GE) (CMPconst [0] z:(MSUB a x y)) yes no) && z.Uses==1 => ((EQ|NE|LTnoov|LEnoov|GTnoov|GEnoov) (CMP a (MUL <x.Type> x y)) yes no)
688696
((EQ|NE|LT|LE|GT|GE) (CMPWconst [0] z:(MADDW a x y)) yes no) && z.Uses==1 => ((EQ|NE|LTnoov|LEnoov|GTnoov|GEnoov) (CMNW a (MULW <x.Type> x y)) yes no)

src/cmd/compile/internal/ssa/rewriteARM64.go

Lines changed: 180 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/codegen/slices.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,3 +429,21 @@ func Slice0(p *struct{}, i int) []struct{} {
429429
// amd64:-"MULQ"
430430
return unsafe.Slice(p, i)
431431
}
432+
433+
// --------------------------------------- //
434+
// Code generation for slice bounds //
435+
// checking comparison //
436+
// --------------------------------------- //
437+
438+
func SlicePut(a []byte, c uint8) []byte {
439+
// arm64:`CBZ\tR1`
440+
a[0] = c
441+
// arm64:`CMP\t\$1, R1`
442+
a = a[1:]
443+
a[0] = c
444+
// arm64:`CMP\t\$2, R1`
445+
a = a[1:]
446+
a[0] = c
447+
a = a[1:]
448+
return a
449+
}

0 commit comments

Comments
 (0)