SIMD shuffle strength-reduction in JSC's B3 backend
Source/JavaScriptCore/jit/SIMDShuffle.h
Source/JavaScriptCore/b3/B3ReduceSIMDShuffle.cpp
B3 (Bare Bones Backend)는 JSC의 high-level JIT IR로, Wasm/JS frontend와 최종 Air (assembly 수준) backend 사이에 위치합니다. WebAssembly의 i8x16.shuffle은 16바이트 index mask를 사용해 두 개의 128비트 입력 벡터에서 16바이트를 선택하는 연산으로, B3에서는 이를 VectorSwizzle로 표현합니다. 단순한 lowering은 범용적이지만 느린 ARM64의 tbl 명령어(vector table lookup)를 생성합니다. 한편 ARM64 NEON에는 자주 쓰이는 permutation 패턴 전용 명령어들이 존재합니다. UZP(deinterleave), ZIP(interleave), TRN(transpose), EXT(extract/rotate), REV(reverse) 등이 그것으로, table lookup보다 적은 cycle로 실행됩니다.
이 commit은 새로운 B3ReduceSIMDShuffle phase를 추가합니다. 컴파일 시점에 VectorSwizzle의 byte-index 패턴을 분석하여 동등한 NEON 명령어로 대체하는 역할을 합니다. tryMatchCanonicalBinary와 tryMatchCanonicalUnary 패턴 매처는 16바이트 mask를 각 명령어의 알려진 semantics와 대조합니다. 또한 VectorSwizzle 체인도 처리 대상에 포함됩니다. VectorSwizzle이 다른 VectorSwizzle에 입력으로 연결되는 경우, composeShuffle이 두 permutation table을 대수적으로 하나로 합칩니다(result[i] = lhsMask[rhsMask[i]]). 이후 합쳐진 결과를 대상으로 패턴 인식을 다시 수행합니다. XOR-rotate 패턴을 위한 ARM64 SHA3 XAR lowering 규칙도 별도로 추가되었으며, isARM64_SHA3()로 게이팅됩니다.
Wasm i8x16.shuffle
│
▼
B3 VectorSwizzle(a, b, mask[16])
│
├─► B3ReduceSIMDShuffle (new phase):
│ ├─ VectorSwizzle(VectorSwizzle(a,b,m1), c, m2)
│ │ └─► composeShuffle(m1, m2) → single VectorSwizzle
│ └─► tryMatchCanonical*(mask) → specialized opcode
│ UZP1/2, ZIP1/2, TRN1/2, EXT, REV, DupElement
│
└─► B3LowerToAir → ARM64 NEON instruction
tbl (generic fallback) or uzp1/zip1/ext/rev*/...
Significance
이 commit은 ARM64 WebAssembly SIMD를 위한 새로운 JIT code generation 경로를 대거 추가하며, 범용 table lookup을 전용 NEON 명령어로 대체합니다. 패턴 매칭 기반의 JIT transform은 역사적으로 miscompilation 버그가 빈번하게 발생하는 영역으로, 잘못된 연산이나 security와 관련된 type confusion으로 이어질 수 있습니다.