[PATCH] D85128: [Prototype][SVE] Support arm_sve_vector_bits attribute

Cullen Rhodes via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 3 05:41:38 PDT 2020


c-rhodes created this revision.
c-rhodes added reviewers: sdesmalen, paulwalker-arm, rsandifo-arm, efriedma, ctetreau, cameron.mcinally.
Herald added subscribers: aaron.ballman, danielkiss, psnobl, haicheng, hiraditya, kristof.beyls, eraman, tschuett.
Herald added a reviewer: rengolin.
Herald added a reviewer: aaron.ballman.
Herald added projects: clang, LLVM.
c-rhodes requested review of this revision.

This patch is a prototype demonstrating an alternative approach to D83553 <https://reviews.llvm.org/D83553> which
turned out to be an unviable solution.

In that approach vector-length-specific types (VLSTs) defined by the attribute
were by default represented as scalable vectors except in constructs where
scalable vectors aren't supported in IR, such as globals and structs, where they
were represented as fixed-length arrays.  When loading from a VLST to a VLAT, or
when storing a VLAT to a VLST, the address was bitcasted, e.g.

  bitcast [N x i8]* %addr.ptr to <vscale x 16 x i8>*

The issue with that approach was VLSTs were represented as `AttributedType` in
the AST and were not part of the canonical type. This was problematic in places
such as CodeGenTypes that look at the canonical type as special handling was
required for types such as `ConstantArrayType` that needed to be lowered to
fixed-length arrays. See the patch for more information on issues with that
approach.

In this implementation VLSTs are represented as `VectorType` in the AST and
fixed-length vectors in the IR everywhere except in function args/return.
Predicates are represented with `i8` as they were in D83553 <https://reviews.llvm.org/D83553> to avoid layout
issues in structs. For example, in the following C code:

  #if __ARM_FEATURE_SVE_BITS==512
  typedef svbool_t fixed_bool_t __attribute__((arm_sve_vector_bits(512)));
  #endif

`fixed_bool_t` becomes `<8 x i8>` in the IR.

In function args/return VLSTs are coerced from fixed to scalable vectors. This
is implemented through the AArch64 ABI in TargetInfo. As `BuiltinType::SveBool`
and `BuiltinType::SveUint8` are both represented as a `VectorType` of element
type `BuiltinType::UChar`, to support this in the ABI two new vectors kinds were
required to distinguish between predicates and data vectors.

Casting between VLAT/VLST is handled by the `CK_BitCast` operation and this has
been extended in CodeGen to support the new vector kinds, where the cast is
implemented through memory rather than a `bitcast` which is unsupported.
Implementing this as a normal `bitcast` would require relaxing checks in LLVM to
allow bitcasting between scalable and fixed types.  Another option was adding
target-specific intrinsics, although codegen support would need to be added for
these intrinsics. Given this, casting through memory seemed like the best
approach as it's supported today and existing optimisations may remove
unnecessary loads/stores, although there is room for improvement here.

The semantics implemented in D83551 <https://reviews.llvm.org/D83551> are changed as the `AttributedType` has been
replaced by `VectorType` in the AST. When VLSTs were represented as sizeless
types only minimal changes in Sema were necessary to permit them in places such
as structs, but no changes were required for implicit casting as the canonical
types were the same.

The AArch64 ACLE states VLSTs defined by the attribute map to the same AAPCS64
types as the sizeless variants. In the previous approach mangling wasn't
necessary as the canonical types were the same.  The mangling scheme is defined
in the appendices to the Procedure Call Standard for the Arm Architecture, see

  https://github.com/ARM-software/abi-aa/blob/master/aapcs64/aapcs64.rst#appendix-c-mangling

For more information on the attribute see:

  https://developer.arm.com/documentation/100987/latest

NOTE: This patch is intended as a prototype to demonstrate the approach. This is
quite a large patch containing a number of changes, if the approach is
considered valid the plan is to break it up into separate patches.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D85128

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/AST/Type.cpp
  clang/lib/AST/TypePrinter.cpp
  clang/lib/CodeGen/CGCall.cpp
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/lib/CodeGen/TargetInfo.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CodeGen/attr-arm-sve-vector-bits-bitcast.c
  clang/test/CodeGen/attr-arm-sve-vector-bits-call.c
  clang/test/CodeGen/attr-arm-sve-vector-bits-cast.c
  clang/test/CodeGen/attr-arm-sve-vector-bits-codegen.c
  clang/test/CodeGen/attr-arm-sve-vector-bits-globals.c
  clang/test/CodeGen/attr-arm-sve-vector-bits-types.c
  clang/test/CodeGenCXX/aarch64-sve-fixedtypeinfo.cpp
  clang/test/Sema/attr-arm-sve-vector-bits.c
  llvm/lib/Analysis/InlineCost.cpp
  llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
  llvm/lib/Transforms/Scalar/SROA.cpp

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D85128.282560.patch
Type: text/x-patch
Size: 142152 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200803/9955d93a/attachment-0001.bin>


More information about the llvm-commits mailing list