joechrisellis created this revision.
joechrisellis added reviewers: fpetrogalli, peterwaller-arm, DavidTruby.
Herald added subscribers: cfe-commits, psnobl, kristof.beyls, tschuett.
Herald added a reviewer: efriedma.
Herald added a project: clang.
joechrisellis requested review of this revision.

This patch allows C-style casting between fixed-size and scalable
vectors. This kind of cast was previously blocked by the compiler, but
it should be allowed.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D91262

Files:
  clang/lib/Sema/SemaCast.cpp
  clang/test/Sema/aarch64-sve-explicit-casts-fixed-size.cpp
  clang/test/Sema/aarch64-sve-explicit-casts.cpp

Index: clang/test/Sema/aarch64-sve-explicit-casts.cpp
===================================================================
--- /dev/null
+++ clang/test/Sema/aarch64-sve-explicit-casts.cpp
@@ -0,0 +1,36 @@
+// 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
+
+#include <arm_sve.h>
+
+// SVE types cannot be C-style casted to one another.
+// "To avoid any ambiguity [between the two operations], the ACLE does not allow C-style casting from one
+// vector type to another." ~ACLE Section 3.4 (Vector Types)
+// The functions below check that C-style casting between scalable types correctly raises an error.
+
+void svint32_to_svint64() {
+  svint32_t si32;
+  svint64_t si64;
+
+  si64 = (svint64_t) si32; // expected-error-re {{C-style cast from 'svint32_t' {{.*}} is not allowed}}
+}
+
+void svint64_to_svint32() {
+  svint32_t si32;
+  svint64_t si64;
+
+  si32 = (svint32_t) si64; // expected-error-re {{C-style cast from 'svint64_t' {{.*}} is not allowed}}
+}
+
+void svfloat32_to_svfloat64() {
+  svfloat32_t sf32;
+  svfloat64_t sf64;
+
+  sf64 = (svfloat64_t) sf32; // expected-error-re {{C-style cast from 'svfloat32_t' {{.*}} is not allowed}}
+}
+
+void svfloat64_to_svfloat32() {
+  svfloat32_t sf32;
+  svfloat64_t sf64;
+
+  sf32 = (svfloat32_t) sf64; // expected-error-re {{C-style cast from 'svfloat64_t' {{.*}} is not allowed}}
+}
Index: clang/test/Sema/aarch64-sve-explicit-casts-fixed-size.cpp
===================================================================
--- /dev/null
+++ clang/test/Sema/aarch64-sve-explicit-casts-fixed-size.cpp
@@ -0,0 +1,72 @@
+// 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
+
+// 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;
+
+// Fixed-size SVE types can be cast to scalable SVE types (regardless of lane size).
+// NOTE: the list below is not exhaustive for all SVE types.
+
+void svint32_to_fixed_int32_t() {
+  svint32_t si32;
+  fixed_int32_t fi32;
+
+  fi32 = (fixed_int32_t)si32;
+}
+
+void fixed_int32_t_to_svint32() {
+  svint32_t si32;
+  fixed_int32_t fi32;
+
+  si32 = (svint32_t)fi32;
+}
+
+void svint64_to_fixed_int32_t() {
+  svint64_t si64;
+  fixed_int32_t fi32;
+
+  fi32 = (fixed_int32_t)si64;
+}
+
+void fixed_int32_t_to_svint64() {
+  svint64_t si64;
+  fixed_int32_t fi32;
+
+  si64 = (svint64_t)fi32;
+}
+
+void svint32_to_fixed_int64_t() {
+  svint32_t si32;
+  fixed_int64_t fi32;
+
+  fi32 = (fixed_int64_t)si32;
+}
+
+void fixed_int64_t_to_svint32() {
+  svint32_t si32;
+  fixed_int64_t fi32;
+
+  si32 = (svint32_t)fi32;
+}
+
+void svint64_to_fixed_int64_t() {
+  svint64_t si64;
+  fixed_int64_t fi32;
+
+  fi32 = (fixed_int64_t)si64;
+}
+
+void fixed_int64_t_to_svint64() {
+  svint64_t si64;
+  fixed_int64_t fi32;
+
+  si64 = (svint64_t)fi32;
+}
Index: clang/lib/Sema/SemaCast.cpp
===================================================================
--- clang/lib/Sema/SemaCast.cpp
+++ clang/lib/Sema/SemaCast.cpp
@@ -2219,6 +2219,13 @@
   bool destIsVector = DestType->isVectorType();
   bool srcIsVector = SrcType->isVectorType();
   if (srcIsVector || destIsVector) {
+    // Allow bitcasting if either the source or destination is a scalable
+    // vector.
+    if (SrcType->isSizelessBuiltinType() || DestType->isSizelessBuiltinType()) {
+      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++.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to