Skip to content

Commit

Permalink
[Clang][AArch64] Add fix vector types to header into SVE (#73258)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
CarolineConcatto committed Dec 13, 2023
1 parent 41aa0d4 commit ed2d497
Show file tree
Hide file tree
Showing 10 changed files with 206 additions and 16 deletions.
3 changes: 3 additions & 0 deletions clang/lib/Headers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,8 @@ if(ARM IN_LIST LLVM_TARGETS_TO_BUILD OR AArch64 IN_LIST LLVM_TARGETS_TO_BUILD)
clang_generate_header(-gen-arm-mve-header arm_mve.td arm_mve.h)
# Generate arm_cde.h
clang_generate_header(-gen-arm-cde-header arm_cde.td arm_cde.h)
# Generate arm_vector_types.h
clang_generate_header(-gen-arm-vector-type arm_neon.td arm_vector_types.h)

# Add headers to target specific lists
list(APPEND arm_common_generated_files
Expand All @@ -403,6 +405,7 @@ if(ARM IN_LIST LLVM_TARGETS_TO_BUILD OR AArch64 IN_LIST LLVM_TARGETS_TO_BUILD)
"${CMAKE_CURRENT_BINARY_DIR}/arm_sve.h"
"${CMAKE_CURRENT_BINARY_DIR}/arm_sme_draft_spec_subject_to_change.h"
"${CMAKE_CURRENT_BINARY_DIR}/arm_bf16.h"
"${CMAKE_CURRENT_BINARY_DIR}/arm_vector_types.h"
)
endif()
if(RISCV IN_LIST LLVM_TARGETS_TO_BUILD)
Expand Down
15 changes: 14 additions & 1 deletion clang/lib/Sema/SemaType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8360,12 +8360,25 @@ static void HandleNeonVectorTypeAttr(QualType &CurType, const ParsedAttr &Attr,
// not to need a separate attribute)
if (!(S.Context.getTargetInfo().hasFeature("neon") ||
S.Context.getTargetInfo().hasFeature("mve") ||
IsTargetCUDAAndHostARM)) {
S.Context.getTargetInfo().hasFeature("sve") ||
S.Context.getTargetInfo().hasFeature("sme") ||
IsTargetCUDAAndHostARM) &&
VecKind == VectorKind::Neon) {
S.Diag(Attr.getLoc(), diag::err_attribute_unsupported)
<< Attr << "'neon', 'mve', 'sve' or 'sme'";
Attr.setInvalid();
return;
}
if (!(S.Context.getTargetInfo().hasFeature("neon") ||
S.Context.getTargetInfo().hasFeature("mve") ||
IsTargetCUDAAndHostARM) &&
VecKind == VectorKind::NeonPoly) {
S.Diag(Attr.getLoc(), diag::err_attribute_unsupported)
<< Attr << "'neon' or 'mve'";
Attr.setInvalid();
return;
}

// Check the attribute arguments.
if (Attr.getNumArgs() != 1) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
Expand Down
134 changes: 134 additions & 0 deletions clang/test/CodeGen/arm-vector_type-params-returns.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 3

// RUN: %clang_cc1 -DSVE_HEADER -triple aarch64 -target-feature +sve -emit-llvm -O2 -o - %s | opt -S -passes=mem2reg,sroa | FileCheck %s
// RUN: %clang_cc1 -DSVE_HEADER -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -o - /dev/null %s

// RUN: %clang_cc1 -DNEON_HEADER -triple aarch64 -target-feature +sve -emit-llvm -O2 -o - %s | opt -S -passes=mem2reg,sroa | FileCheck %s
// RUN: %clang_cc1 -DNEON_HEADER -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -o - /dev/null %s

// RUN: %clang_cc1 -DSVE_HEADER -DNEON_HEADER -triple aarch64 -target-feature +sve -emit-llvm -O2 -o - %s | opt -S -passes=mem2reg,sroa | FileCheck %s
// 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

// RUN: %clang_cc1 -DNEON_HEADER -DSVE_HEADER2 -triple aarch64 -target-feature +sve -emit-llvm -O2 -o - %s | opt -S -passes=mem2reg,sroa | FileCheck %s
// 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

#ifdef SVE_HEADER
#include <arm_sve.h>
#endif

#ifdef NEON_HEADER
#include <arm_neon.h>
#endif

#ifdef SVE_HEADER_2
#include <arm_sve.h>
#endif

// function return types
// CHECK-LABEL: define dso_local <8 x half> @test_ret_v8f16(
// CHECK-SAME: <8 x half> noundef returned [[V:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
// CHECK-NEXT: entry:
// CHECK-NEXT: ret <8 x half> [[V]]
//
float16x8_t test_ret_v8f16(float16x8_t v) {
return v;
}

// CHECK-LABEL: define dso_local <4 x float> @test_ret_v4f32(
// CHECK-SAME: <4 x float> noundef returned [[V:%.*]]) local_unnamed_addr #[[ATTR0]] {
// CHECK-NEXT: entry:
// CHECK-NEXT: ret <4 x float> [[V]]
//
float32x4_t test_ret_v4f32(float32x4_t v) {
return v;
}

// CHECK-LABEL: define dso_local <2 x double> @test_ret_v2f64(
// CHECK-SAME: <2 x double> noundef returned [[V:%.*]]) local_unnamed_addr #[[ATTR0]] {
// CHECK-NEXT: entry:
// CHECK-NEXT: ret <2 x double> [[V]]
//
float64x2_t test_ret_v2f64(float64x2_t v) {
return v;
}

// CHECK-LABEL: define dso_local <8 x bfloat> @test_ret_v8bf16(
// CHECK-SAME: <8 x bfloat> noundef returned [[V:%.*]]) local_unnamed_addr #[[ATTR0]] {
// CHECK-NEXT: entry:
// CHECK-NEXT: ret <8 x bfloat> [[V]]
//
bfloat16x8_t test_ret_v8bf16(bfloat16x8_t v) {
return v;
}

// CHECK-LABEL: define dso_local <16 x i8> @test_ret_v16s8(
// CHECK-SAME: <16 x i8> noundef returned [[V:%.*]]) local_unnamed_addr #[[ATTR0]] {
// CHECK-NEXT: entry:
// CHECK-NEXT: ret <16 x i8> [[V]]
//
int8x16_t test_ret_v16s8(int8x16_t v) {
return v;
}

// CHECK-LABEL: define dso_local <8 x i16> @test_ret_v8s16(
// CHECK-SAME: <8 x i16> noundef returned [[V:%.*]]) local_unnamed_addr #[[ATTR0]] {
// CHECK-NEXT: entry:
// CHECK-NEXT: ret <8 x i16> [[V]]
//
int16x8_t test_ret_v8s16(int16x8_t v) {
return v;
}

// CHECK-LABEL: define dso_local <4 x i32> @test_ret_v32s4(
// CHECK-SAME: <4 x i32> noundef returned [[V:%.*]]) local_unnamed_addr #[[ATTR0]] {
// CHECK-NEXT: entry:
// CHECK-NEXT: ret <4 x i32> [[V]]
//
int32x4_t test_ret_v32s4(int32x4_t v) {
return v;
}

// CHECK-LABEL: define dso_local <2 x i64> @test_ret_v64s2(
// CHECK-SAME: <2 x i64> noundef returned [[V:%.*]]) local_unnamed_addr #[[ATTR0]] {
// CHECK-NEXT: entry:
// CHECK-NEXT: ret <2 x i64> [[V]]
//
int64x2_t test_ret_v64s2(int64x2_t v) {
return v;
}

// CHECK-LABEL: define dso_local <16 x i8> @test_ret_v16u8(
// CHECK-SAME: <16 x i8> noundef returned [[V:%.*]]) local_unnamed_addr #[[ATTR0]] {
// CHECK-NEXT: entry:
// CHECK-NEXT: ret <16 x i8> [[V]]
//
uint8x16_t test_ret_v16u8(uint8x16_t v) {
return v;
}

// CHECK-LABEL: define dso_local <8 x i16> @test_ret_v8u16(
// CHECK-SAME: <8 x i16> noundef returned [[V:%.*]]) local_unnamed_addr #[[ATTR0]] {
// CHECK-NEXT: entry:
// CHECK-NEXT: ret <8 x i16> [[V]]
//
uint16x8_t test_ret_v8u16(uint16x8_t v) {
return v;
}

// CHECK-LABEL: define dso_local <4 x i32> @test_ret_v32u4(
// CHECK-SAME: <4 x i32> noundef returned [[V:%.*]]) local_unnamed_addr #[[ATTR0]] {
// CHECK-NEXT: entry:
// CHECK-NEXT: ret <4 x i32> [[V]]
//
uint32x4_t test_ret_v32u4(uint32x4_t v) {
return v;
}

// CHECK-LABEL: define dso_local <2 x i64> @test_ret_v64u2(
// CHECK-SAME: <2 x i64> noundef returned [[V:%.*]]) local_unnamed_addr #[[ATTR0]] {
// CHECK-NEXT: entry:
// CHECK-NEXT: ret <2 x i64> [[V]]
//
uint64x2_t test_ret_v64u2(uint64x2_t v) {
return v;
}
5 changes: 3 additions & 2 deletions clang/test/Sema/aarch64-sve-intrinsics/acle_sve_target.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -fsyntax-only -verify -emit-llvm -o - -ferror-limit 100 %s
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +neon -fsyntax-only -verify -emit-llvm -o - -ferror-limit 100 %s
// REQUIRES: aarch64-registered-target

// Test that functions with the correct target attributes can use the correct SVE intrinsics.
Expand Down Expand Up @@ -29,4 +29,5 @@ void __attribute__((target("sve2-sha3"))) test_sve2_sha3()
void __attribute__((target("sve2"))) test_f16(svbool_t pg)
{
svlogb_f16_z(pg, svundef_f16());
}
}

2 changes: 1 addition & 1 deletion clang/test/Sema/arm-vector-types-support.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 %s -triple armv7 -fsyntax-only -verify

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=}}
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=}}
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=}}
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=}}
3 changes: 2 additions & 1 deletion clang/test/SemaCUDA/neon-attrs.cu
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@

// quiet-no-diagnostics
typedef __attribute__((neon_vector_type(4))) float float32x4_t;
// expected-error@-1 {{'neon_vector_type' attribute is not supported on targets missing 'neon' or 'mve'}}
// expected-error@-1 {{'neon_vector_type' attribute is not supported on targets missing 'neon', 'mve', 'sve' or 'sme'}}
// expect
typedef unsigned char poly8_t;
typedef __attribute__((neon_polyvector_type(8))) poly8_t poly8x8_t;
// expected-error@-1 {{'neon_polyvector_type' attribute is not supported on targets missing 'neon' or 'mve'}}
51 changes: 40 additions & 11 deletions clang/utils/TableGen/NeonEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,8 @@ class NeonEmitter {
// Emit arm_bf16.h.inc
void runBF16(raw_ostream &o);

void runVectorTypes(raw_ostream &o);

// Emit all the __builtin prototypes used in arm_neon.h, arm_fp16.h and
// arm_bf16.h
void runHeader(raw_ostream &o);
Expand Down Expand Up @@ -2355,13 +2357,7 @@ void NeonEmitter::run(raw_ostream &OS) {

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

// Emit NEON-specific scalar typedefs.
OS << "typedef float float32_t;\n";
OS << "typedef __fp16 float16_t;\n";

OS << "#ifdef __aarch64__\n";
OS << "typedef double float64_t;\n";
OS << "#endif\n\n";
OS << "#include <arm_vector_types.h>\n";

// For now, signedness of polynomial types depends on target
OS << "#ifdef __aarch64__\n";
Expand All @@ -2374,10 +2370,7 @@ void NeonEmitter::run(raw_ostream &OS) {
OS << "typedef int16_t poly16_t;\n";
OS << "typedef int64_t poly64_t;\n";
OS << "#endif\n";

emitNeonTypeDefs("cQcsQsiQilQlUcQUcUsQUsUiQUiUlQUlhQhfQfdQdPcQPcPsQPsPlQPl", OS);

emitNeonTypeDefs("bQb", OS);
emitNeonTypeDefs("PcQPcPsQPsPlQPl", OS);

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

void NeonEmitter::runVectorTypes(raw_ostream &OS) {
OS << "/*===---- arm_vector_types - ARM vector type "
"------===\n"
" *\n"
" *\n"
" * Part of the LLVM Project, under the Apache License v2.0 with LLVM "
"Exceptions.\n"
" * See https://llvm.org/LICENSE.txt for license information.\n"
" * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception\n"
" *\n"
" *===-----------------------------------------------------------------"
"------===\n"
" */\n\n";
OS << "#if !defined(__ARM_NEON_H) && !defined(__ARM_SVE_H)\n";
OS << "#error \"This file should not be used standalone. Please include"
" arm_neon.h or arm_sve.h instead\"\n\n";
OS << "#endif\n";
OS << "#ifndef __ARM_NEON_TYPES_H\n";
OS << "#define __ARM_NEON_TYPES_H\n";
OS << "typedef float float32_t;\n";
OS << "typedef __fp16 float16_t;\n";

OS << "#ifdef __aarch64__\n";
OS << "typedef double float64_t;\n";
OS << "#endif\n\n";

emitNeonTypeDefs("cQcsQsiQilQlUcQUcUsQUsUiQUiUlQUlhQhfQfdQd", OS);

emitNeonTypeDefs("bQb", OS);
OS << "#endif // __ARM_NEON_TYPES_H\n";
}

void NeonEmitter::runBF16(raw_ostream &OS) {
OS << "/*===---- arm_bf16.h - ARM BF16 intrinsics "
"-----------------------------------===\n"
Expand Down Expand Up @@ -2640,6 +2665,10 @@ void clang::EmitNeonSema(RecordKeeper &Records, raw_ostream &OS) {
NeonEmitter(Records).runHeader(OS);
}

void clang::EmitVectorTypes(RecordKeeper &Records, raw_ostream &OS) {
NeonEmitter(Records).runVectorTypes(OS);
}

void clang::EmitNeonTest(RecordKeeper &Records, raw_ostream &OS) {
llvm_unreachable("Neon test generation no longer implemented!");
}
2 changes: 2 additions & 0 deletions clang/utils/TableGen/SveEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1286,6 +1286,7 @@ void SVEEmitter::createHeader(raw_ostream &OS) {
OS << "typedef __SVBfloat16_t svbfloat16_t;\n";

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

OS << "typedef __SVFloat32_t svfloat32_t;\n";
OS << "typedef __SVFloat64_t svfloat64_t;\n";
Expand Down Expand Up @@ -1730,4 +1731,5 @@ void EmitSmeBuiltinCG(RecordKeeper &Records, raw_ostream &OS) {
void EmitSmeRangeChecks(RecordKeeper &Records, raw_ostream &OS) {
SVEEmitter(Records).createSMERangeChecks(OS);
}

} // End namespace clang
6 changes: 6 additions & 0 deletions clang/utils/TableGen/TableGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ enum ActionType {
GenArmNeon,
GenArmFP16,
GenArmBF16,
GenArmVectorType,
GenArmNeonSema,
GenArmNeonTest,
GenArmMveHeader,
Expand Down Expand Up @@ -229,6 +230,8 @@ cl::opt<ActionType> Action(
clEnumValN(GenArmNeon, "gen-arm-neon", "Generate arm_neon.h for clang"),
clEnumValN(GenArmFP16, "gen-arm-fp16", "Generate arm_fp16.h for clang"),
clEnumValN(GenArmBF16, "gen-arm-bf16", "Generate arm_bf16.h for clang"),
clEnumValN(GenArmVectorType, "gen-arm-vector-type",
"Generate arm_vector_types.h for clang"),
clEnumValN(GenArmNeonSema, "gen-arm-neon-sema",
"Generate ARM NEON sema support for clang"),
clEnumValN(GenArmNeonTest, "gen-arm-neon-test",
Expand Down Expand Up @@ -449,6 +452,9 @@ bool ClangTableGenMain(raw_ostream &OS, RecordKeeper &Records) {
case GenArmFP16:
EmitFP16(Records, OS);
break;
case GenArmVectorType:
EmitVectorTypes(Records, OS);
break;
case GenArmBF16:
EmitBF16(Records, OS);
break;
Expand Down
1 change: 1 addition & 0 deletions clang/utils/TableGen/TableGenBackends.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ void EmitNeon(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
void EmitFP16(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
void EmitBF16(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
void EmitNeonSema(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
void EmitVectorTypes(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
void EmitNeonTest(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);

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

0 comments on commit ed2d497

Please sign in to comment.