diff --git a/clang/include/clang/Basic/BuiltinsRISCV.td b/clang/include/clang/Basic/BuiltinsRISCV.td index b2cd5648e008f..5927eaf80d57a 100644 --- a/clang/include/clang/Basic/BuiltinsRISCV.td +++ b/clang/include/clang/Basic/BuiltinsRISCV.td @@ -157,3 +157,8 @@ def pause : RISCVBuiltin<"void()">; // XCV extensions. //===----------------------------------------------------------------------===// include "clang/Basic/BuiltinsRISCVXCV.td" + +//===----------------------------------------------------------------------===// +// XAndes extensions. +//===----------------------------------------------------------------------===// +include "clang/Basic/BuiltinsRISCVXAndes.td" diff --git a/clang/include/clang/Basic/BuiltinsRISCVXAndes.td b/clang/include/clang/Basic/BuiltinsRISCVXAndes.td new file mode 100644 index 0000000000000..ea9a7166bc6e8 --- /dev/null +++ b/clang/include/clang/Basic/BuiltinsRISCVXAndes.td @@ -0,0 +1,27 @@ +//==- BuiltinsRISCVXAndes.td - RISC-V Andes Builtin database -----*- C++ -*-==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines the Andes-specific builtin function database. Users of +// this file must define the BUILTIN macro to make use of this information. +// +//===----------------------------------------------------------------------===// + +class RISCVXAndesBuiltin : TargetBuiltin { + let Spellings = ["__builtin_riscv_nds_" # NAME]; + let Prototype = prototype; + let Features = features; +} + +let Attributes = [NoThrow, Const] in { +//===----------------------------------------------------------------------===// +// XAndesBFHCvt extension. +//===----------------------------------------------------------------------===// + +def fcvt_s_bf16 : RISCVXAndesBuiltin<"float(__bf16)", "xandesbfhcvt">; +def fcvt_bf16_s : RISCVXAndesBuiltin<"__bf16(float)", "xandesbfhcvt">; +} // Attributes = [NoThrow, Const] diff --git a/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp b/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp index 89e3f6f203df3..b08a0588c5ac1 100644 --- a/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp +++ b/clang/lib/CodeGen/TargetBuiltins/RISCV.cpp @@ -413,6 +413,12 @@ Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned BuiltinID, ID = Intrinsic::riscv_cv_alu_subuRN; break; + // XAndesBFHCvt + case RISCV::BI__builtin_riscv_nds_fcvt_s_bf16: + return Builder.CreateFPExt(Ops[0], FloatTy); + case RISCV::BI__builtin_riscv_nds_fcvt_bf16_s: + return Builder.CreateFPTrunc(Ops[0], BFloatTy); + // Vector builtins are handled from here. #include "clang/Basic/riscv_vector_builtin_cg.inc" diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt index c96d209c1fc0c..76ac8409e568f 100644 --- a/clang/lib/Headers/CMakeLists.txt +++ b/clang/lib/Headers/CMakeLists.txt @@ -127,6 +127,7 @@ set(riscv_files riscv_bitmanip.h riscv_corev_alu.h riscv_crypto.h + riscv_nds.h riscv_ntlh.h sifive_vector.h andes_vector.h diff --git a/clang/lib/Headers/riscv_nds.h b/clang/lib/Headers/riscv_nds.h new file mode 100644 index 0000000000000..5ccef00e332ed --- /dev/null +++ b/clang/lib/Headers/riscv_nds.h @@ -0,0 +1,35 @@ +/*===---- riscv_nds.h - Andes intrinsics -----------------------------------=== + * + * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + * See https://llvm.org/LICENSE.txt for license information. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __RISCV_NDS_H +#define __RISCV_NDS_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#if defined(__riscv_xandesbfhcvt) + +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__)) + +static __inline__ float __DEFAULT_FN_ATTRS __riscv_nds_fcvt_s_bf16(__bf16 bf) { + return __builtin_riscv_nds_fcvt_s_bf16(bf); +} + +static __inline__ __bf16 __DEFAULT_FN_ATTRS __riscv_nds_fcvt_bf16_s(float sf) { + return __builtin_riscv_nds_fcvt_bf16_s(sf); +} + +#endif // defined(__riscv_xandesbfhcvt) + +#if defined(__cplusplus) +} +#endif + +#endif // define __RISCV_NDS_H diff --git a/clang/test/CodeGen/RISCV/riscv-xandesbfhcvt-c-api.c b/clang/test/CodeGen/RISCV/riscv-xandesbfhcvt-c-api.c new file mode 100644 index 0000000000000..9feeafe42c79f --- /dev/null +++ b/clang/test/CodeGen/RISCV/riscv-xandesbfhcvt-c-api.c @@ -0,0 +1,25 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// RUN: %clang_cc1 -triple riscv32 -target-feature +xandesbfhcvt -emit-llvm %s -o - \ +// RUN: -disable-O0-optnone | opt -S -passes=mem2reg | FileCheck %s +// RUN: %clang_cc1 -triple riscv64 -target-feature +xandesbfhcvt -emit-llvm %s -o - \ +// RUN: -disable-O0-optnone | opt -S -passes=mem2reg | FileCheck %s + +#include + +// CHECK-LABEL: @test_fcvt_s_bf16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = fpext bfloat [[BF:%.*]] to float +// CHECK-NEXT: ret float [[TMP0]] +// +float test_fcvt_s_bf16(__bf16 bf) { + return __riscv_nds_fcvt_s_bf16(bf); +} + +// CHECK-LABEL: @test_fcvt_bf16_s( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = fptrunc float [[SF:%.*]] to bfloat +// CHECK-NEXT: ret bfloat [[TMP0]] +// +__bf16 test_fcvt_bf16_s(float sf) { + return __riscv_nds_fcvt_bf16_s(sf); +} diff --git a/clang/test/CodeGen/RISCV/riscv-xandesbfhcvt.c b/clang/test/CodeGen/RISCV/riscv-xandesbfhcvt.c new file mode 100644 index 0000000000000..2f5e754d38704 --- /dev/null +++ b/clang/test/CodeGen/RISCV/riscv-xandesbfhcvt.c @@ -0,0 +1,23 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// RUN: %clang_cc1 -triple riscv32 -target-feature +xandesbfhcvt -emit-llvm %s -o - \ +// RUN: -disable-O0-optnone | opt -S -passes=mem2reg | FileCheck %s +// RUN: %clang_cc1 -triple riscv64 -target-feature +xandesbfhcvt -emit-llvm %s -o - \ +// RUN: -disable-O0-optnone | opt -S -passes=mem2reg | FileCheck %s + +// CHECK-LABEL: @test_fcvt_s_bf16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = fpext bfloat [[BF:%.*]] to float +// CHECK-NEXT: ret float [[TMP0]] +// +float test_fcvt_s_bf16(__bf16 bf) { + return __builtin_riscv_nds_fcvt_s_bf16(bf); +} + +// CHECK-LABEL: @test_fcvt_bf16_s( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = fptrunc float [[SF:%.*]] to bfloat +// CHECK-NEXT: ret bfloat [[TMP0]] +// +__bf16 test_fcvt_bf16_s(float sf) { + return __builtin_riscv_nds_fcvt_bf16_s(sf); +} diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 359e529df46f3..45fcb27e2f88e 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -129,7 +129,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM, if (Subtarget.hasStdExtZfhmin()) addRegisterClass(MVT::f16, &RISCV::FPR16RegClass); - if (Subtarget.hasStdExtZfbfmin()) + if (Subtarget.hasStdExtZfbfmin() || Subtarget.hasVendorXAndesBFHCvt()) addRegisterClass(MVT::bf16, &RISCV::FPR16RegClass); if (Subtarget.hasStdExtF()) addRegisterClass(MVT::f32, &RISCV::FPR32RegClass); diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td index 38992b6c05d08..fb4959db75c71 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td @@ -767,6 +767,13 @@ def : Sh2AddPat; def : Sh3AddPat; } // Predicates = [HasVendorXAndesPerf, IsRV64] +let Predicates = [HasVendorXAndesBFHCvt] in { +def : Pat<(fpextend (bf16 FPR16:$rs)), + (NDS_FCVT_S_BF16 (bf16 FPR16:$rs))>; +def : Pat<(bf16 (fpround FPR32:$rs)), + (NDS_FCVT_BF16_S FPR32:$rs)>; +} // Predicates = [HasVendorXAndesBFHCvt] + let Predicates = [HasVendorXAndesVBFHCvt] in { defm PseudoNDS_VFWCVT_S_BF16 : VPseudoVWCVT_S_BF16; defm PseudoNDS_VFNCVT_BF16_S : VPseudoVNCVT_BF16_S; diff --git a/llvm/test/CodeGen/RISCV/xandesbfhcvt.ll b/llvm/test/CodeGen/RISCV/xandesbfhcvt.ll new file mode 100644 index 0000000000000..e4524394b9991 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/xandesbfhcvt.ll @@ -0,0 +1,27 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=riscv32 -mattr=+xandesbfhcvt -target-abi ilp32f \ +; RUN: -verify-machineinstrs < %s | FileCheck %s +; RUN: llc -mtriple=riscv64 -mattr=+xandesbfhcvt -target-abi lp64f \ +; RUN: -verify-machineinstrs < %s | FileCheck %s + +declare bfloat @llvm.riscv.nds.fcvt.bf16.s(float) + +define float @fcvt_s_bf16(bfloat %a) nounwind { +; CHECK-LABEL: fcvt_s_bf16: +; CHECK: # %bb.0: +; CHECK-NEXT: nds.fcvt.s.bf16 fa0, fa0 +; CHECK-NEXT: ret + %1 = fpext bfloat %a to float + ret float %1 +} + +declare float @llvm.riscv.nds.fcvt.s.bf16(bfloat) + +define bfloat @fcvt_bf16_s(float %a) nounwind { +; CHECK-LABEL: fcvt_bf16_s: +; CHECK: # %bb.0: +; CHECK-NEXT: nds.fcvt.bf16.s fa0, fa0 +; CHECK-NEXT: ret + %1 = fptrunc float %a to bfloat + ret bfloat %1 +}