summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/AST/ExprConstant.cpp25
-rw-r--r--clang/test/CodeGenOpenCLCXX/constexpr.cl28
2 files changed, 53 insertions, 0 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 0b658cbb712..7e33b9d354b 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -7080,6 +7080,31 @@ public:
DerivedSuccess(Result, E);
}
+ bool VisitExtVectorElementExpr(const ExtVectorElementExpr *E) {
+ APValue Val;
+ if (!Evaluate(Val, Info, E->getBase()))
+ return false;
+
+ if (Val.isVector()) {
+ SmallVector<uint32_t, 4> Indices;
+ E->getEncodedElementAccess(Indices);
+ if (Indices.size() == 1) {
+ // Return scalar.
+ return DerivedSuccess(Val.getVectorElt(Indices[0]), E);
+ } else {
+ // Construct new APValue vector.
+ SmallVector<APValue, 4> Elts;
+ for (unsigned I = 0; I < Indices.size(); ++I) {
+ Elts.push_back(Val.getVectorElt(Indices[I]));
+ }
+ APValue VecResult(Elts.data(), Indices.size());
+ return DerivedSuccess(VecResult, E);
+ }
+ }
+
+ return false;
+ }
+
bool VisitCastExpr(const CastExpr *E) {
switch (E->getCastKind()) {
default:
diff --git a/clang/test/CodeGenOpenCLCXX/constexpr.cl b/clang/test/CodeGenOpenCLCXX/constexpr.cl
index b7175020b81..8c3fad08ea7 100644
--- a/clang/test/CodeGenOpenCLCXX/constexpr.cl
+++ b/clang/test/CodeGenOpenCLCXX/constexpr.cl
@@ -1,5 +1,8 @@
// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=clc++ -O0 -emit-llvm -o - | FileCheck %s
+typedef int int2 __attribute__((ext_vector_type(2)));
+typedef int int4 __attribute__((ext_vector_type(4)));
+
struct Storage final {
constexpr const float& operator[](const int index) const noexcept {
return InternalStorage[index];
@@ -24,3 +27,28 @@ constexpr float FloatConstant = compute();
kernel void foo(global float *x) {
*x = FloatConstant;
}
+
+// Test evaluation of constant vectors.
+// CHECK-LABEL: define spir_kernel void @vecEval
+// CHECK: store i32 3
+// CHECK: store <2 x i32> <i32 22, i32 33>, <2 x i32>
+
+const int oneElt = int4(3).x;
+const int2 twoElts = (int4)(11, 22, 33, 44).yz;
+
+kernel void vecEval(global int *x, global int2 *y) {
+ *x = oneElt;
+ *y = twoElts;
+}
+
+// Test evaluation of vectors initialized through a constexpr function.
+// CHECK-LABEL: define spir_kernel void @vecEval2
+// CHECK: store <2 x i32>
+constexpr int2 addOne(int2 x) {
+ return (int2)(x.x + 1, x.y + 1);
+}
+const int2 fromConstexprFunc = addOne(int2(2));
+
+kernel void vecEval2(global int2 *x) {
+ *x = fromConstexprFunc;
+}
OpenPOWER on IntegriCloud