[clang] [clang] improve consistency with GCC vector comparison (PR #148954)
Imple Lee via cfe-commits
cfe-commits at lists.llvm.org
Sat Jul 19 09:12:54 PDT 2025
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+ImpleLee at 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+ImpleLee at 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+ImpleLee at 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);
More information about the cfe-commits
mailing list