Skip to content

Commit 3e4153c

Browse files
authored
[RISCV] Implement Builtins for XAndesBFHCvt extension. (#148804)
XAndesBFHCvt provides two builtins functions for converting between float and bf16. Users can use them to convert bf16 values loaded from memory to float, perform arithmetic operations, then convert them back to bf16 and store them to memory. The load/store and move operations for bf16 will be handled in a later patch.
1 parent d7f6660 commit 3e4153c

File tree

10 files changed

+157
-1
lines changed

10 files changed

+157
-1
lines changed

clang/include/clang/Basic/BuiltinsRISCV.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,3 +157,8 @@ def pause : RISCVBuiltin<"void()">;
157157
// XCV extensions.
158158
//===----------------------------------------------------------------------===//
159159
include "clang/Basic/BuiltinsRISCVXCV.td"
160+
161+
//===----------------------------------------------------------------------===//
162+
// XAndes extensions.
163+
//===----------------------------------------------------------------------===//
164+
include "clang/Basic/BuiltinsRISCVXAndes.td"
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//==- BuiltinsRISCVXAndes.td - RISC-V Andes Builtin database -----*- C++ -*-==//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file defines the Andes-specific builtin function database. Users of
10+
// this file must define the BUILTIN macro to make use of this information.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
class RISCVXAndesBuiltin<string prototype, string features = ""> : TargetBuiltin {
15+
let Spellings = ["__builtin_riscv_nds_" # NAME];
16+
let Prototype = prototype;
17+
let Features = features;
18+
}
19+
20+
let Attributes = [NoThrow, Const] in {
21+
//===----------------------------------------------------------------------===//
22+
// XAndesBFHCvt extension.
23+
//===----------------------------------------------------------------------===//
24+
25+
def fcvt_s_bf16 : RISCVXAndesBuiltin<"float(__bf16)", "xandesbfhcvt">;
26+
def fcvt_bf16_s : RISCVXAndesBuiltin<"__bf16(float)", "xandesbfhcvt">;
27+
} // Attributes = [NoThrow, Const]

clang/lib/CodeGen/TargetBuiltins/RISCV.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,12 @@ Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned BuiltinID,
413413
ID = Intrinsic::riscv_cv_alu_subuRN;
414414
break;
415415

416+
// XAndesBFHCvt
417+
case RISCV::BI__builtin_riscv_nds_fcvt_s_bf16:
418+
return Builder.CreateFPExt(Ops[0], FloatTy);
419+
case RISCV::BI__builtin_riscv_nds_fcvt_bf16_s:
420+
return Builder.CreateFPTrunc(Ops[0], BFloatTy);
421+
416422
// Vector builtins are handled from here.
417423
#include "clang/Basic/riscv_vector_builtin_cg.inc"
418424

clang/lib/Headers/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ set(riscv_files
127127
riscv_bitmanip.h
128128
riscv_corev_alu.h
129129
riscv_crypto.h
130+
riscv_nds.h
130131
riscv_ntlh.h
131132
sifive_vector.h
132133
andes_vector.h

clang/lib/Headers/riscv_nds.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*===---- riscv_nds.h - Andes intrinsics -----------------------------------===
2+
*
3+
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
* See https://llvm.org/LICENSE.txt for license information.
5+
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
*
7+
*===-----------------------------------------------------------------------===
8+
*/
9+
10+
#ifndef __RISCV_NDS_H
11+
#define __RISCV_NDS_H
12+
13+
#if defined(__cplusplus)
14+
extern "C" {
15+
#endif
16+
17+
#if defined(__riscv_xandesbfhcvt)
18+
19+
#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__))
20+
21+
static __inline__ float __DEFAULT_FN_ATTRS __riscv_nds_fcvt_s_bf16(__bf16 bf) {
22+
return __builtin_riscv_nds_fcvt_s_bf16(bf);
23+
}
24+
25+
static __inline__ __bf16 __DEFAULT_FN_ATTRS __riscv_nds_fcvt_bf16_s(float sf) {
26+
return __builtin_riscv_nds_fcvt_bf16_s(sf);
27+
}
28+
29+
#endif // defined(__riscv_xandesbfhcvt)
30+
31+
#if defined(__cplusplus)
32+
}
33+
#endif
34+
35+
#endif // define __RISCV_NDS_H
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
2+
// RUN: %clang_cc1 -triple riscv32 -target-feature +xandesbfhcvt -emit-llvm %s -o - \
3+
// RUN: -disable-O0-optnone | opt -S -passes=mem2reg | FileCheck %s
4+
// RUN: %clang_cc1 -triple riscv64 -target-feature +xandesbfhcvt -emit-llvm %s -o - \
5+
// RUN: -disable-O0-optnone | opt -S -passes=mem2reg | FileCheck %s
6+
7+
#include <riscv_nds.h>
8+
9+
// CHECK-LABEL: @test_fcvt_s_bf16(
10+
// CHECK-NEXT: entry:
11+
// CHECK-NEXT: [[TMP0:%.*]] = fpext bfloat [[BF:%.*]] to float
12+
// CHECK-NEXT: ret float [[TMP0]]
13+
//
14+
float test_fcvt_s_bf16(__bf16 bf) {
15+
return __riscv_nds_fcvt_s_bf16(bf);
16+
}
17+
18+
// CHECK-LABEL: @test_fcvt_bf16_s(
19+
// CHECK-NEXT: entry:
20+
// CHECK-NEXT: [[TMP0:%.*]] = fptrunc float [[SF:%.*]] to bfloat
21+
// CHECK-NEXT: ret bfloat [[TMP0]]
22+
//
23+
__bf16 test_fcvt_bf16_s(float sf) {
24+
return __riscv_nds_fcvt_bf16_s(sf);
25+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
2+
// RUN: %clang_cc1 -triple riscv32 -target-feature +xandesbfhcvt -emit-llvm %s -o - \
3+
// RUN: -disable-O0-optnone | opt -S -passes=mem2reg | FileCheck %s
4+
// RUN: %clang_cc1 -triple riscv64 -target-feature +xandesbfhcvt -emit-llvm %s -o - \
5+
// RUN: -disable-O0-optnone | opt -S -passes=mem2reg | FileCheck %s
6+
7+
// CHECK-LABEL: @test_fcvt_s_bf16(
8+
// CHECK-NEXT: entry:
9+
// CHECK-NEXT: [[TMP0:%.*]] = fpext bfloat [[BF:%.*]] to float
10+
// CHECK-NEXT: ret float [[TMP0]]
11+
//
12+
float test_fcvt_s_bf16(__bf16 bf) {
13+
return __builtin_riscv_nds_fcvt_s_bf16(bf);
14+
}
15+
16+
// CHECK-LABEL: @test_fcvt_bf16_s(
17+
// CHECK-NEXT: entry:
18+
// CHECK-NEXT: [[TMP0:%.*]] = fptrunc float [[SF:%.*]] to bfloat
19+
// CHECK-NEXT: ret bfloat [[TMP0]]
20+
//
21+
__bf16 test_fcvt_bf16_s(float sf) {
22+
return __builtin_riscv_nds_fcvt_bf16_s(sf);
23+
}

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
128128

129129
if (Subtarget.hasStdExtZfhmin())
130130
addRegisterClass(MVT::f16, &RISCV::FPR16RegClass);
131-
if (Subtarget.hasStdExtZfbfmin())
131+
if (Subtarget.hasStdExtZfbfmin() || Subtarget.hasVendorXAndesBFHCvt())
132132
addRegisterClass(MVT::bf16, &RISCV::FPR16RegClass);
133133
if (Subtarget.hasStdExtF())
134134
addRegisterClass(MVT::f32, &RISCV::FPR32RegClass);

llvm/lib/Target/RISCV/RISCVInstrInfoXAndes.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -767,6 +767,13 @@ def : Sh2AddPat<NDS_LEA_W_ZE>;
767767
def : Sh3AddPat<NDS_LEA_D_ZE>;
768768
} // Predicates = [HasVendorXAndesPerf, IsRV64]
769769

770+
let Predicates = [HasVendorXAndesBFHCvt] in {
771+
def : Pat<(fpextend (bf16 FPR16:$rs)),
772+
(NDS_FCVT_S_BF16 (bf16 FPR16:$rs))>;
773+
def : Pat<(bf16 (fpround FPR32:$rs)),
774+
(NDS_FCVT_BF16_S FPR32:$rs)>;
775+
} // Predicates = [HasVendorXAndesBFHCvt]
776+
770777
let Predicates = [HasVendorXAndesVBFHCvt] in {
771778
defm PseudoNDS_VFWCVT_S_BF16 : VPseudoVWCVT_S_BF16;
772779
defm PseudoNDS_VFNCVT_BF16_S : VPseudoVNCVT_BF16_S;
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc -mtriple=riscv32 -mattr=+xandesbfhcvt -target-abi ilp32f \
3+
; RUN: -verify-machineinstrs < %s | FileCheck %s
4+
; RUN: llc -mtriple=riscv64 -mattr=+xandesbfhcvt -target-abi lp64f \
5+
; RUN: -verify-machineinstrs < %s | FileCheck %s
6+
7+
declare bfloat @llvm.riscv.nds.fcvt.bf16.s(float)
8+
9+
define float @fcvt_s_bf16(bfloat %a) nounwind {
10+
; CHECK-LABEL: fcvt_s_bf16:
11+
; CHECK: # %bb.0:
12+
; CHECK-NEXT: nds.fcvt.s.bf16 fa0, fa0
13+
; CHECK-NEXT: ret
14+
%1 = fpext bfloat %a to float
15+
ret float %1
16+
}
17+
18+
declare float @llvm.riscv.nds.fcvt.s.bf16(bfloat)
19+
20+
define bfloat @fcvt_bf16_s(float %a) nounwind {
21+
; CHECK-LABEL: fcvt_bf16_s:
22+
; CHECK: # %bb.0:
23+
; CHECK-NEXT: nds.fcvt.bf16.s fa0, fa0
24+
; CHECK-NEXT: ret
25+
%1 = fptrunc float %a to bfloat
26+
ret bfloat %1
27+
}

0 commit comments

Comments
 (0)