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

Reply via email to