https://github.com/ImpleLee updated https://github.com/llvm/llvm-project/pull/148954
>From 3b19742073d1625bbf5bb997325dac2f5003e17d Mon Sep 17 00:00:00 2001 From: Imple Lee <80144331+imple...@users.noreply.github.com> Date: Wed, 16 Jul 2025 04:23:45 +0800 Subject: [PATCH 1/3] [clang] improve consistency with GCC vector comparison fixes issue #132604 --- clang/lib/Sema/SemaExpr.cpp | 22 +++++++++++----------- clang/test/Sema/vector-gcc-compat.c | 6 ++++-- clang/test/Sema/vector-gcc-compat.cpp | 6 ++++-- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index a3f534ee6712e..8a81cda9912f7 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -12901,24 +12901,24 @@ QualType Sema::GetSignedVectorType(QualType V) { return Context.getExtVectorType(Context.LongLongTy, VTy->getNumElements()); } - if (TypeSize == Context.getTypeSize(Context.Int128Ty)) - return Context.getVectorType(Context.Int128Ty, VTy->getNumElements(), - VectorKind::Generic); - if (TypeSize == Context.getTypeSize(Context.LongLongTy)) - return Context.getVectorType(Context.LongLongTy, VTy->getNumElements(), - VectorKind::Generic); - if (TypeSize == Context.getTypeSize(Context.LongTy)) - return Context.getVectorType(Context.LongTy, VTy->getNumElements(), - VectorKind::Generic); if (TypeSize == Context.getTypeSize(Context.IntTy)) return Context.getVectorType(Context.IntTy, VTy->getNumElements(), VectorKind::Generic); + if (TypeSize == Context.getTypeSize(Context.SignedCharTy)) + return Context.getVectorType(Context.SignedCharTy, VTy->getNumElements(), + VectorKind::Generic); if (TypeSize == Context.getTypeSize(Context.ShortTy)) return Context.getVectorType(Context.ShortTy, VTy->getNumElements(), VectorKind::Generic); - assert(TypeSize == Context.getTypeSize(Context.CharTy) && + if (TypeSize == Context.getTypeSize(Context.LongTy)) + return Context.getVectorType(Context.LongTy, VTy->getNumElements(), + VectorKind::Generic); + if (TypeSize == Context.getTypeSize(Context.LongLongTy)) + return Context.getVectorType(Context.LongLongTy, VTy->getNumElements(), + VectorKind::Generic); + assert(TypeSize == Context.getTypeSize(Context.Int128Ty) && "Unhandled vector element size in vector compare"); - return Context.getVectorType(Context.CharTy, VTy->getNumElements(), + return Context.getVectorType(Context.Int128Ty, VTy->getNumElements(), VectorKind::Generic); } diff --git a/clang/test/Sema/vector-gcc-compat.c b/clang/test/Sema/vector-gcc-compat.c index 7764b3bf686ad..7d9d25019666c 100644 --- a/clang/test/Sema/vector-gcc-compat.c +++ b/clang/test/Sema/vector-gcc-compat.c @@ -3,6 +3,8 @@ // Test the compatibility of clang's vector extensions with gcc's vector // extensions for C. Notably &&, ||, ?: and ! are not available. typedef long long v2i64 __attribute__((vector_size(16))); +// this type is specifically used as the result type of comparison of v2i64 +typedef long v2i_long __attribute__((vector_size(16))); typedef int v2i32 __attribute__((vector_size(8))); typedef short v2i16 __attribute__((vector_size(4))); typedef char v2i8 __attribute__((vector_size(2))); @@ -81,7 +83,7 @@ void arithmeticTest(void) { void comparisonTest(void) { v2i64 v2i64_a = (v2i64){0, 1}; - v2i64 v2i64_r; + v2i_long v2i64_r; v2i64_r = v2i64_a == 1; v2i64_r = v2i64_a != 1; @@ -166,7 +168,7 @@ void floatTestConstantComparison(void) { void doubleTestConstantComparison(void) { v2f64 v2f64_a = {0.4, 0.4}; - v2i64 v2i64_r; + v2i_long v2i64_r; v2i64_r = v2f64_a > 0.4; v2i64_r = v2f64_a >= 0.4; v2i64_r = v2f64_a < 0.4; diff --git a/clang/test/Sema/vector-gcc-compat.cpp b/clang/test/Sema/vector-gcc-compat.cpp index 42c24d91ea8f3..e66cee128cd90 100644 --- a/clang/test/Sema/vector-gcc-compat.cpp +++ b/clang/test/Sema/vector-gcc-compat.cpp @@ -5,6 +5,8 @@ // || operators work on vector types. typedef long long v2i64 __attribute__((vector_size(16))); // expected-warning {{'long long' is incompatible with C++98}} +// this type is specifically used as the result type of comparison of v2i64 +typedef long v2i_long __attribute__((vector_size(16))); typedef int v2i32 __attribute__((vector_size(8))); typedef short v2i16 __attribute__((vector_size(4))); typedef char v2i8 __attribute__((vector_size(2))); @@ -60,7 +62,7 @@ void arithmeticTest(void) { void comparisonTest(void) { v2i64 v2i64_a = (v2i64){0, 1}; // expected-warning {{compound literals are a C99-specific feature}} - v2i64 v2i64_r; + v2i_long v2i64_r; v2i64_r = v2i64_a == 1; v2i64_r = v2i64_a != 1; @@ -141,7 +143,7 @@ void floatTestConstantComparison(void) { void doubleTestConstantComparison(void) { v2f64 v2f64_a = {0.4, 0.4}; - v2i64 v2i64_r; + v2i_long v2i64_r; v2i64_r = v2f64_a > 0.4; v2i64_r = v2f64_a >= 0.4; v2i64_r = v2f64_a < 0.4; >From 9f51acabbdb13fec9184afb6506867db5b3886f0 Mon Sep 17 00:00:00 2001 From: Imple Lee <80144331+imple...@users.noreply.github.com> Date: Sun, 20 Jul 2025 00:11:02 +0800 Subject: [PATCH 2/3] use the logic of determining vector type for `mode` attribute They seem to be the same in GCC --- clang/include/clang/AST/ASTContext.h | 8 ++++++++ clang/lib/AST/ASTContext.cpp | 23 +++++++++++++++++++++++ clang/lib/Sema/SemaDeclAttr.cpp | 3 +-- clang/lib/Sema/SemaExpr.cpp | 22 +++------------------- 4 files changed, 35 insertions(+), 21 deletions(-) diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 2b9cd035623cc..606e451771f6b 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -876,6 +876,14 @@ class ASTContext : public RefCountedBase<ASTContext> { QualType getIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const; + /// getGCCCompatibleIntTypeForBitwidth - + /// sets integer QualTy according to specified details: + /// bitwidth, signed/unsigned. + /// this function is compatible with GCC's preference: + /// int > signed char > short > long > long long > int128_t + /// Returns empty type if there is no appropriate target types. + QualType getGCCCompatibleIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const; + /// getRealTypeForBitwidth - /// sets floating point QualTy according to specified bitwidth. /// Returns empty type if there is no appropriate target types. diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index b13bdd5642977..f3367a5a6eb48 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -13206,6 +13206,29 @@ QualType ASTContext::getIntTypeForBitwidth(unsigned DestWidth, return QualTy; } +/// getGCCCompatibleIntTypeForBitwidth - +/// sets integer QualTy according to specified details: +/// bitwidth, signed/unsigned. +/// this function is compatible with GCC's preference: +/// int > signed char > short > long > long long > int128_t +/// Returns empty type if there is no appropriate target types. +QualType ASTContext::getGCCCompatibleIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const { + const TargetInfo &Target = getTargetInfo(); + if (Target.getIntWidth() == DestWidth) + return Signed ? IntTy : UnsignedIntTy; + if (Target.getCharWidth() == DestWidth) + return Signed ? SignedCharTy : UnsignedCharTy; + if (Target.getShortWidth() == DestWidth) + return Signed ? ShortTy : UnsignedShortTy; + if (Target.getLongWidth() == DestWidth) + return Signed ? LongTy : UnsignedLongTy; + if (Target.getLongLongWidth() == DestWidth) + return Signed ? LongLongTy : UnsignedLongLongTy; + if (DestWidth == 128) + return Signed ? Int128Ty : UnsignedInt128Ty; + return {}; +} + /// getRealTypeForBitwidth - /// sets floating point QualTy according to specified bitwidth. /// Returns empty type if there is no appropriate target types. diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 52313e6a15ff1..58736f9080086 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -4949,8 +4949,7 @@ void Sema::AddModeAttr(Decl *D, const AttributeCommonInfo &CI, QualType NewElemTy; if (IntegerMode) - NewElemTy = Context.getIntTypeForBitwidth(DestWidth, - OldElemTy->isSignedIntegerType()); + NewElemTy = Context.getGCCCompatibleIntTypeForBitwidth(DestWidth, OldElemTy->isSignedIntegerType()); else NewElemTy = Context.getRealTypeForBitwidth(DestWidth, ExplicitType); diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 8a81cda9912f7..01fc5f13daf88 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -12901,25 +12901,9 @@ QualType Sema::GetSignedVectorType(QualType V) { return Context.getExtVectorType(Context.LongLongTy, VTy->getNumElements()); } - if (TypeSize == Context.getTypeSize(Context.IntTy)) - return Context.getVectorType(Context.IntTy, VTy->getNumElements(), - VectorKind::Generic); - if (TypeSize == Context.getTypeSize(Context.SignedCharTy)) - return Context.getVectorType(Context.SignedCharTy, VTy->getNumElements(), - VectorKind::Generic); - if (TypeSize == Context.getTypeSize(Context.ShortTy)) - return Context.getVectorType(Context.ShortTy, VTy->getNumElements(), - VectorKind::Generic); - if (TypeSize == Context.getTypeSize(Context.LongTy)) - return Context.getVectorType(Context.LongTy, VTy->getNumElements(), - VectorKind::Generic); - if (TypeSize == Context.getTypeSize(Context.LongLongTy)) - return Context.getVectorType(Context.LongLongTy, VTy->getNumElements(), - VectorKind::Generic); - assert(TypeSize == Context.getTypeSize(Context.Int128Ty) && - "Unhandled vector element size in vector compare"); - return Context.getVectorType(Context.Int128Ty, VTy->getNumElements(), - VectorKind::Generic); + QualType ETy = Context.getGCCCompatibleIntTypeForBitwidth(TypeSize, 1); + assert(!ETy.isNull() && "Unhandled vector element size in vector compare"); + return Context.getVectorType(ETy, VTy->getNumElements(), VectorKind::Generic); } QualType Sema::GetSignedSizelessVectorType(QualType V) { >From dcde7fd25e0db99966b68ec9399a89fa5db4f259 Mon Sep 17 00:00:00 2001 From: Imple Lee <80144331+imple...@users.noreply.github.com> Date: Sun, 20 Jul 2025 00:12:25 +0800 Subject: [PATCH 3/3] clang-format --- clang/include/clang/AST/ASTContext.h | 3 ++- clang/lib/AST/ASTContext.cpp | 3 ++- clang/lib/Sema/SemaDeclAttr.cpp | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 606e451771f6b..051d357d027e4 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -882,7 +882,8 @@ class ASTContext : public RefCountedBase<ASTContext> { /// this function is compatible with GCC's preference: /// int > signed char > short > long > long long > int128_t /// Returns empty type if there is no appropriate target types. - QualType getGCCCompatibleIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const; + QualType getGCCCompatibleIntTypeForBitwidth(unsigned DestWidth, + unsigned Signed) const; /// getRealTypeForBitwidth - /// sets floating point QualTy according to specified bitwidth. diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index f3367a5a6eb48..0e4ce88a1ce8a 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -13212,7 +13212,8 @@ QualType ASTContext::getIntTypeForBitwidth(unsigned DestWidth, /// this function is compatible with GCC's preference: /// int > signed char > short > long > long long > int128_t /// Returns empty type if there is no appropriate target types. -QualType ASTContext::getGCCCompatibleIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const { +QualType ASTContext::getGCCCompatibleIntTypeForBitwidth(unsigned DestWidth, + unsigned Signed) const { const TargetInfo &Target = getTargetInfo(); if (Target.getIntWidth() == DestWidth) return Signed ? IntTy : UnsignedIntTy; diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 58736f9080086..413a274a2a577 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -4949,7 +4949,8 @@ void Sema::AddModeAttr(Decl *D, const AttributeCommonInfo &CI, QualType NewElemTy; if (IntegerMode) - NewElemTy = Context.getGCCCompatibleIntTypeForBitwidth(DestWidth, OldElemTy->isSignedIntegerType()); + NewElemTy = Context.getGCCCompatibleIntTypeForBitwidth( + DestWidth, OldElemTy->isSignedIntegerType()); else NewElemTy = Context.getRealTypeForBitwidth(DestWidth, ExplicitType); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits