Skip to content

Commit ed2d497

Browse files
[Clang][AArch64] Add fix vector types to header into SVE (#73258)
This patch is needed for the reduction instructions in sve2.1 It add a new header to sve with all the fixed vector types. The new types are only added if neon is not declared.
1 parent 41aa0d4 commit ed2d497

File tree

10 files changed

+206
-16
lines changed

10 files changed

+206
-16
lines changed

clang/lib/Headers/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,8 @@ if(ARM IN_LIST LLVM_TARGETS_TO_BUILD OR AArch64 IN_LIST LLVM_TARGETS_TO_BUILD)
387387
clang_generate_header(-gen-arm-mve-header arm_mve.td arm_mve.h)
388388
# Generate arm_cde.h
389389
clang_generate_header(-gen-arm-cde-header arm_cde.td arm_cde.h)
390+
# Generate arm_vector_types.h
391+
clang_generate_header(-gen-arm-vector-type arm_neon.td arm_vector_types.h)
390392

391393
# Add headers to target specific lists
392394
list(APPEND arm_common_generated_files
@@ -403,6 +405,7 @@ if(ARM IN_LIST LLVM_TARGETS_TO_BUILD OR AArch64 IN_LIST LLVM_TARGETS_TO_BUILD)
403405
"${CMAKE_CURRENT_BINARY_DIR}/arm_sve.h"
404406
"${CMAKE_CURRENT_BINARY_DIR}/arm_sme_draft_spec_subject_to_change.h"
405407
"${CMAKE_CURRENT_BINARY_DIR}/arm_bf16.h"
408+
"${CMAKE_CURRENT_BINARY_DIR}/arm_vector_types.h"
406409
)
407410
endif()
408411
if(RISCV IN_LIST LLVM_TARGETS_TO_BUILD)

clang/lib/Sema/SemaType.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8360,12 +8360,25 @@ static void HandleNeonVectorTypeAttr(QualType &CurType, const ParsedAttr &Attr,
83608360
// not to need a separate attribute)
83618361
if (!(S.Context.getTargetInfo().hasFeature("neon") ||
83628362
S.Context.getTargetInfo().hasFeature("mve") ||
8363-
IsTargetCUDAAndHostARM)) {
8363+
S.Context.getTargetInfo().hasFeature("sve") ||
8364+
S.Context.getTargetInfo().hasFeature("sme") ||
8365+
IsTargetCUDAAndHostARM) &&
8366+
VecKind == VectorKind::Neon) {
8367+
S.Diag(Attr.getLoc(), diag::err_attribute_unsupported)
8368+
<< Attr << "'neon', 'mve', 'sve' or 'sme'";
8369+
Attr.setInvalid();
8370+
return;
8371+
}
8372+
if (!(S.Context.getTargetInfo().hasFeature("neon") ||
8373+
S.Context.getTargetInfo().hasFeature("mve") ||
8374+
IsTargetCUDAAndHostARM) &&
8375+
VecKind == VectorKind::NeonPoly) {
83648376
S.Diag(Attr.getLoc(), diag::err_attribute_unsupported)
83658377
<< Attr << "'neon' or 'mve'";
83668378
Attr.setInvalid();
83678379
return;
83688380
}
8381+
83698382
// Check the attribute arguments.
83708383
if (Attr.getNumArgs() != 1) {
83718384
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 3
2+
3+
// RUN: %clang_cc1 -DSVE_HEADER -triple aarch64 -target-feature +sve -emit-llvm -O2 -o - %s | opt -S -passes=mem2reg,sroa | FileCheck %s
4+
// RUN: %clang_cc1 -DSVE_HEADER -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -o - /dev/null %s
5+
6+
// RUN: %clang_cc1 -DNEON_HEADER -triple aarch64 -target-feature +sve -emit-llvm -O2 -o - %s | opt -S -passes=mem2reg,sroa | FileCheck %s
7+
// RUN: %clang_cc1 -DNEON_HEADER -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -o - /dev/null %s
8+
9+
// RUN: %clang_cc1 -DSVE_HEADER -DNEON_HEADER -triple aarch64 -target-feature +sve -emit-llvm -O2 -o - %s | opt -S -passes=mem2reg,sroa | FileCheck %s
10+
// RUN: %clang_cc1 -DSVE_HEADER -DNEON_HEADER -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -o - /dev/null %s
11+
12+
// RUN: %clang_cc1 -DNEON_HEADER -DSVE_HEADER2 -triple aarch64 -target-feature +sve -emit-llvm -O2 -o - %s | opt -S -passes=mem2reg,sroa | FileCheck %s
13+
// RUN: %clang_cc1 -DNEON_HEADER -DSVE_HEADER2 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -o - /dev/null %s
14+
15+
#ifdef SVE_HEADER
16+
#include <arm_sve.h>
17+
#endif
18+
19+
#ifdef NEON_HEADER
20+
#include <arm_neon.h>
21+
#endif
22+
23+
#ifdef SVE_HEADER_2
24+
#include <arm_sve.h>
25+
#endif
26+
27+
// function return types
28+
// CHECK-LABEL: define dso_local <8 x half> @test_ret_v8f16(
29+
// CHECK-SAME: <8 x half> noundef returned [[V:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
30+
// CHECK-NEXT: entry:
31+
// CHECK-NEXT: ret <8 x half> [[V]]
32+
//
33+
float16x8_t test_ret_v8f16(float16x8_t v) {
34+
return v;
35+
}
36+
37+
// CHECK-LABEL: define dso_local <4 x float> @test_ret_v4f32(
38+
// CHECK-SAME: <4 x float> noundef returned [[V:%.*]]) local_unnamed_addr #[[ATTR0]] {
39+
// CHECK-NEXT: entry:
40+
// CHECK-NEXT: ret <4 x float> [[V]]
41+
//
42+
float32x4_t test_ret_v4f32(float32x4_t v) {
43+
return v;
44+
}
45+
46+
// CHECK-LABEL: define dso_local <2 x double> @test_ret_v2f64(
47+
// CHECK-SAME: <2 x double> noundef returned [[V:%.*]]) local_unnamed_addr #[[ATTR0]] {
48+
// CHECK-NEXT: entry:
49+
// CHECK-NEXT: ret <2 x double> [[V]]
50+
//
51+
float64x2_t test_ret_v2f64(float64x2_t v) {
52+
return v;
53+
}
54+
55+
// CHECK-LABEL: define dso_local <8 x bfloat> @test_ret_v8bf16(
56+
// CHECK-SAME: <8 x bfloat> noundef returned [[V:%.*]]) local_unnamed_addr #[[ATTR0]] {
57+
// CHECK-NEXT: entry:
58+
// CHECK-NEXT: ret <8 x bfloat> [[V]]
59+
//
60+
bfloat16x8_t test_ret_v8bf16(bfloat16x8_t v) {
61+
return v;
62+
}
63+
64+
// CHECK-LABEL: define dso_local <16 x i8> @test_ret_v16s8(
65+
// CHECK-SAME: <16 x i8> noundef returned [[V:%.*]]) local_unnamed_addr #[[ATTR0]] {
66+
// CHECK-NEXT: entry:
67+
// CHECK-NEXT: ret <16 x i8> [[V]]
68+
//
69+
int8x16_t test_ret_v16s8(int8x16_t v) {
70+
return v;
71+
}
72+
73+
// CHECK-LABEL: define dso_local <8 x i16> @test_ret_v8s16(
74+
// CHECK-SAME: <8 x i16> noundef returned [[V:%.*]]) local_unnamed_addr #[[ATTR0]] {
75+
// CHECK-NEXT: entry:
76+
// CHECK-NEXT: ret <8 x i16> [[V]]
77+
//
78+
int16x8_t test_ret_v8s16(int16x8_t v) {
79+
return v;
80+
}
81+
82+
// CHECK-LABEL: define dso_local <4 x i32> @test_ret_v32s4(
83+
// CHECK-SAME: <4 x i32> noundef returned [[V:%.*]]) local_unnamed_addr #[[ATTR0]] {
84+
// CHECK-NEXT: entry:
85+
// CHECK-NEXT: ret <4 x i32> [[V]]
86+
//
87+
int32x4_t test_ret_v32s4(int32x4_t v) {
88+
return v;
89+
}
90+
91+
// CHECK-LABEL: define dso_local <2 x i64> @test_ret_v64s2(
92+
// CHECK-SAME: <2 x i64> noundef returned [[V:%.*]]) local_unnamed_addr #[[ATTR0]] {
93+
// CHECK-NEXT: entry:
94+
// CHECK-NEXT: ret <2 x i64> [[V]]
95+
//
96+
int64x2_t test_ret_v64s2(int64x2_t v) {
97+
return v;
98+
}
99+
100+
// CHECK-LABEL: define dso_local <16 x i8> @test_ret_v16u8(
101+
// CHECK-SAME: <16 x i8> noundef returned [[V:%.*]]) local_unnamed_addr #[[ATTR0]] {
102+
// CHECK-NEXT: entry:
103+
// CHECK-NEXT: ret <16 x i8> [[V]]
104+
//
105+
uint8x16_t test_ret_v16u8(uint8x16_t v) {
106+
return v;
107+
}
108+
109+
// CHECK-LABEL: define dso_local <8 x i16> @test_ret_v8u16(
110+
// CHECK-SAME: <8 x i16> noundef returned [[V:%.*]]) local_unnamed_addr #[[ATTR0]] {
111+
// CHECK-NEXT: entry:
112+
// CHECK-NEXT: ret <8 x i16> [[V]]
113+
//
114+
uint16x8_t test_ret_v8u16(uint16x8_t v) {
115+
return v;
116+
}
117+
118+
// CHECK-LABEL: define dso_local <4 x i32> @test_ret_v32u4(
119+
// CHECK-SAME: <4 x i32> noundef returned [[V:%.*]]) local_unnamed_addr #[[ATTR0]] {
120+
// CHECK-NEXT: entry:
121+
// CHECK-NEXT: ret <4 x i32> [[V]]
122+
//
123+
uint32x4_t test_ret_v32u4(uint32x4_t v) {
124+
return v;
125+
}
126+
127+
// CHECK-LABEL: define dso_local <2 x i64> @test_ret_v64u2(
128+
// CHECK-SAME: <2 x i64> noundef returned [[V:%.*]]) local_unnamed_addr #[[ATTR0]] {
129+
// CHECK-NEXT: entry:
130+
// CHECK-NEXT: ret <2 x i64> [[V]]
131+
//
132+
uint64x2_t test_ret_v64u2(uint64x2_t v) {
133+
return v;
134+
}

clang/test/Sema/aarch64-sve-intrinsics/acle_sve_target.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -fsyntax-only -verify -emit-llvm -o - -ferror-limit 100 %s
1+
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +neon -fsyntax-only -verify -emit-llvm -o - -ferror-limit 100 %s
22
// REQUIRES: aarch64-registered-target
33

44
// Test that functions with the correct target attributes can use the correct SVE intrinsics.
@@ -29,4 +29,5 @@ void __attribute__((target("sve2-sha3"))) test_sve2_sha3()
2929
void __attribute__((target("sve2"))) test_f16(svbool_t pg)
3030
{
3131
svlogb_f16_z(pg, svundef_f16());
32-
}
32+
}
33+
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// RUN: %clang_cc1 %s -triple armv7 -fsyntax-only -verify
22

3-
typedef __attribute__((neon_vector_type(2))) int int32x2_t; // expected-error{{'neon_vector_type' attribute is not supported on targets missing 'neon' or 'mve'; specify an appropriate -march= or -mcpu=}}
3+
typedef __attribute__((neon_vector_type(2))) int int32x2_t; // expected-error{{'neon_vector_type' attribute is not supported on targets missing 'neon', 'mve', 'sve' or 'sme'; specify an appropriate -march= or -mcpu=}}
44
typedef __attribute__((neon_polyvector_type(16))) short poly8x16_t; // expected-error{{'neon_polyvector_type' attribute is not supported on targets missing 'neon' or 'mve'; specify an appropriate -march= or -mcpu=}}
55
typedef __attribute__((arm_sve_vector_bits(256))) void nosveflag; // expected-error{{'arm_sve_vector_bits' attribute is not supported on targets missing 'sve'; specify an appropriate -march= or -mcpu=}}

clang/test/SemaCUDA/neon-attrs.cu

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515

1616
// quiet-no-diagnostics
1717
typedef __attribute__((neon_vector_type(4))) float float32x4_t;
18-
// expected-error@-1 {{'neon_vector_type' attribute is not supported on targets missing 'neon' or 'mve'}}
18+
// expected-error@-1 {{'neon_vector_type' attribute is not supported on targets missing 'neon', 'mve', 'sve' or 'sme'}}
19+
// expect
1920
typedef unsigned char poly8_t;
2021
typedef __attribute__((neon_polyvector_type(8))) poly8_t poly8x8_t;
2122
// expected-error@-1 {{'neon_polyvector_type' attribute is not supported on targets missing 'neon' or 'mve'}}

clang/utils/TableGen/NeonEmitter.cpp

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,8 @@ class NeonEmitter {
593593
// Emit arm_bf16.h.inc
594594
void runBF16(raw_ostream &o);
595595

596+
void runVectorTypes(raw_ostream &o);
597+
596598
// Emit all the __builtin prototypes used in arm_neon.h, arm_fp16.h and
597599
// arm_bf16.h
598600
void runHeader(raw_ostream &o);
@@ -2355,13 +2357,7 @@ void NeonEmitter::run(raw_ostream &OS) {
23552357

23562358
OS << "#include <arm_bf16.h>\n";
23572359

2358-
// Emit NEON-specific scalar typedefs.
2359-
OS << "typedef float float32_t;\n";
2360-
OS << "typedef __fp16 float16_t;\n";
2361-
2362-
OS << "#ifdef __aarch64__\n";
2363-
OS << "typedef double float64_t;\n";
2364-
OS << "#endif\n\n";
2360+
OS << "#include <arm_vector_types.h>\n";
23652361

23662362
// For now, signedness of polynomial types depends on target
23672363
OS << "#ifdef __aarch64__\n";
@@ -2374,10 +2370,7 @@ void NeonEmitter::run(raw_ostream &OS) {
23742370
OS << "typedef int16_t poly16_t;\n";
23752371
OS << "typedef int64_t poly64_t;\n";
23762372
OS << "#endif\n";
2377-
2378-
emitNeonTypeDefs("cQcsQsiQilQlUcQUcUsQUsUiQUiUlQUlhQhfQfdQdPcQPcPsQPsPlQPl", OS);
2379-
2380-
emitNeonTypeDefs("bQb", OS);
2373+
emitNeonTypeDefs("PcQPcPsQPsPlQPl", OS);
23812374

23822375
OS << "#define __ai static __inline__ __attribute__((__always_inline__, "
23832376
"__nodebug__))\n\n";
@@ -2546,6 +2539,38 @@ void NeonEmitter::runFP16(raw_ostream &OS) {
25462539
OS << "#endif /* __ARM_FP16_H */\n";
25472540
}
25482541

2542+
void NeonEmitter::runVectorTypes(raw_ostream &OS) {
2543+
OS << "/*===---- arm_vector_types - ARM vector type "
2544+
"------===\n"
2545+
" *\n"
2546+
" *\n"
2547+
" * Part of the LLVM Project, under the Apache License v2.0 with LLVM "
2548+
"Exceptions.\n"
2549+
" * See https://llvm.org/LICENSE.txt for license information.\n"
2550+
" * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception\n"
2551+
" *\n"
2552+
" *===-----------------------------------------------------------------"
2553+
"------===\n"
2554+
" */\n\n";
2555+
OS << "#if !defined(__ARM_NEON_H) && !defined(__ARM_SVE_H)\n";
2556+
OS << "#error \"This file should not be used standalone. Please include"
2557+
" arm_neon.h or arm_sve.h instead\"\n\n";
2558+
OS << "#endif\n";
2559+
OS << "#ifndef __ARM_NEON_TYPES_H\n";
2560+
OS << "#define __ARM_NEON_TYPES_H\n";
2561+
OS << "typedef float float32_t;\n";
2562+
OS << "typedef __fp16 float16_t;\n";
2563+
2564+
OS << "#ifdef __aarch64__\n";
2565+
OS << "typedef double float64_t;\n";
2566+
OS << "#endif\n\n";
2567+
2568+
emitNeonTypeDefs("cQcsQsiQilQlUcQUcUsQUsUiQUiUlQUlhQhfQfdQd", OS);
2569+
2570+
emitNeonTypeDefs("bQb", OS);
2571+
OS << "#endif // __ARM_NEON_TYPES_H\n";
2572+
}
2573+
25492574
void NeonEmitter::runBF16(raw_ostream &OS) {
25502575
OS << "/*===---- arm_bf16.h - ARM BF16 intrinsics "
25512576
"-----------------------------------===\n"
@@ -2640,6 +2665,10 @@ void clang::EmitNeonSema(RecordKeeper &Records, raw_ostream &OS) {
26402665
NeonEmitter(Records).runHeader(OS);
26412666
}
26422667

2668+
void clang::EmitVectorTypes(RecordKeeper &Records, raw_ostream &OS) {
2669+
NeonEmitter(Records).runVectorTypes(OS);
2670+
}
2671+
26432672
void clang::EmitNeonTest(RecordKeeper &Records, raw_ostream &OS) {
26442673
llvm_unreachable("Neon test generation no longer implemented!");
26452674
}

clang/utils/TableGen/SveEmitter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1286,6 +1286,7 @@ void SVEEmitter::createHeader(raw_ostream &OS) {
12861286
OS << "typedef __SVBfloat16_t svbfloat16_t;\n";
12871287

12881288
OS << "#include <arm_bf16.h>\n";
1289+
OS << "#include <arm_vector_types.h>\n";
12891290

12901291
OS << "typedef __SVFloat32_t svfloat32_t;\n";
12911292
OS << "typedef __SVFloat64_t svfloat64_t;\n";
@@ -1730,4 +1731,5 @@ void EmitSmeBuiltinCG(RecordKeeper &Records, raw_ostream &OS) {
17301731
void EmitSmeRangeChecks(RecordKeeper &Records, raw_ostream &OS) {
17311732
SVEEmitter(Records).createSMERangeChecks(OS);
17321733
}
1734+
17331735
} // End namespace clang

clang/utils/TableGen/TableGen.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ enum ActionType {
7373
GenArmNeon,
7474
GenArmFP16,
7575
GenArmBF16,
76+
GenArmVectorType,
7677
GenArmNeonSema,
7778
GenArmNeonTest,
7879
GenArmMveHeader,
@@ -229,6 +230,8 @@ cl::opt<ActionType> Action(
229230
clEnumValN(GenArmNeon, "gen-arm-neon", "Generate arm_neon.h for clang"),
230231
clEnumValN(GenArmFP16, "gen-arm-fp16", "Generate arm_fp16.h for clang"),
231232
clEnumValN(GenArmBF16, "gen-arm-bf16", "Generate arm_bf16.h for clang"),
233+
clEnumValN(GenArmVectorType, "gen-arm-vector-type",
234+
"Generate arm_vector_types.h for clang"),
232235
clEnumValN(GenArmNeonSema, "gen-arm-neon-sema",
233236
"Generate ARM NEON sema support for clang"),
234237
clEnumValN(GenArmNeonTest, "gen-arm-neon-test",
@@ -449,6 +452,9 @@ bool ClangTableGenMain(raw_ostream &OS, RecordKeeper &Records) {
449452
case GenArmFP16:
450453
EmitFP16(Records, OS);
451454
break;
455+
case GenArmVectorType:
456+
EmitVectorTypes(Records, OS);
457+
break;
452458
case GenArmBF16:
453459
EmitBF16(Records, OS);
454460
break;

clang/utils/TableGen/TableGenBackends.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ void EmitNeon(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
9797
void EmitFP16(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
9898
void EmitBF16(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
9999
void EmitNeonSema(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
100+
void EmitVectorTypes(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
100101
void EmitNeonTest(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
101102

102103
void EmitSveHeader(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);

0 commit comments

Comments
 (0)