[PATCH] D158056: [clang] Implement constexpr operator[] for vectors

2023-08-16 Thread Joey Rabil via Phabricator via cfe-commits
DaPorkchop_ updated this revision to Diff 550731.
DaPorkchop_ added a comment.

Fixed test code for `CodeGenCXX/temporaries.cpp`

Creating and extracting a reference to a temporary
vector's element is now able to be evaluated at compile
time, which made this test case fail (since it was looking
for code which no longer needs to be generated).


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D158056/new/

https://reviews.llvm.org/D158056

Files:
  clang/include/clang/Basic/DiagnosticASTKinds.td
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/Interp/State.h
  clang/test/CodeGenCXX/temporaries.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
@@ -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 -triple x86_64-linux-gnu -Wno-unused-value %s
 
 using FourCharsVecSize __attribute__((vector_size(4))) = char;
 using FourIntsVecSize __attribute__((vector_size(16))) = int;
@@ -50,6 +44,12 @@
 a != b;   \
 a &\
 a || b;   \
+a += a[1];\
+a[1] += 1;\
+a[1] = 1; \
+a[1] = b[1];  \
+a[1]++;   \
+++a[1];   \
 auto c = (a, b);  \
 return c; \
   }
@@ -92,6 +92,15 @@
 MathShiftOpsInts(FourIntsExtVec);
 MathShiftOpsInts(FourLongLongsExtVec);
 
+template
+constexpr bool VectorsEqual(T a, U b) {
+  for (unsigned I = 0; I < 4; ++I) {
+if (a[I] != b[I])
+  return false;
+  }
+  return true;
+}
+
 template 
 constexpr auto CmpMul(T t, U u) {
   t *= u;
@@ -150,564 +159,711 @@
   return t;
 }
 
+template 
+constexpr auto UpdateElementsInPlace(T t, U u) {
+  t[0] += u[0];
+  t[1]++;
+  t[2] = 1;
+  return t;
+}
+
 // Only int vs float makes a difference here, so we only need to test 1 of each.
 // Test Char to make sure the mixed-nature of shifts around char is evident.
 void CharUsage() {
   constexpr auto a = FourCharsVecSize{6, 3, 2, 1} +
  FourCharsVecSize{12, 15, 5, 7};
-  // CHECK: store <4 x i8> 
+  static_assert(VectorsEqual(a, FourCharsVecSize{18, 18, 7, 8}), "");
+
   constexpr auto b = FourCharsVecSize{19, 15, 13, 12} -
  FourCharsVecSize{13, 14, 5, 3};
-  // CHECK: store <4 x i8> 
+  static_assert(VectorsEqual(b, FourCharsVecSize{6, 1, 8, 9}), "");
+
   constexpr auto c = FourCharsVecSize{8, 4, 2, 1} *
  FourCharsVecSize{3, 4, 5, 6};
-  // CHECK: store <4 x i8> 
+  static_assert(VectorsEqual(c, FourCharsVecSize{24, 16, 10, 6}), "");
+
   constexpr auto d = FourCharsVecSize{12, 12, 10, 10} /
  FourCharsVecSize{6, 4, 5, 2};
-  // CHECK: store <4 x i8> 
+  static_assert(VectorsEqual(d, FourCharsVecSize{2, 3, 2, 5}), "");
+
   constexpr auto e = FourCharsVecSize{12, 12, 10, 10} %
  FourCharsVecSize{6, 4, 4, 3};
-  // CHECK: store <4 x i8> 
+  static_assert(VectorsEqual(e, FourCharsVecSize{0, 0, 2, 1}), "");
 
   constexpr auto f = FourCharsVecSize{6, 3, 2, 1} + 3;
-  // CHECK: store <4 x i8> 
+  static_assert(VectorsEqual(f, FourCharsVecSize{9, 6, 5, 4}), "");
+
   constexpr auto g = FourCharsVecSize{19, 15, 12, 10} - 3;
-  // CHECK: store <4 x i8> 
+  static_assert(VectorsEqual(g, FourCharsVecSize{16, 12, 9, 7}), "");
+
   constexpr auto h = FourCharsVecSize{8, 4, 2, 1} * 3;
-  // CHECK: store <4 x i8> 
+  static_assert(VectorsEqual(h, FourCharsVecSize{24, 12, 6, 3}), "");
+
   constexpr auto j = FourCharsVecSize{12, 15, 18, 21} / 3;
-  // CHECK: store <4 x i8> 
+  static_assert(VectorsEqual(j, FourCharsVecSize{4, 5, 6, 7}), "");
+
   constexpr auto k = FourCharsVecSize{12, 17, 19, 22} % 3;
-  // CHECK: store <4 x i8> 
+  static_assert(VectorsEqual(k, FourCharsVecSize{0, 2, 1, 1}), "");
 
   constexpr auto l = 3 + FourCharsVecSize{6, 3, 2, 1};
-  // CHECK: store <4 x i8> 
+  static_assert(VectorsEqual(l, FourCharsVecSize{9, 6, 5, 4}), "");
+
   constexpr auto m = 20 - FourCharsVecSize{19, 15, 12, 10};
-  // CHECK: store <4 x i8> 
+  

[PATCH] D158056: [clang] Implement constexpr operator[] for vectors

2023-08-16 Thread Joey Rabil via Phabricator via cfe-commits
DaPorkchop_ created this revision.
DaPorkchop_ added reviewers: erichkeane, rsmith, efriedma, void.
Herald added a project: All.
DaPorkchop_ requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This implements the array subscript operator for vector types.

As vectors don't decay into pointers, I've opted to evaluate the vector
operand as an LValue, which still gives the expected behavior.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D158056

Files:
  clang/include/clang/Basic/DiagnosticASTKinds.td
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/Interp/State.h
  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
@@ -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 -triple x86_64-linux-gnu -Wno-unused-value %s
 
 using FourCharsVecSize __attribute__((vector_size(4))) = char;
 using FourIntsVecSize __attribute__((vector_size(16))) = int;
@@ -50,6 +44,12 @@
 a != b;   \
 a &\
 a || b;   \
+a += a[1];\
+a[1] += 1;\
+a[1] = 1; \
+a[1] = b[1];  \
+a[1]++;   \
+++a[1];   \
 auto c = (a, b);  \
 return c; \
   }
@@ -92,6 +92,15 @@
 MathShiftOpsInts(FourIntsExtVec);
 MathShiftOpsInts(FourLongLongsExtVec);
 
+template
+constexpr bool VectorsEqual(T a, U b) {
+  for (unsigned I = 0; I < 4; ++I) {
+if (a[I] != b[I])
+  return false;
+  }
+  return true;
+}
+
 template 
 constexpr auto CmpMul(T t, U u) {
   t *= u;
@@ -150,564 +159,711 @@
   return t;
 }
 
+template 
+constexpr auto UpdateElementsInPlace(T t, U u) {
+  t[0] += u[0];
+  t[1]++;
+  t[2] = 1;
+  return t;
+}
+
 // Only int vs float makes a difference here, so we only need to test 1 of each.
 // Test Char to make sure the mixed-nature of shifts around char is evident.
 void CharUsage() {
   constexpr auto a = FourCharsVecSize{6, 3, 2, 1} +
  FourCharsVecSize{12, 15, 5, 7};
-  // CHECK: store <4 x i8> 
+  static_assert(VectorsEqual(a, FourCharsVecSize{18, 18, 7, 8}), "");
+
   constexpr auto b = FourCharsVecSize{19, 15, 13, 12} -
  FourCharsVecSize{13, 14, 5, 3};
-  // CHECK: store <4 x i8> 
+  static_assert(VectorsEqual(b, FourCharsVecSize{6, 1, 8, 9}), "");
+
   constexpr auto c = FourCharsVecSize{8, 4, 2, 1} *
  FourCharsVecSize{3, 4, 5, 6};
-  // CHECK: store <4 x i8> 
+  static_assert(VectorsEqual(c, FourCharsVecSize{24, 16, 10, 6}), "");
+
   constexpr auto d = FourCharsVecSize{12, 12, 10, 10} /
  FourCharsVecSize{6, 4, 5, 2};
-  // CHECK: store <4 x i8> 
+  static_assert(VectorsEqual(d, FourCharsVecSize{2, 3, 2, 5}), "");
+
   constexpr auto e = FourCharsVecSize{12, 12, 10, 10} %
  FourCharsVecSize{6, 4, 4, 3};
-  // CHECK: store <4 x i8> 
+  static_assert(VectorsEqual(e, FourCharsVecSize{0, 0, 2, 1}), "");
 
   constexpr auto f = FourCharsVecSize{6, 3, 2, 1} + 3;
-  // CHECK: store <4 x i8> 
+  static_assert(VectorsEqual(f, FourCharsVecSize{9, 6, 5, 4}), "");
+
   constexpr auto g = FourCharsVecSize{19, 15, 12, 10} - 3;
-  // CHECK: store <4 x i8> 
+  static_assert(VectorsEqual(g, FourCharsVecSize{16, 12, 9, 7}), "");
+
   constexpr auto h = FourCharsVecSize{8, 4, 2, 1} * 3;
-  // CHECK: store <4 x i8> 
+  static_assert(VectorsEqual(h, FourCharsVecSize{24, 12, 6, 3}), "");
+
   constexpr auto j = FourCharsVecSize{12, 15, 18, 21} / 3;
-  // CHECK: store <4 x i8> 
+  static_assert(VectorsEqual(j, FourCharsVecSize{4, 5, 6, 7}), "");
+
   constexpr auto k = FourCharsVecSize{12, 17, 19, 22} % 3;
-  // CHECK: store <4 x i8> 
+  static_assert(VectorsEqual(k, FourCharsVecSize{0, 2, 1, 1}), "");
 
   constexpr auto l = 3 + FourCharsVecSize{6, 3, 2, 1};
-  // CHECK: store <4 x i8> 
+  static_assert(VectorsEqual(l, FourCharsVecSize{9, 6, 5, 4}), "");
+
   constexpr auto m = 20 - FourCharsVecSize{19, 15, 12, 10};
-  // CHECK: