From 101ffdb0168928e0650f7c5990f098d0d0b4ca86 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Sat, 31 Aug 2019 00:12:29 +0000 Subject: [PATCH] [WebAssembly] Add SIMD QFMA/QFMS Summary: Adds clang builtins and LLVM intrinsics for these experimental instructions. They are not implemented in engines yet, but that is ok because the user must opt into using them by calling the builtins. Reviewers: aheejin, dschuff Reviewed By: aheejin Subscribers: sbc100, jgravelle-google, hiraditya, sunfish, cfe-commits, llvm-commits Tags: #clang, #llvm Differential Revision: https://reviews.llvm.org/D67020 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@370556 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/BuiltinsWebAssembly.def | 5 ++++ lib/CodeGen/CGBuiltin.cpp | 24 +++++++++++++++++- test/CodeGen/builtins-wasm.c | 28 +++++++++++++++++++++ 3 files changed, 56 insertions(+), 1 deletion(-) diff --git a/include/clang/Basic/BuiltinsWebAssembly.def b/include/clang/Basic/BuiltinsWebAssembly.def index acd713d465..37f945a319 100644 --- a/include/clang/Basic/BuiltinsWebAssembly.def +++ b/include/clang/Basic/BuiltinsWebAssembly.def @@ -108,6 +108,11 @@ TARGET_BUILTIN(__builtin_wasm_max_f64x2, "V2dV2dV2d", "nc", "unimplemented-simd1 TARGET_BUILTIN(__builtin_wasm_sqrt_f32x4, "V4fV4f", "nc", "unimplemented-simd128") TARGET_BUILTIN(__builtin_wasm_sqrt_f64x2, "V2dV2d", "nc", "unimplemented-simd128") +TARGET_BUILTIN(__builtin_wasm_qfma_f32x4, "V4fV4fV4fV4f", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_qfms_f32x4, "V4fV4fV4fV4f", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_qfma_f64x2, "V2dV2dV2dV2d", "nc", "unimplemented-simd128") +TARGET_BUILTIN(__builtin_wasm_qfms_f64x2, "V2dV2dV2dV2d", "nc", "unimplemented-simd128") + TARGET_BUILTIN(__builtin_wasm_trunc_saturate_s_i32x4_f32x4, "V4iV4f", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_trunc_saturate_u_i32x4_f32x4, "V4iV4f", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_trunc_saturate_s_i64x2_f64x2, "V2LLiV2d", "nc", "unimplemented-simd128") diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index e9e9fe2aa0..1b2468d336 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -14173,7 +14173,29 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, Function *Callee = CGM.getIntrinsic(Intrinsic::sqrt, Vec->getType()); return Builder.CreateCall(Callee, {Vec}); } - + case WebAssembly::BI__builtin_wasm_qfma_f32x4: + case WebAssembly::BI__builtin_wasm_qfms_f32x4: + case WebAssembly::BI__builtin_wasm_qfma_f64x2: + case WebAssembly::BI__builtin_wasm_qfms_f64x2: { + Value *A = EmitScalarExpr(E->getArg(0)); + Value *B = EmitScalarExpr(E->getArg(1)); + Value *C = EmitScalarExpr(E->getArg(2)); + unsigned IntNo; + switch (BuiltinID) { + case WebAssembly::BI__builtin_wasm_qfma_f32x4: + case WebAssembly::BI__builtin_wasm_qfma_f64x2: + IntNo = Intrinsic::wasm_qfma; + break; + case WebAssembly::BI__builtin_wasm_qfms_f32x4: + case WebAssembly::BI__builtin_wasm_qfms_f64x2: + IntNo = Intrinsic::wasm_qfms; + break; + default: + llvm_unreachable("unexpected builtin ID"); + } + Function *Callee = CGM.getIntrinsic(IntNo, A->getType()); + return Builder.CreateCall(Callee, {A, B, C}); + } default: return nullptr; } diff --git a/test/CodeGen/builtins-wasm.c b/test/CodeGen/builtins-wasm.c index f3129b787a..43299bd26f 100644 --- a/test/CodeGen/builtins-wasm.c +++ b/test/CodeGen/builtins-wasm.c @@ -412,6 +412,34 @@ f64x2 sqrt_f64x2(f64x2 x) { // WEBASSEMBLY: ret } +f32x4 qfma_f32x4(f32x4 a, f32x4 b, f32x4 c) { + return __builtin_wasm_qfma_f32x4(a, b, c); + // WEBASSEMBLY: call <4 x float> @llvm.wasm.qfma.v4f32( + // WEBASSEMBLY-SAME: <4 x float> %a, <4 x float> %b, <4 x float> %c) + // WEBASSEMBLY-NEXT: ret +} + +f32x4 qfms_f32x4(f32x4 a, f32x4 b, f32x4 c) { + return __builtin_wasm_qfms_f32x4(a, b, c); + // WEBASSEMBLY: call <4 x float> @llvm.wasm.qfms.v4f32( + // WEBASSEMBLY-SAME: <4 x float> %a, <4 x float> %b, <4 x float> %c) + // WEBASSEMBLY-NEXT: ret +} + +f64x2 qfma_f64x2(f64x2 a, f64x2 b, f64x2 c) { + return __builtin_wasm_qfma_f64x2(a, b, c); + // WEBASSEMBLY: call <2 x double> @llvm.wasm.qfma.v2f64( + // WEBASSEMBLY-SAME: <2 x double> %a, <2 x double> %b, <2 x double> %c) + // WEBASSEMBLY-NEXT: ret +} + +f64x2 qfms_f64x2(f64x2 a, f64x2 b, f64x2 c) { + return __builtin_wasm_qfms_f64x2(a, b, c); + // WEBASSEMBLY: call <2 x double> @llvm.wasm.qfms.v2f64( + // WEBASSEMBLY-SAME: <2 x double> %a, <2 x double> %b, <2 x double> %c) + // WEBASSEMBLY-NEXT: ret +} + i32x4 trunc_saturate_s_i32x4_f32x4(f32x4 f) { return __builtin_wasm_trunc_saturate_s_i32x4_f32x4(f); // WEBASSEMBLY: call <4 x i32> @llvm.wasm.trunc.saturate.signed.v4i32.v4f32(<4 x float> %f) -- 2.40.0