From 8a11fbf479b8888d50b8cdb14e0d25cdc0b5a207 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Wed, 9 Oct 2019 17:45:47 +0000 Subject: [PATCH] [WebAssembly] Add builtin and intrinsic for v8x16.swizzle Summary: This clang builtin and corresponding LLVM intrinsic are necessary to expose the exact semantics of the underlying WebAssembly instruction to users. LLVM produces a poison value if the dynamic swizzle indices are greater than the vector size, but the WebAssembly instruction sets the corresponding output lane to zero. Users who depend on this behavior can safely use this builtin. Depends on D68527. Reviewers: aheejin, dschuff Subscribers: sbc100, jgravelle-google, hiraditya, sunfish, cfe-commits, llvm-commits Tags: #clang, #llvm Differential Revision: https://reviews.llvm.org/D68531 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@374189 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/IR/IntrinsicsWebAssembly.td | 4 ++++ lib/Target/WebAssembly/WebAssemblyInstrSIMD.td | 4 ++++ test/CodeGen/WebAssembly/simd-intrinsics.ll | 10 ++++++++++ 3 files changed, 18 insertions(+) diff --git a/include/llvm/IR/IntrinsicsWebAssembly.td b/include/llvm/IR/IntrinsicsWebAssembly.td index 6b5d0cbf799..ef5219b05bb 100644 --- a/include/llvm/IR/IntrinsicsWebAssembly.td +++ b/include/llvm/IR/IntrinsicsWebAssembly.td @@ -89,6 +89,10 @@ def int_wasm_atomic_notify: // SIMD intrinsics //===----------------------------------------------------------------------===// +def int_wasm_swizzle : + Intrinsic<[llvm_v16i8_ty], + [llvm_v16i8_ty, llvm_v16i8_ty], + [IntrNoMem, IntrSpeculatable]>; def int_wasm_sub_saturate_signed : Intrinsic<[llvm_anyvector_ty], [LLVMMatchType<0>, LLVMMatchType<0>], diff --git a/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td b/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td index 16549f39b18..fc5d73dac52 100644 --- a/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td +++ b/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td @@ -278,12 +278,16 @@ def : Pat<(vec_t (wasm_shuffle (vec_t V128:$x), (vec_t V128:$y), // Swizzle lanes: v8x16.swizzle def wasm_swizzle_t : SDTypeProfile<1, 2, []>; def wasm_swizzle : SDNode<"WebAssemblyISD::SWIZZLE", wasm_swizzle_t>; +let Predicates = [HasUnimplementedSIMD128] in defm SWIZZLE : SIMD_I<(outs V128:$dst), (ins V128:$src, V128:$mask), (outs), (ins), [(set (v16i8 V128:$dst), (wasm_swizzle (v16i8 V128:$src), (v16i8 V128:$mask)))], "v8x16.swizzle\t$dst, $src, $mask", "v8x16.swizzle", 192>; +def : Pat<(int_wasm_swizzle (v16i8 V128:$src), (v16i8 V128:$mask)), + (SWIZZLE V128:$src, V128:$mask)>; + // Create vector with identical lanes: splat def splat2 : PatFrag<(ops node:$x), (build_vector node:$x, node:$x)>; def splat4 : PatFrag<(ops node:$x), (build_vector diff --git a/test/CodeGen/WebAssembly/simd-intrinsics.ll b/test/CodeGen/WebAssembly/simd-intrinsics.ll index f88b8b45426..6a901ee4dad 100644 --- a/test/CodeGen/WebAssembly/simd-intrinsics.ll +++ b/test/CodeGen/WebAssembly/simd-intrinsics.ll @@ -11,6 +11,16 @@ target triple = "wasm32-unknown-unknown" ; ============================================================================== ; 16 x i8 ; ============================================================================== +; CHECK-LABEL: swizzle_v16i8: +; SIMD128-NEXT: .functype swizzle_v16i8 (v128, v128) -> (v128){{$}} +; SIMD128-NEXT: v8x16.swizzle $push[[R:[0-9]+]]=, $0, $1{{$}} +; SIMD128-NEXT: return $pop[[R]]{{$}} +declare <16 x i8> @llvm.wasm.swizzle(<16 x i8>, <16 x i8>) +define <16 x i8> @swizzle_v16i8(<16 x i8> %x, <16 x i8> %y) { + %a = call <16 x i8> @llvm.wasm.swizzle(<16 x i8> %x, <16 x i8> %y) + ret <16 x i8> %a +} + ; CHECK-LABEL: add_sat_s_v16i8: ; SIMD128-NEXT: .functype add_sat_s_v16i8 (v128, v128) -> (v128){{$}} ; SIMD128-NEXT: i8x16.add_saturate_s $push[[R:[0-9]+]]=, $0, $1{{$}} -- 2.40.0