Skip to content

Commit fd4d8da

Browse files
[CLANG]Add Neon vectors for fpm8_t
This patch adds these new vector sizes for neon: fpm8x16_t and fpm8x8_t According to the ARM ACLE PR#323[1]. [1] ARM-software/acle#323
1 parent 1fc6bf3 commit fd4d8da

File tree

12 files changed

+183
-17
lines changed

12 files changed

+183
-17
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//===--- arm_fpm8.td - ARM FPM8 compiler interface ------------------------===//
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 TableGen definitions from which the ARM BF16 header
10+
// file will be generated.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
include "arm_neon_incl.td"

clang/include/clang/Basic/arm_neon_incl.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ def OP_UNAVAILABLE : Operation {
216216
// h: half-float
217217
// d: double
218218
// b: bfloat16
219+
// m: fpm8
219220
//
220221
// Typespec modifiers
221222
// ------------------
@@ -240,6 +241,7 @@ def OP_UNAVAILABLE : Operation {
240241
// B: change to BFloat16
241242
// P: change to polynomial category.
242243
// p: change polynomial to equivalent integer category. Otherwise nop.
244+
// M: change to Fpm8.
243245
//
244246
// >: double element width (vector size unchanged).
245247
// <: half element width (vector size unchanged).

clang/lib/Basic/Targets/AArch64.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,9 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
543543
Builder.defineMacro("__ARM_FEATURE_BF16_SCALAR_ARITHMETIC", "1");
544544
}
545545

546+
if (HasFpm8) {
547+
Builder.defineMacro("__ARM_FEATURE_FP8", "1");
548+
}
546549
if ((FPU & SveMode) && HasBFloat16) {
547550
Builder.defineMacro("__ARM_FEATURE_SVE_BF16", "1");
548551
}

clang/lib/Basic/Targets/ARM.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,8 @@ bool ARMTargetInfo::hasBFloat16Type() const {
661661
return HasBFloat16 || (FPU && !SoftFloat);
662662
}
663663

664+
bool ARMTargetInfo::hasFpm8Type() const { return true; }
665+
664666
bool ARMTargetInfo::isValidCPUName(StringRef Name) const {
665667
return Name == "generic" ||
666668
llvm::ARM::parseCPUArch(Name) != llvm::ARM::ArchKind::INVALID;

clang/lib/Basic/Targets/ARM.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,8 @@ class LLVM_LIBRARY_VISIBILITY ARMTargetInfo : public TargetInfo {
176176

177177
bool hasBFloat16Type() const override;
178178

179+
bool hasFpm8Type() const override;
180+
179181
bool isValidCPUName(StringRef Name) const override;
180182
void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
181183

clang/lib/Headers/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,8 @@ if(ARM IN_LIST LLVM_TARGETS_TO_BUILD OR AArch64 IN_LIST LLVM_TARGETS_TO_BUILD)
391391
clang_generate_header(-gen-arm-sme-header arm_sme.td arm_sme.h)
392392
# Generate arm_bf16.h
393393
clang_generate_header(-gen-arm-bf16 arm_bf16.td arm_bf16.h)
394+
# Generate arm_fpm8.h
395+
clang_generate_header(-gen-arm-fpm8 arm_fpm8.td arm_fpm8.h)
394396
# Generate arm_mve.h
395397
clang_generate_header(-gen-arm-mve-header arm_mve.td arm_mve.h)
396398
# Generate arm_cde.h
@@ -414,6 +416,7 @@ if(ARM IN_LIST LLVM_TARGETS_TO_BUILD OR AArch64 IN_LIST LLVM_TARGETS_TO_BUILD)
414416
"${CMAKE_CURRENT_BINARY_DIR}/arm_sme.h"
415417
"${CMAKE_CURRENT_BINARY_DIR}/arm_bf16.h"
416418
"${CMAKE_CURRENT_BINARY_DIR}/arm_vector_types.h"
419+
"${CMAKE_CURRENT_BINARY_DIR}/arm_fpm8.h"
417420
)
418421
endif()
419422
if(RISCV IN_LIST LLVM_TARGETS_TO_BUILD)

clang/lib/Sema/SemaExpr.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10215,6 +10215,11 @@ QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS,
1021510215
const VectorType *RHSVecType = RHSType->getAs<VectorType>();
1021610216
assert(LHSVecType || RHSVecType);
1021710217

10218+
// Any operation with Fpm8 type is only possible with C intrinsics
10219+
if ((LHSVecType && LHSVecType->getElementType()->isFpm8Type()) ||
10220+
(RHSVecType && RHSVecType->getElementType()->isFpm8Type()))
10221+
return InvalidOperands(Loc, LHS, RHS);
10222+
1021810223
// AltiVec-style "vector bool op vector bool" combinations are allowed
1021910224
// for some operators but not others.
1022010225
if (!AllowBothBool && LHSVecType &&

clang/test/CodeGen/arm-fpm8.c

Lines changed: 71 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,34 @@
1-
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 4
2-
// RUN: %clang_cc1 -emit-llvm -triple aarch64-arm-none-eabi -target-feature -fp8 -o - %s | FileCheck %s
1+
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5
2+
// RUN: %clang_cc1 -emit-llvm -triple aarch64-arm-none-eabi -target-feature -fp8 -target-feature +neon -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-C
3+
// RUN: %clang_cc1 -emit-llvm -triple aarch64-arm-none-eabi -target-feature -fp8 -target-feature +neon -o - -x c++ %s | FileCheck %s --check-prefixes=CHECK,CHECK-CXX
34

45
// REQUIRES: aarch64-registered-target
56

6-
// CHECK-LABEL: define dso_local i8 @func1n(
7-
// CHECK-SAME: i8 noundef [[FPM8:%.*]]) #[[ATTR0:[0-9]+]] {
8-
// CHECK-NEXT: entry:
9-
// CHECK-NEXT: [[FPM8_ADDR:%.*]] = alloca i8, align 1
10-
// CHECK-NEXT: [[F1N:%.*]] = alloca [10 x i8], align 1
11-
// CHECK-NEXT: store i8 [[FPM8]], ptr [[FPM8_ADDR]], align 1
12-
// CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[FPM8_ADDR]], align 1
13-
// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x i8], ptr [[F1N]], i64 0, i64 2
14-
// CHECK-NEXT: store i8 [[TMP0]], ptr [[ARRAYIDX]], align 1
15-
// CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [10 x i8], ptr [[F1N]], i64 0, i64 2
16-
// CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1
17-
// CHECK-NEXT: ret i8 [[TMP1]]
7+
// CHECK-C-LABEL: define dso_local i8 @func1n(
8+
// CHECK-C-SAME: i8 noundef [[FPM8:%.*]]) #[[ATTR0:[0-9]+]] {
9+
// CHECK-C-NEXT: [[ENTRY:.*:]]
10+
// CHECK-C-NEXT: [[FPM8_ADDR:%.*]] = alloca i8, align 1
11+
// CHECK-C-NEXT: [[F1N:%.*]] = alloca [10 x i8], align 1
12+
// CHECK-C-NEXT: store i8 [[FPM8]], ptr [[FPM8_ADDR]], align 1
13+
// CHECK-C-NEXT: [[TMP0:%.*]] = load i8, ptr [[FPM8_ADDR]], align 1
14+
// CHECK-C-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x i8], ptr [[F1N]], i64 0, i64 2
15+
// CHECK-C-NEXT: store i8 [[TMP0]], ptr [[ARRAYIDX]], align 1
16+
// CHECK-C-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [10 x i8], ptr [[F1N]], i64 0, i64 2
17+
// CHECK-C-NEXT: [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1
18+
// CHECK-C-NEXT: ret i8 [[TMP1]]
19+
//
20+
// CHECK-CXX-LABEL: define dso_local noundef i8 @_Z6func1nw(
21+
// CHECK-CXX-SAME: i8 noundef [[FPM8:%.*]]) #[[ATTR0:[0-9]+]] {
22+
// CHECK-CXX-NEXT: [[ENTRY:.*:]]
23+
// CHECK-CXX-NEXT: [[FPM8_ADDR:%.*]] = alloca i8, align 1
24+
// CHECK-CXX-NEXT: [[F1N:%.*]] = alloca [10 x i8], align 1
25+
// CHECK-CXX-NEXT: store i8 [[FPM8]], ptr [[FPM8_ADDR]], align 1
26+
// CHECK-CXX-NEXT: [[TMP0:%.*]] = load i8, ptr [[FPM8_ADDR]], align 1
27+
// CHECK-CXX-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x i8], ptr [[F1N]], i64 0, i64 2
28+
// CHECK-CXX-NEXT: store i8 [[TMP0]], ptr [[ARRAYIDX]], align 1
29+
// CHECK-CXX-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [10 x i8], ptr [[F1N]], i64 0, i64 2
30+
// CHECK-CXX-NEXT: [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1
31+
// CHECK-CXX-NEXT: ret i8 [[TMP1]]
1832
//
1933
__fpm8 func1n(__fpm8 fpm8) {
2034
__fpm8 f1n[10];
@@ -23,4 +37,47 @@ __fpm8 func1n(__fpm8 fpm8) {
2337
}
2438

2539

40+
#include <arm_neon.h>
41+
42+
// CHECK-C-LABEL: define dso_local <16 x i8> @test_ret_fpm8x16_t(
43+
// CHECK-C-SAME: <16 x i8> noundef [[V:%.*]]) #[[ATTR0]] {
44+
// CHECK-C-NEXT: [[ENTRY:.*:]]
45+
// CHECK-C-NEXT: [[V_ADDR:%.*]] = alloca <16 x i8>, align 16
46+
// CHECK-C-NEXT: store <16 x i8> [[V]], ptr [[V_ADDR]], align 16
47+
// CHECK-C-NEXT: [[TMP0:%.*]] = load <16 x i8>, ptr [[V_ADDR]], align 16
48+
// CHECK-C-NEXT: ret <16 x i8> [[TMP0]]
49+
//
50+
// CHECK-CXX-LABEL: define dso_local noundef <16 x i8> @_Z18test_ret_fpm8x16_t13__Fpm8_tx16_t(
51+
// CHECK-CXX-SAME: <16 x i8> noundef [[V:%.*]]) #[[ATTR0]] {
52+
// CHECK-CXX-NEXT: [[ENTRY:.*:]]
53+
// CHECK-CXX-NEXT: [[V_ADDR:%.*]] = alloca <16 x i8>, align 16
54+
// CHECK-CXX-NEXT: store <16 x i8> [[V]], ptr [[V_ADDR]], align 16
55+
// CHECK-CXX-NEXT: [[TMP0:%.*]] = load <16 x i8>, ptr [[V_ADDR]], align 16
56+
// CHECK-CXX-NEXT: ret <16 x i8> [[TMP0]]
57+
//
58+
fpm8x16_t test_ret_fpm8x16_t(fpm8x16_t v) {
59+
return v;
60+
}
61+
62+
// CHECK-C-LABEL: define dso_local <8 x i8> @test_ret_fpm8x8_t(
63+
// CHECK-C-SAME: <8 x i8> noundef [[V:%.*]]) #[[ATTR0]] {
64+
// CHECK-C-NEXT: [[ENTRY:.*:]]
65+
// CHECK-C-NEXT: [[V_ADDR:%.*]] = alloca <8 x i8>, align 8
66+
// CHECK-C-NEXT: store <8 x i8> [[V]], ptr [[V_ADDR]], align 8
67+
// CHECK-C-NEXT: [[TMP0:%.*]] = load <8 x i8>, ptr [[V_ADDR]], align 8
68+
// CHECK-C-NEXT: ret <8 x i8> [[TMP0]]
69+
//
70+
// CHECK-CXX-LABEL: define dso_local noundef <8 x i8> @_Z17test_ret_fpm8x8_t12__Fpm8_tx8_t(
71+
// CHECK-CXX-SAME: <8 x i8> noundef [[V:%.*]]) #[[ATTR0]] {
72+
// CHECK-CXX-NEXT: [[ENTRY:.*:]]
73+
// CHECK-CXX-NEXT: [[V_ADDR:%.*]] = alloca <8 x i8>, align 8
74+
// CHECK-CXX-NEXT: store <8 x i8> [[V]], ptr [[V_ADDR]], align 8
75+
// CHECK-CXX-NEXT: [[TMP0:%.*]] = load <8 x i8>, ptr [[V_ADDR]], align 8
76+
// CHECK-CXX-NEXT: ret <8 x i8> [[TMP0]]
77+
//
78+
fpm8x8_t test_ret_fpm8x8_t(fpm8x8_t v) {
79+
return v;
80+
}
2681

82+
//// NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
83+
// CHECK: {{.*}}

clang/test/Sema/arm-fpm8.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
// RUN: %clang_cc1 -fsyntax-only -verify=scalar -triple aarch64-arm-none-eabi -target-feature -fp8 %s
1+
// RUN: %clang_cc1 -fsyntax-only -verify=scalar,neon -triple aarch64-arm-none-eabi \
2+
// RUN: -target-feature -fp8 -target-feature +neon %s
23

34
// REQUIRES: aarch64-registered-target
45
__fpm8 test_static_cast_from_char(char in) {
@@ -33,3 +34,20 @@ void test(bool b) {
3334
fpm8 + (b ? u8 : fpm8); // scalar-error {{incompatible operand types ('char' and '__fpm8')}}
3435
}
3536

37+
#include <arm_neon.h>
38+
39+
void test_vector(fpm8x8_t a, fpm8x8_t b, uint8x8_t c) {
40+
a + b; // neon-error {{invalid operands to binary expression ('fpm8x8_t' (vector of 8 'fpm8_t' values) and 'fpm8x8_t')}}
41+
a - b; // neon-error {{invalid operands to binary expression ('fpm8x8_t' (vector of 8 'fpm8_t' values) and 'fpm8x8_t')}}
42+
a * b; // neon-error {{invalid operands to binary expression ('fpm8x8_t' (vector of 8 'fpm8_t' values) and 'fpm8x8_t')}}
43+
a / b; // neon-error {{invalid operands to binary expression ('fpm8x8_t' (vector of 8 'fpm8_t' values) and 'fpm8x8_t')}}
44+
45+
a + c; // neon-error {{invalid operands to binary expression ('fpm8x8_t' (vector of 8 'fpm8_t' values) and 'uint8x8_t' (vector of 8 'uint8_t' values))}}
46+
a - c; // neon-error {{invalid operands to binary expression ('fpm8x8_t' (vector of 8 'fpm8_t' values) and 'uint8x8_t' (vector of 8 'uint8_t' values))}}
47+
a * c; // neon-error {{invalid operands to binary expression ('fpm8x8_t' (vector of 8 'fpm8_t' values) and 'uint8x8_t' (vector of 8 'uint8_t' values))}}
48+
a / c; // neon-error {{invalid operands to binary expression ('fpm8x8_t' (vector of 8 'fpm8_t' values) and 'uint8x8_t' (vector of 8 'uint8_t' values))}}
49+
c + b; // neon-error {{invalid operands to binary expression ('uint8x8_t' (vector of 8 'uint8_t' values) and 'fpm8x8_t' (vector of 8 'fpm8_t' values))}}
50+
c - b; // neon-error {{invalid operands to binary expression ('uint8x8_t' (vector of 8 'uint8_t' values) and 'fpm8x8_t' (vector of 8 'fpm8_t' values))}}
51+
c * b; // neon-error {{invalid operands to binary expression ('uint8x8_t' (vector of 8 'uint8_t' values) and 'fpm8x8_t' (vector of 8 'fpm8_t' values))}}
52+
c / b; // neon-error {{invalid operands to binary expression ('uint8x8_t' (vector of 8 'uint8_t' values) and 'fpm8x8_t' (vector of 8 'fpm8_t' values))}}
53+
}

clang/utils/TableGen/NeonEmitter.cpp

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,8 @@ enum EltType {
9999
Float16,
100100
Float32,
101101
Float64,
102-
BFloat16
102+
BFloat16,
103+
Fpm8
103104
};
104105

105106
} // end namespace NeonTypeFlags
@@ -148,6 +149,7 @@ class Type {
148149
UInt,
149150
Poly,
150151
BFloat16,
152+
Fpm8,
151153
};
152154
TypeKind Kind;
153155
bool Immediate, Constant, Pointer;
@@ -201,6 +203,7 @@ class Type {
201203
bool isLong() const { return isInteger() && ElementBitwidth == 64; }
202204
bool isVoid() const { return Kind == Void; }
203205
bool isBFloat16() const { return Kind == BFloat16; }
206+
bool isFpm8() const { return Kind == Fpm8; }
204207
unsigned getNumElements() const { return Bitwidth / ElementBitwidth; }
205208
unsigned getSizeInBits() const { return Bitwidth; }
206209
unsigned getElementSizeInBits() const { return ElementBitwidth; }
@@ -595,6 +598,8 @@ class NeonEmitter {
595598
// Emit arm_bf16.h.inc
596599
void runBF16(raw_ostream &o);
597600

601+
void runFpm8(raw_ostream &o);
602+
598603
void runVectorTypes(raw_ostream &o);
599604

600605
// Emit all the __builtin prototypes used in arm_neon.h, arm_fp16.h and
@@ -622,6 +627,8 @@ std::string Type::str() const {
622627
S += "float";
623628
else if (isBFloat16())
624629
S += "bfloat";
630+
else if (isFpm8())
631+
S += "fpm";
625632
else
626633
S += "int";
627634

@@ -664,6 +671,8 @@ std::string Type::builtin_str() const {
664671
else if (isBFloat16()) {
665672
assert(ElementBitwidth == 16 && "BFloat16 can only be 16 bits");
666673
S += "y";
674+
} else if (isFpm8()) {
675+
S += "c";
667676
} else
668677
switch (ElementBitwidth) {
669678
case 16: S += "h"; break;
@@ -718,6 +727,11 @@ unsigned Type::getNeonEnum() const {
718727
Base = (unsigned)NeonTypeFlags::Float16 + (Addend - 1);
719728
}
720729

730+
if (isFpm8()) {
731+
assert(Addend == 1 && "Fpm8 is only 8 bit");
732+
Base = (unsigned)NeonTypeFlags::Fpm8;
733+
}
734+
721735
if (isBFloat16()) {
722736
assert(Addend == 1 && "BFloat16 is only 16 bit");
723737
Base = (unsigned)NeonTypeFlags::BFloat16;
@@ -744,6 +758,8 @@ Type Type::fromTypedefName(StringRef Name) {
744758
T.Kind = Poly;
745759
} else if (Name.consume_front("bfloat")) {
746760
T.Kind = BFloat16;
761+
} else if (Name.consume_front("fpm")) {
762+
T.Kind = Fpm8;
747763
} else {
748764
assert(Name.starts_with("int"));
749765
Name = Name.drop_front(3);
@@ -840,6 +856,10 @@ void Type::applyTypespec(bool &Quad) {
840856
if (isPoly())
841857
NumVectors = 0;
842858
break;
859+
case 'm':
860+
Kind = Fpm8;
861+
ElementBitwidth = 8;
862+
break;
843863
case 'b':
844864
Kind = BFloat16;
845865
ElementBitwidth = 16;
@@ -874,6 +894,10 @@ void Type::applyModifiers(StringRef Mods) {
874894
Kind = BFloat16;
875895
ElementBitwidth = 16;
876896
break;
897+
case 'M':
898+
Kind = Fpm8;
899+
ElementBitwidth = 8;
900+
break;
877901
case 'F':
878902
Kind = Float;
879903
break;
@@ -958,6 +982,9 @@ std::string Intrinsic::getInstTypeCode(Type T, ClassKind CK) const {
958982
if (T.isBFloat16())
959983
return "bf16";
960984

985+
if (T.isFpm8())
986+
return "fpm8";
987+
961988
if (T.isPoly())
962989
typeCode = 'p';
963990
else if (T.isInteger())
@@ -995,7 +1022,7 @@ std::string Intrinsic::getBuiltinTypeStr() {
9951022

9961023
Type RetT = getReturnType();
9971024
if ((LocalCK == ClassI || LocalCK == ClassW) && RetT.isScalar() &&
998-
!RetT.isFloating() && !RetT.isBFloat16())
1025+
!RetT.isFloating() && !RetT.isBFloat16() && !RetT.isFpm8())
9991026
RetT.makeInteger(RetT.getElementSizeInBits(), false);
10001027

10011028
// Since the return value must be one type, return a vector type of the
@@ -2378,6 +2405,8 @@ void NeonEmitter::run(raw_ostream &OS) {
23782405

23792406
OS << "#include <arm_bf16.h>\n";
23802407

2408+
OS << "#include <arm_fpm8.h>\n";
2409+
23812410
OS << "#include <arm_vector_types.h>\n";
23822411

23832412
// For now, signedness of polynomial types depends on target
@@ -2560,6 +2589,27 @@ void NeonEmitter::runFP16(raw_ostream &OS) {
25602589
OS << "#endif /* __ARM_FP16_H */\n";
25612590
}
25622591

2592+
void NeonEmitter::runFpm8(raw_ostream &OS) {
2593+
OS << "/*===---- arm_fpm8 - ARM vector type "
2594+
"------===\n"
2595+
" *\n"
2596+
" *\n"
2597+
" * Part of the LLVM Project, under the Apache License v2.0 with LLVM "
2598+
"Exceptions.\n"
2599+
" * See https://llvm.org/LICENSE.txt for license information.\n"
2600+
" * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception\n"
2601+
" *\n"
2602+
" *===-----------------------------------------------------------------"
2603+
"------===\n"
2604+
" */\n\n";
2605+
OS << "#ifndef __ARM_FPM8_H\n";
2606+
OS << "#define __ARM_FPM8_H\n\n";
2607+
OS << "typedef __fpm8 fpm8_t;\n";
2608+
2609+
emitNeonTypeDefs("mQm", OS);
2610+
OS << "#endif // __ARM_FPM8_H\n";
2611+
}
2612+
25632613
void NeonEmitter::runVectorTypes(raw_ostream &OS) {
25642614
OS << "/*===---- arm_vector_types - ARM vector type "
25652615
"------===\n"
@@ -2682,6 +2732,10 @@ void clang::EmitBF16(RecordKeeper &Records, raw_ostream &OS) {
26822732
NeonEmitter(Records).runBF16(OS);
26832733
}
26842734

2735+
void clang::EmitFpm8(RecordKeeper &Records, raw_ostream &OS) {
2736+
NeonEmitter(Records).runFpm8(OS);
2737+
}
2738+
26852739
void clang::EmitNeonSema(RecordKeeper &Records, raw_ostream &OS) {
26862740
NeonEmitter(Records).runHeader(OS);
26872741
}

0 commit comments

Comments
 (0)