Skip to content

Commit dbf149c

Browse files
committed
[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
1 parent c6c785b commit dbf149c

File tree

5 files changed

+101
-10
lines changed

5 files changed

+101
-10
lines changed

clang/include/clang/AST/Type.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2029,6 +2029,9 @@ class alignas(8) Type : public ExtQualsTypeCommonBase {
20292029
/// Returns true for SVE scalable vector types.
20302030
bool isSVESizelessBuiltinType() const;
20312031

2032+
/// Returns true for RVV scalable vector types.
2033+
bool isRVVSizelessBuiltinType() const;
2034+
20322035
/// Check if this is a WebAssembly Reference Type.
20332036
bool isWebAssemblyReferenceType() const;
20342037
bool isWebAssemblyExternrefType() const;

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3165,8 +3165,8 @@ def err_attribute_zero_size : Error<"zero %0 size">;
31653165
def err_attribute_size_too_large : Error<"%0 size too large">;
31663166
def err_typecheck_sve_ambiguous : Error<
31673167
"cannot combine fixed-length and sizeless SVE vectors in expression, result is ambiguous (%0 and %1)">;
3168-
def err_typecheck_sve_gnu_ambiguous : Error<
3169-
"cannot combine GNU and SVE vectors in expression, result is ambiguous (%0 and %1)">;
3168+
def err_typecheck_sve_rvv_gnu_ambiguous : Error<
3169+
"cannot combine GNU and %select{SVE|RVV}0 vectors in expression, result is ambiguous (%1 and %2)">;
31703170
def err_typecheck_vector_not_convertable_implict_truncation : Error<
31713171
"cannot convert between %select{scalar|vector}0 type %1 and vector type"
31723172
" %2 as implicit conversion would cause truncation">;

clang/lib/AST/Type.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2372,6 +2372,19 @@ bool Type::isSVESizelessBuiltinType() const {
23722372
return false;
23732373
}
23742374

2375+
bool Type::isRVVSizelessBuiltinType() const {
2376+
if (const BuiltinType *BT = getAs<BuiltinType>()) {
2377+
switch (BT->getKind()) {
2378+
#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
2379+
#include "clang/Basic/RISCVVTypes.def"
2380+
return true;
2381+
default:
2382+
return false;
2383+
}
2384+
}
2385+
return false;
2386+
}
2387+
23752388
bool Type::isVLSTBuiltinType() const {
23762389
if (const BuiltinType *BT = getAs<BuiltinType>()) {
23772390
switch (BT->getKind()) {

clang/lib/Sema/SemaExpr.cpp

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10750,26 +10750,39 @@ QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS,
1075010750
return QualType();
1075110751
}
1075210752

10753-
// Expressions containing GNU and SVE (fixed or sizeless) vectors are invalid
10754-
// since the ambiguity can affect the ABI.
10755-
auto IsSveGnuConversion = [](QualType FirstType, QualType SecondType) {
10753+
// Expressions containing GNU and SVE or RVV (fixed or sizeless) vectors are
10754+
// invalid since the ambiguity can affect the ABI.
10755+
auto IsSveRVVGnuConversion = [](QualType FirstType, QualType SecondType,
10756+
unsigned &SVEorRVV) {
1075610757
const VectorType *FirstVecType = FirstType->getAs<VectorType>();
1075710758
const VectorType *SecondVecType = SecondType->getAs<VectorType>();
1075810759

10760+
SVEorRVV = 0;
1075910761
if (FirstVecType && SecondVecType)
1076010762
return FirstVecType->getVectorKind() == VectorType::GenericVector &&
1076110763
(SecondVecType->getVectorKind() ==
1076210764
VectorType::SveFixedLengthDataVector ||
1076310765
SecondVecType->getVectorKind() ==
1076410766
VectorType::SveFixedLengthPredicateVector);
1076510767

10766-
return FirstType->isSizelessBuiltinType() && SecondVecType &&
10767-
SecondVecType->getVectorKind() == VectorType::GenericVector;
10768+
if (SecondVecType &&
10769+
SecondVecType->getVectorKind() == VectorType::GenericVector) {
10770+
if (FirstType->isSVESizelessBuiltinType())
10771+
return true;
10772+
if (FirstType->isRVVSizelessBuiltinType()) {
10773+
SVEorRVV = 1;
10774+
return true;
10775+
}
10776+
}
10777+
10778+
return false;
1076810779
};
1076910780

10770-
if (IsSveGnuConversion(LHSType, RHSType) ||
10771-
IsSveGnuConversion(RHSType, LHSType)) {
10772-
Diag(Loc, diag::err_typecheck_sve_gnu_ambiguous) << LHSType << RHSType;
10781+
unsigned SVEorRVV;
10782+
if (IsSveRVVGnuConversion(LHSType, RHSType, SVEorRVV) ||
10783+
IsSveRVVGnuConversion(RHSType, LHSType, SVEorRVV)) {
10784+
Diag(Loc, diag::err_typecheck_sve_rvv_gnu_ambiguous)
10785+
<< SVEorRVV << LHSType << RHSType;
1077310786
return QualType();
1077410787
}
1077510788

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// RUN: %clang_cc1 -triple riscv64-none-linux-gnu -target-feature +zve64x -ffreestanding -fsyntax-only -verify %s
2+
3+
// TODO: Support for a arm_sve_vector_bits like attribute will come in the future.
4+
5+
#include <stdint.h>
6+
7+
#define N 64
8+
9+
typedef __rvv_int8m1_t vint8m1_t;
10+
typedef __rvv_uint8m1_t vuint8m1_t;
11+
typedef __rvv_int16m1_t vint16m1_t;
12+
typedef __rvv_uint16m1_t vuint16m1_t;
13+
typedef __rvv_int32m1_t vint32m1_t;
14+
typedef __rvv_uint32m1_t vuint32m1_t;
15+
typedef __rvv_int64m1_t vint64m1_t;
16+
typedef __rvv_uint64m1_t vuint64m1_t;
17+
typedef __rvv_float32m1_t vfloat32m1_t;
18+
typedef __rvv_float64m1_t vfloat64m1_t;
19+
20+
// GNU vector types
21+
typedef int8_t gnu_int8_t __attribute__((vector_size(N / 8)));
22+
typedef int16_t gnu_int16_t __attribute__((vector_size(N / 8)));
23+
typedef int32_t gnu_int32_t __attribute__((vector_size(N / 8)));
24+
typedef int64_t gnu_int64_t __attribute__((vector_size(N / 8)));
25+
26+
typedef uint8_t gnu_uint8_t __attribute__((vector_size(N / 8)));
27+
typedef uint16_t gnu_uint16_t __attribute__((vector_size(N / 8)));
28+
typedef uint32_t gnu_uint32_t __attribute__((vector_size(N / 8)));
29+
typedef uint64_t gnu_uint64_t __attribute__((vector_size(N / 8)));
30+
31+
typedef float gnu_float32_t __attribute__((vector_size(N / 8)));
32+
typedef double gnu_float64_t __attribute__((vector_size(N / 8)));
33+
34+
35+
void f(int c) {
36+
vint8m1_t ss8;
37+
gnu_int8_t gs8;
38+
39+
// Check conditional expressions where the result is ambiguous are
40+
// ill-formed.
41+
void *sel __attribute__((unused));
42+
43+
sel = c ? gs8 : ss8; // expected-error {{cannot combine GNU and RVV vectors in expression, result is ambiguous}}
44+
sel = c ? ss8 : gs8; // expected-error {{cannot combine GNU and RVV vectors in expression, result is ambiguous}}
45+
46+
// Check binary expressions where the result is ambiguous are ill-formed.
47+
ss8 = ss8 + gs8; // expected-error {{cannot combine GNU and RVV vectors in expression, result is ambiguous}}
48+
49+
gs8 = gs8 + ss8; // expected-error {{cannot combine GNU and RVV vectors in expression, result is ambiguous}}
50+
51+
ss8 += gs8; // expected-error {{cannot combine GNU and RVV vectors in expression, result is ambiguous}}
52+
53+
gs8 += ss8; // expected-error {{cannot combine GNU and RVV vectors in expression, result is ambiguous}}
54+
55+
ss8 = ss8 == gs8; // expected-error {{cannot combine GNU and RVV vectors in expression, result is ambiguous}}
56+
57+
gs8 = gs8 == ss8; // expected-error {{cannot combine GNU and RVV vectors in expression, result is ambiguous}}
58+
59+
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))}}
60+
61+
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'))}}
62+
}

0 commit comments

Comments
 (0)