Skip to content

[Clang] support vector subscript expressions in constant evaluator (WIP) #76379

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

vikramRH
Copy link
Contributor

Feel free to add additional reviewers as relevant,

I'm yet to update float test cases as I'm not sure whether it would be safe to directly compare float results in static assert. Would it okay to integer cast the results and compare them ?

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Dec 26, 2023
@vikramRH vikramRH changed the title [Clang] support vector subscript expressions in constant evaluator [Clang] support vector subscript expressions in constant evaluator (WIP) Dec 26, 2023
@llvmbot
Copy link
Member

llvmbot commented Dec 26, 2023

@llvm/pr-subscribers-clang

Author: Vikram Hegde (vikramRH)

Changes

Feel free to add additional reviewers as relevant,

I'm yet to update float test cases as I'm not sure whether it would be safe to directly compare float results in static assert. Would it okay to integer cast the results and compare them ?


Patch is 42.71 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/76379.diff

3 Files Affected:

  • (modified) clang/lib/AST/ExprConstant.cpp (+57-4)
  • (modified) clang/test/CodeGenCXX/temporaries.cpp (+4-8)
  • (modified) clang/test/SemaCXX/constexpr-vectors.cpp (+607-139)
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index f6aeee1a4e935d..0074b8aa00fc75 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -226,6 +226,12 @@ namespace {
         ArraySize = 0;
         MostDerivedLength = I + 1;
         IsArray = false;
+      } else if (Type->isVectorType()) {
+        const VectorType *CT = Type->castAs<VectorType>();
+        Type = CT->getElementType();
+        ArraySize = CT->getNumElements();
+        MostDerivedLength = I + 1;
+        IsArray = true;
       } else {
         // Path[I] describes a base class.
         ArraySize = 0;
@@ -437,6 +443,15 @@ namespace {
       MostDerivedArraySize = 2;
       MostDerivedPathLength = Entries.size();
     }
+    /// Update this designator to refer to the given vector component.
+    void addVectorUnchecked(const VectorType *VecTy) {
+      Entries.push_back(PathEntry::ArrayIndex(0));
+
+      MostDerivedType = VecTy->getElementType();
+      MostDerivedIsArrayElement = true;
+      MostDerivedArraySize = VecTy->getNumElements();
+      MostDerivedPathLength = Entries.size();
+    }
     void diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info, const Expr *E);
     void diagnosePointerArithmetic(EvalInfo &Info, const Expr *E,
                                    const APSInt &N);
@@ -1732,6 +1747,10 @@ namespace {
       if (checkSubobject(Info, E, Imag ? CSK_Imag : CSK_Real))
         Designator.addComplexUnchecked(EltTy, Imag);
     }
+    void addVector(EvalInfo &Info, const Expr *E, const VectorType *VecTy) {
+      if (checkSubobject(Info, E, CSK_ArrayIndex))
+        Designator.addVectorUnchecked(VecTy);
+    }
     void clearIsNullPointer() {
       IsNullPtr = false;
     }
@@ -1890,6 +1909,8 @@ static bool EvaluateFixedPointOrInteger(const Expr *E, APFixedPoint &Result,
 static bool EvaluateFixedPoint(const Expr *E, APFixedPoint &Result,
                                EvalInfo &Info);
 
+static bool EvaluateVector(const Expr *E, APValue &Result, EvalInfo &Info);
+
 //===----------------------------------------------------------------------===//
 // Misc utilities
 //===----------------------------------------------------------------------===//
@@ -3278,6 +3299,19 @@ static bool HandleLValueComplexElement(EvalInfo &Info, const Expr *E,
   return true;
 }
 
+static bool HandeLValueVectorComponent(EvalInfo &Info, const Expr *E,
+                                       LValue &LVal, const VectorType *VecTy,
+                                       APSInt &Adjustment) {
+  LVal.addVector(Info, E, VecTy);
+
+  CharUnits SizeOfComponent;
+  if (!HandleSizeof(Info, E->getExprLoc(), VecTy->getElementType(),
+                    SizeOfComponent))
+    return false;
+  LVal.adjustOffsetAndIndex(Info, E, Adjustment, SizeOfComponent);
+  return true;
+}
+
 /// Try to evaluate the initializer for a variable declaration.
 ///
 /// \param Info   Information about the ongoing evaluation.
@@ -3718,7 +3752,8 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj,
     }
 
     // If this is our last pass, check that the final object type is OK.
-    if (I == N || (I == N - 1 && ObjType->isAnyComplexType())) {
+    if (I == N || (I == N - 1 &&
+                   (ObjType->isAnyComplexType() || ObjType->isVectorType()))) {
       // Accesses to volatile objects are prohibited.
       if (ObjType.isVolatileQualified() && isFormalAccess(handler.AccessKind)) {
         if (Info.getLangOpts().CPlusPlus) {
@@ -3823,6 +3858,10 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj,
         return handler.found(Index ? O->getComplexFloatImag()
                                    : O->getComplexFloatReal(), ObjType);
       }
+    } else if (ObjType->isVectorType()) {
+      // Next Subobject is a vector element
+      uint64_t Index = Sub.Entries[I].getAsArrayIndex();
+      O = &O->getVectorElt(Index);
     } else if (const FieldDecl *Field = getAsField(Sub.Entries[I])) {
       if (Field->isMutable() &&
           !Obj.mayAccessMutableMembers(Info, handler.AccessKind)) {
@@ -8756,14 +8795,28 @@ bool LValueExprEvaluator::VisitMemberExpr(const MemberExpr *E) {
 }
 
 bool LValueExprEvaluator::VisitArraySubscriptExpr(const ArraySubscriptExpr *E) {
-  // FIXME: Deal with vectors as array subscript bases.
-  if (E->getBase()->getType()->isVectorType() ||
-      E->getBase()->getType()->isSveVLSBuiltinType())
+
+  if (E->getBase()->getType()->isSveVLSBuiltinType())
     return Error(E);
 
   APSInt Index;
   bool Success = true;
 
+  if (E->getBase()->getType()->isVectorType()) {
+    for (const Expr *SubExpr : {E->getLHS(), E->getRHS()}) {
+      Success = (SubExpr == E->getBase())
+                    ? EvaluateLValue(SubExpr, Result, Info, true)
+                    : EvaluateInteger(SubExpr, Index, Info);
+    }
+    if (Success) {
+      Success = HandeLValueVectorComponent(
+          Info, E, Result, E->getBase()->getType()->castAs<VectorType>(),
+          Index);
+      return Success;
+    }
+    return false;
+  }
+
   // C++17's rules require us to evaluate the LHS first, regardless of which
   // side is the base.
   for (const Expr *SubExpr : {E->getLHS(), E->getRHS()}) {
diff --git a/clang/test/CodeGenCXX/temporaries.cpp b/clang/test/CodeGenCXX/temporaries.cpp
index c5adb42a6f1737..aa00cff3aa9014 100644
--- a/clang/test/CodeGenCXX/temporaries.cpp
+++ b/clang/test/CodeGenCXX/temporaries.cpp
@@ -673,16 +673,12 @@ namespace Vector {
     vi4a v;
     vi4b w;
   };
-  // CHECK: alloca
-  // CHECK: extractelement
-  // CHECK: store i32 {{.*}}, ptr @_ZGRN6Vector1rE_
-  // CHECK: store ptr @_ZGRN6Vector1rE_, ptr @_ZN6Vector1rE,
+  // @_ZGRN6Vector1rE_ = internal global i32 0, align 4
+  // @_ZN6Vector1rE = constant ptr @_ZGRN6Vector1rE_, align 8
   int &&r = S().v[1];
 
-  // CHECK: alloca
-  // CHECK: extractelement
-  // CHECK: store i32 {{.*}}, ptr @_ZGRN6Vector1sE_
-  // CHECK: store ptr @_ZGRN6Vector1sE_, ptr @_ZN6Vector1sE,
+  // @_ZGRN6Vector1sE_ = internal global i32 0, align 4
+  // @_ZN6Vector1sE = constant ptr @_ZGRN6Vector1sE_, align 8
   int &&s = S().w[1];
   // FIXME PR16204: The following code leads to an assertion in Sema.
   //int &&s = S().w.y;
diff --git a/clang/test/SemaCXX/constexpr-vectors.cpp b/clang/test/SemaCXX/constexpr-vectors.cpp
index 99b045f888d87c..b00ccb75c86a51 100644
--- a/clang/test/SemaCXX/constexpr-vectors.cpp
+++ b/clang/test/SemaCXX/constexpr-vectors.cpp
@@ -1,10 +1,4 @@
-// RUN: %clang_cc1 -std=c++14 -Wno-unused-value %s -disable-llvm-passes -triple x86_64-linux-gnu -emit-llvm -o - | FileCheck %s
-
-// FIXME: Unfortunately there is no good way to validate that our values are
-// correct since Vector types don't have operator [] implemented for constexpr.
-// Instead, we need to use filecheck to ensure the emitted IR is correct. Once
-// someone implements array subscript operator for these types as constexpr,
-// this test should modified to jsut use static asserts.
+// RUN: %clang_cc1 -std=c++14 -Wno-unused-value %s -triple x86_64-linux-gnu -emit-llvm -o /dev/null
 
 using FourCharsVecSize __attribute__((vector_size(4))) = char;
 using FourIntsVecSize __attribute__((vector_size(16))) = int;
@@ -155,306 +149,711 @@ constexpr auto CmpBinOr(T t, U u) {
 void CharUsage() {
   constexpr auto a = FourCharsVecSize{6, 3, 2, 1} +
                      FourCharsVecSize{12, 15, 5, 7};
-  // CHECK: store <4 x i8> <i8 18, i8 18, i8 7, i8 8>
+  static_assert(a[0] == 18 , "");
+  static_assert(a[1] == 18 , "");
+  static_assert(a[2] == 7 , "");
+  static_assert(a[3] == 8 , "");
+
   constexpr auto b = FourCharsVecSize{19, 15, 13, 12} -
                      FourCharsVecSize{13, 14, 5, 3};
-  // CHECK: store <4 x i8> <i8 6, i8 1, i8 8, i8 9>
+  static_assert(b[0] == 6 , "");
+  static_assert(b[1] == 1 , "");
+  static_assert(b[2] == 8 , "");
+  static_assert(b[3] == 9 , "");
+
   constexpr auto c = FourCharsVecSize{8, 4, 2, 1} *
                      FourCharsVecSize{3, 4, 5, 6};
-  // CHECK: store <4 x i8> <i8 24, i8 16, i8 10, i8 6>
+  static_assert(c[0] == 24 , "");
+  static_assert(c[1] == 16 , "");
+  static_assert(c[2] == 10 , "");
+  static_assert(c[3] == 6 , "");
+
   constexpr auto d = FourCharsVecSize{12, 12, 10, 10} /
                      FourCharsVecSize{6, 4, 5, 2};
-  // CHECK: store <4 x i8> <i8 2, i8 3, i8 2, i8 5>
+  static_assert(d[0] == 2 , "");
+  static_assert(d[1] == 3 , "");
+  static_assert(d[2] == 2 , "");
+  static_assert(d[3] == 5 , "");
+  
   constexpr auto e = FourCharsVecSize{12, 12, 10, 10} %
                      FourCharsVecSize{6, 4, 4, 3};
-  // CHECK: store <4 x i8> <i8 0, i8 0, i8 2, i8 1>
+  static_assert(e[0] == 0 , "");
+  static_assert(e[1] == 0 , "");
+  static_assert(e[2] == 2 , "");
+  static_assert(e[3] == 1 , "");
 
   constexpr auto f = FourCharsVecSize{6, 3, 2, 1} + 3;
-  // CHECK: store <4 x i8> <i8 9, i8 6, i8 5, i8 4>
+  static_assert(f[0] == 9 , "");
+  static_assert(f[1] == 6 , "");
+  static_assert(f[2] == 5 , "");
+  static_assert(f[3] == 4 , "");
+
   constexpr auto g = FourCharsVecSize{19, 15, 12, 10} - 3;
-  // CHECK: store <4 x i8> <i8 16, i8 12, i8 9, i8 7>
+  static_assert(g[0] == 16 , "");
+  static_assert(g[1] == 12 , "");
+  static_assert(g[2] == 9 , "");
+  static_assert(g[3] == 7 , "");
+
   constexpr auto h = FourCharsVecSize{8, 4, 2, 1} * 3;
-  // CHECK: store <4 x i8> <i8 24, i8 12, i8 6, i8 3>
+  static_assert(h[0] == 24 , "");
+  static_assert(h[1] == 12 , "");
+  static_assert(h[2] == 6 , "");
+  static_assert(h[3] == 3 , "");
+
   constexpr auto j = FourCharsVecSize{12, 15, 18, 21} / 3;
-  // CHECK: store <4 x i8> <i8 4, i8 5, i8 6, i8 7>
+  static_assert(j[0] == 4 , "");
+  static_assert(j[1] == 5 , "");
+  static_assert(j[2] == 6 , "");
+  static_assert(j[3] == 7 , "");
+  
   constexpr auto k = FourCharsVecSize{12, 17, 19, 22} % 3;
-  // CHECK: store <4 x i8> <i8 0, i8 2, i8 1, i8 1>
+  static_assert(k[0] == 0 , "");
+  static_assert(k[1] == 2 , "");
+  static_assert(k[2] == 1 , "");
+  static_assert(k[3] == 1 , "");
 
   constexpr auto l = 3 + FourCharsVecSize{6, 3, 2, 1};
-  // CHECK: store <4 x i8> <i8 9, i8 6, i8 5, i8 4>
+  static_assert(f[0] == 9 , "");
+  static_assert(f[1] == 6 , "");
+  static_assert(f[2] == 5 , "");
+  static_assert(f[3] == 4 , "");
+
   constexpr auto m = 20 - FourCharsVecSize{19, 15, 12, 10};
-  // CHECK: store <4 x i8> <i8 1, i8 5, i8 8, i8 10>
+  static_assert(m[0] == 1 , "");
+  static_assert(m[1] == 5 , "");
+  static_assert(m[2] == 8 , "");
+  static_assert(m[3] == 10 , "");
+
   constexpr auto n = 3 * FourCharsVecSize{8, 4, 2, 1};
-  // CHECK: store <4 x i8> <i8 24, i8 12, i8 6, i8 3>
+  static_assert(n[0] == 24 , "");
+  static_assert(n[1] == 12 , "");
+  static_assert(n[2] == 6 , "");
+  static_assert(n[3] == 3 , "");
+
   constexpr auto o = 100 / FourCharsVecSize{12, 15, 18, 21};
-  // CHECK: store <4 x i8> <i8 8, i8 6, i8 5, i8 4>
+  static_assert(o[0] == 8 , "");
+  static_assert(o[1] == 6 , "");
+  static_assert(o[2] == 5 , "");
+  static_assert(o[3] == 4 , "");
+
   constexpr auto p = 100 % FourCharsVecSize{12, 15, 18, 21};
-  // CHECK: store <4 x i8> <i8 4, i8 10, i8 10, i8 16>
+  static_assert(p[0] == 4 , "");
+  static_assert(p[1] == 10 , "");
+  static_assert(p[2] == 10 , "");
+  static_assert(p[3] == 16 , "");
 
   constexpr auto q = FourCharsVecSize{6, 3, 2, 1} << FourCharsVecSize{1, 1, 2, 2};
-  // CHECK: store <4 x i8> <i8 12, i8 6, i8 8, i8 4>
+  static_assert(q[0] == 12 , "");
+  static_assert(q[1] == 6 , "");
+  static_assert(q[2] == 8 , "");
+  static_assert(q[3] == 4 , "");
+
   constexpr auto r = FourCharsVecSize{19, 15, 12, 10} >>
                      FourCharsVecSize{1, 1, 2, 2};
-  // CHECK: store <4 x i8> <i8 9, i8 7, i8 3, i8 2>
+  static_assert(r[0] == 9 , "");
+  static_assert(r[1] == 7 , "");
+  static_assert(r[2] == 3 , "");
+  static_assert(r[3] == 2 , "");
+
   constexpr auto s = FourCharsVecSize{6, 3, 5, 10} << 1;
-  // CHECK: store <4 x i8> <i8 12, i8 6, i8 10, i8 20>
+  static_assert(s[0] == 12 , "");
+  static_assert(s[1] == 6 , "");
+  static_assert(s[2] == 10 , "");
+  static_assert(s[3] == 20 , "");
+
   constexpr auto t = FourCharsVecSize{19, 15, 10, 20} >> 1;
-  // CHECK: store <4 x i8> <i8 9, i8 7, i8 5, i8 10>
+  static_assert(t[0] == 9 , "");
+  static_assert(t[1] == 7 , "");
+  static_assert(t[2] == 5 , "");
+  static_assert(t[3] == 10 , "");
+
   constexpr auto u = 12 << FourCharsVecSize{1, 2, 3, 3};
-  // CHECK: store <4 x i8> <i8 24, i8 48, i8 96, i8 96>
+  static_assert(u[0] == 24 , "");
+  static_assert(u[1] == 48 , "");
+  static_assert(u[2] == 96 , "");
+  static_assert(u[3] == 96 , "");
+
   constexpr auto v = 12 >> FourCharsVecSize{1, 2, 2, 1};
-  // CHECK: store <4 x i8> <i8 6, i8 3, i8 3, i8 6>
+  static_assert(v[0] == 6 , "");
+  static_assert(v[1] == 3 , "");
+  static_assert(v[2] == 3 , "");
+  static_assert(v[3] == 6 , "");
 
   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>
+  static_assert(w[0] == -1 , "");
+  static_assert(w[1] == -1 , "");
+  static_assert(w[2] == 0 , "");
+  static_assert(w[3] == 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>
+  static_assert(x[0] == 0 , "");
+  static_assert(x[1] == 0 , "");
+  static_assert(x[2] == -1 , "");
+  static_assert(x[3] == -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>
+  static_assert(y[0] == -1 , "");
+  static_assert(y[1] == -1 , "");
+  static_assert(y[2] == -1 , "");
+  static_assert(y[3] == 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>
+  static_assert(z[0] == 0 , "");
+  static_assert(z[1] == 0 , "");
+  static_assert(z[2] == -1 , "");
+  static_assert(z[3] == -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>
+  static_assert(A[0] == 0 , "");
+  static_assert(A[1] == 0 , "");
+  static_assert(A[2] == -1 , "");
+  static_assert(A[3] == 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>
+  static_assert(B[0] == -1 , "");
+  static_assert(B[1] == -1 , "");
+  static_assert(B[2] == 0 , "");
+  static_assert(B[3] == -1 , "");
 
   constexpr auto C = FourCharsVecSize{1, 2, 3, 4} < 3;
-  // CHECK: store <4 x i8> <i8 -1, i8 -1, i8 0, i8 0>
+  static_assert(C[0] == -1 , "");
+  static_assert(C[1] == -1 , "");
+  static_assert(C[2] == 0 , "");
+  static_assert(C[3] == 0 , "");
+
   constexpr auto D = FourCharsVecSize{1, 2, 3, 4} > 3;
-  // CHECK: store <4 x i8> <i8 0, i8 0, i8 0, i8 -1>
+  static_assert(D[0] == 0 , "");
+  static_assert(D[1] == 0 , "");
+  static_assert(D[2] == 0 , "");
+  static_assert(D[3] == -1 , "");
+
   constexpr auto E = FourCharsVecSize{1, 2, 3, 4} <= 3;
-  // CHECK: store <4 x i8> <i8 -1, i8 -1, i8 -1, i8 0>
+  static_assert(E[0] == -1 , "");
+  static_assert(E[1] == -1 , "");
+  static_assert(E[2] == -1 , "");
+  static_assert(E[3] == 0 , "");
+
   constexpr auto F = FourCharsVecSize{1, 2, 3, 4} >= 3;
-  // CHECK: store <4 x i8> <i8 0, i8 0, i8 -1, i8 -1>
+  static_assert(F[0] == 0 , "");
+  static_assert(F[1] == 0 , "");
+  static_assert(F[2] == -1 , "");
+  static_assert(F[3] == -1 , "");
+
   constexpr auto G = FourCharsVecSize{1, 2, 3, 4} == 3;
-  // CHECK: store <4 x i8> <i8 0, i8 0, i8 -1, i8 0>
+  static_assert(G[0] == 0 , "");
+  static_assert(G[1] == 0 , "");
+  static_assert(G[2] == -1 , "");
+  static_assert(G[3] == 0 , "");
+
   constexpr auto H = FourCharsVecSize{1, 2, 3, 4} != 3;
-  // CHECK: store <4 x i8> <i8 -1, i8 -1, i8 0, i8 -1>
+  static_assert(H[0] == -1 , "");
+  static_assert(H[1] == -1 , "");
+  static_assert(H[2] == 0 , "");
+  static_assert(H[3] == -1 , "");
 
   constexpr auto I = FourCharsVecSize{1, 2, 3, 4} &
                      FourCharsVecSize{4, 3, 2, 1};
-  // CHECK: store <4 x i8> <i8 0, i8 2, i8 2, i8 0>
+  static_assert(I[0] == 0 , "");
+  static_assert(I[1] == 2 , "");
+  static_assert(I[2] == 2 , "");
+  static_assert(I[3] == 0 , "");
+
   constexpr auto J = FourCharsVecSize{1, 2, 3, 4} ^
                      FourCharsVecSize { 4, 3, 2, 1 };
-  // CHECK: store <4 x i8> <i8 5, i8 1, i8 1, i8 5>
+  static_assert(J[0] == 5 , "");
+  static_assert(J[1] == 1 , "");
+  static_assert(J[2] == 1 , "");
+  static_assert(J[3] == 5 , "");
+
   constexpr auto K = FourCharsVecSize{1, 2, 3, 4} |
                      FourCharsVecSize{4, 3, 2, 1};
-  // CHECK: store <4 x i8> <i8 5, i8 3, i8 3, i8 5>
+  static_assert(K[0] == 5 , "");
+  static_assert(K[1] == 3 , "");
+  static_assert(K[2] == 3 , "");
+  static_assert(K[3] == 5 , "");
+
   constexpr auto L = FourCharsVecSize{1, 2, 3, 4} & 3;
-  // CHECK: store <4 x i8> <i8 1, i8 2, i8 3, i8 0>
+  static_assert(L[0] == 1 , "");
+  static_assert(L[1] == 2 , "");
+  static_assert(L[2] == 3 , "");
+  static_assert(L[3] == 0 , "");
+
   constexpr auto M = FourCharsVecSize{1, 2, 3, 4} ^ 3;
-  // CHECK: store <4 x i8> <i8 2, i8 1, i8 0, i8 7>
+  static_assert(M[0] == 2 , "");
+  static_assert(M[1] == 1 , "");
+  static_assert(M[2] == 0 , "");
+  static_assert(M[3] == 7 , "");
+
   constexpr auto N = FourCharsVecSize{1, 2, 3, 4} | 3;
-  // CHECK: store <4 x i8> <i8 3, i8 3, i8 3, i8 7>
+  static_assert(N[0] == 3 , "");
+  static_assert(N[1] == 3 , "");
+  static_assert(N[2] == 3 , "");
+  static_assert(N[3] == 7 , "");
 
   constexpr auto O = FourCharsVecSize{5, 0, 6, 0} &&
                      FourCharsVecSize{5, 5, 0, 0};
-  // CHECK: store <4 x i8> <i8 1, i8 0, i8 0, i8 0>
+  static_assert(O[0] == 1 , "");
+  static_assert(O[1] == 0 , "");
+  static_assert(O[2] == 0 , "");
+  static_assert(O[3] == 0 , "");
+
   constexpr auto P = FourCharsVecSize{5, 0, 6, 0} ||
                      FourCharsVecSize{5, 5, 0, 0};
-  // CHECK: store <4 x i8> <i8 1, i8 1, i8 1, i8 0>
+  static_assert(P[0] == 1 , "");
+  static_assert(P[1] == 1 , "");
+  static_assert(P[2] == 1 , "");
+  static_assert(P[3] == 0 , "");
 
   constexpr auto Q = FourCharsVecSize{5, 0, 6, 0} && 3;
-  // CHECK: store <4 x i8> <i8 1, i8 0, i8 1, i8 0>
+  static_assert(Q[0] == 1 , "");
+  static_assert(Q[1] == 0 , "");
+  static_assert(Q[2] == 1 , "");
+  static_assert(Q[3] == 0 , "");
+
   constexpr auto R = FourCharsVecSize{5, 0, 6, 0} || 3;
-  // CHECK: store <4 x i8> <i8 1, i8 1, i8 1, i8 1>
+  static_assert(R[0] == 1 , "");
+  static_assert(R[1] == 1 , "");
+  static_assert(R[2] == 1 , "");
+  static_assert(R[3] == 1 , "");
 
   constexpr auto T = CmpMul(a, b);
-  // CHECK: store <4 x i8> <i8 108, i8 18, i8 56, i8 72>
+  static_assert(T[0] == 108 , "");
+  static_assert(T[1] == 18 , "");
+  static_assert(T[2] == 56 , "");
+  static_assert(T[3] == 72 , "");
 
   constexpr auto U = CmpDiv(a, b);
-  // CHECK: store <4 x i8> <i8 3, i8 18, i8 0, i8 0>
+  static_assert(U[0] == 3 , "");
+  static_assert(U[1] == 18 , "");
+  static_assert(U[2] == 0 , "");
+  static_assert(U[3] == 0 , "");
 
   constexpr auto V = CmpRem(a, b);
-  // CHECK: store <4 x i8> <i8 0, i8 0, i8 7, i8 8>
+  static_assert(V[0] == 0 , "");
+  static_assert(V[1] == 0 , "");
+  static_assert(V[2] == 7 , "");
+  static_assert(V[3] == 8 , "");
 
   constexpr auto X = CmpAdd(a, b);
-  // CHECK: store <4 x i8> <i8 24, i8 19, i8 15, i8 17>
+  static_assert(X[0] == 24 , "");
+  static_assert(X[1] == 19 , "");
+  static_assert(X[2] == 15 , "");
+  static_assert(X[3] == 17 , "");
 
   constexpr auto Y = CmpSub(a, b);
-  // CHECK: store <4 x i8> <i8 12, i8 17, i8 -1, i8 -1>
+  static_assert(Y[0] == 12 , "");
+  static_assert(Y[1] == 17 , "");
+  static_assert(Y[2] == -1 , "");
+  static_assert(Y[3] == -1 , "");
 
   constexpr auto InvH = -H;
-  // CHECK: store <4 x i8> <i8 1, i8 1, i8 0, i8 1>
+  static_assert(InvH[0] == 1 , "");
+  static_assert(InvH[1] == 1 , "");
+  static_assert(InvH[2] == 0 , "");
+  static_assert(InvH[3] == 1 , "");
+
   constexpr auto Z = CmpLSH(a, InvH);
-  // CHECK: store <4 x i8> <i8 36, i8 36, i8 7, i8 16>
+  static_asser...
[truncated]

@vikramRH
Copy link
Contributor Author

It seems there are few crashes with systemZ vectors. Looking into them

@yuanfang-chen
Copy link
Collaborator

#72607

@vikramRH vikramRH closed this Dec 28, 2023
@vikramRH
Copy link
Contributor Author

Putting this on hold hold as @yuanfang-chen already has a PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants