[clang] 53fd8db - [Clang][AArch64][SVE] Allow subscript operator for SVE types
David Truby via cfe-commits
cfe-commits at lists.llvm.org
Thu Apr 14 05:21:00 PDT 2022
Author: David Truby
Date: 2022-04-14T13:20:50+01:00
New Revision: 53fd8db79192f38feaec11c761e0d0fbdf1516b0
URL: https://github.com/llvm/llvm-project/commit/53fd8db79192f38feaec11c761e0d0fbdf1516b0
DIFF: https://github.com/llvm/llvm-project/commit/53fd8db79192f38feaec11c761e0d0fbdf1516b0.diff
LOG: [Clang][AArch64][SVE] Allow subscript operator for SVE types
Undefined behaviour is just passed on to extract_element when the
index is out of bounds. Subscript on svbool_t is not allowed as
this doesn't really have meaningful semantics.
Differential Revision: https://reviews.llvm.org/D122732
Added:
clang/test/CodeGen/aarch64-sve-vector-subscript-ops.c
clang/test/Sema/aarch64-sve-vector-subscript-ops.c
Modified:
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/AST/ExprConstant.cpp
clang/lib/CodeGen/CGExprScalar.cpp
clang/lib/Sema/SemaExpr.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 3213163ee7876..ea3db40aad571 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6638,6 +6638,8 @@ def err_subscript_function_type : Error<
"subscript of pointer to function type %0">;
def err_subscript_incomplete_or_sizeless_type : Error<
"subscript of pointer to %select{incomplete|sizeless}0 type %1">;
+def err_subscript_svbool_t : Error<
+ "subscript of svbool_t is not allowed">;
def err_dereference_incomplete_type : Error<
"dereference of pointer to incomplete type %0">;
def ext_gnu_subscript_void_type : Extension<
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 93950ac5341ba..50d6340ed31f7 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -8423,7 +8423,8 @@ bool LValueExprEvaluator::VisitMemberExpr(const MemberExpr *E) {
bool LValueExprEvaluator::VisitArraySubscriptExpr(const ArraySubscriptExpr *E) {
// FIXME: Deal with vectors as array subscript bases.
- if (E->getBase()->getType()->isVectorType())
+ if (E->getBase()->getType()->isVectorType() ||
+ E->getBase()->getType()->isVLSTBuiltinType())
return Error(E);
APSInt Index;
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 0711c993088bc..d3fe04d5a7915 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -1767,7 +1767,8 @@ Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
// loads the lvalue formed by the subscript expr. However, we have to be
// careful, because the base of a vector subscript is occasionally an rvalue,
// so we can't get it as an lvalue.
- if (!E->getBase()->getType()->isVectorType())
+ if (!E->getBase()->getType()->isVectorType() &&
+ !E->getBase()->getType()->isVLSTBuiltinType())
return EmitLoadOfLValue(E);
// Handle the vector case. The base must be a vector, the index must be an
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index da1fed4d72aec..faff375314e92 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -27,11 +27,13 @@
#include "clang/AST/OperationKinds.h"
#include "clang/AST/ParentMapContext.h"
#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/Type.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/DiagnosticSema.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/Specifiers.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Lex/LiteralSupport.h"
#include "clang/Lex/Preprocessor.h"
@@ -5683,6 +5685,33 @@ Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc,
OK = OK_VectorComponent;
ResultType = VTy->getElementType();
+ QualType BaseType = BaseExpr->getType();
+ Qualifiers BaseQuals = BaseType.getQualifiers();
+ Qualifiers MemberQuals = ResultType.getQualifiers();
+ Qualifiers Combined = BaseQuals + MemberQuals;
+ if (Combined != MemberQuals)
+ ResultType = Context.getQualifiedType(ResultType, Combined);
+ } else if (LHSTy->isBuiltinType() &&
+ LHSTy->getAs<BuiltinType>()->isVLSTBuiltinType()) {
+ const BuiltinType *BTy = LHSTy->getAs<BuiltinType>();
+ if (BTy->isSVEBool())
+ return ExprError(Diag(LLoc, diag::err_subscript_svbool_t)
+ << LHSExp->getSourceRange() << RHSExp->getSourceRange());
+
+ BaseExpr = LHSExp;
+ IndexExpr = RHSExp;
+ if (getLangOpts().CPlusPlus11 && LHSExp->isPRValue()) {
+ ExprResult Materialized = TemporaryMaterializationConversion(LHSExp);
+ if (Materialized.isInvalid())
+ return ExprError();
+ LHSExp = Materialized.get();
+ }
+ VK = LHSExp->getValueKind();
+ if (VK != VK_PRValue)
+ OK = OK_VectorComponent;
+
+ ResultType = BTy->getSveEltType(Context);
+
QualType BaseType = BaseExpr->getType();
Qualifiers BaseQuals = BaseType.getQualifiers();
Qualifiers MemberQuals = ResultType.getQualifiers();
diff --git a/clang/test/CodeGen/aarch64-sve-vector-subscript-ops.c b/clang/test/CodeGen/aarch64-sve-vector-subscript-ops.c
new file mode 100644
index 0000000000000..7e3beaf523963
--- /dev/null
+++ b/clang/test/CodeGen/aarch64-sve-vector-subscript-ops.c
@@ -0,0 +1,90 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve \
+// RUN: -fallow-half-arguments-and-returns -disable-O0-optnone \
+// RUN: -emit-llvm -o - %s | opt -S -sroa | FileCheck %s
+
+// REQUIRES: aarch64-registered-target
+
+#include <arm_sve.h>
+#include <stddef.h>
+
+// CHECK-LABEL: @subscript_int16(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[VECEXT:%.*]] = extractelement <vscale x 8 x i16> [[A:%.*]], i64 [[B:%.*]]
+// CHECK-NEXT: ret i16 [[VECEXT]]
+//
+int16_t subscript_int16(svint16_t a, size_t b) {
+ return a[b];
+}
+
+// CHECK-LABEL: @subscript_uint16(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[VECEXT:%.*]] = extractelement <vscale x 8 x i16> [[A:%.*]], i64 [[B:%.*]]
+// CHECK-NEXT: ret i16 [[VECEXT]]
+//
+uint16_t subscript_uint16(svuint16_t a, size_t b) {
+ return a[b];
+}
+
+// CHECK-LABEL: @subscript_int32(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[VECEXT:%.*]] = extractelement <vscale x 4 x i32> [[A:%.*]], i64 [[B:%.*]]
+// CHECK-NEXT: ret i32 [[VECEXT]]
+//
+int32_t subscript_int32(svint32_t a, size_t b) {
+ return a[b];
+}
+
+// CHECK-LABEL: @subscript_uint32(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[VECEXT:%.*]] = extractelement <vscale x 4 x i32> [[A:%.*]], i64 [[B:%.*]]
+// CHECK-NEXT: ret i32 [[VECEXT]]
+//
+uint32_t subscript_uint32(svuint32_t a, size_t b) {
+ return a[b];
+}
+
+// CHECK-LABEL: @subscript_int64(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[VECEXT:%.*]] = extractelement <vscale x 2 x i64> [[A:%.*]], i64 [[B:%.*]]
+// CHECK-NEXT: ret i64 [[VECEXT]]
+//
+int64_t subscript_int64(svint64_t a, size_t b) {
+ return a[b];
+}
+
+// CHECK-LABEL: @subscript_uint64(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[VECEXT:%.*]] = extractelement <vscale x 2 x i64> [[A:%.*]], i64 [[B:%.*]]
+// CHECK-NEXT: ret i64 [[VECEXT]]
+//
+uint64_t subscript_uint64(svuint64_t a, size_t b) {
+ return a[b];
+}
+
+// CHECK-LABEL: @subscript_float16(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[VECEXT:%.*]] = extractelement <vscale x 8 x half> [[A:%.*]], i64 [[B:%.*]]
+// CHECK-NEXT: ret half [[VECEXT]]
+//
+__fp16 subscript_float16(svfloat16_t a, size_t b) {
+ return a[b];
+}
+
+// CHECK-LABEL: @subscript_float32(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[VECEXT:%.*]] = extractelement <vscale x 4 x float> [[A:%.*]], i64 [[B:%.*]]
+// CHECK-NEXT: ret float [[VECEXT]]
+//
+float subscript_float32(svfloat32_t a, size_t b) {
+ return a[b];
+}
+
+// CHECK-LABEL: @subscript_float64(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[VECEXT:%.*]] = extractelement <vscale x 2 x double> [[A:%.*]], i64 [[B:%.*]]
+// CHECK-NEXT: ret double [[VECEXT]]
+//
+double subscript_float64(svfloat64_t a, size_t b) {
+ return a[b];
+}
diff --git a/clang/test/Sema/aarch64-sve-vector-subscript-ops.c b/clang/test/Sema/aarch64-sve-vector-subscript-ops.c
new file mode 100644
index 0000000000000..d84bf71f4c162
--- /dev/null
+++ b/clang/test/Sema/aarch64-sve-vector-subscript-ops.c
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -verify -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only %s
+
+// REQUIRES: aarch64-registered-target
+
+#include <arm_sve.h>
+
+void subscript(svint8_t i8, svint16_t i16, svint32_t i32, svint64_t i64,
+ svuint8_t u8, svuint16_t u16, svuint32_t u32, svuint64_t u64,
+ svfloat16_t f16, svfloat32_t f32, svfloat64_t f64,
+ svbool_t b) {
+ (void)b[0]; // expected-error{{subscript of svbool_t is not allowed}}
+ (void)b[0.f]; // expected-error{{subscript of svbool_t is not allowed}}
+ (void)b[0.]; // expected-error{{subscript of svbool_t is not allowed}}
+
+ (void)i8[0.f]; // expected-error{{array subscript is not an integer}}
+ (void)i8[0.]; // expected-error{{array subscript is not an integer}}
+
+ (void)u8[0.f]; // expected-error{{array subscript is not an integer}}
+ (void)u8[0.]; // expected-error{{array subscript is not an integer}}
+
+ (void)i16[0.f]; // expected-error{{array subscript is not an integer}}
+ (void)i16[0.]; // expected-error{{array subscript is not an integer}}
+
+ (void)u16[0.f]; // expected-error{{array subscript is not an integer}}
+ (void)u16[0.]; // expected-error{{array subscript is not an integer}}
+
+ (void)i32[0.f]; // expected-error{{array subscript is not an integer}}
+ (void)i32[0.]; // expected-error{{array subscript is not an integer}}
+
+ (void)u32[0.f]; // expected-error{{array subscript is not an integer}}
+ (void)u32[0.]; // expected-error{{array subscript is not an integer}}
+
+ (void)i64[0.f]; // expected-error{{array subscript is not an integer}}
+ (void)i64[0.]; // expected-error{{array subscript is not an integer}}
+
+ (void)u64[0.f]; // expected-error{{array subscript is not an integer}}
+ (void)u64[0.]; // expected-error{{array subscript is not an integer}}
+
+ (void)f16[0.f]; // expected-error{{array subscript is not an integer}}
+ (void)f16[0.]; // expected-error{{array subscript is not an integer}}
+
+ (void)f32[0.f]; // expected-error{{array subscript is not an integer}}
+ (void)f32[0.]; // expected-error{{array subscript is not an integer}}
+
+ (void)f64[0.f]; // expected-error{{array subscript is not an integer}}
+ (void)f64[0.]; // expected-error{{array subscript is not an integer}}
+}
More information about the cfe-commits
mailing list