From 652ed557456f79f1a3cfcd06e9b90e3dbb23e4d1 Mon Sep 17 00:00:00 2001 From: "Engels, Frederik" Date: Tue, 4 Aug 2026 11:33:21 +0100 Subject: [PATCH 1/6] Disable diagnostics for neon attributes for SYCL device compilation Changes in ItaniumMangle.cpp are to make this aux-triple and SYCL aware, which will cause us to go into aarch64 mangling path that correctly handles long long for windows. Checks are added to SemaType to ensure that the selected long or long long is indeed 64-bit, previously this would allow 32-bit long to be a valid polyvector type (which it's not). These are both tested with neon-polyvector-types.cpp. The -verify lines check for error for non 64-bit types, long on windows and int on linux. The -verify=quiet ensures that we use the aarch64 mangling path, the non aarch64 mangling path only accepts long long and not long. Co-authored-by: Lomuller, Victor --- clang/lib/AST/ItaniumMangle.cpp | 8 ++++--- clang/lib/Sema/SemaType.cpp | 7 ++++-- clang/test/SemaSYCL/neon-polyvector-types.cpp | 24 +++++++++++++++++++ 3 files changed, 34 insertions(+), 5 deletions(-) create mode 100644 clang/test/SemaSYCL/neon-polyvector-types.cpp diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 197a874eb180b..1216f9f8280a2 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -4328,9 +4328,11 @@ void CXXNameMangler::mangleRISCVFixedRVVVectorType( void CXXNameMangler::mangleType(const VectorType *T) { if ((T->getVectorKind() == VectorKind::Neon || T->getVectorKind() == VectorKind::NeonPoly)) { - llvm::Triple Target = getASTContext().getTargetInfo().getTriple(); - llvm::Triple::ArchType Arch = - getASTContext().getTargetInfo().getTriple().getArch(); + const TargetInfo *TI = getASTContext().getLangOpts().SYCLIsDevice + ? getASTContext().getAuxTargetInfo() + : &getASTContext().getTargetInfo(); + llvm::Triple Target = TI->getTriple(); + llvm::Triple::ArchType Arch = Target.getArch(); if ((Arch == llvm::Triple::aarch64 || Arch == llvm::Triple::aarch64_be) && !Target.isOSDarwin()) mangleAArch64NeonVectorType(T); diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 9d2d41c1c6317..873200e7cbdde 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -8547,6 +8547,8 @@ static bool isPermittedNeonBaseType(QualType &Ty, VectorKind VecKind, Sema &S) { return false; llvm::Triple Triple = S.Context.getTargetInfo().getTriple(); + if(S.getLangOpts().SYCLIsDevice) + Triple = S.Context.getAuxTargetInfo()->getTriple(); // Signed poly is mathematically wrong, but has been baked into some ABIs by // now. @@ -8558,8 +8560,9 @@ static bool isPermittedNeonBaseType(QualType &Ty, VectorKind VecKind, Sema &S) { // AArch64 polynomial vectors are unsigned. return BTy->getKind() == BuiltinType::UChar || BTy->getKind() == BuiltinType::UShort || - BTy->getKind() == BuiltinType::ULong || - BTy->getKind() == BuiltinType::ULongLong; + ((BTy->getKind() == BuiltinType::ULong || + BTy->getKind() == BuiltinType::ULongLong) && + S.Context.getTypeSize(BTy) == 64); } else { // AArch32 polynomial vectors are signed. return BTy->getKind() == BuiltinType::SChar || diff --git a/clang/test/SemaSYCL/neon-polyvector-types.cpp b/clang/test/SemaSYCL/neon-polyvector-types.cpp new file mode 100644 index 0000000000000..9b5cca49f0a8b --- /dev/null +++ b/clang/test/SemaSYCL/neon-polyvector-types.cpp @@ -0,0 +1,24 @@ +// Both of these should fail on bad_poly32_t, yielding 32-bit types +// RUN: %clang_cc1 %s -fsycl-is-device -triple spir64 -aux-triple aarch64-pc-windows-msvc -target-feature +neon -DLONG -fsyntax-only -verify +// RUN: %clang_cc1 %s -fsycl-is-device -triple spir64 -aux-triple arm64-unknown-linux-gnu -target-feature +neon -ULONG -fsyntax-only -verify +// This will succeed on linux as long is 64-bit +// RUN: %clang_cc1 %s -fsycl-is-device -triple spir64 -aux-triple arm64-unknown-linux-gnu -target-feature +neon -DLONG -fsyntax-only -verify=quiet +typedef unsigned char poly8_t; +typedef unsigned short poly16_t; +typedef __UINT64_TYPE__ poly64_t; + +#if defined(LONG) +// 32-bit on windows (LLP64) +// 64-bit on linux (LP64) +typedef unsigned long bad_poly32_t; +#else +typedef unsigned int bad_poly32_t; +#endif + +typedef __attribute__((neon_polyvector_type(16))) poly8_t poly8x16_t; +typedef __attribute__((neon_polyvector_type(8))) poly16_t poly16x8_t; +typedef __attribute__((neon_polyvector_type(2))) poly64_t poly64x2_t; + +// quiet-no-diagnostics +typedef __attribute__((neon_polyvector_type(2))) bad_poly32_t bad_poly32x2_t; +// expected-error@-1{{invalid vector element type}} From 87264ceb72f9b1fc62f943ad16addee7ec2beccf Mon Sep 17 00:00:00 2001 From: Frederik Engels Date: Mon, 10 Aug 2026 16:31:18 +0100 Subject: [PATCH 2/6] use isTargetDevice and check for TI being set --- clang/lib/AST/ItaniumMangle.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 1216f9f8280a2..92fd48a7d63e7 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -4328,9 +4328,11 @@ void CXXNameMangler::mangleRISCVFixedRVVVectorType( void CXXNameMangler::mangleType(const VectorType *T) { if ((T->getVectorKind() == VectorKind::Neon || T->getVectorKind() == VectorKind::NeonPoly)) { - const TargetInfo *TI = getASTContext().getLangOpts().SYCLIsDevice + const TargetInfo *TI = getASTContext().getLangOpts().isTargetDevice() ? getASTContext().getAuxTargetInfo() : &getASTContext().getTargetInfo(); + if(!TI) + TI = &getASTContext().getTargetInfo(); llvm::Triple Target = TI->getTriple(); llvm::Triple::ArchType Arch = Target.getArch(); if ((Arch == llvm::Triple::aarch64 || From 63269948aafe980b2c5a699bcf9781073ec81742 Mon Sep 17 00:00:00 2001 From: Frederik Engels Date: Mon, 10 Aug 2026 16:36:35 +0100 Subject: [PATCH 3/6] check for bitwidth rather than specific types --- clang/lib/Sema/SemaType.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 873200e7cbdde..2bbba608b6575 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -8558,11 +8558,9 @@ static bool isPermittedNeonBaseType(QualType &Ty, VectorKind VecKind, Sema &S) { if (VecKind == VectorKind::NeonPoly) { if (IsPolyUnsigned) { // AArch64 polynomial vectors are unsigned. - return BTy->getKind() == BuiltinType::UChar || - BTy->getKind() == BuiltinType::UShort || - ((BTy->getKind() == BuiltinType::ULong || - BTy->getKind() == BuiltinType::ULongLong) && - S.Context.getTypeSize(BTy) == 64); + auto bitwidth = S.Context.getTypeSize(BTy); + return BTy->isUnsignedInteger() && + (bitwidth == 8 || bitwidth == 16 || bitwidth == 64); } else { // AArch32 polynomial vectors are signed. return BTy->getKind() == BuiltinType::SChar || From 53d1939f4d5ed7ce69d0f1b8cad01507075fc6b5 Mon Sep 17 00:00:00 2001 From: Frederik Engels Date: Mon, 10 Aug 2026 16:38:36 +0100 Subject: [PATCH 4/6] remove aux target check This is already taken care of by an earlier change to dpc++ --- clang/lib/Sema/SemaType.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 2bbba608b6575..51bcb22f41ee8 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -8547,8 +8547,6 @@ static bool isPermittedNeonBaseType(QualType &Ty, VectorKind VecKind, Sema &S) { return false; llvm::Triple Triple = S.Context.getTargetInfo().getTriple(); - if(S.getLangOpts().SYCLIsDevice) - Triple = S.Context.getAuxTargetInfo()->getTriple(); // Signed poly is mathematically wrong, but has been baked into some ABIs by // now. From 161801770ca87a970ee1a66df4649300ca504fdf Mon Sep 17 00:00:00 2001 From: Frederik Engels Date: Thu, 13 Aug 2026 11:32:48 +0100 Subject: [PATCH 5/6] apply clang-format --- clang/lib/AST/ItaniumMangle.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 92fd48a7d63e7..9dd1e860d7b59 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -4331,8 +4331,8 @@ void CXXNameMangler::mangleType(const VectorType *T) { const TargetInfo *TI = getASTContext().getLangOpts().isTargetDevice() ? getASTContext().getAuxTargetInfo() : &getASTContext().getTargetInfo(); - if(!TI) - TI = &getASTContext().getTargetInfo(); + if (!TI) + TI = &getASTContext().getTargetInfo(); llvm::Triple Target = TI->getTriple(); llvm::Triple::ArchType Arch = Target.getArch(); if ((Arch == llvm::Triple::aarch64 || From 01fd1945aff44905a041eb253625d1199fe75327 Mon Sep 17 00:00:00 2001 From: Frederik Engels Date: Thu, 13 Aug 2026 13:26:23 +0100 Subject: [PATCH 6/6] fix polyvector test --- clang/test/SemaSYCL/neon-polyvector-types.cpp | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/clang/test/SemaSYCL/neon-polyvector-types.cpp b/clang/test/SemaSYCL/neon-polyvector-types.cpp index 9b5cca49f0a8b..0dbd8206fd827 100644 --- a/clang/test/SemaSYCL/neon-polyvector-types.cpp +++ b/clang/test/SemaSYCL/neon-polyvector-types.cpp @@ -1,24 +1,22 @@ -// Both of these should fail on bad_poly32_t, yielding 32-bit types -// RUN: %clang_cc1 %s -fsycl-is-device -triple spir64 -aux-triple aarch64-pc-windows-msvc -target-feature +neon -DLONG -fsyntax-only -verify -// RUN: %clang_cc1 %s -fsycl-is-device -triple spir64 -aux-triple arm64-unknown-linux-gnu -target-feature +neon -ULONG -fsyntax-only -verify -// This will succeed on linux as long is 64-bit -// RUN: %clang_cc1 %s -fsycl-is-device -triple spir64 -aux-triple arm64-unknown-linux-gnu -target-feature +neon -DLONG -fsyntax-only -verify=quiet +// Does a run with a SYCL device, where neon polyvector type errors are ignored. +// afterwards compile for the host where neon polyvector type errors aren't ignored + +// polyvector type errors get ignored with SYCL enabled +// RUN: %clang_cc1 %s -fsycl-is-device -triple spir64 -aux-triple arm64-unknown-linux-gnu -target-feature +neon -fsyntax-only -verify=quiet + +// diagnostic for bad_poly32_t +// RUN: %clang_cc1 %s -triple arm64-unknown-linux-gnu -target-feature +neon -fsyntax-only -verify typedef unsigned char poly8_t; typedef unsigned short poly16_t; -typedef __UINT64_TYPE__ poly64_t; +typedef unsigned long poly64_t; -#if defined(LONG) -// 32-bit on windows (LLP64) -// 64-bit on linux (LP64) -typedef unsigned long bad_poly32_t; -#else typedef unsigned int bad_poly32_t; -#endif typedef __attribute__((neon_polyvector_type(16))) poly8_t poly8x16_t; typedef __attribute__((neon_polyvector_type(8))) poly16_t poly16x8_t; typedef __attribute__((neon_polyvector_type(2))) poly64_t poly64x2_t; +// this error will get ignored when running SYCL // quiet-no-diagnostics typedef __attribute__((neon_polyvector_type(2))) bad_poly32_t bad_poly32x2_t; // expected-error@-1{{invalid vector element type}}