From 52818fd97f0f2b13d12e66de9f06b9f4cbc0be07 Mon Sep 17 00:00:00 2001 From: Phoebe Wang Date: Mon, 6 Jun 2022 08:31:44 +0800 Subject: [PATCH] [Clang][FP16] Add 4 builtins for _Float16 We are lacking builtins support for `_Float16`. In most cases, we can use other floating-type builtins and truncate them to `_Float16`. But it's a problem to SNaN, e.g., https://gcc.godbolt.org/z/cqr5nG1jh This patch adds `__builtin_nansf16` support as well as other 3 ones since they are usually used together. Reviewed By: LuoYuanke Differential Revision: https://reviews.llvm.org/D127050 --- clang/include/clang/Basic/Builtins.def | 4 ++++ clang/lib/AST/ExprConstant.cpp | 4 ++++ clang/test/CodeGen/builtin_Float16.c | 17 +++++++++++++++++ 3 files changed, 25 insertions(+) create mode 100644 clang/test/CodeGen/builtin_Float16.c diff --git a/clang/include/clang/Basic/Builtins.def b/clang/include/clang/Basic/Builtins.def index 6fb6d95..f47e8de 100644 --- a/clang/include/clang/Basic/Builtins.def +++ b/clang/include/clang/Basic/Builtins.def @@ -142,10 +142,12 @@ BUILTIN(__builtin_frexpf128, "LLdLLdi*", "Fn") BUILTIN(__builtin_huge_val, "d", "nc") BUILTIN(__builtin_huge_valf, "f", "nc") BUILTIN(__builtin_huge_vall, "Ld", "nc") +BUILTIN(__builtin_huge_valf16, "x", "nc") BUILTIN(__builtin_huge_valf128, "LLd", "nc") BUILTIN(__builtin_inf , "d" , "nc") BUILTIN(__builtin_inff , "f" , "nc") BUILTIN(__builtin_infl , "Ld" , "nc") +BUILTIN(__builtin_inff16 , "x" , "nc") BUILTIN(__builtin_inff128 , "LLd" , "nc") BUILTIN(__builtin_labs , "LiLi" , "Fnc") BUILTIN(__builtin_llabs, "LLiLLi", "Fnc") @@ -160,10 +162,12 @@ BUILTIN(__builtin_modff128, "LLdLLdLLd*", "Fn") BUILTIN(__builtin_nan, "dcC*" , "FnU") BUILTIN(__builtin_nanf, "fcC*" , "FnU") BUILTIN(__builtin_nanl, "LdcC*", "FnU") +BUILTIN(__builtin_nanf16, "xcC*", "FnU") BUILTIN(__builtin_nanf128, "LLdcC*", "FnU") BUILTIN(__builtin_nans, "dcC*" , "FnU") BUILTIN(__builtin_nansf, "fcC*" , "FnU") BUILTIN(__builtin_nansl, "LdcC*", "FnU") +BUILTIN(__builtin_nansf16, "xcC*", "FnU") BUILTIN(__builtin_nansf128, "LLdcC*", "FnU") BUILTIN(__builtin_powi , "ddi" , "Fnc") BUILTIN(__builtin_powif, "ffi" , "Fnc") diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index f679dba..896650e 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -13880,10 +13880,12 @@ bool FloatExprEvaluator::VisitCallExpr(const CallExpr *E) { case Builtin::BI__builtin_huge_val: case Builtin::BI__builtin_huge_valf: case Builtin::BI__builtin_huge_vall: + case Builtin::BI__builtin_huge_valf16: case Builtin::BI__builtin_huge_valf128: case Builtin::BI__builtin_inf: case Builtin::BI__builtin_inff: case Builtin::BI__builtin_infl: + case Builtin::BI__builtin_inff16: case Builtin::BI__builtin_inff128: { const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(E->getType()); @@ -13894,6 +13896,7 @@ bool FloatExprEvaluator::VisitCallExpr(const CallExpr *E) { case Builtin::BI__builtin_nans: case Builtin::BI__builtin_nansf: case Builtin::BI__builtin_nansl: + case Builtin::BI__builtin_nansf16: case Builtin::BI__builtin_nansf128: if (!TryEvaluateBuiltinNaN(Info.Ctx, E->getType(), E->getArg(0), true, Result)) @@ -13903,6 +13906,7 @@ bool FloatExprEvaluator::VisitCallExpr(const CallExpr *E) { case Builtin::BI__builtin_nan: case Builtin::BI__builtin_nanf: case Builtin::BI__builtin_nanl: + case Builtin::BI__builtin_nanf16: case Builtin::BI__builtin_nanf128: // If this is __builtin_nan() turn this into a nan, otherwise we // can't constant fold it. diff --git a/clang/test/CodeGen/builtin_Float16.c b/clang/test/CodeGen/builtin_Float16.c new file mode 100644 index 0000000..099d2ad --- /dev/null +++ b/clang/test/CodeGen/builtin_Float16.c @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -emit-llvm -o - -triple x86_64-linux-pc -target-feature +avx512fp16 %s | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -o - -triple spir-unknown-unknown %s | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -o - -triple armv7a--none-eabi %s | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -o - -triple aarch64-linux-gnu %s | FileCheck %s + +void test_float16_builtins(void) { + volatile _Float16 res; + + // CHECK: store volatile half 0xH7C00, ptr %res, align 2 + res = __builtin_huge_valf16(); + // CHECK: store volatile half 0xH7C00, ptr %res, align 2 + res = __builtin_inff16(); + // CHECK: store volatile half 0xH7E00, ptr %res, align 2 + res = __builtin_nanf16(""); + // CHECK: store volatile half 0xH7D00, ptr %res, align 2 + res = __builtin_nansf16(""); +} -- 2.7.4