-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[clang][ExprConst] Reject unary vector shuffles #158589
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
Conversation
This is not implemented at compile time and asserts later in codegen, so reject it here.
@llvm/pr-subscribers-clang Author: Timm Baeder (tbaederr) ChangesThis is not implemented at compile time and asserts later in codegen, so reject it here. Fixed the coding style in Fixes #158471 Full diff: https://github.com/llvm/llvm-project/pull/158589.diff 4 Files Affected:
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index 78b74acc3789d..99f4bfbea973d 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -3986,6 +3986,10 @@ bool Compiler<Emitter>::VisitConvertVectorExpr(const ConvertVectorExpr *E) {
template <class Emitter>
bool Compiler<Emitter>::VisitShuffleVectorExpr(const ShuffleVectorExpr *E) {
+ // FIXME: Unary shuffle with mask not currently supported.
+ if (E->getNumSubExprs() == 2)
+ return this->emitInvalid(E);
+
assert(Initializing);
assert(E->getNumSubExprs() > 2);
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 820b053057067..f80691f57e602 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -12160,6 +12160,9 @@ static bool handleVectorShuffle(EvalInfo &Info, const ShuffleVectorExpr *E,
}
bool VectorExprEvaluator::VisitShuffleVectorExpr(const ShuffleVectorExpr *E) {
+ // FIXME: Unary shuffle with mask not currently supported.
+ if (E->getNumSubExprs() == 2)
+ return Error(E);
APValue VecVal1;
const Expr *Vec1 = E->getExpr(0);
if (!EvaluateAsRValue(Info, Vec1, VecVal1))
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 077f4311ed729..446d3ceb1b45e 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -5558,7 +5558,8 @@ bool Sema::BuiltinComplex(CallExpr *TheCall) {
/// BuiltinShuffleVector - Handle __builtin_shufflevector.
// This is declared to take (...), so we have to check everything.
ExprResult Sema::BuiltinShuffleVector(CallExpr *TheCall) {
- if (TheCall->getNumArgs() < 2)
+ unsigned NumArgs = TheCall->getNumArgs();
+ if (NumArgs < 2)
return ExprError(Diag(TheCall->getEndLoc(),
diag::err_typecheck_call_too_few_args_at_least)
<< 0 /*function call*/ << 2 << TheCall->getNumArgs()
@@ -5567,8 +5568,8 @@ ExprResult Sema::BuiltinShuffleVector(CallExpr *TheCall) {
// Determine which of the following types of shufflevector we're checking:
// 1) unary, vector mask: (lhs, mask)
// 2) binary, scalar mask: (lhs, rhs, index, ..., index)
- QualType resType = TheCall->getArg(0)->getType();
- unsigned numElements = 0;
+ QualType ResType = TheCall->getArg(0)->getType();
+ unsigned NumElements = 0;
if (!TheCall->getArg(0)->isTypeDependent() &&
!TheCall->getArg(1)->isTypeDependent()) {
@@ -5582,39 +5583,39 @@ ExprResult Sema::BuiltinShuffleVector(CallExpr *TheCall) {
<< SourceRange(TheCall->getArg(0)->getBeginLoc(),
TheCall->getArg(1)->getEndLoc()));
- numElements = LHSType->castAs<VectorType>()->getNumElements();
- unsigned numResElements = TheCall->getNumArgs() - 2;
+ NumElements = LHSType->castAs<VectorType>()->getNumElements();
+ unsigned NumResElements = TheCall->getNumArgs() - 2;
// Check to see if we have a call with 2 vector arguments, the unary shuffle
// with mask. If so, verify that RHS is an integer vector type with the
// same number of elts as lhs.
if (TheCall->getNumArgs() == 2) {
if (!RHSType->hasIntegerRepresentation() ||
- RHSType->castAs<VectorType>()->getNumElements() != numElements)
+ RHSType->castAs<VectorType>()->getNumElements() != NumElements)
return ExprError(Diag(TheCall->getBeginLoc(),
diag::err_vec_builtin_incompatible_vector)
<< TheCall->getDirectCallee()
- << /*isMorethantwoArgs*/ false
+ << /*isMoreThanTwoArgs*/ false
<< SourceRange(TheCall->getArg(1)->getBeginLoc(),
TheCall->getArg(1)->getEndLoc()));
} else if (!Context.hasSameUnqualifiedType(LHSType, RHSType)) {
return ExprError(Diag(TheCall->getBeginLoc(),
diag::err_vec_builtin_incompatible_vector)
<< TheCall->getDirectCallee()
- << /*isMorethantwoArgs*/ false
+ << /*isMoreThanTwoArgs*/ false
<< SourceRange(TheCall->getArg(0)->getBeginLoc(),
TheCall->getArg(1)->getEndLoc()));
- } else if (numElements != numResElements) {
+ } else if (NumElements != NumResElements) {
QualType eltType = LHSType->castAs<VectorType>()->getElementType();
- resType = resType->isExtVectorType()
- ? Context.getExtVectorType(eltType, numResElements)
- : Context.getVectorType(eltType, numResElements,
+ ResType = ResType->isExtVectorType()
+ ? Context.getExtVectorType(eltType, NumResElements)
+ : Context.getVectorType(eltType, NumResElements,
VectorKind::Generic);
}
}
- for (unsigned i = 2; i < TheCall->getNumArgs(); i++) {
- Expr *Arg = TheCall->getArg(i);
+ for (unsigned I = 2; I != NumArgs; ++I) {
+ Expr *Arg = TheCall->getArg(I);
if (Arg->isTypeDependent() || Arg->isValueDependent())
continue;
@@ -5628,21 +5629,21 @@ ExprResult Sema::BuiltinShuffleVector(CallExpr *TheCall) {
if (Result->isSigned() && Result->isAllOnes())
;
else if (Result->getActiveBits() > 64 ||
- Result->getZExtValue() >= numElements * 2)
+ Result->getZExtValue() >= NumElements * 2)
return ExprError(Diag(TheCall->getBeginLoc(),
diag::err_shufflevector_argument_too_large)
<< Arg->getSourceRange());
- TheCall->setArg(i, ConstantExpr::Create(Context, Arg, APValue(*Result)));
+ TheCall->setArg(I, ConstantExpr::Create(Context, Arg, APValue(*Result)));
}
- SmallVector<Expr *> exprs;
- for (unsigned i = 0, e = TheCall->getNumArgs(); i != e; i++) {
- exprs.push_back(TheCall->getArg(i));
- TheCall->setArg(i, nullptr);
+ SmallVector<Expr *> Exprs;
+ for (unsigned I = 0; I != NumArgs; I++) {
+ Exprs.push_back(TheCall->getArg(I));
+ TheCall->setArg(I, nullptr);
}
- return new (Context) ShuffleVectorExpr(Context, exprs, resType,
+ return new (Context) ShuffleVectorExpr(Context, Exprs, ResType,
TheCall->getCallee()->getBeginLoc(),
TheCall->getRParenLoc());
}
diff --git a/clang/test/Sema/constant-builtins-vector.cpp b/clang/test/Sema/constant-builtins-vector.cpp
index 714a7fb753214..455284ef65e9b 100644
--- a/clang/test/Sema/constant-builtins-vector.cpp
+++ b/clang/test/Sema/constant-builtins-vector.cpp
@@ -731,6 +731,19 @@ permitted in a constexpr context}}
vector4charConst1,
vector4charConst2, -1, -1, -1, -1);
+namespace UnaryShuffleUnsupported {
+ typedef int vi6 __attribute__((ext_vector_type(2)));
+ constexpr int foo() { // expected-error {{never produces a constant expression}}
+ vi6 a = {1,2};
+ vi6 b = {3,4};
+ vi6 r = __builtin_shufflevector(a, b); // expected-note 2{{subexpression not valid in a constant expression}}
+
+ return r[0] + r[1];
+ }
+ static_assert(foo() == 0); // expected-error {{not an integral constant expression}} \
+ // expected-note {{in call to}}
+}
+
static_assert(__builtin_reduce_add((vector4char){}) == 0);
static_assert(__builtin_reduce_add((vector4char){1, 2, 3, 4}) == 10);
static_assert(__builtin_reduce_add((vector4short){10, 20, 30, 40}) == 100);
|
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.
Thank you for the fix, I think it looks good. Can we add a release note so the users know it is not supported yet and will be rejected for now?
Added. |
This is not implemented at compile time and asserts in assertion builds, so reject it here.
Fixed the coding style in
BuiltinShuffleVector
at the same time.Fixes #158471