Skip to content

Commit 9ca8248

Browse files
authored
[clang] Save ShuffleVectorExpr args as ConstantExpr (#139709)
The passed indices have to be constant integers anyway, which we verify before creating the ShuffleVectorExpr. Use the value we create there and save the indices using a ConstantExpr instead. This way, we don't have to evaluate the args every time we call getShuffleMaskIdx().
1 parent edc9d91 commit 9ca8248

File tree

6 files changed

+22
-18
lines changed

6 files changed

+22
-18
lines changed

clang/include/clang/AST/Expr.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4566,9 +4566,11 @@ class ShuffleVectorExpr : public Expr {
45664566

45674567
void setExprs(const ASTContext &C, ArrayRef<Expr *> Exprs);
45684568

4569-
llvm::APSInt getShuffleMaskIdx(const ASTContext &Ctx, unsigned N) const {
4569+
llvm::APSInt getShuffleMaskIdx(unsigned N) const {
45704570
assert((N < NumExprs - 2) && "Shuffle idx out of range!");
4571-
return getExpr(N+2)->EvaluateKnownConstInt(Ctx);
4571+
assert(isa<ConstantExpr>(getExpr(N + 2)) &&
4572+
"Index expression must be a ConstantExpr");
4573+
return cast<ConstantExpr>(getExpr(N + 2))->getAPValueResult().getInt();
45724574
}
45734575

45744576
// Iterators

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3883,7 +3883,7 @@ bool Compiler<Emitter>::VisitShuffleVectorExpr(const ShuffleVectorExpr *E) {
38833883
return false;
38843884
}
38853885
for (unsigned I = 0; I != NumOutputElems; ++I) {
3886-
APSInt ShuffleIndex = E->getShuffleMaskIdx(Ctx.getASTContext(), I);
3886+
APSInt ShuffleIndex = E->getShuffleMaskIdx(I);
38873887
assert(ShuffleIndex >= -1);
38883888
if (ShuffleIndex == -1)
38893889
return this->emitInvalidShuffleVectorIndex(I, E);

clang/lib/AST/ExprConstant.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11571,7 +11571,7 @@ static bool handleVectorShuffle(EvalInfo &Info, const ShuffleVectorExpr *E,
1157111571
unsigned const TotalElementsInInputVector1 = VecVal1.getVectorLength();
1157211572
unsigned const TotalElementsInInputVector2 = VecVal2.getVectorLength();
1157311573

11574-
APSInt IndexVal = E->getShuffleMaskIdx(Info.Ctx, EltNum);
11574+
APSInt IndexVal = E->getShuffleMaskIdx(EltNum);
1157511575
int64_t index = IndexVal.getExtValue();
1157611576
// The spec says that -1 should be treated as undef for optimizations,
1157711577
// but in constexpr we'd have to produce an APValue::Indeterminate,

clang/lib/CodeGen/CGExprScalar.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1906,7 +1906,7 @@ Value *ScalarExprEmitter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
19061906

19071907
SmallVector<int, 32> Indices;
19081908
for (unsigned i = 2; i < E->getNumSubExprs(); ++i) {
1909-
llvm::APSInt Idx = E->getShuffleMaskIdx(CGF.getContext(), i-2);
1909+
llvm::APSInt Idx = E->getShuffleMaskIdx(i - 2);
19101910
// Check for -1 and output it as undef in the IR.
19111911
if (Idx.isSigned() && Idx.isAllOnes())
19121912
Indices.push_back(-1);

clang/lib/Sema/SemaChecking.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5342,29 +5342,29 @@ ExprResult Sema::BuiltinShuffleVector(CallExpr *TheCall) {
53425342
}
53435343

53445344
for (unsigned i = 2; i < TheCall->getNumArgs(); i++) {
5345-
if (TheCall->getArg(i)->isTypeDependent() ||
5346-
TheCall->getArg(i)->isValueDependent())
5345+
Expr *Arg = TheCall->getArg(i);
5346+
if (Arg->isTypeDependent() || Arg->isValueDependent())
53475347
continue;
53485348

53495349
std::optional<llvm::APSInt> Result;
5350-
if (!(Result = TheCall->getArg(i)->getIntegerConstantExpr(Context)))
5350+
if (!(Result = Arg->getIntegerConstantExpr(Context)))
53515351
return ExprError(Diag(TheCall->getBeginLoc(),
53525352
diag::err_shufflevector_nonconstant_argument)
5353-
<< TheCall->getArg(i)->getSourceRange());
5353+
<< Arg->getSourceRange());
53545354

53555355
// Allow -1 which will be translated to undef in the IR.
53565356
if (Result->isSigned() && Result->isAllOnes())
5357-
continue;
5358-
5359-
if (Result->getActiveBits() > 64 ||
5360-
Result->getZExtValue() >= numElements * 2)
5357+
;
5358+
else if (Result->getActiveBits() > 64 ||
5359+
Result->getZExtValue() >= numElements * 2)
53615360
return ExprError(Diag(TheCall->getBeginLoc(),
53625361
diag::err_shufflevector_argument_too_large)
5363-
<< TheCall->getArg(i)->getSourceRange());
5364-
}
5362+
<< Arg->getSourceRange());
53655363

5366-
SmallVector<Expr*, 32> exprs;
5364+
TheCall->setArg(i, ConstantExpr::Create(Context, Arg, APValue(*Result)));
5365+
}
53675366

5367+
SmallVector<Expr *> exprs;
53685368
for (unsigned i = 0, e = TheCall->getNumArgs(); i != e; i++) {
53695369
exprs.push_back(TheCall->getArg(i));
53705370
TheCall->setArg(i, nullptr);

clang/unittests/AST/ASTImporterTest.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -308,8 +308,10 @@ TEST_P(ImportExpr, ImportShuffleVectorExpr) {
308308
const auto Pattern = functionDecl(hasDescendant(shuffleVectorExpr(
309309
allOf(has(declRefExpr(to(parmVarDecl(hasName("a"))))),
310310
has(declRefExpr(to(parmVarDecl(hasName("b"))))),
311-
has(integerLiteral(equals(0))), has(integerLiteral(equals(1))),
312-
has(integerLiteral(equals(2))), has(integerLiteral(equals(3)))))));
311+
has(constantExpr(has(integerLiteral(equals(0))))),
312+
has(constantExpr(has(integerLiteral(equals(1))))),
313+
has(constantExpr(has(integerLiteral(equals(2))))),
314+
has(constantExpr(has(integerLiteral(equals(3)))))))));
313315
testImport(Code, Lang_C99, "", Lang_C99, Verifier, Pattern);
314316
}
315317

0 commit comments

Comments
 (0)