-
Notifications
You must be signed in to change notification settings - Fork 14.5k
[clang] improve consistency with GCC vector comparison #148954
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the LLVM GitHub User Guide. You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums. |
@llvm/pr-subscribers-clang Author: Imple Lee (ImpleLee) Changesfixes issue #132604 GCC's order of types of vector comparison should be Full diff: https://github.com/llvm/llvm-project/pull/148954.diff 3 Files Affected:
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;
|
clang/lib/Sema/SemaExpr.cpp
Outdated
if (TypeSize == Context.getTypeSize(Context.IntTy)) | ||
return Context.getVectorType(Context.IntTy, VTy->getNumElements(), | ||
VectorKind::Generic); | ||
if (TypeSize == Context.getTypeSize(Context.SignedCharTy)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does the ordering of these matter since they are doing direct comparison of size? The only thing that seems to matter here is the order of long vs long-long, since they can be the same size, right? So only those two need to swap?
But otherwise putting these in any sort of order should have some sort of semblence of ordering if we're going for that. For example, int before char is... awkward. We should probably make sure we're doing this in the 'rank order' from C/C++.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are several other inconsistencies:
signed char
should be used instead ofchar
int
should be prioritized over other types, so on ILP32 and LLP64, the resultant types should just beint
instead oflong
.
Maybe it is better to just duplicate the GCC type order to ensure compatibility.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do think making int
before char
is awkward, but if we want to be totally consistent with GCC, following their rule is possibly the best way...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe a better option is to communicate with GCC developers to decide a not-so-awkward (and also backward-compatible and explicit) rule.
Originally posted by @zygoloid in #132604 I now prefer this proposal over the current PR. I will convert this PR into a draft PR when implementing it, and ask for review again after that. |
They seem to be the same in GCC
Now I make a utility function There is currently no test about this, but I don't know how to or even whether should I write relevant tests. There are many other places in clang that uses |
fixes issue #132604
GCC's preference of vector comparison types should be
int > signed char > short > long > long long
, so I just duplicate that.reference: gcc-help mailing list: https://gcc.gnu.org/pipermail/gcc-help/2025-July/144357.html