From: Thomas Lively Date: Thu, 11 Oct 2018 00:07:55 +0000 (+0000) Subject: [WebAssembly] Saturating float-to-int builtins X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=58281c244d412d25880a9b0dfebc6fb88ce55c50;p=clang [WebAssembly] Saturating float-to-int builtins Summary: Depends on D53007 and D53004. Reviewers: aheejin, dschuff Subscribers: sbc100, jgravelle-google, sunfish, kristina, cfe-commits Differential Revision: https://reviews.llvm.org/D53009 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@344205 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/BuiltinsWebAssembly.def b/include/clang/Basic/BuiltinsWebAssembly.def index 494d3cf3ac..e27e3c2d75 100644 --- a/include/clang/Basic/BuiltinsWebAssembly.def +++ b/include/clang/Basic/BuiltinsWebAssembly.def @@ -39,6 +39,16 @@ BUILTIN(__builtin_wasm_atomic_wait_i32, "ii*iLLi", "n") BUILTIN(__builtin_wasm_atomic_wait_i64, "iLLi*LLiLLi", "n") BUILTIN(__builtin_wasm_atomic_notify, "Uii*i", "n") +// Saturating fp-to-int conversions +BUILTIN(__builtin_wasm_trunc_saturate_s_i32_f32, "if", "nc") +BUILTIN(__builtin_wasm_trunc_saturate_u_i32_f32, "if", "nc") +BUILTIN(__builtin_wasm_trunc_saturate_s_i32_f64, "id", "nc") +BUILTIN(__builtin_wasm_trunc_saturate_u_i32_f64, "id", "nc") +BUILTIN(__builtin_wasm_trunc_saturate_s_i64_f32, "LLif", "nc") +BUILTIN(__builtin_wasm_trunc_saturate_u_i64_f32, "LLif", "nc") +BUILTIN(__builtin_wasm_trunc_saturate_s_i64_f64, "LLid", "nc") +BUILTIN(__builtin_wasm_trunc_saturate_u_i64_f64, "LLid", "nc") + // SIMD builtins BUILTIN(__builtin_wasm_extract_lane_s_i8x16, "iV16cIi", "nc") BUILTIN(__builtin_wasm_extract_lane_u_i8x16, "iV16cIi", "nc") @@ -81,4 +91,9 @@ BUILTIN(__builtin_wasm_abs_f64x2, "V2dV2d", "nc") BUILTIN(__builtin_wasm_sqrt_f32x4, "V4fV4f", "nc") BUILTIN(__builtin_wasm_sqrt_f64x2, "V2dV2d", "nc") +BUILTIN(__builtin_wasm_trunc_saturate_s_v4i32_v4f32, "V4iV4f", "nc") +BUILTIN(__builtin_wasm_trunc_saturate_u_v4i32_v4f32, "V4iV4f", "nc") +BUILTIN(__builtin_wasm_trunc_saturate_s_v2i64_v2f64, "V2LLiV2d", "nc") +BUILTIN(__builtin_wasm_trunc_saturate_u_v2i64_v2f64, "V2LLiV2d", "nc") + #undef BUILTIN diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index 18b300bf11..70c50d3782 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -12456,6 +12456,30 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_atomic_notify); return Builder.CreateCall(Callee, {Addr, Count}); } + case WebAssembly::BI__builtin_wasm_trunc_saturate_s_i32_f32: + case WebAssembly::BI__builtin_wasm_trunc_saturate_s_i32_f64: + case WebAssembly::BI__builtin_wasm_trunc_saturate_s_i64_f32: + case WebAssembly::BI__builtin_wasm_trunc_saturate_s_i64_f64: + case WebAssembly::BI__builtin_wasm_trunc_saturate_s_v4i32_v4f32: + case WebAssembly::BI__builtin_wasm_trunc_saturate_s_v2i64_v2f64: { + Value *Src = EmitScalarExpr(E->getArg(0)); + llvm::Type *ResT = ConvertType(E->getType()); + Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_trunc_saturate_signed, + {ResT, Src->getType()}); + return Builder.CreateCall(Callee, {Src}); + } + case WebAssembly::BI__builtin_wasm_trunc_saturate_u_i32_f32: + case WebAssembly::BI__builtin_wasm_trunc_saturate_u_i32_f64: + case WebAssembly::BI__builtin_wasm_trunc_saturate_u_i64_f32: + case WebAssembly::BI__builtin_wasm_trunc_saturate_u_i64_f64: + case WebAssembly::BI__builtin_wasm_trunc_saturate_u_v4i32_v4f32: + case WebAssembly::BI__builtin_wasm_trunc_saturate_u_v2i64_v2f64: { + Value *Src = EmitScalarExpr(E->getArg(0)); + llvm::Type *ResT = ConvertType(E->getType()); + Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_trunc_saturate_unsigned, + {ResT, Src->getType()}); + return Builder.CreateCall(Callee, {Src}); + } case WebAssembly::BI__builtin_wasm_extract_lane_s_i8x16: case WebAssembly::BI__builtin_wasm_extract_lane_u_i8x16: case WebAssembly::BI__builtin_wasm_extract_lane_s_i16x8: diff --git a/test/CodeGen/builtins-wasm.c b/test/CodeGen/builtins-wasm.c index 55ef1b3bda..1e94a8d818 100644 --- a/test/CodeGen/builtins-wasm.c +++ b/test/CodeGen/builtins-wasm.c @@ -83,6 +83,54 @@ unsigned int atomic_notify(int *addr, int count) { // WEBASSEMBLY64: call i32 @llvm.wasm.atomic.notify(i32* %{{.*}}, i32 %{{.*}}) } +int trunc_saturate_s_i32_f32(float f) { + return __builtin_wasm_trunc_saturate_s_i32_f32(f); + // WEBASSEMBLY: call i32 @llvm.wasm.trunc.saturate.signed.i32.f32(float %f) + // WEBASSEMBLY-NEXT: ret +} + +int trunc_saturate_u_i32_f32(float f) { + return __builtin_wasm_trunc_saturate_u_i32_f32(f); + // WEBASSEMBLY: call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f32(float %f) + // WEBASSEMBLY-NEXT: ret +} + +int trunc_saturate_s_i32_f64(double f) { + return __builtin_wasm_trunc_saturate_s_i32_f64(f); + // WEBASSEMBLY: call i32 @llvm.wasm.trunc.saturate.signed.i32.f64(double %f) + // WEBASSEMBLY-NEXT: ret +} + +int trunc_saturate_u_i32_f64(double f) { + return __builtin_wasm_trunc_saturate_u_i32_f64(f); + // WEBASSEMBLY: call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f64(double %f) + // WEBASSEMBLY-NEXT: ret +} + +long long trunc_saturate_s_i64_f32(float f) { + return __builtin_wasm_trunc_saturate_s_i64_f32(f); + // WEBASSEMBLY: call i64 @llvm.wasm.trunc.saturate.signed.i64.f32(float %f) + // WEBASSEMBLY-NEXT: ret +} + +long long trunc_saturate_u_i64_f32(float f) { + return __builtin_wasm_trunc_saturate_u_i64_f32(f); + // WEBASSEMBLY: call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f32(float %f) + // WEBASSEMBLY-NEXT: ret +} + +long long trunc_saturate_s_i64_f64(double f) { + return __builtin_wasm_trunc_saturate_s_i64_f64(f); + // WEBASSEMBLY: call i64 @llvm.wasm.trunc.saturate.signed.i64.f64(double %f) + // WEBASSEMBLY-NEXT: ret +} + +long long trunc_saturate_u_i64_f64(double f) { + return __builtin_wasm_trunc_saturate_u_i64_f64(f); + // WEBASSEMBLY: call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f64(double %f) + // WEBASSEMBLY-NEXT: ret +} + int extract_lane_s_i8x16(i8x16 v) { return __builtin_wasm_extract_lane_s_i8x16(v, 13); // WEBASSEMBLY: extractelement <16 x i8> %v, i32 13 @@ -300,3 +348,27 @@ f64x2 sqrt_f64x2(f64x2 x) { // WEBASSEMBLY: call <2 x double> @llvm.sqrt.v2f64(<2 x double> %x) // WEBASSEMBLY: ret } + +i32x4 trunc_saturate_s_v4i32_v4f32(f32x4 f) { + return __builtin_wasm_trunc_saturate_s_v4i32_v4f32(f); + // WEBASSEMBLY: call <4 x i32> @llvm.wasm.trunc.saturate.signed.v4i32.v4f32(<4 x float> %f) + // WEBASSEMBLY-NEXT: ret +} + +i32x4 trunc_saturate_u_v4i32_v4f32(f32x4 f) { + return __builtin_wasm_trunc_saturate_u_v4i32_v4f32(f); + // WEBASSEMBLY: call <4 x i32> @llvm.wasm.trunc.saturate.unsigned.v4i32.v4f32(<4 x float> %f) + // WEBASSEMBLY-NEXT: ret +} + +i64x2 trunc_saturate_s_v2i64_v2f64(f64x2 f) { + return __builtin_wasm_trunc_saturate_s_v2i64_v2f64(f); + // WEBASSEMBLY: call <2 x i64> @llvm.wasm.trunc.saturate.signed.v2i64.v2f64(<2 x double> %f) + // WEBASSEMBLY-NEXT: ret +} + +i64x2 trunc_saturate_u_v2i64_v2f64(f64x2 f) { + return __builtin_wasm_trunc_saturate_u_v2i64_v2f64(f); + // WEBASSEMBLY: call <2 x i64> @llvm.wasm.trunc.saturate.unsigned.v2i64.v2f64(<2 x double> %f) + // WEBASSEMBLY-NEXT: ret +}