[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