Author: Thomas Lively Date: 2021-01-28T10:59:32-08:00 New Revision: 4b68b64dcc5bcd6f29779b820791611c60438385
URL: https://github.com/llvm/llvm-project/commit/4b68b64dcc5bcd6f29779b820791611c60438385 DIFF: https://github.com/llvm/llvm-project/commit/4b68b64dcc5bcd6f29779b820791611c60438385.diff LOG: [WebAssembly] Prototype i8x16 to i32x4 widening instructions As proposed in https://github.com/WebAssembly/simd/pull/395 and matching the opcodes used in V8: https://chromium-review.googlesource.com/c/v8/v8/+/2617385/4/src/wasm/wasm-opcodes.h Differential Revision: https://reviews.llvm.org/D95557 Added: Modified: clang/include/clang/Basic/BuiltinsWebAssembly.def clang/lib/CodeGen/CGBuiltin.cpp clang/test/CodeGen/builtins-wasm.c llvm/include/llvm/IR/IntrinsicsWebAssembly.td llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll llvm/test/MC/WebAssembly/simd-encodings.s Removed: ################################################################################ diff --git a/clang/include/clang/Basic/BuiltinsWebAssembly.def b/clang/include/clang/Basic/BuiltinsWebAssembly.def index bb7d6d379e58..84f346bcb928 100644 --- a/clang/include/clang/Basic/BuiltinsWebAssembly.def +++ b/clang/include/clang/Basic/BuiltinsWebAssembly.def @@ -206,6 +206,9 @@ TARGET_BUILTIN(__builtin_wasm_widen_high_s_i32x4_i64x2, "V2LLiV4i", "nc", "simd1 TARGET_BUILTIN(__builtin_wasm_widen_low_u_i32x4_i64x2, "V2LLUiV4Ui", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_widen_high_u_i32x4_i64x2, "V2LLUiV4Ui", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_widen_s_i8x16_i32x4, "V4iV16ScIi", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_widen_u_i8x16_i32x4, "V4UiV16UcIi", "nc", "simd128") + TARGET_BUILTIN(__builtin_wasm_convert_low_s_i32x4_f64x2, "V2dV4i", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_convert_low_u_i32x4_f64x2, "V2dV4Ui", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_trunc_saturate_zero_s_f64x2_i32x4, "V4iV2d", "nc", "simd128") diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 113541bd5024..973a20f2f58c 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -17220,6 +17220,24 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, Function *Callee = CGM.getIntrinsic(IntNo); return Builder.CreateCall(Callee, Vec); } + case WebAssembly::BI__builtin_wasm_widen_s_i8x16_i32x4: + case WebAssembly::BI__builtin_wasm_widen_u_i8x16_i32x4: { + Value *Vec = EmitScalarExpr(E->getArg(0)); + llvm::APSInt SubVecConst = + *E->getArg(1)->getIntegerConstantExpr(getContext()); + Value *SubVec = llvm::ConstantInt::get(getLLVMContext(), SubVecConst); + unsigned IntNo; + switch (BuiltinID) { + case WebAssembly::BI__builtin_wasm_widen_s_i8x16_i32x4: + IntNo = Intrinsic::wasm_widen_signed; + break; + case WebAssembly::BI__builtin_wasm_widen_u_i8x16_i32x4: + IntNo = Intrinsic::wasm_widen_unsigned; + break; + } + Function *Callee = CGM.getIntrinsic(IntNo); + return Builder.CreateCall(Callee, {Vec, SubVec}); + } case WebAssembly::BI__builtin_wasm_convert_low_s_i32x4_f64x2: case WebAssembly::BI__builtin_wasm_convert_low_u_i32x4_f64x2: { Value *Vec = EmitScalarExpr(E->getArg(0)); diff --git a/clang/test/CodeGen/builtins-wasm.c b/clang/test/CodeGen/builtins-wasm.c index 61fc76cd1873..771764c85d6b 100644 --- a/clang/test/CodeGen/builtins-wasm.c +++ b/clang/test/CodeGen/builtins-wasm.c @@ -976,6 +976,18 @@ u64x2 widen_high_u_i32x4_i64x2(u32x4 x) { // WEBASSEMBLY: ret } +i32x4 widen_s_i8x16_i32x4(i8x16 x) { + return __builtin_wasm_widen_s_i8x16_i32x4(x, 3); + // WEBASSEMBLY: call <4 x i32> @llvm.wasm.widen.signed(<16 x i8> %x, i32 3) + // WEBASSEMBLY: ret +} + +u32x4 widen_u_i8x16_i32x4(u8x16 x) { + return __builtin_wasm_widen_u_i8x16_i32x4(x, 3); + // WEBASSEMBLY: call <4 x i32> @llvm.wasm.widen.unsigned(<16 x i8> %x, i32 3) + // WEBASSEMBLY: ret +} + f64x2 convert_low_s_i32x4_f64x2(i32x4 x) { return __builtin_wasm_convert_low_s_i32x4_f64x2(x); // WEBASSEMBLY: call <2 x double> @llvm.wasm.convert.low.signed(<4 x i32> %x) diff --git a/llvm/include/llvm/IR/IntrinsicsWebAssembly.td b/llvm/include/llvm/IR/IntrinsicsWebAssembly.td index d306d0ccb90d..323b9a770c05 100644 --- a/llvm/include/llvm/IR/IntrinsicsWebAssembly.td +++ b/llvm/include/llvm/IR/IntrinsicsWebAssembly.td @@ -348,6 +348,14 @@ def int_wasm_promote_low : Intrinsic<[llvm_v2f64_ty], [llvm_v4f32_ty], [IntrNoMem, IntrSpeculatable]>; +// TODO: Remove these if possible if they are merged to the spec. +def int_wasm_widen_signed : + Intrinsic<[llvm_v4i32_ty], [llvm_v16i8_ty, llvm_i32_ty], + [IntrNoMem, IntrSpeculatable, ImmArg<ArgIndex<1>>]>; +def int_wasm_widen_unsigned : + Intrinsic<[llvm_v4i32_ty], [llvm_v16i8_ty, llvm_i32_ty], + [IntrNoMem, IntrSpeculatable, ImmArg<ArgIndex<1>>]>; + //===----------------------------------------------------------------------===// // Thread-local storage intrinsics //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td index 9f3d0f4ab2c3..404cbcdf56b8 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td @@ -1256,7 +1256,6 @@ defm "" : SIMDConvert<I32x4, I16x8, int_wasm_extadd_pairwise_signed, defm "" : SIMDConvert<I32x4, I16x8, int_wasm_extadd_pairwise_unsigned, "extadd_pairwise_i16x8_u", 0xa6>; - // Prototype f64x2 conversions defm "" : SIMDConvert<F64x2, I32x4, int_wasm_convert_low_signed, "convert_low_i32x4_s", 0x53>; @@ -1271,6 +1270,25 @@ defm "" : SIMDConvert<F32x4, F64x2, int_wasm_demote_zero, defm "" : SIMDConvert<F64x2, F32x4, int_wasm_promote_low, "promote_low_f32x4", 0x69>; +// Prototype i8x16 to i32x4 widening +defm WIDEN_I8x16_TO_I32x4_S : + SIMD_I<(outs V128:$dst), (ins V128:$vec, vec_i8imm_op:$idx), + (outs), (ins vec_i8imm_op:$idx), + [(set (I32x4.vt V128:$dst), + (I32x4.vt (int_wasm_widen_signed + (I8x16.vt V128:$vec), (i32 timm:$idx))))], + "i32x4.widen_i8x16_s\t$dst, $vec, $idx", + "i32x4.widen_i8x16_s\t$idx", 0x67>; +defm WIDEN_I8x16_TO_I32x4_U : + SIMD_I<(outs V128:$dst), (ins V128:$vec, vec_i8imm_op:$idx), + (outs), (ins vec_i8imm_op:$idx), + [(set (I32x4.vt V128:$dst), + (I32x4.vt (int_wasm_widen_unsigned + (I8x16.vt V128:$vec), (i32 timm:$idx))))], + "i32x4.widen_i8x16_u\t$dst, $vec, $idx", + "i32x4.widen_i8x16_u\t$idx", 0x68>; + + //===----------------------------------------------------------------------===// // Quasi-Fused Multiply- Add and Subtract (QFMA/QFMS) //===----------------------------------------------------------------------===// diff --git a/llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll b/llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll index 59f31f09b7f4..f223615c57a1 100644 --- a/llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll +++ b/llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll @@ -586,6 +586,27 @@ define <4 x i32> @trunc_sat_zero_unsigned_v4i32(<2 x double> %a) { ret <4 x i32> %v } + +; CHECK-LABEL: widen_signed_v4i32: +; SIMD128-NEXT: .functype widen_signed_v4i32 (v128) -> (v128){{$}} +; SIMD128-NEXT: i32x4.widen_i8x16_s $push[[R:[0-9]+]]=, $0, 1{{$}} +; SIMD128-NEXT: return $pop[[R]]{{$}} +declare <4 x i32> @llvm.wasm.widen.signed(<16 x i8>, i32 immarg) +define <4 x i32> @widen_signed_v4i32(<16 x i8> %x) { + %v = call <4 x i32> @llvm.wasm.widen.signed(<16 x i8> %x, i32 1) + ret <4 x i32> %v +} + +; CHECK-LABEL: widen_unsigned_v4i32: +; SIMD128-NEXT: .functype widen_unsigned_v4i32 (v128) -> (v128){{$}} +; SIMD128-NEXT: i32x4.widen_i8x16_u $push[[R:[0-9]+]]=, $0, 1{{$}} +; SIMD128-NEXT: return $pop[[R]]{{$}} +declare <4 x i32> @llvm.wasm.widen.unsigned(<16 x i8>, i32 immarg) +define <4 x i32> @widen_unsigned_v4i32(<16 x i8> %x) { + %v = call <4 x i32> @llvm.wasm.widen.unsigned(<16 x i8> %x, i32 1) + ret <4 x i32> %v +} + ; ============================================================================== ; 2 x i64 ; ============================================================================== diff --git a/llvm/test/MC/WebAssembly/simd-encodings.s b/llvm/test/MC/WebAssembly/simd-encodings.s index 7a84548bd584..099c6489e703 100644 --- a/llvm/test/MC/WebAssembly/simd-encodings.s +++ b/llvm/test/MC/WebAssembly/simd-encodings.s @@ -760,4 +760,10 @@ main: # CHECK: f64x2.promote_low_f32x4 # encoding: [0xfd,0x69] f64x2.promote_low_f32x4 + # CHECK: i32x4.widen_i8x16_s 3 # encoding: [0xfd,0x67,0x03] + i32x4.widen_i8x16_s 3 + + # CHECK: i32x4.widen_i8x16_u 3 # encoding: [0xfd,0x68,0x03] + i32x4.widen_i8x16_u 3 + end_function _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits