tlively created this revision. tlively added a reviewer: aheejin. Herald added subscribers: wingo, ecnelises, sunfish, hiraditya, jgravelle-google, sbc100, dschuff. tlively requested review of this revision. Herald added projects: clang, LLVM. Herald added subscribers: llvm-commits, cfe-commits.
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 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D95557 Files: 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
Index: llvm/test/MC/WebAssembly/simd-encodings.s =================================================================== --- llvm/test/MC/WebAssembly/simd-encodings.s +++ llvm/test/MC/WebAssembly/simd-encodings.s @@ -760,4 +760,10 @@ # 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 Index: llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll =================================================================== --- llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll +++ llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll @@ -586,6 +586,27 @@ 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 ; ============================================================================== Index: llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td =================================================================== --- llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td +++ llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td @@ -1256,7 +1256,6 @@ 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<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) //===----------------------------------------------------------------------===// Index: llvm/include/llvm/IR/IntrinsicsWebAssembly.td =================================================================== --- llvm/include/llvm/IR/IntrinsicsWebAssembly.td +++ llvm/include/llvm/IR/IntrinsicsWebAssembly.td @@ -348,6 +348,14 @@ 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 //===----------------------------------------------------------------------===// Index: clang/test/CodeGen/builtins-wasm.c =================================================================== --- clang/test/CodeGen/builtins-wasm.c +++ clang/test/CodeGen/builtins-wasm.c @@ -976,6 +976,18 @@ // 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) Index: clang/lib/CodeGen/CGBuiltin.cpp =================================================================== --- clang/lib/CodeGen/CGBuiltin.cpp +++ clang/lib/CodeGen/CGBuiltin.cpp @@ -17220,6 +17220,24 @@ 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)); Index: clang/include/clang/Basic/BuiltinsWebAssembly.def =================================================================== --- clang/include/clang/Basic/BuiltinsWebAssembly.def +++ clang/include/clang/Basic/BuiltinsWebAssembly.def @@ -206,6 +206,9 @@ 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")
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits