Skip to content

Commit 0c9c48c

Browse files
committed
[RISCV] Implement Builtins for XAndesBFHCvt extension.
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 27b3b4a commit 0c9c48c

File tree

11 files changed

+168
-1
lines changed

11 files changed

+168
-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: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,14 @@ 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+
ID = Intrinsic::riscv_nds_fcvt_s_bf16;
419+
break;
420+
case RISCV::BI__builtin_riscv_nds_fcvt_bf16_s:
421+
ID = Intrinsic::riscv_nds_fcvt_bf16_s;
422+
break;
423+
416424
// Vector builtins are handled from here.
417425
#include "clang/Basic/riscv_vector_builtin_cg.inc"
418426

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:%.*]] = call float @llvm.riscv.nds.fcvt.s.bf16(bfloat [[BF:%.*]])
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:%.*]] = call bfloat @llvm.riscv.nds.fcvt.bf16.s(float [[SF:%.*]])
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:%.*]] = call float @llvm.riscv.nds.fcvt.s.bf16(bfloat [[BF:%.*]])
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:%.*]] = call bfloat @llvm.riscv.nds.fcvt.bf16.s(float [[SF:%.*]])
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/include/llvm/IR/IntrinsicsRISCVXAndes.td

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,15 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
let TargetPrefix = "riscv" in {
14+
// Andes Scalar BFloat16 Conversion Extension
15+
def int_riscv_nds_fcvt_s_bf16
16+
: DefaultAttrsIntrinsic<[llvm_float_ty], [llvm_bfloat_ty],
17+
[IntrNoMem, IntrSpeculatable]>;
18+
19+
def int_riscv_nds_fcvt_bf16_s
20+
: DefaultAttrsIntrinsic<[llvm_bfloat_ty], [llvm_float_ty],
21+
[IntrNoMem, IntrSpeculatable]>;
22+
1423
// Andes Vector BFloat16 Conversion Extension
1524
def int_riscv_nds_vfwcvt_s_bf16 : RISCVConversionUnMasked;
1625
def int_riscv_nds_vfncvt_bf16_s : RISCVConversionUnMaskedRoundingMode;

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

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

130130
if (Subtarget.hasStdExtZfhmin())
131131
addRegisterClass(MVT::f16, &RISCV::FPR16RegClass);
132-
if (Subtarget.hasStdExtZfbfmin())
132+
if (Subtarget.hasStdExtZfbfmin() || Subtarget.hasVendorXAndesBFHCvt())
133133
addRegisterClass(MVT::bf16, &RISCV::FPR16RegClass);
134134
if (Subtarget.hasStdExtF())
135135
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<(int_riscv_nds_fcvt_s_bf16 (bf16 FPR16:$rs)),
772+
(NDS_FCVT_S_BF16 (bf16 FPR16:$rs))>;
773+
def : Pat<(bf16 (int_riscv_nds_fcvt_bf16_s 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;

0 commit comments

Comments
 (0)