joechrisellis updated this revision to Diff 304796.
joechrisellis marked 2 inline comments as done.
joechrisellis added a comment.

Address @c-rhodes's comments.

- Only allow casting between VLATs and VLSTs.
- Add C test.
- Move C++ test to the correct directory.
- Remove superfluous test.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D91262

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaCast.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/test/Sema/aarch64-sve-explicit-casts-fixed-size.c
  clang/test/SemaCXX/aarch64-sve-explicit-casts-fixed-size.cpp

Index: clang/test/SemaCXX/aarch64-sve-explicit-casts-fixed-size.cpp
===================================================================
--- /dev/null
+++ clang/test/SemaCXX/aarch64-sve-explicit-casts-fixed-size.cpp
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -msve-vector-bits=128 -flax-vector-conversions=none -fallow-half-arguments-and-returns -ffreestanding -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -msve-vector-bits=256 -flax-vector-conversions=none -fallow-half-arguments-and-returns -ffreestanding -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -msve-vector-bits=512 -flax-vector-conversions=none -fallow-half-arguments-and-returns -ffreestanding -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -msve-vector-bits=1024 -flax-vector-conversions=none -fallow-half-arguments-and-returns -ffreestanding -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -msve-vector-bits=2048 -flax-vector-conversions=none -fallow-half-arguments-and-returns -ffreestanding -fsyntax-only -verify %s
+
+// expected-no-diagnostics
+
+#include <arm_sve.h>
+
+#define N __ARM_FEATURE_SVE_BITS
+#define FIXED_ATTR __attribute__((arm_sve_vector_bits(N)))
+
+typedef svfloat32_t fixed_float32_t FIXED_ATTR;
+typedef svfloat64_t fixed_float64_t FIXED_ATTR;
+typedef svint32_t fixed_int32_t FIXED_ATTR;
+typedef svint64_t fixed_int64_t FIXED_ATTR;
+
+// SVE VLSTs can be cast to SVE VLATs, regardless of lane size.
+// NOTE: the list below is NOT exhaustive for all SVE types.
+
+#define TESTCASE(from, to) \
+    void from##_to_##to() {\
+        from a;            \
+        to b;              \
+                           \
+        b = (to) a;        \
+    }
+
+TESTCASE(fixed_float32_t, svfloat32_t)
+TESTCASE(fixed_float32_t, svfloat64_t)
+TESTCASE(fixed_float32_t, svint32_t)
+TESTCASE(fixed_float32_t, svint64_t)
+
+TESTCASE(fixed_float64_t, svfloat32_t)
+TESTCASE(fixed_float64_t, svfloat64_t)
+TESTCASE(fixed_float64_t, svint32_t)
+TESTCASE(fixed_float64_t, svint64_t)
+
+TESTCASE(fixed_int32_t, svfloat32_t)
+TESTCASE(fixed_int32_t, svfloat64_t)
+TESTCASE(fixed_int32_t, svint32_t)
+TESTCASE(fixed_int32_t, svint64_t)
+
+TESTCASE(fixed_int64_t, svfloat32_t)
+TESTCASE(fixed_int64_t, svfloat64_t)
+TESTCASE(fixed_int64_t, svint32_t)
+TESTCASE(fixed_int64_t, svint64_t)
+
+TESTCASE(svfloat32_t, fixed_float32_t)
+TESTCASE(svfloat32_t, fixed_float64_t)
+TESTCASE(svfloat32_t, fixed_int32_t)
+TESTCASE(svfloat32_t, fixed_int64_t)
+
+TESTCASE(svfloat64_t, fixed_float32_t)
+TESTCASE(svfloat64_t, fixed_float64_t)
+TESTCASE(svfloat64_t, fixed_int32_t)
+TESTCASE(svfloat64_t, fixed_int64_t)
+
+TESTCASE(svint32_t, fixed_float32_t)
+TESTCASE(svint32_t, fixed_float64_t)
+TESTCASE(svint32_t, fixed_int32_t)
+TESTCASE(svint32_t, fixed_int64_t)
+
+TESTCASE(svint64_t, fixed_float32_t)
+TESTCASE(svint64_t, fixed_float64_t)
+TESTCASE(svint64_t, fixed_int32_t)
+TESTCASE(svint64_t, fixed_int64_t)
Index: clang/test/Sema/aarch64-sve-explicit-casts-fixed-size.c
===================================================================
--- /dev/null
+++ clang/test/Sema/aarch64-sve-explicit-casts-fixed-size.c
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -msve-vector-bits=128 -flax-vector-conversions=none -fallow-half-arguments-and-returns -ffreestanding -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -msve-vector-bits=256 -flax-vector-conversions=none -fallow-half-arguments-and-returns -ffreestanding -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -msve-vector-bits=512 -flax-vector-conversions=none -fallow-half-arguments-and-returns -ffreestanding -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -msve-vector-bits=1024 -flax-vector-conversions=none -fallow-half-arguments-and-returns -ffreestanding -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -msve-vector-bits=2048 -flax-vector-conversions=none -fallow-half-arguments-and-returns -ffreestanding -fsyntax-only -verify %s
+
+// expected-no-diagnostics
+
+#include <arm_sve.h>
+
+#define N __ARM_FEATURE_SVE_BITS
+#define FIXED_ATTR __attribute__((arm_sve_vector_bits(N)))
+
+typedef svfloat32_t fixed_float32_t FIXED_ATTR;
+typedef svfloat64_t fixed_float64_t FIXED_ATTR;
+typedef svint32_t fixed_int32_t FIXED_ATTR;
+typedef svint64_t fixed_int64_t FIXED_ATTR;
+
+// SVE VLSTs can be cast to SVE VLATs, regardless of lane size.
+// NOTE: the list below is NOT exhaustive for all SVE types.
+
+#define TESTCASE(from, to) \
+    void from##_to_##to() {\
+        from a;            \
+        to b;              \
+                           \
+        b = (to) a;        \
+    }
+
+TESTCASE(fixed_float32_t, svfloat32_t)
+TESTCASE(fixed_float32_t, svfloat64_t)
+TESTCASE(fixed_float32_t, svint32_t)
+TESTCASE(fixed_float32_t, svint64_t)
+
+TESTCASE(fixed_float64_t, svfloat32_t)
+TESTCASE(fixed_float64_t, svfloat64_t)
+TESTCASE(fixed_float64_t, svint32_t)
+TESTCASE(fixed_float64_t, svint64_t)
+
+TESTCASE(fixed_int32_t, svfloat32_t)
+TESTCASE(fixed_int32_t, svfloat64_t)
+TESTCASE(fixed_int32_t, svint32_t)
+TESTCASE(fixed_int32_t, svint64_t)
+
+TESTCASE(fixed_int64_t, svfloat32_t)
+TESTCASE(fixed_int64_t, svfloat64_t)
+TESTCASE(fixed_int64_t, svint32_t)
+TESTCASE(fixed_int64_t, svint64_t)
+
+TESTCASE(svfloat32_t, fixed_float32_t)
+TESTCASE(svfloat32_t, fixed_float64_t)
+TESTCASE(svfloat32_t, fixed_int32_t)
+TESTCASE(svfloat32_t, fixed_int64_t)
+
+TESTCASE(svfloat64_t, fixed_float32_t)
+TESTCASE(svfloat64_t, fixed_float64_t)
+TESTCASE(svfloat64_t, fixed_int32_t)
+TESTCASE(svfloat64_t, fixed_int64_t)
+
+TESTCASE(svint32_t, fixed_float32_t)
+TESTCASE(svint32_t, fixed_float64_t)
+TESTCASE(svint32_t, fixed_int32_t)
+TESTCASE(svint32_t, fixed_int64_t)
+
+TESTCASE(svint64_t, fixed_float32_t)
+TESTCASE(svint64_t, fixed_float64_t)
+TESTCASE(svint64_t, fixed_int32_t)
+TESTCASE(svint64_t, fixed_int64_t)
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -7197,6 +7197,27 @@
   return true;
 }
 
+/// Are the two types SVE-bitcast-compatible types? I.e. can we bitcast from the
+/// first SVE type (e.g. an SVE VLAT) to the second type (e.g. an SVE VLST)?
+///
+/// This will also return false if the two given types do not make sense from
+/// the perspective of SVE bitcasts.
+bool Sema::isValidSveBitcast(QualType srcTy, QualType destTy) {
+  assert(srcTy->isVectorType() || destTy->isVectorType());
+
+  auto ValidScalableConversion = [](QualType FirstType, QualType SecondType) {
+    if (!FirstType->getAs<BuiltinType>())
+      return false;
+
+    const auto *VecTy = SecondType->getAs<VectorType>();
+    return VecTy &&
+           VecTy->getVectorKind() == VectorType::SveFixedLengthDataVector;
+  };
+
+  return ValidScalableConversion(srcTy, destTy) ||
+         ValidScalableConversion(destTy, srcTy);
+}
+
 /// Are the two types lax-compatible vector types?  That is, given
 /// that one of them is a vector, do they have equal storage sizes,
 /// where the storage size is the number of elements times the element
Index: clang/lib/Sema/SemaCast.cpp
===================================================================
--- clang/lib/Sema/SemaCast.cpp
+++ clang/lib/Sema/SemaCast.cpp
@@ -2214,11 +2214,17 @@
     return TC_Success;
   }
 
-  // Allow reinterpret_casts between vectors of the same size and
-  // between vectors and integers of the same size.
+  // Allow reinterpret_casts between SVE VLATs/VLSTs, vectors of the same
+  // size and between vectors and integers of the same size.
   bool destIsVector = DestType->isVectorType();
   bool srcIsVector = SrcType->isVectorType();
   if (srcIsVector || destIsVector) {
+    // We can bitcast between SVE VLATs and VLSTs, and vice-versa.
+    if (Self.isValidSveBitcast(SrcType, DestType)) {
+      Kind = CK_BitCast;
+      return TC_Success;
+    }
+
     // The non-vector type, if any, must have integral type.  This is
     // the same rule that C vector casts use; note, however, that enum
     // types are not integral in C++.
@@ -2752,6 +2758,14 @@
     return;
   }
 
+  // If either the src or dest are a vector, it's possible that we want to do an
+  // SVE bitcast. We can bitcast between SVE VLATs and VLSTs, and vice-versa.
+  if (SrcType->isVectorType() || DestType->isVectorType())
+    if (Self.isValidSveBitcast(SrcType, DestType)) {
+      Kind = CK_BitCast;
+      return;
+    }
+
   if (!DestType->isScalarType() && !DestType->isVectorType()) {
     const RecordType *DestRecordTy = DestType->getAs<RecordType>();
 
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -11499,6 +11499,8 @@
   QualType CheckMatrixMultiplyOperands(ExprResult &LHS, ExprResult &RHS,
                                        SourceLocation Loc, bool IsCompAssign);
 
+  bool isValidSveBitcast(QualType srcType, QualType destType);
+
   bool areLaxCompatibleVectorTypes(QualType srcType, QualType destType);
   bool isLaxVectorConversion(QualType srcType, QualType destType);
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to