Skip to content

Commit 6be0d40

Browse files
authored
Merge pull request #130 from sx-aurora-dev/merge/clang-vector-constexpr-unary
Merge/clang vector constexpr unary
2 parents 65140a3 + eabcce4 commit 6be0d40

File tree

3 files changed

+210
-60
lines changed

3 files changed

+210
-60
lines changed

clang/lib/AST/ExprConstant.cpp

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2931,6 +2931,11 @@ handleCompareOpForVectorHelper(const APTy &LHSValue, BinaryOperatorKind Opcode,
29312931
break;
29322932
}
29332933

2934+
// The boolean operations on these vector types use an instruction that
2935+
// results in a mask of '-1' for the 'truth' value. Ensure that we negate 1
2936+
// to -1 to make sure that we produce the correct value.
2937+
Result.negate();
2938+
29342939
return true;
29352940
}
29362941

@@ -10179,7 +10184,8 @@ namespace {
1017910184
bool VisitInitListExpr(const InitListExpr *E);
1018010185
bool VisitUnaryImag(const UnaryOperator *E);
1018110186
bool VisitBinaryOperator(const BinaryOperator *E);
10182-
// FIXME: Missing: unary -, unary ~, conditional operator (for GNU
10187+
bool VisitUnaryOperator(const UnaryOperator *E);
10188+
// FIXME: Missing: conditional operator (for GNU
1018310189
// conditional select), shufflevector, ExtVectorElementExpr
1018410190
};
1018510191
} // end anonymous namespace
@@ -10364,6 +10370,83 @@ bool VectorExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
1036410370
return Success(LHSValue, E);
1036510371
}
1036610372

10373+
static llvm::Optional<APValue> handleVectorUnaryOperator(ASTContext &Ctx,
10374+
QualType ResultTy,
10375+
UnaryOperatorKind Op,
10376+
APValue Elt) {
10377+
switch (Op) {
10378+
case UO_Plus:
10379+
// Nothing to do here.
10380+
return Elt;
10381+
case UO_Minus:
10382+
if (Elt.getKind() == APValue::Int) {
10383+
Elt.getInt().negate();
10384+
} else {
10385+
assert(Elt.getKind() == APValue::Float &&
10386+
"Vector can only be int or float type");
10387+
Elt.getFloat().changeSign();
10388+
}
10389+
return Elt;
10390+
case UO_Not:
10391+
// This is only valid for integral types anyway, so we don't have to handle
10392+
// float here.
10393+
assert(Elt.getKind() == APValue::Int &&
10394+
"Vector operator ~ can only be int");
10395+
Elt.getInt().flipAllBits();
10396+
return Elt;
10397+
case UO_LNot: {
10398+
if (Elt.getKind() == APValue::Int) {
10399+
Elt.getInt() = !Elt.getInt();
10400+
// operator ! on vectors returns -1 for 'truth', so negate it.
10401+
Elt.getInt().negate();
10402+
return Elt;
10403+
}
10404+
assert(Elt.getKind() == APValue::Float &&
10405+
"Vector can only be int or float type");
10406+
// Float types result in an int of the same size, but -1 for true, or 0 for
10407+
// false.
10408+
APSInt EltResult{Ctx.getIntWidth(ResultTy),
10409+
ResultTy->isUnsignedIntegerType()};
10410+
if (Elt.getFloat().isZero())
10411+
EltResult.setAllBits();
10412+
else
10413+
EltResult.clearAllBits();
10414+
10415+
return APValue{EltResult};
10416+
}
10417+
default:
10418+
// FIXME: Implement the rest of the unary operators.
10419+
return llvm::None;
10420+
}
10421+
}
10422+
10423+
bool VectorExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
10424+
Expr *SubExpr = E->getSubExpr();
10425+
const auto *VD = SubExpr->getType()->castAs<VectorType>();
10426+
// This result element type differs in the case of negating a floating point
10427+
// vector, since the result type is the a vector of the equivilant sized
10428+
// integer.
10429+
const QualType ResultEltTy = VD->getElementType();
10430+
UnaryOperatorKind Op = E->getOpcode();
10431+
10432+
APValue SubExprValue;
10433+
if (!Evaluate(SubExprValue, Info, SubExpr))
10434+
return false;
10435+
10436+
assert(SubExprValue.getVectorLength() == VD->getNumElements() &&
10437+
"Vector length doesn't match type?");
10438+
10439+
SmallVector<APValue, 4> ResultElements;
10440+
for (unsigned EltNum = 0; EltNum < VD->getNumElements(); ++EltNum) {
10441+
llvm::Optional<APValue> Elt = handleVectorUnaryOperator(
10442+
Info.Ctx, ResultEltTy, Op, SubExprValue.getVectorElt(EltNum));
10443+
if (!Elt)
10444+
return false;
10445+
ResultElements.push_back(*Elt);
10446+
}
10447+
return Success(APValue(ResultElements.data(), ResultElements.size()), E);
10448+
}
10449+
1036710450
//===----------------------------------------------------------------------===//
1036810451
// Array Evaluation
1036910452
//===----------------------------------------------------------------------===//

clang/lib/Sema/SemaExpr.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12297,11 +12297,13 @@ QualType Sema::GetSignedVectorType(QualType V) {
1229712297
if (isa<ExtVectorType>(VTy)) {
1229812298
if (TypeSize == Context.getTypeSize(Context.CharTy))
1229912299
return Context.getExtVectorType(Context.CharTy, VTy->getNumElements());
12300-
else if (TypeSize == Context.getTypeSize(Context.ShortTy))
12300+
if (TypeSize == Context.getTypeSize(Context.ShortTy))
1230112301
return Context.getExtVectorType(Context.ShortTy, VTy->getNumElements());
12302-
else if (TypeSize == Context.getTypeSize(Context.IntTy))
12302+
if (TypeSize == Context.getTypeSize(Context.IntTy))
1230312303
return Context.getExtVectorType(Context.IntTy, VTy->getNumElements());
12304-
else if (TypeSize == Context.getTypeSize(Context.LongTy))
12304+
if (TypeSize == Context.getTypeSize(Context.Int128Ty))
12305+
return Context.getExtVectorType(Context.Int128Ty, VTy->getNumElements());
12306+
if (TypeSize == Context.getTypeSize(Context.LongTy))
1230512307
return Context.getExtVectorType(Context.LongTy, VTy->getNumElements());
1230612308
assert(TypeSize == Context.getTypeSize(Context.LongLongTy) &&
1230712309
"Unhandled vector element size in vector compare");
@@ -12310,16 +12312,19 @@ QualType Sema::GetSignedVectorType(QualType V) {
1231012312

1231112313
if (VTy->isExtVectorBoolType())
1231212314
return Context.getExtVectorType(Context.BoolTy, VTy->getNumElements());
12313-
else if (TypeSize == Context.getTypeSize(Context.LongLongTy))
12315+
if (TypeSize == Context.getTypeSize(Context.Int128Ty))
12316+
return Context.getVectorType(Context.Int128Ty, VTy->getNumElements(),
12317+
VectorType::GenericVector);
12318+
if (TypeSize == Context.getTypeSize(Context.LongLongTy))
1231412319
return Context.getVectorType(Context.LongLongTy, VTy->getNumElements(),
1231512320
VectorType::GenericVector);
12316-
else if (TypeSize == Context.getTypeSize(Context.LongTy))
12321+
if (TypeSize == Context.getTypeSize(Context.LongTy))
1231712322
return Context.getVectorType(Context.LongTy, VTy->getNumElements(),
1231812323
VectorType::GenericVector);
12319-
else if (TypeSize == Context.getTypeSize(Context.IntTy))
12324+
if (TypeSize == Context.getTypeSize(Context.IntTy))
1232012325
return Context.getVectorType(Context.IntTy, VTy->getNumElements(),
1232112326
VectorType::GenericVector);
12322-
else if (TypeSize == Context.getTypeSize(Context.ShortTy))
12327+
if (TypeSize == Context.getTypeSize(Context.ShortTy))
1232312328
return Context.getVectorType(Context.ShortTy, VTy->getNumElements(),
1232412329
VectorType::GenericVector);
1232512330
assert(TypeSize == Context.getTypeSize(Context.CharTy) &&

0 commit comments

Comments
 (0)