-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[clang] Support constexpr bitcasts between equal-size vector and integer types #167016
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: None (Lokesh-Reddy011) ChangesDescriptionThis patch fixes an issue where constexpr evaluation failed for bitcasts between vector and integer types of equal bit width (e.g., The change updates ExampleThe following code previously failed but now compiles successfully with the patch: #include <immintrin.h>
constexpr __m64 foo(__m64 a, int b) {
return (__m64)(long long)a << b;
}
int main() {
foo((__m64){5}, 1);
return 0;
}Testing
Full diff: https://github.com/llvm/llvm-project/pull/167016.diff 1 Files Affected:
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 97eeba8b9d6cc..5b8900f02aeb9 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -17078,7 +17078,24 @@ bool IntExprEvaluator::VisitCastExpr(const CastExpr *E) {
case CK_HLSLAggregateSplatCast:
llvm_unreachable("invalid cast kind for integral value");
- case CK_BitCast:
+ case CK_BitCast:{
+ APValue Sub;
+ if (!Evaluate(Sub, Info, E->getSubExpr()))
+ return false;
+
+ QualType SrcTy = E->getSubExpr()->getType();
+ QualType DstTy = E->getType();
+
+ // Allow reinterpretation if bit widths match
+ if (Info.Ctx.getTypeSize(SrcTy) == Info.Ctx.getTypeSize(DstTy)) {
+ // Use APValue::BitCast if available, else just copy value bits
+ Result = Sub;
+ return true;
+ }
+
+ return Error(E);
+}
+
case CK_Dependent:
case CK_LValueBitCast:
case CK_ARCProduceObject:
|
|
Please let me know if further modifications or additional test coverage are recommended. |
You can test this locally with the following command:git-clang-format --diff origin/main HEAD --extensions cpp -- clang/lib/AST/ExprConstant.cpp --diff_from_common_commit
View the diff from clang-format here.diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 9c958c0e1..fd20bcd0c 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -17724,23 +17724,23 @@ bool IntExprEvaluator::VisitCastExpr(const CastExpr *E) {
case CK_HLSLAggregateSplatCast:
llvm_unreachable("invalid cast kind for integral value");
- case CK_BitCast:{
- APValue Sub;
- if (!Evaluate(Sub, Info, E->getSubExpr()))
- return false;
+ case CK_BitCast: {
+ APValue Sub;
+ if (!Evaluate(Sub, Info, E->getSubExpr()))
+ return false;
- QualType SrcTy = E->getSubExpr()->getType();
- QualType DstTy = E->getType();
+ QualType SrcTy = E->getSubExpr()->getType();
+ QualType DstTy = E->getType();
- // Allow reinterpretation if bit widths match
- if (Info.Ctx.getTypeSize(SrcTy) == Info.Ctx.getTypeSize(DstTy)) {
- // Use APValue::BitCast if available, else just copy value bits
- Result = Sub;
- return true;
- }
+ // Allow reinterpretation if bit widths match
+ if (Info.Ctx.getTypeSize(SrcTy) == Info.Ctx.getTypeSize(DstTy)) {
+ // Use APValue::BitCast if available, else just copy value bits
+ Result = Sub;
+ return true;
+ }
- return Error(E);
-}
+ return Error(E);
+ }
case CK_Dependent:
case CK_LValueBitCast:
|
|
You should be able to create a generic test without including anything: typedef long long __m64 __attribute__((__vector_size__(8), __aligned__(8)));
constexpr __m64 PR159905(__m64 a, int b) {
return (__m64)(long long)a << b;
}
|
|
|
||
| // Allow reinterpretation if bit widths match | ||
| if (Info.Ctx.getTypeSize(SrcTy) == Info.Ctx.getTypeSize(DstTy)) { | ||
| // Use APValue::BitCast if available, else just copy value bits |
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.
What is APValue::BitCast?
| case CK_BitCast: | ||
| case CK_BitCast:{ | ||
| APValue Sub; | ||
| if (!Evaluate(Sub, Info, E->getSubExpr())) |
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.
We know the types before evaluating the subexpression, so we don't have to do this unless the sizes match.
RKSimon
left a comment
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.
test coverage
Description
This patch fixes an issue where constexpr evaluation failed for bitcasts between vector and integer types of equal bit width (e.g.,
__m64↔long long).The change updates
ExprConstant.cppto allow reinterpretation when source and destination types have matching bit sizes. In that case, theAPValueis copied directly instead of producing an error.Fixes #159905
Example
The following code previously failed but now compiles successfully with the patch:
Testing
clang++ -std=c++20— works correctly after the patch.clang/testsince it requires<immintrin.h>, whose path varies across systems.