[clang] dbf149c - [RISCV] Properly diagnose mixing RVV scalable vectors with GNU vectors.

Craig Topper via cfe-commits cfe-commits at lists.llvm.org
Thu Feb 23 09:00:41 PST 2023


Author: Craig Topper
Date: 2023-02-23T09:00:32-08:00
New Revision: dbf149c91b7bdf08b2d4dd94ab76f3209af4c6d4

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

LOG: [RISCV] Properly diagnose mixing RVV scalable vectors with GNU vectors.

This case was being picked up by SVE code and printing an SVE
specific message.

This patch distinquishes RVV from SVE and provides a correct error
message for RVV.

The use of the generic isSizelessBuiltinType was also picking up
WebAssembly reference types which was probably an accident so I've
removed that.

I've named the test similar to SVE's test that contains this check.
Their test also tests the arm_sve_vector_bits attribute. I plan to
add something similar for RISC-V soon so I've adopted this naming.

Reviewed By: c-rhodes

Differential Revision: https://reviews.llvm.org/D144613

Added: 
    clang/test/Sema/attr-riscv-rvv-vector-bits.c

Modified: 
    clang/include/clang/AST/Type.h
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/lib/AST/Type.cpp
    clang/lib/Sema/SemaExpr.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 7dd058b9c53c..10cb4c819d7c 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -2029,6 +2029,9 @@ class alignas(8) Type : public ExtQualsTypeCommonBase {
   /// Returns true for SVE scalable vector types.
   bool isSVESizelessBuiltinType() const;
 
+  /// Returns true for RVV scalable vector types.
+  bool isRVVSizelessBuiltinType() const;
+
   /// Check if this is a WebAssembly Reference Type.
   bool isWebAssemblyReferenceType() const;
   bool isWebAssemblyExternrefType() const;

diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 86c5c4e288c9..81e3f5e2d062 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3165,8 +3165,8 @@ def err_attribute_zero_size : Error<"zero %0 size">;
 def err_attribute_size_too_large : Error<"%0 size too large">;
 def err_typecheck_sve_ambiguous : Error<
   "cannot combine fixed-length and sizeless SVE vectors in expression, result is ambiguous (%0 and %1)">;
-def err_typecheck_sve_gnu_ambiguous : Error<
-  "cannot combine GNU and SVE vectors in expression, result is ambiguous (%0 and %1)">;
+def err_typecheck_sve_rvv_gnu_ambiguous : Error<
+  "cannot combine GNU and %select{SVE|RVV}0 vectors in expression, result is ambiguous (%1 and %2)">;
 def err_typecheck_vector_not_convertable_implict_truncation : Error<
    "cannot convert between %select{scalar|vector}0 type %1 and vector type"
    " %2 as implicit conversion would cause truncation">;

diff  --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 04359c7d82cb..7710adbb274a 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -2372,6 +2372,19 @@ bool Type::isSVESizelessBuiltinType() const {
   return false;
 }
 
+bool Type::isRVVSizelessBuiltinType() const {
+  if (const BuiltinType *BT = getAs<BuiltinType>()) {
+    switch (BT->getKind()) {
+#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/RISCVVTypes.def"
+      return true;
+    default:
+      return false;
+    }
+  }
+  return false;
+}
+
 bool Type::isVLSTBuiltinType() const {
   if (const BuiltinType *BT = getAs<BuiltinType>()) {
     switch (BT->getKind()) {

diff  --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 3b8c8a4def51..817eed986e08 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -10750,12 +10750,14 @@ QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS,
     return QualType();
   }
 
-  // Expressions containing GNU and SVE (fixed or sizeless) vectors are invalid
-  // since the ambiguity can affect the ABI.
-  auto IsSveGnuConversion = [](QualType FirstType, QualType SecondType) {
+  // Expressions containing GNU and SVE or RVV (fixed or sizeless) vectors are
+  // invalid since the ambiguity can affect the ABI.
+  auto IsSveRVVGnuConversion = [](QualType FirstType, QualType SecondType,
+                                  unsigned &SVEorRVV) {
     const VectorType *FirstVecType = FirstType->getAs<VectorType>();
     const VectorType *SecondVecType = SecondType->getAs<VectorType>();
 
+    SVEorRVV = 0;
     if (FirstVecType && SecondVecType)
       return FirstVecType->getVectorKind() == VectorType::GenericVector &&
              (SecondVecType->getVectorKind() ==
@@ -10763,13 +10765,24 @@ QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS,
               SecondVecType->getVectorKind() ==
                   VectorType::SveFixedLengthPredicateVector);
 
-    return FirstType->isSizelessBuiltinType() && SecondVecType &&
-           SecondVecType->getVectorKind() == VectorType::GenericVector;
+    if (SecondVecType &&
+        SecondVecType->getVectorKind() == VectorType::GenericVector) {
+      if (FirstType->isSVESizelessBuiltinType())
+        return true;
+      if (FirstType->isRVVSizelessBuiltinType()) {
+        SVEorRVV = 1;
+        return true;
+      }
+    }
+
+    return false;
   };
 
-  if (IsSveGnuConversion(LHSType, RHSType) ||
-      IsSveGnuConversion(RHSType, LHSType)) {
-    Diag(Loc, diag::err_typecheck_sve_gnu_ambiguous) << LHSType << RHSType;
+  unsigned SVEorRVV;
+  if (IsSveRVVGnuConversion(LHSType, RHSType, SVEorRVV) ||
+      IsSveRVVGnuConversion(RHSType, LHSType, SVEorRVV)) {
+    Diag(Loc, diag::err_typecheck_sve_rvv_gnu_ambiguous)
+        << SVEorRVV << LHSType << RHSType;
     return QualType();
   }
 

diff  --git a/clang/test/Sema/attr-riscv-rvv-vector-bits.c b/clang/test/Sema/attr-riscv-rvv-vector-bits.c
new file mode 100644
index 000000000000..bd69c4857888
--- /dev/null
+++ b/clang/test/Sema/attr-riscv-rvv-vector-bits.c
@@ -0,0 +1,62 @@
+// RUN: %clang_cc1 -triple riscv64-none-linux-gnu -target-feature +zve64x -ffreestanding -fsyntax-only -verify %s
+
+// TODO: Support for a arm_sve_vector_bits like attribute will come in the future.
+
+#include <stdint.h>
+
+#define N 64
+
+typedef __rvv_int8m1_t vint8m1_t;
+typedef __rvv_uint8m1_t vuint8m1_t;
+typedef __rvv_int16m1_t vint16m1_t;
+typedef __rvv_uint16m1_t vuint16m1_t;
+typedef __rvv_int32m1_t vint32m1_t;
+typedef __rvv_uint32m1_t vuint32m1_t;
+typedef __rvv_int64m1_t vint64m1_t;
+typedef __rvv_uint64m1_t vuint64m1_t;
+typedef __rvv_float32m1_t vfloat32m1_t;
+typedef __rvv_float64m1_t vfloat64m1_t;
+
+// GNU vector types
+typedef int8_t gnu_int8_t __attribute__((vector_size(N / 8)));
+typedef int16_t gnu_int16_t __attribute__((vector_size(N / 8)));
+typedef int32_t gnu_int32_t __attribute__((vector_size(N / 8)));
+typedef int64_t gnu_int64_t __attribute__((vector_size(N / 8)));
+
+typedef uint8_t gnu_uint8_t __attribute__((vector_size(N / 8)));
+typedef uint16_t gnu_uint16_t __attribute__((vector_size(N / 8)));
+typedef uint32_t gnu_uint32_t __attribute__((vector_size(N / 8)));
+typedef uint64_t gnu_uint64_t __attribute__((vector_size(N / 8)));
+
+typedef float gnu_float32_t __attribute__((vector_size(N / 8)));
+typedef double gnu_float64_t __attribute__((vector_size(N / 8)));
+
+
+void f(int c) {
+  vint8m1_t ss8;
+  gnu_int8_t gs8;
+
+  // Check conditional expressions where the result is ambiguous are
+  // ill-formed.
+  void *sel __attribute__((unused));
+
+  sel = c ? gs8 : ss8; // expected-error {{cannot combine GNU and RVV vectors in expression, result is ambiguous}}
+  sel = c ? ss8 : gs8; // expected-error {{cannot combine GNU and RVV vectors in expression, result is ambiguous}}
+
+  // Check binary expressions where the result is ambiguous are ill-formed.
+  ss8 = ss8 + gs8; // expected-error {{cannot combine GNU and RVV vectors in expression, result is ambiguous}}
+
+  gs8 = gs8 + ss8; // expected-error {{cannot combine GNU and RVV vectors in expression, result is ambiguous}}
+
+  ss8 += gs8; // expected-error {{cannot combine GNU and RVV vectors in expression, result is ambiguous}}
+
+  gs8 += ss8; // expected-error {{cannot combine GNU and RVV vectors in expression, result is ambiguous}}
+
+  ss8 = ss8 == gs8; // expected-error {{cannot combine GNU and RVV vectors in expression, result is ambiguous}}
+
+  gs8 = gs8 == ss8; // expected-error {{cannot combine GNU and RVV vectors in expression, result is ambiguous}}
+
+  ss8 = ss8 & gs8; // expected-error {{invalid operands to binary expression ('vint8m1_t' (aka '__rvv_int8m1_t') and 'gnu_int8_t' (vector of 8 'int8_t' values))}}
+
+  gs8 = gs8 & ss8; // expected-error {{invalid operands to binary expression ('gnu_int8_t' (vector of 8 'int8_t' values) and 'vint8m1_t' (aka '__rvv_int8m1_t'))}}
+}


        


More information about the cfe-commits mailing list