erichkeane updated this revision to Diff 394230.
erichkeane added a comment.
Enable __int128 vectors, and fix the issue of the >64 bit vectors for negation.
Also add a test for these.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D115670/new/
https://reviews.llvm.org/D115670
Files:
clang/lib/AST/ExprConstant.cpp
clang/lib/Sema/SemaExpr.cpp
clang/test/SemaCXX/constexpr-vectors.cpp
Index: clang/test/SemaCXX/constexpr-vectors.cpp
===================================================================
--- clang/test/SemaCXX/constexpr-vectors.cpp
+++ clang/test/SemaCXX/constexpr-vectors.cpp
@@ -11,12 +11,15 @@
using FourLongLongsVecSize __attribute__((vector_size(32))) = long long;
using FourFloatsVecSize __attribute__((vector_size(16))) = float;
using FourDoublesVecSize __attribute__((vector_size(32))) = double;
+using FourI128VecSize __attribute__((vector_size(64))) = __int128;
using FourCharsExtVec __attribute__((ext_vector_type(4))) = char;
using FourIntsExtVec __attribute__((ext_vector_type(4))) = int;
using FourLongLongsExtVec __attribute__((ext_vector_type(4))) = long long;
using FourFloatsExtVec __attribute__((ext_vector_type(4))) = float;
using FourDoublesExtVec __attribute__((ext_vector_type(4))) = double;
+using FourI128ExtVec __attribute__((ext_vector_type(4))) = __int128;
+
// Next a series of tests to make sure these operations are usable in
// constexpr functions. Template instantiations don't emit Winvalid-constexpr,
@@ -204,35 +207,35 @@
constexpr auto w = FourCharsVecSize{1, 2, 3, 4} <
FourCharsVecSize{4, 3, 2, 1};
- // CHECK: store <4 x i8> <i8 1, i8 1, i8 0, i8 0>
+ // CHECK: store <4 x i8> <i8 -1, i8 -1, i8 0, i8 0>
constexpr auto x = FourCharsVecSize{1, 2, 3, 4} >
FourCharsVecSize{4, 3, 2, 1};
- // CHECK: store <4 x i8> <i8 0, i8 0, i8 1, i8 1>
+ // CHECK: store <4 x i8> <i8 0, i8 0, i8 -1, i8 -1>
constexpr auto y = FourCharsVecSize{1, 2, 3, 4} <=
FourCharsVecSize{4, 3, 3, 1};
- // CHECK: store <4 x i8> <i8 1, i8 1, i8 1, i8 0>
+ // CHECK: store <4 x i8> <i8 -1, i8 -1, i8 -1, i8 0>
constexpr auto z = FourCharsVecSize{1, 2, 3, 4} >=
FourCharsVecSize{4, 3, 3, 1};
- // CHECK: store <4 x i8> <i8 0, i8 0, i8 1, i8 1>
+ // CHECK: store <4 x i8> <i8 0, i8 0, i8 -1, i8 -1>
constexpr auto A = FourCharsVecSize{1, 2, 3, 4} ==
FourCharsVecSize{4, 3, 3, 1};
- // CHECK: store <4 x i8> <i8 0, i8 0, i8 1, i8 0>
+ // CHECK: store <4 x i8> <i8 0, i8 0, i8 -1, i8 0>
constexpr auto B = FourCharsVecSize{1, 2, 3, 4} !=
FourCharsVecSize{4, 3, 3, 1};
- // CHECK: store <4 x i8> <i8 1, i8 1, i8 0, i8 1>
+ // CHECK: store <4 x i8> <i8 -1, i8 -1, i8 0, i8 -1>
constexpr auto C = FourCharsVecSize{1, 2, 3, 4} < 3;
- // CHECK: store <4 x i8> <i8 1, i8 1, i8 0, i8 0>
+ // CHECK: store <4 x i8> <i8 -1, i8 -1, i8 0, i8 0>
constexpr auto D = FourCharsVecSize{1, 2, 3, 4} > 3;
- // CHECK: store <4 x i8> <i8 0, i8 0, i8 0, i8 1>
+ // CHECK: store <4 x i8> <i8 0, i8 0, i8 0, i8 -1>
constexpr auto E = FourCharsVecSize{1, 2, 3, 4} <= 3;
- // CHECK: store <4 x i8> <i8 1, i8 1, i8 1, i8 0>
+ // CHECK: store <4 x i8> <i8 -1, i8 -1, i8 -1, i8 0>
constexpr auto F = FourCharsVecSize{1, 2, 3, 4} >= 3;
- // CHECK: store <4 x i8> <i8 0, i8 0, i8 1, i8 1>
+ // CHECK: store <4 x i8> <i8 0, i8 0, i8 -1, i8 -1>
constexpr auto G = FourCharsVecSize{1, 2, 3, 4} == 3;
- // CHECK: store <4 x i8> <i8 0, i8 0, i8 1, i8 0>
+ // CHECK: store <4 x i8> <i8 0, i8 0, i8 -1, i8 0>
constexpr auto H = FourCharsVecSize{1, 2, 3, 4} != 3;
- // CHECK: store <4 x i8> <i8 1, i8 1, i8 0, i8 1>
+ // CHECK: store <4 x i8> <i8 -1, i8 -1, i8 0, i8 -1>
constexpr auto I = FourCharsVecSize{1, 2, 3, 4} &
FourCharsVecSize{4, 3, 2, 1};
@@ -277,10 +280,12 @@
constexpr auto Y = CmpSub(a, b);
// CHECK: store <4 x i8> <i8 12, i8 17, i8 -1, i8 -1>
- constexpr auto Z = CmpLSH(a, H);
+ constexpr auto InvH = -H;
+ // CHECK: store <4 x i8> <i8 1, i8 1, i8 0, i8 1>
+ constexpr auto Z = CmpLSH(a, InvH);
// CHECK: store <4 x i8> <i8 36, i8 36, i8 7, i8 16>
- constexpr auto aa = CmpRSH(a, H);
+ constexpr auto aa = CmpRSH(a, InvH);
// CHECK: store <4 x i8> <i8 9, i8 9, i8 7, i8 4>
constexpr auto ab = CmpBinAnd(a, b);
@@ -348,35 +353,35 @@
constexpr auto w = FourCharsExtVec{1, 2, 3, 4} <
FourCharsExtVec{4, 3, 2, 1};
- // CHECK: store <4 x i8> <i8 1, i8 1, i8 0, i8 0>
+ // CHECK: store <4 x i8> <i8 -1, i8 -1, i8 0, i8 0>
constexpr auto x = FourCharsExtVec{1, 2, 3, 4} >
FourCharsExtVec{4, 3, 2, 1};
- // CHECK: store <4 x i8> <i8 0, i8 0, i8 1, i8 1>
+ // CHECK: store <4 x i8> <i8 0, i8 0, i8 -1, i8 -1>
constexpr auto y = FourCharsExtVec{1, 2, 3, 4} <=
FourCharsExtVec{4, 3, 3, 1};
- // CHECK: store <4 x i8> <i8 1, i8 1, i8 1, i8 0>
+ // CHECK: store <4 x i8> <i8 -1, i8 -1, i8 -1, i8 0>
constexpr auto z = FourCharsExtVec{1, 2, 3, 4} >=
FourCharsExtVec{4, 3, 3, 1};
- // CHECK: store <4 x i8> <i8 0, i8 0, i8 1, i8 1>
+ // CHECK: store <4 x i8> <i8 0, i8 0, i8 -1, i8 -1>
constexpr auto A = FourCharsExtVec{1, 2, 3, 4} ==
FourCharsExtVec{4, 3, 3, 1};
- // CHECK: store <4 x i8> <i8 0, i8 0, i8 1, i8 0>
+ // CHECK: store <4 x i8> <i8 0, i8 0, i8 -1, i8 0>
constexpr auto B = FourCharsExtVec{1, 2, 3, 4} !=
FourCharsExtVec{4, 3, 3, 1};
- // CHECK: store <4 x i8> <i8 1, i8 1, i8 0, i8 1>
+ // CHECK: store <4 x i8> <i8 -1, i8 -1, i8 0, i8 -1>
constexpr auto C = FourCharsExtVec{1, 2, 3, 4} < 3;
- // CHECK: store <4 x i8> <i8 1, i8 1, i8 0, i8 0>
+ // CHECK: store <4 x i8> <i8 -1, i8 -1, i8 0, i8 0>
constexpr auto D = FourCharsExtVec{1, 2, 3, 4} > 3;
- // CHECK: store <4 x i8> <i8 0, i8 0, i8 0, i8 1>
+ // CHECK: store <4 x i8> <i8 0, i8 0, i8 0, i8 -1>
constexpr auto E = FourCharsExtVec{1, 2, 3, 4} <= 3;
- // CHECK: store <4 x i8> <i8 1, i8 1, i8 1, i8 0>
+ // CHECK: store <4 x i8> <i8 -1, i8 -1, i8 -1, i8 0>
constexpr auto F = FourCharsExtVec{1, 2, 3, 4} >= 3;
- // CHECK: store <4 x i8> <i8 0, i8 0, i8 1, i8 1>
+ // CHECK: store <4 x i8> <i8 0, i8 0, i8 -1, i8 -1>
constexpr auto G = FourCharsExtVec{1, 2, 3, 4} == 3;
- // CHECK: store <4 x i8> <i8 0, i8 0, i8 1, i8 0>
+ // CHECK: store <4 x i8> <i8 0, i8 0, i8 -1, i8 0>
constexpr auto H = FourCharsExtVec{1, 2, 3, 4} != 3;
- // CHECK: store <4 x i8> <i8 1, i8 1, i8 0, i8 1>
+ // CHECK: store <4 x i8> <i8 -1, i8 -1, i8 0, i8 -1>
constexpr auto I = FourCharsExtVec{1, 2, 3, 4} &
FourCharsExtVec{4, 3, 2, 1};
@@ -421,10 +426,13 @@
constexpr auto Y = CmpSub(a, b);
// CHECK: store <4 x i8> <i8 12, i8 17, i8 -1, i8 -1>
- constexpr auto Z = CmpLSH(a, H);
+ constexpr auto InvH = -H;
+ // CHECK: store <4 x i8> <i8 1, i8 1, i8 0, i8 1>
+
+ constexpr auto Z = CmpLSH(a, InvH);
// CHECK: store <4 x i8> <i8 36, i8 36, i8 7, i8 16>
- constexpr auto aa = CmpRSH(a, H);
+ constexpr auto aa = CmpRSH(a, InvH);
// CHECK: store <4 x i8> <i8 9, i8 9, i8 7, i8 4>
constexpr auto ab = CmpBinAnd(a, b);
@@ -471,35 +479,35 @@
constexpr auto w = FourFloatsVecSize{1, 2, 3, 4} <
FourFloatsVecSize{4, 3, 2, 1};
- // CHECK: store <4 x i32> <i32 1, i32 1, i32 0, i32 0>
+ // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 0, i32 0>
constexpr auto x = FourFloatsVecSize{1, 2, 3, 4} >
FourFloatsVecSize{4, 3, 2, 1};
- // CHECK: store <4 x i32> <i32 0, i32 0, i32 1, i32 1>
+ // CHECK: store <4 x i32> <i32 0, i32 0, i32 -1, i32 -1>
constexpr auto y = FourFloatsVecSize{1, 2, 3, 4} <=
FourFloatsVecSize{4, 3, 3, 1};
- // CHECK: store <4 x i32> <i32 1, i32 1, i32 1, i32 0>
+ // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 -1, i32 0>
constexpr auto z = FourFloatsVecSize{1, 2, 3, 4} >=
FourFloatsVecSize{4, 3, 3, 1};
- // CHECK: store <4 x i32> <i32 0, i32 0, i32 1, i32 1>
+ // CHECK: store <4 x i32> <i32 0, i32 0, i32 -1, i32 -1>
constexpr auto A = FourFloatsVecSize{1, 2, 3, 4} ==
FourFloatsVecSize{4, 3, 3, 1};
- // CHECK: store <4 x i32> <i32 0, i32 0, i32 1, i32 0>
+ // CHECK: store <4 x i32> <i32 0, i32 0, i32 -1, i32 0>
constexpr auto B = FourFloatsVecSize{1, 2, 3, 4} !=
FourFloatsVecSize{4, 3, 3, 1};
- // CHECK: store <4 x i32> <i32 1, i32 1, i32 0, i32 1>
+ // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 0, i32 -1>
constexpr auto C = FourFloatsVecSize{1, 2, 3, 4} < 3;
- // CHECK: store <4 x i32> <i32 1, i32 1, i32 0, i32 0>
+ // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 0, i32 0>
constexpr auto D = FourFloatsVecSize{1, 2, 3, 4} > 3;
- // CHECK: store <4 x i32> <i32 0, i32 0, i32 0, i32 1>
+ // CHECK: store <4 x i32> <i32 0, i32 0, i32 0, i32 -1>
constexpr auto E = FourFloatsVecSize{1, 2, 3, 4} <= 3;
- // CHECK: store <4 x i32> <i32 1, i32 1, i32 1, i32 0>
+ // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 -1, i32 0>
constexpr auto F = FourFloatsVecSize{1, 2, 3, 4} >= 3;
- // CHECK: store <4 x i32> <i32 0, i32 0, i32 1, i32 1>
+ // CHECK: store <4 x i32> <i32 0, i32 0, i32 -1, i32 -1>
constexpr auto G = FourFloatsVecSize{1, 2, 3, 4} == 3;
- // CHECK: store <4 x i32> <i32 0, i32 0, i32 1, i32 0>
+ // CHECK: store <4 x i32> <i32 0, i32 0, i32 -1, i32 0>
constexpr auto H = FourFloatsVecSize{1, 2, 3, 4} != 3;
- // CHECK: store <4 x i32> <i32 1, i32 1, i32 0, i32 1>
+ // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 0, i32 -1>
constexpr auto O = FourFloatsVecSize{5, 0, 6, 0} &&
FourFloatsVecSize{5, 5, 0, 0};
@@ -524,6 +532,9 @@
constexpr auto Y = CmpSub(a, b);
// CHECK: store <4 x float> <float 1.200000e+01, float 1.700000e+01, float -1.000000e+00, float -1.000000e+00>
+
+ constexpr auto Z = -Y;
+ // CHECK: store <4 x float> <float -1.200000e+01, float -1.700000e+01, float 1.000000e+00, float 1.000000e+00>
}
void FloatVecUsage() {
@@ -560,35 +571,35 @@
constexpr auto w = FourFloatsVecSize{1, 2, 3, 4} <
FourFloatsVecSize{4, 3, 2, 1};
- // CHECK: store <4 x i32> <i32 1, i32 1, i32 0, i32 0>
+ // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 0, i32 0>
constexpr auto x = FourFloatsVecSize{1, 2, 3, 4} >
FourFloatsVecSize{4, 3, 2, 1};
- // CHECK: store <4 x i32> <i32 0, i32 0, i32 1, i32 1>
+ // CHECK: store <4 x i32> <i32 0, i32 0, i32 -1, i32 -1>
constexpr auto y = FourFloatsVecSize{1, 2, 3, 4} <=
FourFloatsVecSize{4, 3, 3, 1};
- // CHECK: store <4 x i32> <i32 1, i32 1, i32 1, i32 0>
+ // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 -1, i32 0>
constexpr auto z = FourFloatsVecSize{1, 2, 3, 4} >=
FourFloatsVecSize{4, 3, 3, 1};
- // CHECK: store <4 x i32> <i32 0, i32 0, i32 1, i32 1>
+ // CHECK: store <4 x i32> <i32 0, i32 0, i32 -1, i32 -1>
constexpr auto A = FourFloatsVecSize{1, 2, 3, 4} ==
FourFloatsVecSize{4, 3, 3, 1};
- // CHECK: store <4 x i32> <i32 0, i32 0, i32 1, i32 0>
+ // CHECK: store <4 x i32> <i32 0, i32 0, i32 -1, i32 0>
constexpr auto B = FourFloatsVecSize{1, 2, 3, 4} !=
FourFloatsVecSize{4, 3, 3, 1};
- // CHECK: store <4 x i32> <i32 1, i32 1, i32 0, i32 1>
+ // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 0, i32 -1>
constexpr auto C = FourFloatsVecSize{1, 2, 3, 4} < 3;
- // CHECK: store <4 x i32> <i32 1, i32 1, i32 0, i32 0>
+ // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 0, i32 0>
constexpr auto D = FourFloatsVecSize{1, 2, 3, 4} > 3;
- // CHECK: store <4 x i32> <i32 0, i32 0, i32 0, i32 1>
+ // CHECK: store <4 x i32> <i32 0, i32 0, i32 0, i32 -1>
constexpr auto E = FourFloatsVecSize{1, 2, 3, 4} <= 3;
- // CHECK: store <4 x i32> <i32 1, i32 1, i32 1, i32 0>
+ // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 -1, i32 0>
constexpr auto F = FourFloatsVecSize{1, 2, 3, 4} >= 3;
- // CHECK: store <4 x i32> <i32 0, i32 0, i32 1, i32 1>
+ // CHECK: store <4 x i32> <i32 0, i32 0, i32 -1, i32 -1>
constexpr auto G = FourFloatsVecSize{1, 2, 3, 4} == 3;
- // CHECK: store <4 x i32> <i32 0, i32 0, i32 1, i32 0>
+ // CHECK: store <4 x i32> <i32 0, i32 0, i32 -1, i32 0>
constexpr auto H = FourFloatsVecSize{1, 2, 3, 4} != 3;
- // CHECK: store <4 x i32> <i32 1, i32 1, i32 0, i32 1>
+ // CHECK: store <4 x i32> <i32 -1, i32 -1, i32 0, i32 -1>
constexpr auto O = FourFloatsVecSize{5, 0, 6, 0} &&
FourFloatsVecSize{5, 5, 0, 0};
@@ -613,4 +624,21 @@
constexpr auto Y = CmpSub(a, b);
// CHECK: store <4 x float> <float 1.200000e+01, float 1.700000e+01, float -1.000000e+00, float -1.000000e+00>
+
+ constexpr auto Z = -Y;
+ // CHECK: store <4 x float> <float -1.200000e+01, float -1.700000e+01, float 1.000000e+00, float 1.000000e+00>
+}
+
+void I128Usage() {
+ constexpr auto a = FourI128VecSize{1, 2, 3, 4};
+ // CHECK: store <4 x i128> <i128 1, i128 2, i128 3, i128 4>
+ constexpr auto b = a < 3;
+ // CHECK: store <4 x i128> <i128 -1, i128 -1, i128 0, i128 0>
+}
+
+void I128VecUsage() {
+ constexpr auto a = FourI128ExtVec{1, 2, 3, 4};
+ // CHECK: store <4 x i128> <i128 1, i128 2, i128 3, i128 4>
+ constexpr auto b = a < 3;
+ // CHECK: store <4 x i128> <i128 -1, i128 -1, i128 0, i128 0>
}
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -12265,6 +12265,8 @@
return Context.getExtVectorType(Context.ShortTy, VTy->getNumElements());
else if (TypeSize == Context.getTypeSize(Context.IntTy))
return Context.getExtVectorType(Context.IntTy, VTy->getNumElements());
+ else if (TypeSize == Context.getTypeSize(Context.Int128Ty))
+ return Context.getExtVectorType(Context.Int128Ty, VTy->getNumElements());
else if (TypeSize == Context.getTypeSize(Context.LongTy))
return Context.getExtVectorType(Context.LongTy, VTy->getNumElements());
assert(TypeSize == Context.getTypeSize(Context.LongLongTy) &&
@@ -12272,7 +12274,10 @@
return Context.getExtVectorType(Context.LongLongTy, VTy->getNumElements());
}
- if (TypeSize == Context.getTypeSize(Context.LongLongTy))
+ if (TypeSize == Context.getTypeSize(Context.Int128Ty))
+ return Context.getVectorType(Context.Int128Ty, VTy->getNumElements(),
+ VectorType::GenericVector);
+ else if (TypeSize == Context.getTypeSize(Context.LongLongTy))
return Context.getVectorType(Context.LongLongTy, VTy->getNumElements(),
VectorType::GenericVector);
else if (TypeSize == Context.getTypeSize(Context.LongTy))
Index: clang/lib/AST/ExprConstant.cpp
===================================================================
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -2931,6 +2931,11 @@
break;
}
+ // The boolean operations on these vector types use an instruction that
+ // results in a mask of '-1' for the 'truth' value. Ensure that we negate 1
+ // to -1 to make sure that we produce the correct value.
+ Result.negate();
+
return true;
}
@@ -10179,7 +10184,8 @@
bool VisitInitListExpr(const InitListExpr *E);
bool VisitUnaryImag(const UnaryOperator *E);
bool VisitBinaryOperator(const BinaryOperator *E);
- // FIXME: Missing: unary -, unary ~, conditional operator (for GNU
+ bool VisitUnaryOperator(const UnaryOperator *E);
+ // FIXME: Missing: unary ~, conditional operator (for GNU
// conditional select), shufflevector, ExtVectorElementExpr
};
} // end anonymous namespace
@@ -10364,6 +10370,43 @@
return Success(LHSValue, E);
}
+bool VectorExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
+ Expr *SubExpr = E->getSubExpr();
+ const auto *VD = SubExpr->getType()->castAs<VectorType>();
+ UnaryOperatorKind Op = E->getOpcode();
+
+ APValue SubExprValue;
+ if (!Evaluate(SubExprValue, Info, SubExpr))
+ return false;
+
+ assert(SubExprValue.getVectorLength() == VD->getNumElements() &&
+ "Vector length doesn't match type?");
+
+ switch (Op) {
+ default:
+ // FIXME: Implement the rest of the unary operators.
+ return false;
+ case UO_Minus: {
+ for (unsigned EltNum = 0; EltNum < VD->getNumElements(); ++EltNum) {
+ APValue &Elt = SubExprValue.getVectorElt(EltNum);
+ if (Elt.getKind() == APValue::Int) {
+ Elt.setInt(-Elt.getInt());
+ } else {
+ assert(Elt.getKind() == APValue::Float &&
+ "Vector can only be int or float type");
+ Elt.setFloat(-Elt.getFloat());
+ }
+ }
+ break;
+ }
+ case UO_Plus:
+ // Do nothing, Unary plus is a no-op.
+ break;
+ }
+
+ return Success(SubExprValue, E);
+}
+
//===----------------------------------------------------------------------===//
// Array Evaluation
//===----------------------------------------------------------------------===//
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits