[clang] 8e95454 - [clang][Interp] Support ExtVectorElementExprs

Timm Bäder via cfe-commits cfe-commits at lists.llvm.org
Sat Jun 15 06:12:54 PDT 2024


Author: Timm Bäder
Date: 2024-06-15T15:12:36+02:00
New Revision: 8e954541581270c497cc961b08eff69dc41bc18d

URL: https://github.com/llvm/llvm-project/commit/8e954541581270c497cc961b08eff69dc41bc18d
DIFF: https://github.com/llvm/llvm-project/commit/8e954541581270c497cc961b08eff69dc41bc18d.diff

LOG: [clang][Interp] Support ExtVectorElementExprs

Added: 
    

Modified: 
    clang/lib/AST/Interp/ByteCodeExprGen.cpp
    clang/lib/AST/Interp/ByteCodeExprGen.h
    clang/test/AST/Interp/vectors.cpp
    clang/test/CodeGenOpenCLCXX/constexpr.clcpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 13a68f3d05f6a..e61c0a70a0d8a 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -2735,6 +2735,65 @@ bool ByteCodeExprGen<Emitter>::VisitShuffleVectorExpr(
   return true;
 }
 
+template <class Emitter>
+bool ByteCodeExprGen<Emitter>::VisitExtVectorElementExpr(
+    const ExtVectorElementExpr *E) {
+  const Expr *Base = E->getBase();
+
+  SmallVector<uint32_t, 4> Indices;
+  E->getEncodedElementAccess(Indices);
+
+  if (Indices.size() == 1) {
+    if (!this->visit(Base))
+      return false;
+
+    if (E->isGLValue()) {
+      if (!this->emitConstUint32(Indices[0], E))
+        return false;
+      return this->emitArrayElemPtrPop(PT_Uint32, E);
+    }
+    // Else, also load the value.
+    return this->emitArrayElemPop(classifyPrim(E->getType()), Indices[0], E);
+  }
+
+  // Create a local variable for the base.
+  unsigned BaseOffset = allocateLocalPrimitive(Base, PT_Ptr, /*IsConst=*/true,
+                                               /*IsExtended=*/false);
+  if (!this->visit(Base))
+    return false;
+  if (!this->emitSetLocal(PT_Ptr, BaseOffset, E))
+    return false;
+
+  // Now the vector variable for the return value.
+  if (!Initializing) {
+    std::optional<unsigned> ResultIndex;
+    ResultIndex = allocateLocal(E);
+    if (!ResultIndex)
+      return false;
+    if (!this->emitGetPtrLocal(*ResultIndex, E))
+      return false;
+  }
+
+  assert(Indices.size() == E->getType()->getAs<VectorType>()->getNumElements());
+
+  PrimType ElemT =
+      classifyPrim(E->getType()->getAs<VectorType>()->getElementType());
+  uint32_t DstIndex = 0;
+  for (uint32_t I : Indices) {
+    if (!this->emitGetLocal(PT_Ptr, BaseOffset, E))
+      return false;
+    if (!this->emitArrayElemPop(ElemT, I, E))
+      return false;
+    if (!this->emitInitElem(ElemT, DstIndex, E))
+      return false;
+    ++DstIndex;
+  }
+
+  // Leave the result pointer on the stack.
+  assert(!DiscardResult);
+  return true;
+}
+
 template <class Emitter>
 bool ByteCodeExprGen<Emitter>::VisitObjCBoxedExpr(const ObjCBoxedExpr *E) {
   if (!E->isExpressibleAsConstantInitializer())

diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.h b/clang/lib/AST/Interp/ByteCodeExprGen.h
index 7bb5304cac71e..b0faac8020fb2 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.h
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.h
@@ -128,6 +128,7 @@ class ByteCodeExprGen : public ConstStmtVisitor<ByteCodeExprGen<Emitter>, bool>,
   bool VisitAddrLabelExpr(const AddrLabelExpr *E);
   bool VisitConvertVectorExpr(const ConvertVectorExpr *E);
   bool VisitShuffleVectorExpr(const ShuffleVectorExpr *E);
+  bool VisitExtVectorElementExpr(const ExtVectorElementExpr *E);
   bool VisitObjCBoxedExpr(const ObjCBoxedExpr *E);
 
 protected:

diff  --git a/clang/test/AST/Interp/vectors.cpp b/clang/test/AST/Interp/vectors.cpp
index 1e0d473cbca5a..61c400b57b3f8 100644
--- a/clang/test/AST/Interp/vectors.cpp
+++ b/clang/test/AST/Interp/vectors.cpp
@@ -70,3 +70,14 @@ namespace BoolToSignedIntegralCast{
   static_assert(intsT[2] == -1, "");// ref-error {{not an integral constant expression}}
   static_assert(intsT[3] == -1, "");// ref-error {{not an integral constant expression}}
 }
+
+namespace VectorElementExpr {
+  typedef int int2 __attribute__((ext_vector_type(2)));
+  typedef int int4 __attribute__((ext_vector_type(4)));
+  constexpr int oneElt = int4(3).x;
+  static_assert(oneElt == 3);
+
+  constexpr int2 twoElts = ((int4){11, 22, 33, 44}).yz;
+  static_assert(twoElts.x == 22, ""); // ref-error {{not an integral constant expression}}
+  static_assert(twoElts.y == 33, ""); // ref-error {{not an integral constant expression}}
+}

diff  --git a/clang/test/CodeGenOpenCLCXX/constexpr.clcpp b/clang/test/CodeGenOpenCLCXX/constexpr.clcpp
index 0576418c944ba..5de7106fe5417 100644
--- a/clang/test/CodeGenOpenCLCXX/constexpr.clcpp
+++ b/clang/test/CodeGenOpenCLCXX/constexpr.clcpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 %s -triple spir-unknown-unknown -O0 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple spir-unknown-unknown -O0 -emit-llvm -o - -fexperimental-new-constant-interpreter | FileCheck %s
 
 typedef int int2 __attribute__((ext_vector_type(2)));
 typedef int int4 __attribute__((ext_vector_type(4)));


        


More information about the cfe-commits mailing list