This is an automated email from the ASF dual-hosted git repository.

zeroshade pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-go.git


The following commit(s) were added to refs/heads/main by this push:
     new 89448e69 perf(compute): add ARM64 NEON comparisons for 8- and 16-bit 
integers (#1288)
89448e69 is described below

commit 89448e691dcf4930492d83ebad760f54d8bea6fc
Author: Minh Vu <[email protected]>
AuthorDate: Fri Sep 4 18:28:26 2026 +0200

    perf(compute): add ARM64 NEON comparisons for 8- and 16-bit integers (#1288)
    
    ## Summary
    
    - Add ARM64 NEON comparisons for `int8`, `uint8`, `int16`, and `uint16`.
    - Cover array-array, array-scalar, and scalar-array inputs.
    - Keep the existing generic fallback for tails and bitmap offsets.
    - Add correctness coverage for signed and unsigned boundaries and bit
    packing.
    - Add native benchmarks for the narrow integer types.
    
    ## Benchmark
    
    Apple M1 Pro, Go 1.26.3. `-benchtime=50ms -count=3`. Baseline is `-tags
    noasm`.
    
    | Case | NEON | Generic | Speedup |
    | --- | ---: | ---: | ---: |
    | int8 array-array 64K alternating | 5.01 us | 75.7 us | 15.1x |
    | uint8 array-scalar 1M random50 | 68.9 us | 1.00 ms | 14.5x |
    | int16 scalar-array 64K clustered50 | 4.31 us | 59.1 us | 13.7x |
    | uint16 array-array 1M all | 79.7 us | 1.02 ms | 12.8x |
    
    The benchmark matrix also covers 1K, 64K, and 1M elements, all three
    operand shapes, alternating, random 25/50/75%, clustered 50%, all, and
    none patterns.
    
    ## Tests
    
    - `go test ./arrow/compute/internal/kernels ./arrow/compute`
    - `go test -race ./arrow/compute/internal/kernels ./arrow/compute`
    - `go test -tags noasm ./arrow/compute/internal/kernels ./arrow/compute`
    - Darwin/amd64 and Linux/amd64 compile checks
---
 .../internal/kernels/scalar_comparison_arm64.go    |   15 +-
 .../kernels/scalar_comparison_arm64_test.go        |   52 +
 .../kernels/scalar_comparison_narrow_arm64.s       | 1068 ++++++++++++++++++++
 .../kernels/scalar_comparison_narrow_bench_test.go |  105 ++
 4 files changed, 1237 insertions(+), 3 deletions(-)

diff --git a/arrow/compute/internal/kernels/scalar_comparison_arm64.go 
b/arrow/compute/internal/kernels/scalar_comparison_arm64.go
index f5d99611..f5af8701 100644
--- a/arrow/compute/internal/kernels/scalar_comparison_arm64.go
+++ b/arrow/compute/internal/kernels/scalar_comparison_arm64.go
@@ -34,9 +34,13 @@ const (
 //go:noescape
 func _comparison_neon(typ int, op int, shape int, left, right, out 
unsafe.Pointer, groups int64)
 
+//go:noescape
+func _comparison_narrow_neon(typ int, op int, shape int, left, right, out 
unsafe.Pointer, groups int64)
+
 func neonComparisonSupported(typ arrow.Type) bool {
        switch typ {
-       case arrow.INT32, arrow.UINT32, arrow.INT64, arrow.UINT64,
+       case arrow.INT8, arrow.UINT8, arrow.INT16, arrow.UINT16,
+               arrow.INT32, arrow.UINT32, arrow.INT64, arrow.UINT64,
                arrow.FLOAT32, arrow.FLOAT64:
                return true
        default:
@@ -92,8 +96,13 @@ func compareNeon(typ arrow.Type, op CompareOperator, width, 
shape int, left, rig
                case neonCompareScalarArray:
                        assemblyRight = right[:bulk*width]
                }
-               _comparison_neon(int(typ), int(op), shape,
-                       unsafe.Pointer(&assemblyLeft[0]), 
unsafe.Pointer(&assemblyRight[0]), unsafe.Pointer(&out[0]), int64(bulk/8))
+               if width <= 2 {
+                       _comparison_narrow_neon(int(typ), int(op), shape,
+                               unsafe.Pointer(&assemblyLeft[0]), 
unsafe.Pointer(&assemblyRight[0]), unsafe.Pointer(&out[0]), int64(bulk/8))
+               } else {
+                       _comparison_neon(int(typ), int(op), shape,
+                               unsafe.Pointer(&assemblyLeft[0]), 
unsafe.Pointer(&assemblyRight[0]), unsafe.Pointer(&out[0]), int64(bulk/8))
+               }
        }
 
        if tail := n - bulk; tail != 0 {
diff --git a/arrow/compute/internal/kernels/scalar_comparison_arm64_test.go 
b/arrow/compute/internal/kernels/scalar_comparison_arm64_test.go
index 460d8aca..4e92d475 100644
--- a/arrow/compute/internal/kernels/scalar_comparison_arm64_test.go
+++ b/arrow/compute/internal/kernels/scalar_comparison_arm64_test.go
@@ -118,6 +118,54 @@ func TestNeonComparisons(t *testing.T) {
                testNeonComparison(t, left, right, uint32(1<<31), uint32(7))
        })
 
+       t.Run("int8", func(t *testing.T) {
+               leftPattern := []int8{-1 << 7, -17, -1, 0, 1, 17, 1<<7 - 1, 42, 
-42, 3, 9, -9, 5, -5, 2, -2}
+               rightPattern := []int8{1<<7 - 1, -17, 0, 1, -1, -42, -1 << 7, 
42, 4, -3, 9, -10, -5, 5, -2, 2}
+               left := make([]int8, neonComparisonTestLength)
+               right := make([]int8, neonComparisonTestLength)
+               for i := range left {
+                       left[i] = leftPattern[i%len(leftPattern)]
+                       right[i] = rightPattern[i%len(rightPattern)]
+               }
+               testNeonComparison(t, left, right, int8(-3), int8(4))
+       })
+
+       t.Run("uint8", func(t *testing.T) {
+               leftPattern := []uint8{0, 1, 2, 1<<7 - 1, 1 << 7, ^uint8(0), 
42, 7, 100, 3, 19, 5, 77, 11, 12, 13}
+               rightPattern := []uint8{^uint8(0), 1, 3, 1 << 7, 1<<7 - 1, 0, 
42, 8, 99, 4, 19, 6, 78, 10, 13, 12}
+               left := make([]uint8, neonComparisonTestLength)
+               right := make([]uint8, neonComparisonTestLength)
+               for i := range left {
+                       left[i] = leftPattern[i%len(leftPattern)]
+                       right[i] = rightPattern[i%len(rightPattern)]
+               }
+               testNeonComparison(t, left, right, uint8(1<<7), uint8(7))
+       })
+
+       t.Run("int16", func(t *testing.T) {
+               leftPattern := []int16{-1 << 15, -17, -1, 0, 1, 17, 1<<15 - 1, 
42, -42, 3, 9, -9, 5, -5, 2, -2}
+               rightPattern := []int16{1<<15 - 1, -17, 0, 1, -1, -42, -1 << 
15, 42, 4, -3, 9, -10, -5, 5, -2, 2}
+               left := make([]int16, neonComparisonTestLength)
+               right := make([]int16, neonComparisonTestLength)
+               for i := range left {
+                       left[i] = leftPattern[i%len(leftPattern)]
+                       right[i] = rightPattern[i%len(rightPattern)]
+               }
+               testNeonComparison(t, left, right, int16(-3), int16(4))
+       })
+
+       t.Run("uint16", func(t *testing.T) {
+               leftPattern := []uint16{0, 1, 2, 1<<15 - 1, 1 << 15, 
^uint16(0), 42, 7, 100, 3, 19, 5, 77, 11, 12, 13}
+               rightPattern := []uint16{^uint16(0), 1, 3, 1 << 15, 1<<15 - 1, 
0, 42, 8, 99, 4, 19, 6, 78, 10, 13, 12}
+               left := make([]uint16, neonComparisonTestLength)
+               right := make([]uint16, neonComparisonTestLength)
+               for i := range left {
+                       left[i] = leftPattern[i%len(leftPattern)]
+                       right[i] = rightPattern[i%len(rightPattern)]
+               }
+               testNeonComparison(t, left, right, uint16(1<<15), uint16(7))
+       })
+
        t.Run("int64", func(t *testing.T) {
                leftPattern := []int64{-1 << 63, -17, -1, 0, 1, 17, 1<<63 - 1, 
42, -42, 3, 9, -9, 5, -5, 2, -2}
                rightPattern := []int64{1<<63 - 1, -17, 0, 1, -1, -42, -1 << 
63, 42, 4, -3, 9, -10, -5, 5, -2, 2}
@@ -168,6 +216,10 @@ func TestNeonComparisons(t *testing.T) {
 }
 
 func TestNeonComparisonBitPacking(t *testing.T) {
+       t.Run("int8", testNeonComparisonBitPacking[int8])
+       t.Run("uint8", testNeonComparisonBitPacking[uint8])
+       t.Run("int16", testNeonComparisonBitPacking[int16])
+       t.Run("uint16", testNeonComparisonBitPacking[uint16])
        t.Run("int32", testNeonComparisonBitPacking[int32])
        t.Run("uint32", testNeonComparisonBitPacking[uint32])
        t.Run("int64", testNeonComparisonBitPacking[int64])
diff --git a/arrow/compute/internal/kernels/scalar_comparison_narrow_arm64.s 
b/arrow/compute/internal/kernels/scalar_comparison_narrow_arm64.s
new file mode 100644
index 00000000..c52be4b7
--- /dev/null
+++ b/arrow/compute/internal/kernels/scalar_comparison_narrow_arm64.s
@@ -0,0 +1,1068 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//go:build go1.18 && arm64 && !noasm && !appengine
+
+#include "textflag.h"
+
+DATA LCMPNEON_NARROW_WEIGHTS<>+0(SB)/8, $0x0706050403020100
+DATA LCMPNEON_NARROW_WEIGHTS<>+8(SB)/8, $0x0003000200010000
+DATA LCMPNEON_NARROW_WEIGHTS<>+16(SB)/8, $0x0007000600050004
+GLOBL LCMPNEON_NARROW_WEIGHTS<>(SB), (NOPTR+RODATA), $24
+
+TEXT ยท_comparison_narrow_neon(SB), NOSPLIT|NOFRAME, $0-56
+       MOVD typ+0(FP), R0
+       MOVD op+8(FP), R1
+       MOVD shape+16(FP), R2
+       MOVD left+24(FP), R3
+       MOVD right+32(FP), R4
+       MOVD out+40(FP), R5
+       MOVD groups+48(FP), R6
+
+       CMP $2, R0
+       BEQ Lnarrow8Unsigned
+       CMP $3, R0
+       BEQ Lnarrow8Signed
+       CMP $4, R0
+       BEQ Lnarrow16Unsigned
+       CMP $5, R0
+       BEQ Lnarrow16Signed
+       JMP LnarrowReturn
+
+Lnarrow8Signed:
+       MOVD $LCMPNEON_NARROW_WEIGHTS<>(SB), R10
+       VLD1 (R10), [V20.B8]
+       CMP $0, R2
+       BEQ Lnarrow8SignedAASelect
+       CMP $1, R2
+       BEQ Lnarrow8SignedASSelect
+       CMP $2, R2
+       BEQ Lnarrow8SignedSASelect
+       JMP LnarrowReturn
+
+Lnarrow8SignedAASelect:
+       CMP $0, R1
+       BEQ Lnarrow8SignedAAEQ
+       CMP $1, R1
+       BEQ Lnarrow8SignedAANE
+       CMP $2, R1
+       BEQ Lnarrow8SignedAAGT
+       CMP $3, R1
+       BEQ Lnarrow8SignedAAGE
+       JMP LnarrowReturn
+
+Lnarrow8SignedASSelect:
+       CMP $0, R1
+       BEQ Lnarrow8SignedASEQ
+       CMP $1, R1
+       BEQ Lnarrow8SignedASNE
+       CMP $2, R1
+       BEQ Lnarrow8SignedASGT
+       CMP $3, R1
+       BEQ Lnarrow8SignedASGE
+       JMP LnarrowReturn
+
+Lnarrow8SignedSASelect:
+       CMP $0, R1
+       BEQ Lnarrow8SignedSAEQ
+       CMP $1, R1
+       BEQ Lnarrow8SignedSANE
+       CMP $2, R1
+       BEQ Lnarrow8SignedSAGT
+       CMP $3, R1
+       BEQ Lnarrow8SignedSAGE
+       JMP LnarrowReturn
+
+Lnarrow8SignedAAEQ:
+Lnarrow8SignedAAEQLoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R3), [V0.B8]
+       VLD1 (R4), [V1.B8]
+       WORD $0x2e218c02
+       VUSHR $7, V2.B8, V2.B8
+       WORD $0x2e344442
+       VADDV V2.B8, V2
+       VMOV V2.B[0], R7
+       MOVB R7, (R5)
+       ADD $8, R3, R3
+       ADD $8, R4, R4
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow8SignedAAEQLoop
+
+Lnarrow8SignedAANE:
+Lnarrow8SignedAANELoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R3), [V0.B8]
+       VLD1 (R4), [V1.B8]
+       WORD $0x2e218c02
+       WORD $0x2e205842
+       VUSHR $7, V2.B8, V2.B8
+       WORD $0x2e344442
+       VADDV V2.B8, V2
+       VMOV V2.B[0], R7
+       MOVB R7, (R5)
+       ADD $8, R3, R3
+       ADD $8, R4, R4
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow8SignedAANELoop
+
+Lnarrow8SignedAAGT:
+Lnarrow8SignedAAGTLoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R3), [V0.B8]
+       VLD1 (R4), [V1.B8]
+       WORD $0x0e213402
+       VUSHR $7, V2.B8, V2.B8
+       WORD $0x2e344442
+       VADDV V2.B8, V2
+       VMOV V2.B[0], R7
+       MOVB R7, (R5)
+       ADD $8, R3, R3
+       ADD $8, R4, R4
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow8SignedAAGTLoop
+
+Lnarrow8SignedAAGE:
+Lnarrow8SignedAAGELoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R3), [V0.B8]
+       VLD1 (R4), [V1.B8]
+       WORD $0x0e213c02
+       VUSHR $7, V2.B8, V2.B8
+       WORD $0x2e344442
+       VADDV V2.B8, V2
+       VMOV V2.B[0], R7
+       MOVB R7, (R5)
+       ADD $8, R3, R3
+       ADD $8, R4, R4
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow8SignedAAGELoop
+
+Lnarrow8SignedASEQ:
+VLD1R (R4), [V1.B8]
+Lnarrow8SignedASEQLoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R3), [V0.B8]
+       WORD $0x2e218c02
+       VUSHR $7, V2.B8, V2.B8
+       WORD $0x2e344442
+       VADDV V2.B8, V2
+       VMOV V2.B[0], R7
+       MOVB R7, (R5)
+       ADD $8, R3, R3
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow8SignedASEQLoop
+
+Lnarrow8SignedASNE:
+VLD1R (R4), [V1.B8]
+Lnarrow8SignedASNELoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R3), [V0.B8]
+       WORD $0x2e218c02
+       WORD $0x2e205842
+       VUSHR $7, V2.B8, V2.B8
+       WORD $0x2e344442
+       VADDV V2.B8, V2
+       VMOV V2.B[0], R7
+       MOVB R7, (R5)
+       ADD $8, R3, R3
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow8SignedASNELoop
+
+Lnarrow8SignedASGT:
+VLD1R (R4), [V1.B8]
+Lnarrow8SignedASGTLoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R3), [V0.B8]
+       WORD $0x0e213402
+       VUSHR $7, V2.B8, V2.B8
+       WORD $0x2e344442
+       VADDV V2.B8, V2
+       VMOV V2.B[0], R7
+       MOVB R7, (R5)
+       ADD $8, R3, R3
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow8SignedASGTLoop
+
+Lnarrow8SignedASGE:
+VLD1R (R4), [V1.B8]
+Lnarrow8SignedASGELoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R3), [V0.B8]
+       WORD $0x0e213c02
+       VUSHR $7, V2.B8, V2.B8
+       WORD $0x2e344442
+       VADDV V2.B8, V2
+       VMOV V2.B[0], R7
+       MOVB R7, (R5)
+       ADD $8, R3, R3
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow8SignedASGELoop
+
+Lnarrow8SignedSAEQ:
+VLD1R (R3), [V0.B8]
+Lnarrow8SignedSAEQLoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R4), [V1.B8]
+       WORD $0x2e218c02
+       VUSHR $7, V2.B8, V2.B8
+       WORD $0x2e344442
+       VADDV V2.B8, V2
+       VMOV V2.B[0], R7
+       MOVB R7, (R5)
+       ADD $8, R4, R4
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow8SignedSAEQLoop
+
+Lnarrow8SignedSANE:
+VLD1R (R3), [V0.B8]
+Lnarrow8SignedSANELoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R4), [V1.B8]
+       WORD $0x2e218c02
+       WORD $0x2e205842
+       VUSHR $7, V2.B8, V2.B8
+       WORD $0x2e344442
+       VADDV V2.B8, V2
+       VMOV V2.B[0], R7
+       MOVB R7, (R5)
+       ADD $8, R4, R4
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow8SignedSANELoop
+
+Lnarrow8SignedSAGT:
+VLD1R (R3), [V0.B8]
+Lnarrow8SignedSAGTLoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R4), [V1.B8]
+       WORD $0x0e213402
+       VUSHR $7, V2.B8, V2.B8
+       WORD $0x2e344442
+       VADDV V2.B8, V2
+       VMOV V2.B[0], R7
+       MOVB R7, (R5)
+       ADD $8, R4, R4
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow8SignedSAGTLoop
+
+Lnarrow8SignedSAGE:
+VLD1R (R3), [V0.B8]
+Lnarrow8SignedSAGELoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R4), [V1.B8]
+       WORD $0x0e213c02
+       VUSHR $7, V2.B8, V2.B8
+       WORD $0x2e344442
+       VADDV V2.B8, V2
+       VMOV V2.B[0], R7
+       MOVB R7, (R5)
+       ADD $8, R4, R4
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow8SignedSAGELoop
+
+Lnarrow8Unsigned:
+       MOVD $LCMPNEON_NARROW_WEIGHTS<>(SB), R10
+       VLD1 (R10), [V20.B8]
+       CMP $0, R2
+       BEQ Lnarrow8UnsignedAASelect
+       CMP $1, R2
+       BEQ Lnarrow8UnsignedASSelect
+       CMP $2, R2
+       BEQ Lnarrow8UnsignedSASelect
+       JMP LnarrowReturn
+
+Lnarrow8UnsignedAASelect:
+       CMP $0, R1
+       BEQ Lnarrow8UnsignedAAEQ
+       CMP $1, R1
+       BEQ Lnarrow8UnsignedAANE
+       CMP $2, R1
+       BEQ Lnarrow8UnsignedAAGT
+       CMP $3, R1
+       BEQ Lnarrow8UnsignedAAGE
+       JMP LnarrowReturn
+
+Lnarrow8UnsignedASSelect:
+       CMP $0, R1
+       BEQ Lnarrow8UnsignedASEQ
+       CMP $1, R1
+       BEQ Lnarrow8UnsignedASNE
+       CMP $2, R1
+       BEQ Lnarrow8UnsignedASGT
+       CMP $3, R1
+       BEQ Lnarrow8UnsignedASGE
+       JMP LnarrowReturn
+
+Lnarrow8UnsignedSASelect:
+       CMP $0, R1
+       BEQ Lnarrow8UnsignedSAEQ
+       CMP $1, R1
+       BEQ Lnarrow8UnsignedSANE
+       CMP $2, R1
+       BEQ Lnarrow8UnsignedSAGT
+       CMP $3, R1
+       BEQ Lnarrow8UnsignedSAGE
+       JMP LnarrowReturn
+
+Lnarrow8UnsignedAAEQ:
+Lnarrow8UnsignedAAEQLoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R3), [V0.B8]
+       VLD1 (R4), [V1.B8]
+       WORD $0x2e218c02
+       VUSHR $7, V2.B8, V2.B8
+       WORD $0x2e344442
+       VADDV V2.B8, V2
+       VMOV V2.B[0], R7
+       MOVB R7, (R5)
+       ADD $8, R3, R3
+       ADD $8, R4, R4
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow8UnsignedAAEQLoop
+
+Lnarrow8UnsignedAANE:
+Lnarrow8UnsignedAANELoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R3), [V0.B8]
+       VLD1 (R4), [V1.B8]
+       WORD $0x2e218c02
+       WORD $0x2e205842
+       VUSHR $7, V2.B8, V2.B8
+       WORD $0x2e344442
+       VADDV V2.B8, V2
+       VMOV V2.B[0], R7
+       MOVB R7, (R5)
+       ADD $8, R3, R3
+       ADD $8, R4, R4
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow8UnsignedAANELoop
+
+Lnarrow8UnsignedAAGT:
+Lnarrow8UnsignedAAGTLoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R3), [V0.B8]
+       VLD1 (R4), [V1.B8]
+       WORD $0x2e213402
+       VUSHR $7, V2.B8, V2.B8
+       WORD $0x2e344442
+       VADDV V2.B8, V2
+       VMOV V2.B[0], R7
+       MOVB R7, (R5)
+       ADD $8, R3, R3
+       ADD $8, R4, R4
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow8UnsignedAAGTLoop
+
+Lnarrow8UnsignedAAGE:
+Lnarrow8UnsignedAAGELoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R3), [V0.B8]
+       VLD1 (R4), [V1.B8]
+       WORD $0x2e213c02
+       VUSHR $7, V2.B8, V2.B8
+       WORD $0x2e344442
+       VADDV V2.B8, V2
+       VMOV V2.B[0], R7
+       MOVB R7, (R5)
+       ADD $8, R3, R3
+       ADD $8, R4, R4
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow8UnsignedAAGELoop
+
+Lnarrow8UnsignedASEQ:
+VLD1R (R4), [V1.B8]
+Lnarrow8UnsignedASEQLoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R3), [V0.B8]
+       WORD $0x2e218c02
+       VUSHR $7, V2.B8, V2.B8
+       WORD $0x2e344442
+       VADDV V2.B8, V2
+       VMOV V2.B[0], R7
+       MOVB R7, (R5)
+       ADD $8, R3, R3
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow8UnsignedASEQLoop
+
+Lnarrow8UnsignedASNE:
+VLD1R (R4), [V1.B8]
+Lnarrow8UnsignedASNELoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R3), [V0.B8]
+       WORD $0x2e218c02
+       WORD $0x2e205842
+       VUSHR $7, V2.B8, V2.B8
+       WORD $0x2e344442
+       VADDV V2.B8, V2
+       VMOV V2.B[0], R7
+       MOVB R7, (R5)
+       ADD $8, R3, R3
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow8UnsignedASNELoop
+
+Lnarrow8UnsignedASGT:
+VLD1R (R4), [V1.B8]
+Lnarrow8UnsignedASGTLoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R3), [V0.B8]
+       WORD $0x2e213402
+       VUSHR $7, V2.B8, V2.B8
+       WORD $0x2e344442
+       VADDV V2.B8, V2
+       VMOV V2.B[0], R7
+       MOVB R7, (R5)
+       ADD $8, R3, R3
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow8UnsignedASGTLoop
+
+Lnarrow8UnsignedASGE:
+VLD1R (R4), [V1.B8]
+Lnarrow8UnsignedASGELoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R3), [V0.B8]
+       WORD $0x2e213c02
+       VUSHR $7, V2.B8, V2.B8
+       WORD $0x2e344442
+       VADDV V2.B8, V2
+       VMOV V2.B[0], R7
+       MOVB R7, (R5)
+       ADD $8, R3, R3
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow8UnsignedASGELoop
+
+Lnarrow8UnsignedSAEQ:
+VLD1R (R3), [V0.B8]
+Lnarrow8UnsignedSAEQLoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R4), [V1.B8]
+       WORD $0x2e218c02
+       VUSHR $7, V2.B8, V2.B8
+       WORD $0x2e344442
+       VADDV V2.B8, V2
+       VMOV V2.B[0], R7
+       MOVB R7, (R5)
+       ADD $8, R4, R4
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow8UnsignedSAEQLoop
+
+Lnarrow8UnsignedSANE:
+VLD1R (R3), [V0.B8]
+Lnarrow8UnsignedSANELoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R4), [V1.B8]
+       WORD $0x2e218c02
+       WORD $0x2e205842
+       VUSHR $7, V2.B8, V2.B8
+       WORD $0x2e344442
+       VADDV V2.B8, V2
+       VMOV V2.B[0], R7
+       MOVB R7, (R5)
+       ADD $8, R4, R4
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow8UnsignedSANELoop
+
+Lnarrow8UnsignedSAGT:
+VLD1R (R3), [V0.B8]
+Lnarrow8UnsignedSAGTLoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R4), [V1.B8]
+       WORD $0x2e213402
+       VUSHR $7, V2.B8, V2.B8
+       WORD $0x2e344442
+       VADDV V2.B8, V2
+       VMOV V2.B[0], R7
+       MOVB R7, (R5)
+       ADD $8, R4, R4
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow8UnsignedSAGTLoop
+
+Lnarrow8UnsignedSAGE:
+VLD1R (R3), [V0.B8]
+Lnarrow8UnsignedSAGELoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R4), [V1.B8]
+       WORD $0x2e213c02
+       VUSHR $7, V2.B8, V2.B8
+       WORD $0x2e344442
+       VADDV V2.B8, V2
+       VMOV V2.B[0], R7
+       MOVB R7, (R5)
+       ADD $8, R4, R4
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow8UnsignedSAGELoop
+
+Lnarrow16Signed:
+       MOVD $LCMPNEON_NARROW_WEIGHTS<>(SB), R10
+       ADD $8, R10, R10
+       VLD1 (R10), [V20.H8]
+       CMP $0, R2
+       BEQ Lnarrow16SignedAASelect
+       CMP $1, R2
+       BEQ Lnarrow16SignedASSelect
+       CMP $2, R2
+       BEQ Lnarrow16SignedSASelect
+       JMP LnarrowReturn
+
+Lnarrow16SignedAASelect:
+       CMP $0, R1
+       BEQ Lnarrow16SignedAAEQ
+       CMP $1, R1
+       BEQ Lnarrow16SignedAANE
+       CMP $2, R1
+       BEQ Lnarrow16SignedAAGT
+       CMP $3, R1
+       BEQ Lnarrow16SignedAAGE
+       JMP LnarrowReturn
+
+Lnarrow16SignedASSelect:
+       CMP $0, R1
+       BEQ Lnarrow16SignedASEQ
+       CMP $1, R1
+       BEQ Lnarrow16SignedASNE
+       CMP $2, R1
+       BEQ Lnarrow16SignedASGT
+       CMP $3, R1
+       BEQ Lnarrow16SignedASGE
+       JMP LnarrowReturn
+
+Lnarrow16SignedSASelect:
+       CMP $0, R1
+       BEQ Lnarrow16SignedSAEQ
+       CMP $1, R1
+       BEQ Lnarrow16SignedSANE
+       CMP $2, R1
+       BEQ Lnarrow16SignedSAGT
+       CMP $3, R1
+       BEQ Lnarrow16SignedSAGE
+       JMP LnarrowReturn
+
+Lnarrow16SignedAAEQ:
+Lnarrow16SignedAAEQLoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R3), [V0.H8]
+       VLD1 (R4), [V1.H8]
+       WORD $0x6e618c02
+       VUSHR $15, V2.H8, V2.H8
+       WORD $0x6e744442
+       VADDV V2.H8, V2
+       VMOV V2.H[0], R7
+       MOVB R7, (R5)
+       ADD $16, R3, R3
+       ADD $16, R4, R4
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow16SignedAAEQLoop
+
+Lnarrow16SignedAANE:
+Lnarrow16SignedAANELoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R3), [V0.H8]
+       VLD1 (R4), [V1.H8]
+       WORD $0x6e618c02
+       WORD $0x6e205842
+       VUSHR $15, V2.H8, V2.H8
+       WORD $0x6e744442
+       VADDV V2.H8, V2
+       VMOV V2.H[0], R7
+       MOVB R7, (R5)
+       ADD $16, R3, R3
+       ADD $16, R4, R4
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow16SignedAANELoop
+
+Lnarrow16SignedAAGT:
+Lnarrow16SignedAAGTLoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R3), [V0.H8]
+       VLD1 (R4), [V1.H8]
+       WORD $0x4e613402
+       VUSHR $15, V2.H8, V2.H8
+       WORD $0x6e744442
+       VADDV V2.H8, V2
+       VMOV V2.H[0], R7
+       MOVB R7, (R5)
+       ADD $16, R3, R3
+       ADD $16, R4, R4
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow16SignedAAGTLoop
+
+Lnarrow16SignedAAGE:
+Lnarrow16SignedAAGELoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R3), [V0.H8]
+       VLD1 (R4), [V1.H8]
+       WORD $0x4e613c02
+       VUSHR $15, V2.H8, V2.H8
+       WORD $0x6e744442
+       VADDV V2.H8, V2
+       VMOV V2.H[0], R7
+       MOVB R7, (R5)
+       ADD $16, R3, R3
+       ADD $16, R4, R4
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow16SignedAAGELoop
+
+Lnarrow16SignedASEQ:
+VLD1R (R4), [V1.H8]
+Lnarrow16SignedASEQLoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R3), [V0.H8]
+       WORD $0x6e618c02
+       VUSHR $15, V2.H8, V2.H8
+       WORD $0x6e744442
+       VADDV V2.H8, V2
+       VMOV V2.H[0], R7
+       MOVB R7, (R5)
+       ADD $16, R3, R3
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow16SignedASEQLoop
+
+Lnarrow16SignedASNE:
+VLD1R (R4), [V1.H8]
+Lnarrow16SignedASNELoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R3), [V0.H8]
+       WORD $0x6e618c02
+       WORD $0x6e205842
+       VUSHR $15, V2.H8, V2.H8
+       WORD $0x6e744442
+       VADDV V2.H8, V2
+       VMOV V2.H[0], R7
+       MOVB R7, (R5)
+       ADD $16, R3, R3
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow16SignedASNELoop
+
+Lnarrow16SignedASGT:
+VLD1R (R4), [V1.H8]
+Lnarrow16SignedASGTLoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R3), [V0.H8]
+       WORD $0x4e613402
+       VUSHR $15, V2.H8, V2.H8
+       WORD $0x6e744442
+       VADDV V2.H8, V2
+       VMOV V2.H[0], R7
+       MOVB R7, (R5)
+       ADD $16, R3, R3
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow16SignedASGTLoop
+
+Lnarrow16SignedASGE:
+VLD1R (R4), [V1.H8]
+Lnarrow16SignedASGELoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R3), [V0.H8]
+       WORD $0x4e613c02
+       VUSHR $15, V2.H8, V2.H8
+       WORD $0x6e744442
+       VADDV V2.H8, V2
+       VMOV V2.H[0], R7
+       MOVB R7, (R5)
+       ADD $16, R3, R3
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow16SignedASGELoop
+
+Lnarrow16SignedSAEQ:
+VLD1R (R3), [V0.H8]
+Lnarrow16SignedSAEQLoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R4), [V1.H8]
+       WORD $0x6e618c02
+       VUSHR $15, V2.H8, V2.H8
+       WORD $0x6e744442
+       VADDV V2.H8, V2
+       VMOV V2.H[0], R7
+       MOVB R7, (R5)
+       ADD $16, R4, R4
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow16SignedSAEQLoop
+
+Lnarrow16SignedSANE:
+VLD1R (R3), [V0.H8]
+Lnarrow16SignedSANELoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R4), [V1.H8]
+       WORD $0x6e618c02
+       WORD $0x6e205842
+       VUSHR $15, V2.H8, V2.H8
+       WORD $0x6e744442
+       VADDV V2.H8, V2
+       VMOV V2.H[0], R7
+       MOVB R7, (R5)
+       ADD $16, R4, R4
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow16SignedSANELoop
+
+Lnarrow16SignedSAGT:
+VLD1R (R3), [V0.H8]
+Lnarrow16SignedSAGTLoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R4), [V1.H8]
+       WORD $0x4e613402
+       VUSHR $15, V2.H8, V2.H8
+       WORD $0x6e744442
+       VADDV V2.H8, V2
+       VMOV V2.H[0], R7
+       MOVB R7, (R5)
+       ADD $16, R4, R4
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow16SignedSAGTLoop
+
+Lnarrow16SignedSAGE:
+VLD1R (R3), [V0.H8]
+Lnarrow16SignedSAGELoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R4), [V1.H8]
+       WORD $0x4e613c02
+       VUSHR $15, V2.H8, V2.H8
+       WORD $0x6e744442
+       VADDV V2.H8, V2
+       VMOV V2.H[0], R7
+       MOVB R7, (R5)
+       ADD $16, R4, R4
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow16SignedSAGELoop
+
+Lnarrow16Unsigned:
+       MOVD $LCMPNEON_NARROW_WEIGHTS<>(SB), R10
+       ADD $8, R10, R10
+       VLD1 (R10), [V20.H8]
+       CMP $0, R2
+       BEQ Lnarrow16UnsignedAASelect
+       CMP $1, R2
+       BEQ Lnarrow16UnsignedASSelect
+       CMP $2, R2
+       BEQ Lnarrow16UnsignedSASelect
+       JMP LnarrowReturn
+
+Lnarrow16UnsignedAASelect:
+       CMP $0, R1
+       BEQ Lnarrow16UnsignedAAEQ
+       CMP $1, R1
+       BEQ Lnarrow16UnsignedAANE
+       CMP $2, R1
+       BEQ Lnarrow16UnsignedAAGT
+       CMP $3, R1
+       BEQ Lnarrow16UnsignedAAGE
+       JMP LnarrowReturn
+
+Lnarrow16UnsignedASSelect:
+       CMP $0, R1
+       BEQ Lnarrow16UnsignedASEQ
+       CMP $1, R1
+       BEQ Lnarrow16UnsignedASNE
+       CMP $2, R1
+       BEQ Lnarrow16UnsignedASGT
+       CMP $3, R1
+       BEQ Lnarrow16UnsignedASGE
+       JMP LnarrowReturn
+
+Lnarrow16UnsignedSASelect:
+       CMP $0, R1
+       BEQ Lnarrow16UnsignedSAEQ
+       CMP $1, R1
+       BEQ Lnarrow16UnsignedSANE
+       CMP $2, R1
+       BEQ Lnarrow16UnsignedSAGT
+       CMP $3, R1
+       BEQ Lnarrow16UnsignedSAGE
+       JMP LnarrowReturn
+
+Lnarrow16UnsignedAAEQ:
+Lnarrow16UnsignedAAEQLoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R3), [V0.H8]
+       VLD1 (R4), [V1.H8]
+       WORD $0x6e618c02
+       VUSHR $15, V2.H8, V2.H8
+       WORD $0x6e744442
+       VADDV V2.H8, V2
+       VMOV V2.H[0], R7
+       MOVB R7, (R5)
+       ADD $16, R3, R3
+       ADD $16, R4, R4
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow16UnsignedAAEQLoop
+
+Lnarrow16UnsignedAANE:
+Lnarrow16UnsignedAANELoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R3), [V0.H8]
+       VLD1 (R4), [V1.H8]
+       WORD $0x6e618c02
+       WORD $0x6e205842
+       VUSHR $15, V2.H8, V2.H8
+       WORD $0x6e744442
+       VADDV V2.H8, V2
+       VMOV V2.H[0], R7
+       MOVB R7, (R5)
+       ADD $16, R3, R3
+       ADD $16, R4, R4
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow16UnsignedAANELoop
+
+Lnarrow16UnsignedAAGT:
+Lnarrow16UnsignedAAGTLoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R3), [V0.H8]
+       VLD1 (R4), [V1.H8]
+       WORD $0x6e613402
+       VUSHR $15, V2.H8, V2.H8
+       WORD $0x6e744442
+       VADDV V2.H8, V2
+       VMOV V2.H[0], R7
+       MOVB R7, (R5)
+       ADD $16, R3, R3
+       ADD $16, R4, R4
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow16UnsignedAAGTLoop
+
+Lnarrow16UnsignedAAGE:
+Lnarrow16UnsignedAAGELoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R3), [V0.H8]
+       VLD1 (R4), [V1.H8]
+       WORD $0x6e613c02
+       VUSHR $15, V2.H8, V2.H8
+       WORD $0x6e744442
+       VADDV V2.H8, V2
+       VMOV V2.H[0], R7
+       MOVB R7, (R5)
+       ADD $16, R3, R3
+       ADD $16, R4, R4
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow16UnsignedAAGELoop
+
+Lnarrow16UnsignedASEQ:
+VLD1R (R4), [V1.H8]
+Lnarrow16UnsignedASEQLoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R3), [V0.H8]
+       WORD $0x6e618c02
+       VUSHR $15, V2.H8, V2.H8
+       WORD $0x6e744442
+       VADDV V2.H8, V2
+       VMOV V2.H[0], R7
+       MOVB R7, (R5)
+       ADD $16, R3, R3
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow16UnsignedASEQLoop
+
+Lnarrow16UnsignedASNE:
+VLD1R (R4), [V1.H8]
+Lnarrow16UnsignedASNELoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R3), [V0.H8]
+       WORD $0x6e618c02
+       WORD $0x6e205842
+       VUSHR $15, V2.H8, V2.H8
+       WORD $0x6e744442
+       VADDV V2.H8, V2
+       VMOV V2.H[0], R7
+       MOVB R7, (R5)
+       ADD $16, R3, R3
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow16UnsignedASNELoop
+
+Lnarrow16UnsignedASGT:
+VLD1R (R4), [V1.H8]
+Lnarrow16UnsignedASGTLoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R3), [V0.H8]
+       WORD $0x6e613402
+       VUSHR $15, V2.H8, V2.H8
+       WORD $0x6e744442
+       VADDV V2.H8, V2
+       VMOV V2.H[0], R7
+       MOVB R7, (R5)
+       ADD $16, R3, R3
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow16UnsignedASGTLoop
+
+Lnarrow16UnsignedASGE:
+VLD1R (R4), [V1.H8]
+Lnarrow16UnsignedASGELoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R3), [V0.H8]
+       WORD $0x6e613c02
+       VUSHR $15, V2.H8, V2.H8
+       WORD $0x6e744442
+       VADDV V2.H8, V2
+       VMOV V2.H[0], R7
+       MOVB R7, (R5)
+       ADD $16, R3, R3
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow16UnsignedASGELoop
+
+Lnarrow16UnsignedSAEQ:
+VLD1R (R3), [V0.H8]
+Lnarrow16UnsignedSAEQLoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R4), [V1.H8]
+       WORD $0x6e618c02
+       VUSHR $15, V2.H8, V2.H8
+       WORD $0x6e744442
+       VADDV V2.H8, V2
+       VMOV V2.H[0], R7
+       MOVB R7, (R5)
+       ADD $16, R4, R4
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow16UnsignedSAEQLoop
+
+Lnarrow16UnsignedSANE:
+VLD1R (R3), [V0.H8]
+Lnarrow16UnsignedSANELoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R4), [V1.H8]
+       WORD $0x6e618c02
+       WORD $0x6e205842
+       VUSHR $15, V2.H8, V2.H8
+       WORD $0x6e744442
+       VADDV V2.H8, V2
+       VMOV V2.H[0], R7
+       MOVB R7, (R5)
+       ADD $16, R4, R4
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow16UnsignedSANELoop
+
+Lnarrow16UnsignedSAGT:
+VLD1R (R3), [V0.H8]
+Lnarrow16UnsignedSAGTLoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R4), [V1.H8]
+       WORD $0x6e613402
+       VUSHR $15, V2.H8, V2.H8
+       WORD $0x6e744442
+       VADDV V2.H8, V2
+       VMOV V2.H[0], R7
+       MOVB R7, (R5)
+       ADD $16, R4, R4
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow16UnsignedSAGTLoop
+
+Lnarrow16UnsignedSAGE:
+VLD1R (R3), [V0.H8]
+Lnarrow16UnsignedSAGELoop:
+       CMP $0, R6
+       BEQ LnarrowReturn
+       VLD1 (R4), [V1.H8]
+       WORD $0x6e613c02
+       VUSHR $15, V2.H8, V2.H8
+       WORD $0x6e744442
+       VADDV V2.H8, V2
+       VMOV V2.H[0], R7
+       MOVB R7, (R5)
+       ADD $16, R4, R4
+       ADD $1, R5, R5
+       SUB $1, R6, R6
+       JMP Lnarrow16UnsignedSAGELoop
+
+LnarrowReturn:
+       RET
diff --git 
a/arrow/compute/internal/kernels/scalar_comparison_narrow_bench_test.go 
b/arrow/compute/internal/kernels/scalar_comparison_narrow_bench_test.go
new file mode 100644
index 00000000..1086e874
--- /dev/null
+++ b/arrow/compute/internal/kernels/scalar_comparison_narrow_bench_test.go
@@ -0,0 +1,105 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+//go:build go1.18
+
+package kernels
+
+import (
+       "fmt"
+       "testing"
+       "unsafe"
+
+       "github.com/apache/arrow-go/v18/arrow"
+       "github.com/apache/arrow-go/v18/arrow/bitutil"
+)
+
+var narrowComparisonBenchmarkSink byte
+
+func BenchmarkNarrowComparisons(b *testing.B) {
+       b.Run("int8", func(b *testing.B) {
+               benchmarkNarrowComparison[int8](b)
+       })
+       b.Run("uint8", func(b *testing.B) {
+               benchmarkNarrowComparison[uint8](b)
+       })
+       b.Run("int16", func(b *testing.B) {
+               benchmarkNarrowComparison[int16](b)
+       })
+       b.Run("uint16", func(b *testing.B) {
+               benchmarkNarrowComparison[uint16](b)
+       })
+}
+
+func benchmarkNarrowComparison[T arrow.NumericType](b *testing.B) {
+       patterns := []struct {
+               name string
+               pick func(int) bool
+       }{
+               {"alternating", func(i int) bool { return i%2 == 0 }},
+               {"random25", func(i int) bool { return 
(uint32(i)*1664525+1013904223)%100 < 25 }},
+               {"random50", func(i int) bool { return 
(uint32(i)*1664525+1013904223)%100 < 50 }},
+               {"random75", func(i int) bool { return 
(uint32(i)*1664525+1013904223)%100 < 75 }},
+               {"clustered50", func(i int) bool { return (i/64)%2 == 0 }},
+               {"all", func(int) bool { return true }},
+               {"none", func(int) bool { return false }},
+       }
+
+       for _, size := range []int{1 << 10, 1 << 16, 1 << 20} {
+               for _, pattern := range patterns {
+                       left, right := makeNarrowComparisonData[T](size, 
pattern.pick)
+                       leftBytes := arrow.GetBytes(left)
+                       rightBytes := arrow.GetBytes(right)
+                       scalarBytes := arrow.GetBytes([]T{100})
+
+                       for _, shape := range []string{"array_array", 
"array_scalar", "scalar_array"} {
+                               b.Run(fmt.Sprintf("%s/%d/%s", shape, size, 
pattern.name), func(b *testing.B) {
+                                       cmp := genCompareKernel[T](CmpGT)
+                                       out := make([]byte, 
bitutil.BytesForBits(int64(size)))
+                                       b.SetBytes(int64(size) * 
int64(unsafe.Sizeof(T(0))))
+                                       b.ResetTimer()
+                                       for i := 0; i < b.N; i++ {
+                                               switch shape {
+                                               case "array_array":
+                                                       cmp.funcAA(leftBytes, 
rightBytes, out, 0)
+                                               case "array_scalar":
+                                                       cmp.funcAS(leftBytes, 
scalarBytes, out, 0)
+                                               case "scalar_array":
+                                                       cmp.funcSA(scalarBytes, 
rightBytes, out, 0)
+                                               }
+                                               narrowComparisonBenchmarkSink 
^= out[0]
+                                       }
+                               })
+                       }
+               }
+       }
+}
+
+func makeNarrowComparisonData[T arrow.NumericType](size int, pick func(int) 
bool) ([]T, []T) {
+       left := make([]T, size)
+       right := make([]T, size)
+       for i := range left {
+               if pick(i) {
+                       left[i] = 100
+                       right[i] = 50
+               } else {
+                       left[i] = 50
+                       right[i] = 100
+               }
+       }
+       return left, right
+}

Reply via email to