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/383. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D95012 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 @@ -742,4 +742,22 @@ # CHECK: prefetch.nt 16 # encoding: [0xfd,0xc6,0x01,0x00,0x10] prefetch.nt 16 + # CHECK: f64x2.convert_low_i32x4_s # encoding: [0xfd,0x53] + f64x2.convert_low_i32x4_s + + # CHECK: f64x2.convert_low_i32x4_u # encoding: [0xfd,0x54] + f64x2.convert_low_i32x4_u + + # CHECK: i32x4.trunc_sat_zero_f64x2_s # encoding: [0xfd,0x55] + i32x4.trunc_sat_zero_f64x2_s + + # CHECK: i32x4.trunc_sat_zero_f64x2_u # encoding: [0xfd,0x56] + i32x4.trunc_sat_zero_f64x2_u + + # CHECK: f32x4.demote_zero_f64x2 # encoding: [0xfd,0x57] + f32x4.demote_zero_f64x2 + + # CHECK: f64x2.promote_low_f32x4 # encoding: [0xfd,0x69] + f64x2.promote_low_f32x4 + end_function Index: llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll =================================================================== --- llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll +++ llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll @@ -566,6 +566,26 @@ ret <4 x i32> %a } +; CHECK-LABEL: trunc_sat_zero_signed_v4i32: +; SIMD128-NEXT: .functype trunc_sat_zero_signed_v4i32 (v128) -> (v128){{$}} +; SIMD128-NEXT: i32x4.trunc_sat_zero_f64x2_s $push[[R:[0-9]+]]=, $0{{$}} +; SIMD128-NEXT: return $pop[[R]]{{$}} +declare <4 x i32> @llvm.wasm.trunc.saturate.zero.signed(<2 x double>) +define <4 x i32> @trunc_sat_zero_signed_v4i32(<2 x double> %a) { + %v = call <4 x i32> @llvm.wasm.trunc.saturate.zero.signed(<2 x double> %a) + ret <4 x i32> %v +} + +; CHECK-LABEL: trunc_sat_zero_unsigned_v4i32: +; SIMD128-NEXT: .functype trunc_sat_zero_unsigned_v4i32 (v128) -> (v128){{$}} +; SIMD128-NEXT: i32x4.trunc_sat_zero_f64x2_u $push[[R:[0-9]+]]=, $0{{$}} +; SIMD128-NEXT: return $pop[[R]]{{$}} +declare <4 x i32> @llvm.wasm.trunc.saturate.zero.unsigned(<2 x double>) +define <4 x i32> @trunc_sat_zero_unsigned_v4i32(<2 x double> %a) { + %v = call <4 x i32> @llvm.wasm.trunc.saturate.zero.unsigned(<2 x double> %a) + ret <4 x i32> %v +} + ; ============================================================================== ; 2 x i64 ; ============================================================================== @@ -820,6 +840,16 @@ ret <4 x float> %v } +; CHECK-LABEL: demote_zero_v4f32: +; SIMD128-NEXT: .functype demote_zero_v4f32 (v128) -> (v128){{$}} +; SIMD128-NEXT: f32x4.demote_zero_f64x2 $push[[R:[0-9]+]]=, $0{{$}} +; SIMD128-NEXT: return $pop[[R]]{{$}} +declare <4 x float> @llvm.wasm.demote.zero(<2 x double>) +define <4 x float> @demote_zero_v4f32(<2 x double> %a) { + %v = call <4 x float> @llvm.wasm.demote.zero(<2 x double> %a) + ret <4 x float> %v +} + ; ============================================================================== ; 2 x f64 ; ============================================================================== @@ -918,3 +948,33 @@ ) ret <2 x double> %v } + +; CHECK-LABEL: convert_low_signed_v2f64: +; SIMD128-NEXT: .functype convert_low_signed_v2f64 (v128) -> (v128){{$}} +; SIMD128-NEXT: f64x2.convert_low_i32x4_s $push[[R:[0-9]+]]=, $0{{$}} +; SIMD128-NEXT: return $pop[[R]]{{$}} +declare <2 x double> @llvm.wasm.convert.low.signed(<4 x i32>) +define <2 x double> @convert_low_signed_v2f64(<4 x i32> %a) { + %v = call <2 x double> @llvm.wasm.convert.low.signed(<4 x i32> %a) + ret <2 x double> %v +} + +; CHECK-LABEL: convert_low_unsigned_v2f64: +; SIMD128-NEXT: .functype convert_low_unsigned_v2f64 (v128) -> (v128){{$}} +; SIMD128-NEXT: f64x2.convert_low_i32x4_u $push[[R:[0-9]+]]=, $0{{$}} +; SIMD128-NEXT: return $pop[[R]]{{$}} +declare <2 x double> @llvm.wasm.convert.low.unsigned(<4 x i32>) +define <2 x double> @convert_low_unsigned_v2f64(<4 x i32> %a) { + %v = call <2 x double> @llvm.wasm.convert.low.unsigned(<4 x i32> %a) + ret <2 x double> %v +} + +; CHECK-LABEL: promote_low_v2f64: +; SIMD128-NEXT: .functype promote_low_v2f64 (v128) -> (v128){{$}} +; SIMD128-NEXT: f64x2.promote_low_f32x4 $push[[R:[0-9]+]]=, $0{{$}} +; SIMD128-NEXT: return $pop[[R]]{{$}} +declare <2 x double> @llvm.wasm.promote.low(<4 x float>) +define <2 x double> @promote_low_v2f64(<4 x float> %a) { + %v = call <2 x double> @llvm.wasm.promote.low(<4 x float> %a) + ret <2 x double> %v +} Index: llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td =================================================================== --- llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td +++ llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td @@ -1257,6 +1257,20 @@ "extadd_pairwise_i16x8_u", 0xa6>; +// Prototype f64x2 conversions +defm "" : SIMDConvert<F64x2, I32x4, int_wasm_convert_low_signed, + "convert_low_i32x4_s", 0x53>; +defm "" : SIMDConvert<F64x2, I32x4, int_wasm_convert_low_unsigned, + "convert_low_i32x4_u", 0x54>; +defm "" : SIMDConvert<I32x4, F64x2, int_wasm_trunc_saturate_zero_signed, + "trunc_sat_zero_f64x2_s", 0x55>; +defm "" : SIMDConvert<I32x4, F64x2, int_wasm_trunc_saturate_zero_unsigned, + "trunc_sat_zero_f64x2_u", 0x56>; +defm "" : SIMDConvert<F32x4, F64x2, int_wasm_demote_zero, + "demote_zero_f64x2", 0x57>; +defm "" : SIMDConvert<F64x2, F32x4, int_wasm_promote_low, + "promote_low_f32x4", 0x69>; + //===----------------------------------------------------------------------===// // 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 @@ -325,6 +325,26 @@ ReadOnly<ArgIndex<0>>, NoCapture<ArgIndex<0>>], "", [SDNPMemOperand]>; +// TODO: Remove these if possible if they are merged to the spec. +def int_wasm_convert_low_signed : + Intrinsic<[llvm_v2f64_ty], [llvm_v4i32_ty], + [IntrNoMem, IntrSpeculatable]>; +def int_wasm_convert_low_unsigned : + Intrinsic<[llvm_v2f64_ty], [llvm_v4i32_ty], + [IntrNoMem, IntrSpeculatable]>; +def int_wasm_trunc_saturate_zero_signed : + Intrinsic<[llvm_v4i32_ty], [llvm_v2f64_ty], + [IntrNoMem, IntrSpeculatable]>; +def int_wasm_trunc_saturate_zero_unsigned : + Intrinsic<[llvm_v4i32_ty], [llvm_v2f64_ty], + [IntrNoMem, IntrSpeculatable]>; +def int_wasm_demote_zero : + Intrinsic<[llvm_v4f32_ty], [llvm_v2f64_ty], + [IntrNoMem, IntrSpeculatable]>; +def int_wasm_promote_low : + Intrinsic<[llvm_v2f64_ty], [llvm_v4f32_ty], + [IntrNoMem, IntrSpeculatable]>; + //===----------------------------------------------------------------------===// // 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,42 @@ // 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) + // WEBASSEMBLY: ret +} + +f64x2 convert_low_u_i32x4_f64x2(u32x4 x) { + return __builtin_wasm_convert_low_u_i32x4_f64x2(x); + // WEBASSEMBLY: call <2 x double> @llvm.wasm.convert.low.unsigned(<4 x i32> %x) + // WEBASSEMBLY: ret +} + +i32x4 trunc_saturate_zero_s_f64x2_i32x4(f64x2 x) { + return __builtin_wasm_trunc_saturate_zero_s_f64x2_i32x4(x); + // WEBASSEMBLY: call <4 x i32> @llvm.wasm.trunc.saturate.zero.signed(<2 x double> %x) + // WEBASSEMBLY: ret +} + +u32x4 trunc_saturate_zero_u_f64x2_i32x4(f64x2 x) { + return __builtin_wasm_trunc_saturate_zero_u_f64x2_i32x4(x); + // WEBASSEMBLY: call <4 x i32> @llvm.wasm.trunc.saturate.zero.unsigned(<2 x double> %x) + // WEBASSEMBLY: ret +} + +f32x4 wasm_demote_zero_f64x2_f32x4(f64x2 x) { + return __builtin_wasm_demote_zero_f64x2_f32x4(x); + // WEBASSEMBLY: call <4 x float> @llvm.wasm.demote.zero(<2 x double> %x) + // WEBASSEMBLY: ret +} + +f64x2 wasm_promote_low_f32x4_f64x2(f32x4 x) { + return __builtin_wasm_promote_low_f32x4_f64x2(x); + // WEBASSEMBLY: call <2 x double> @llvm.wasm.promote.low(<4 x float> %x) + // WEBASSEMBLY: ret +} + i32x4 load32_zero(int *p) { return __builtin_wasm_load32_zero(p); // WEBASSEMBLY: call <4 x i32> @llvm.wasm.load32.zero(i32* %p) Index: clang/lib/CodeGen/CGBuiltin.cpp =================================================================== --- clang/lib/CodeGen/CGBuiltin.cpp +++ clang/lib/CodeGen/CGBuiltin.cpp @@ -17101,6 +17101,46 @@ Function *Callee = CGM.getIntrinsic(IntNo); return Builder.CreateCall(Callee, Vec); } + 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)); + unsigned IntNo; + switch (BuiltinID) { + case WebAssembly::BI__builtin_wasm_convert_low_s_i32x4_f64x2: + IntNo = Intrinsic::wasm_convert_low_signed; + break; + case WebAssembly::BI__builtin_wasm_convert_low_u_i32x4_f64x2: + IntNo = Intrinsic::wasm_convert_low_unsigned; + break; + } + Function *Callee = CGM.getIntrinsic(IntNo); + return Builder.CreateCall(Callee, Vec); + } + case WebAssembly::BI__builtin_wasm_trunc_saturate_zero_s_f64x2_i32x4: + case WebAssembly::BI__builtin_wasm_trunc_saturate_zero_u_f64x2_i32x4: { + Value *Vec = EmitScalarExpr(E->getArg(0)); + unsigned IntNo; + switch (BuiltinID) { + case WebAssembly::BI__builtin_wasm_trunc_saturate_zero_s_f64x2_i32x4: + IntNo = Intrinsic::wasm_trunc_saturate_zero_signed; + break; + case WebAssembly::BI__builtin_wasm_trunc_saturate_zero_u_f64x2_i32x4: + IntNo = Intrinsic::wasm_trunc_saturate_zero_unsigned; + break; + } + Function *Callee = CGM.getIntrinsic(IntNo); + return Builder.CreateCall(Callee, Vec); + } + case WebAssembly::BI__builtin_wasm_demote_zero_f64x2_f32x4: { + Value *Vec = EmitScalarExpr(E->getArg(0)); + Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_demote_zero); + return Builder.CreateCall(Callee, Vec); + } + case WebAssembly::BI__builtin_wasm_promote_low_f32x4_f64x2: { + Value *Vec = EmitScalarExpr(E->getArg(0)); + Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_promote_low); + return Builder.CreateCall(Callee, Vec); + } case WebAssembly::BI__builtin_wasm_load32_zero: { Value *Ptr = EmitScalarExpr(E->getArg(0)); Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_load32_zero); Index: clang/include/clang/Basic/BuiltinsWebAssembly.def =================================================================== --- clang/include/clang/Basic/BuiltinsWebAssembly.def +++ clang/include/clang/Basic/BuiltinsWebAssembly.def @@ -206,6 +206,13 @@ 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_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") +TARGET_BUILTIN(__builtin_wasm_trunc_saturate_zero_u_f64x2_i32x4, "V4UiV2d", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_demote_zero_f64x2_f32x4, "V4fV2d", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_promote_low_f32x4_f64x2, "V2dV4f", "nc", "simd128") + TARGET_BUILTIN(__builtin_wasm_load32_zero, "V4ii*", "n", "simd128") TARGET_BUILTIN(__builtin_wasm_load64_zero, "V2LLiLLi*", "n", "simd128")
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits