llvm.org GIT mirror llvm / d049378
[SVE][IR] Scalable Vector IR Type * Adds a 'scalable' flag to VectorType * Adds an 'ElementCount' class to VectorType to pass (possibly scalable) vector lengths, with overloaded operators. * Modifies existing helper functions to use ElementCount * Adds support for serializing/deserializing to/from both textual and bitcode IR formats * Extends the verifier to reject global variables of scalable types * Updates documentation See the latest version of the RFC here: http://lists.llvm.org/pipermail/llvm-dev/2018-July/124396.html Reviewers: rengolin, lattner, echristo, chandlerc, hfinkel, rkruppe, samparker, SjoerdMeijer, greened, sebpop Reviewed By: hfinkel, sebpop Differential Revision: https://reviews.llvm.org/D32530 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@361953 91177308-0d34-0410-b5e6-96231b3b80d8 Graham Hunter 4 months ago
19 changed file(s) with 480 addition(s) and 40 deletion(s). Raw diff Collapse all Expand all
673673
674674 Variables and aliases can have a
675675 :ref:`Thread Local Storage Model `.
676
677 :ref:`Scalable vectors ` cannot be global variables or members of
678 structs or arrays because their size is unknown at compile time.
676679
677680 Syntax::
678681
27292732 A vector type is a simple derived type that represents a vector of
27302733 elements. Vector types are used when multiple primitive data are
27312734 operated in parallel using a single instruction (SIMD). A vector type
2732 requires a size (number of elements) and an underlying primitive data
2733 type. Vector types are considered :ref:`first class `.
2735 requires a size (number of elements), an underlying primitive data type,
2736 and a scalable property to represent vectors where the exact hardware
2737 vector length is unknown at compile time. Vector types are considered
2738 :ref:`first class `.
27342739
27352740 :Syntax:
27362741
27372742 ::
27382743
2739 < <# elements> x >
2744 < <# elements> x > ; Fixed-length vector
2745 < vscale x <# elements> x > ; Scalable vector
27402746
27412747 The number of elements is a constant integer value larger than 0;
27422748 elementtype may be any integer, floating-point or pointer type. Vectors
2743 of size zero are not allowed.
2749 of size zero are not allowed. For scalable vectors, the total number of
2750 elements is a constant multiple (called vscale) of the specified number
2751 of elements; vscale is a positive integer that is unknown at compile time
2752 and the same hardware-dependent constant for all scalable vectors at run
2753 time. The size of a specific scalable vector type is thus constant within
2754 IR, even if the exact size in bytes cannot be determined until run time.
27442755
27452756 :Examples:
27462757
2747 +-------------------+--------------------------------------------------+
2748 | ``<4 x i32>`` | Vector of 4 32-bit integer values. |
2749 +-------------------+--------------------------------------------------+
2750 | ``<8 x float>`` | Vector of 8 32-bit floating-point values. |
2751 +-------------------+--------------------------------------------------+
2752 | ``<2 x i64>`` | Vector of 2 64-bit integer values. |
2753 +-------------------+--------------------------------------------------+
2754 | ``<4 x i64*>`` | Vector of 4 pointers to 64-bit integer values. |
2755 +-------------------+--------------------------------------------------+
2758 +------------------------+----------------------------------------------------+
2759 | ``<4 x i32>`` | Vector of 4 32-bit integer values. |
2760 +------------------------+----------------------------------------------------+
2761 | ``<8 x float>`` | Vector of 8 32-bit floating-point values. |
2762 +------------------------+----------------------------------------------------+
2763 | ``<2 x i64>`` | Vector of 2 64-bit integer values. |
2764 +------------------------+----------------------------------------------------+
2765 | ``<4 x i64*>`` | Vector of 4 pointers to 64-bit integer values. |
2766 +------------------------+----------------------------------------------------+
2767 | ```` | Vector with a multiple of 4 32-bit integer values. |
2768 +------------------------+----------------------------------------------------+
27562769
27572770 .. _t_label:
27582771
81348147 ::
81358148
81368149 = extractelement > , ; yields
8150 = extractelement > , ; yields
81378151
81388152 Overview:
81398153 """""""""
81548168
81558169 The result is a scalar of the same type as the element type of ``val``.
81568170 Its value is the value at position ``idx`` of ``val``. If ``idx``
8157 exceeds the length of ``val``, the result is a
8171 exceeds the length of ``val`` for a fixed-length vector, the result is a
8172 :ref:`poison value `. For a scalable vector, if the value
8173 of ``idx`` exceeds the runtime length of the vector, the result is a
81588174 :ref:`poison value `.
81598175
81608176 Example:
81758191 ::
81768192
81778193 = insertelement > , , ; yields >
8194 = insertelement > , , ; yields >
81788195
81798196 Overview:
81808197 """""""""
81968213
81978214 The result is a vector of the same type as ``val``. Its element values
81988215 are those of ``val`` except at position ``idx``, where it gets the value
8199 ``elt``. If ``idx`` exceeds the length of ``val``, the result
8216 ``elt``. If ``idx`` exceeds the length of ``val`` for a fixed-length vector,
8217 the result is a :ref:`poison value `. For a scalable vector,
8218 if the value of ``idx`` exceeds the runtime length of the vector, the result
82008219 is a :ref:`poison value `.
82018220
82028221 Example:
82178236 ::
82188237
82198238 = shufflevector > , > , ; yields >
8239 = shufflevector > , > v2, ; yields >
82208240
82218241 Overview:
82228242 """""""""
82478267 undef. If any element of the mask operand is undef, that element of the
82488268 result is undef. If the shuffle mask selects an undef element from one
82498269 of the input vectors, the resulting element is undef.
8270
8271 For scalable vectors, the only valid mask values at present are
8272 ``zeroinitializer`` and ``undef``, since we cannot write all indices as
8273 literals for a vector with a length unknown at compile time.
82508274
82518275 Example:
82528276 """"""""
1616 #include "llvm/ADT/Hashing.h"
1717 #include "llvm/ADT/StringRef.h"
1818 #include "llvm/Support/PointerLikeTypeTraits.h"
19 #include "llvm/Support/ScalableSize.h"
1920 #include
2021 #include
2122 #include
267268 static bool isEqual(hash_code LHS, hash_code RHS) { return LHS == RHS; }
268269 };
269270
271 template <> struct DenseMapInfo {
272 static inline ElementCount getEmptyKey() { return {~0U, true}; }
273 static inline ElementCount getTombstoneKey() { return {~0U - 1, false}; }
274 static unsigned getHashValue(const ElementCount& EltCnt) {
275 if (EltCnt.Scalable)
276 return (EltCnt.Min * 37U) - 1U;
277
278 return EltCnt.Min * 37U;
279 }
280
281 static bool isEqual(const ElementCount& LHS, const ElementCount& RHS) {
282 return LHS == RHS;
283 }
284 };
285
270286 } // end namespace llvm
271287
272288 #endif // LLVM_ADT_DENSEMAPINFO_H
2222 #include "llvm/IR/Type.h"
2323 #include "llvm/Support/Casting.h"
2424 #include "llvm/Support/Compiler.h"
25 #include "llvm/Support/ScalableSize.h"
2526 #include
2627 #include
2728
386387 SequentialType(const SequentialType &) = delete;
387388 SequentialType &operator=(const SequentialType &) = delete;
388389
390 /// For scalable vectors, this will return the minimum number of elements
391 /// in the vector.
389392 uint64_t getNumElements() const { return NumElements; }
390393 Type *getElementType() const { return ContainedType; }
391394
421424
422425 /// Class to represent vector types.
423426 class VectorType : public SequentialType {
424 VectorType(Type *ElType, unsigned NumEl);
427 /// A fully specified VectorType is of the form . 'n' is the
428 /// minimum number of elements of type Ty contained within the vector, and
429 /// 'scalable' indicates that the total element count is an integer multiple
430 /// of 'n', where the multiple is either guaranteed to be one, or is
431 /// statically unknown at compile time.
432 ///
433 /// If the multiple is known to be 1, then the extra term is discarded in
434 /// textual IR:
435 ///
436 /// <4 x i32> - a vector containing 4 i32s
437 /// - a vector containing an unknown integer multiple
438 /// of 4 i32s
439
440 VectorType(Type *ElType, unsigned NumEl, bool Scalable = false);
441 VectorType(Type *ElType, ElementCount EC);
442
443 // If true, the total number of elements is an unknown multiple of the
444 // minimum 'NumElements' from SequentialType. Otherwise the total number
445 // of elements is exactly equal to 'NumElements'.
446 bool Scalable;
425447
426448 public:
427449 VectorType(const VectorType &) = delete;
428450 VectorType &operator=(const VectorType &) = delete;
429451
430452 /// This static method is the primary way to construct an VectorType.
431 static VectorType *get(Type *ElementType, unsigned NumElements);
453 static VectorType *get(Type *ElementType, ElementCount EC);
454 static VectorType *get(Type *ElementType, unsigned NumElements,
455 bool Scalable = false) {
456 return VectorType::get(ElementType, {NumElements, Scalable});
457 }
432458
433459 /// This static method gets a VectorType with the same number of elements as
434460 /// the input type, and the element type is an integer type of the same width
437463 unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
438464 assert(EltBits && "Element size must be of a non-zero size");
439465 Type *EltTy = IntegerType::get(VTy->getContext(), EltBits);
440 return VectorType::get(EltTy, VTy->getNumElements());
466 return VectorType::get(EltTy, VTy->getElementCount());
441467 }
442468
443469 /// This static method is like getInteger except that the element types are
445471 static VectorType *getExtendedElementVectorType(VectorType *VTy) {
446472 unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
447473 Type *EltTy = IntegerType::get(VTy->getContext(), EltBits * 2);
448 return VectorType::get(EltTy, VTy->getNumElements());
474 return VectorType::get(EltTy, VTy->getElementCount());
449475 }
450476
451477 /// This static method is like getInteger except that the element types are
455481 assert((EltBits & 1) == 0 &&
456482 "Cannot truncate vector element with odd bit-width");
457483 Type *EltTy = IntegerType::get(VTy->getContext(), EltBits / 2);
458 return VectorType::get(EltTy, VTy->getNumElements());
484 return VectorType::get(EltTy, VTy->getElementCount());
459485 }
460486
461487 /// This static method returns a VectorType with half as many elements as the
462488 /// input type and the same element type.
463489 static VectorType *getHalfElementsVectorType(VectorType *VTy) {
464 unsigned NumElts = VTy->getNumElements();
465 assert ((NumElts & 1) == 0 &&
490 auto EltCnt = VTy->getElementCount();
491 assert ((EltCnt.Min & 1) == 0 &&
466492 "Cannot halve vector with odd number of elements.");
467 return VectorType::get(VTy->getElementType(), NumElts/2);
493 return VectorType::get(VTy->getElementType(), EltCnt/2);
468494 }
469495
470496 /// This static method returns a VectorType with twice as many elements as the
471497 /// input type and the same element type.
472498 static VectorType *getDoubleElementsVectorType(VectorType *VTy) {
473 unsigned NumElts = VTy->getNumElements();
474 return VectorType::get(VTy->getElementType(), NumElts*2);
499 auto EltCnt = VTy->getElementCount();
500 assert((VTy->getNumElements() * 2ull) <= UINT_MAX &&
501 "Too many elements in vector");
502 return VectorType::get(VTy->getElementType(), EltCnt*2);
475503 }
476504
477505 /// Return true if the specified type is valid as a element type.
478506 static bool isValidElementType(Type *ElemTy);
479507
480 /// Return the number of bits in the Vector type.
508 /// Return an ElementCount instance to represent the (possibly scalable)
509 /// number of elements in the vector.
510 ElementCount getElementCount() const {
511 uint64_t MinimumEltCnt = getNumElements();
512 assert(MinimumEltCnt <= UINT_MAX && "Too many elements in vector");
513 return { (unsigned)MinimumEltCnt, Scalable };
514 }
515
516 /// Returns whether or not this is a scalable vector (meaning the total
517 /// element count is a multiple of the minimum).
518 bool isScalable() const {
519 return Scalable;
520 }
521
522 /// Return the minimum number of bits in the Vector type.
481523 /// Returns zero when the vector is a vector of pointers.
482524 unsigned getBitWidth() const {
483525 return getNumElements() * getElementType()->getPrimitiveSizeInBits();
491533
492534 unsigned Type::getVectorNumElements() const {
493535 return cast(this)->getNumElements();
536 }
537
538 bool Type::getVectorIsScalable() const {
539 return cast(this)->isScalable();
494540 }
495541
496542 /// Class to represent pointers.
365365 return ContainedTys[0];
366366 }
367367
368 inline bool getVectorIsScalable() const;
368369 inline unsigned getVectorNumElements() const;
369370 Type *getVectorElementType() const {
370371 assert(getTypeID() == VectorTyID);
0 //===- ScalableSize.h - Scalable vector size info ---------------*- C++ -*-===//
1 //
2 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
3 // See https://llvm.org/LICENSE.txt for license information.
4 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5 //
6 //===----------------------------------------------------------------------===//
7 //
8 // This file provides a struct that can be used to query the size of IR types
9 // which may be scalable vectors. It provides convenience operators so that
10 // it can be used in much the same way as a single scalar value.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_SUPPORT_SCALABLESIZE_H
15 #define LLVM_SUPPORT_SCALABLESIZE_H
16
17 namespace llvm {
18
19 class ElementCount {
20 public:
21 unsigned Min; // Minimum number of vector elements.
22 bool Scalable; // If true, NumElements is a multiple of 'Min' determined
23 // at runtime rather than compile time.
24
25 ElementCount(unsigned Min, bool Scalable)
26 : Min(Min), Scalable(Scalable) {}
27
28 ElementCount operator*(unsigned RHS) {
29 return { Min * RHS, Scalable };
30 }
31 ElementCount operator/(unsigned RHS) {
32 return { Min / RHS, Scalable };
33 }
34
35 bool operator==(const ElementCount& RHS) const {
36 return Min == RHS.Min && Scalable == RHS.Scalable;
37 }
38 };
39
40 } // end namespace llvm
41
42 #endif // LLVM_SUPPORT_SCALABLESIZE_H
706706 KEYWORD(xchg); KEYWORD(nand); KEYWORD(max); KEYWORD(min); KEYWORD(umax);
707707 KEYWORD(umin);
708708
709 KEYWORD(vscale);
709710 KEYWORD(x);
710711 KEYWORD(blockaddress);
711712
27202720 /// Type
27212721 /// ::= '[' APSINTVAL 'x' Types ']'
27222722 /// ::= '<' APSINTVAL 'x' Types '>'
2723 /// ::= '<' 'vscale' 'x' APSINTVAL 'x' Types '>'
27232724 bool LLParser::ParseArrayVectorType(Type *&Result, bool isVector) {
2725 bool Scalable = false;
2726
2727 if (isVector && Lex.getKind() == lltok::kw_vscale) {
2728 Lex.Lex(); // consume the 'vscale'
2729 if (ParseToken(lltok::kw_x, "expected 'x' after vscale"))
2730 return true;
2731
2732 Scalable = true;
2733 }
2734
27242735 if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned() ||
27252736 Lex.getAPSIntVal().getBitWidth() > 64)
27262737 return TokError("expected number in address space");
27472758 return Error(SizeLoc, "size too large for vector");
27482759 if (!VectorType::isValidElementType(EltTy))
27492760 return Error(TypeLoc, "invalid vector element type");
2750 Result = VectorType::get(EltTy, unsigned(Size));
2761 Result = VectorType::get(EltTy, unsigned(Size), Scalable);
27512762 } else {
27522763 if (!ArrayType::isValidElementType(EltTy))
27532764 return Error(TypeLoc, "invalid array element type");
3636 bar, // |
3737 colon, // :
3838
39 kw_vscale,
3940 kw_x,
4041 kw_true,
4142 kw_false,
17571757 return error("Invalid type");
17581758 ResultTy = ArrayType::get(ResultTy, Record[0]);
17591759 break;
1760 case bitc::TYPE_CODE_VECTOR: // VECTOR: [numelts, eltty]
1760 case bitc::TYPE_CODE_VECTOR: // VECTOR: [numelts, eltty] or
1761 // [numelts, eltty, scalable]
17611762 if (Record.size() < 2)
17621763 return error("Invalid record");
17631764 if (Record[0] == 0)
17651766 ResultTy = getTypeByID(Record[1]);
17661767 if (!ResultTy || !StructType::isValidElementType(ResultTy))
17671768 return error("Invalid type");
1768 ResultTy = VectorType::get(ResultTy, Record[0]);
1769 bool Scalable = Record.size() > 2 ? Record[2] : false;
1770 ResultTy = VectorType::get(ResultTy, Record[0], Scalable);
17691771 break;
17701772 }
17711773
930930 }
931931 case Type::VectorTyID: {
932932 VectorType *VT = cast(T);
933 // VECTOR [numelts, eltty]
933 // VECTOR [numelts, eltty] or
934 // [numelts, eltty, scalable]
934935 Code = bitc::TYPE_CODE_VECTOR;
935936 TypeVals.push_back(VT->getNumElements());
936937 TypeVals.push_back(VE.getTypeID(VT->getElementType()));
938 if (VT->isScalable())
939 TypeVals.push_back(VT->isScalable());
937940 break;
938941 }
939942 }
619619 }
620620 case Type::VectorTyID: {
621621 VectorType *PTy = cast(Ty);
622 OS << "<" << PTy->getNumElements() << " x ";
622 OS << "<";
623 if (PTy->isScalable())
624 OS << "vscale x ";
625 OS << PTy->getNumElements() << " x ";
623626 print(PTy->getElementType(), OS);
624627 OS << '>';
625628 return;
13331333 unsigned NamedStructTypesUniqueID = 0;
13341334
13351335 DenseMap, ArrayType*> ArrayTypes;
1336 DenseMapunsigned>, VectorType*> VectorTypes;
1336 DenseMapElementCount>, VectorType*> VectorTypes;
13371337 DenseMap PointerTypes; // Pointers in AddrSpace = 0
13381338 DenseMap, PointerType*> ASPointerTypes;
13391339
598598 // VectorType Implementation
599599 //===----------------------------------------------------------------------===//
600600
601 VectorType::VectorType(Type *ElType, unsigned NumEl)
602 : SequentialType(VectorTyID, ElType, NumEl) {}
603
604 VectorType *VectorType::get(Type *ElementType, unsigned NumElements) {
605 assert(NumElements > 0 && "#Elements of a VectorType must be greater than 0");
601 VectorType::VectorType(Type *ElType, ElementCount EC)
602 : SequentialType(VectorTyID, ElType, EC.Min), Scalable(EC.Scalable) {}
603
604 VectorType *VectorType::get(Type *ElementType, ElementCount EC) {
605 assert(EC.Min > 0 && "#Elements of a VectorType must be greater than 0");
606606 assert(isValidElementType(ElementType) && "Element type of a VectorType must "
607607 "be an integer, floating point, or "
608608 "pointer type.");
609609
610610 LLVMContextImpl *pImpl = ElementType->getContext().pImpl;
611611 VectorType *&Entry = ElementType->getContext().pImpl
612 ->VectorTypes[std::make_pair(ElementType, NumElements)];
613
612 ->VectorTypes[std::make_pair(ElementType, EC)];
614613 if (!Entry)
615 Entry = new (pImpl->Alloc) VectorType(ElementType, NumElements);
614 Entry = new (pImpl->Alloc) VectorType(ElementType, EC);
616615 return Entry;
617616 }
618617
4242 //
4343 //===----------------------------------------------------------------------===//
4444
45 #include "LLVMContextImpl.h"
4546 #include "llvm/IR/Verifier.h"
4647 #include "llvm/ADT/APFloat.h"
4748 #include "llvm/ADT/APInt.h"
306307 TBAAVerifier TBAAVerifyHelper;
307308
308309 void checkAtomicMemAccessSize(Type *Ty, const Instruction *I);
310 static bool containsScalableVectorValue(const Type *Ty);
309311
310312 public:
311313 explicit Verifier(raw_ostream *OS, bool ShouldTreatBrokenDebugInfoAsError,
316318 }
317319
318320 bool hasBrokenDebugInfo() const { return BrokenDebugInfo; }
321
322 bool verifyTypes(const Module &M) {
323 LLVMContext &Ctx = M.getContext();
324 for (auto &Entry : Ctx.pImpl->ArrayTypes) {
325 ArrayType *ATy = Entry.second;
326 if (containsScalableVectorValue(ATy)) {
327 CheckFailed("Arrays cannot contain scalable vectors", ATy, &M);
328 Broken = true;
329 }
330 }
331
332 for (StructType* STy : Ctx.pImpl->AnonStructTypes)
333 if (containsScalableVectorValue(STy)) {
334 CheckFailed("Structs cannot contain scalable vectors", STy, &M);
335 Broken = true;
336 }
337
338 for (auto &Entry : Ctx.pImpl->NamedStructTypes) {
339 StructType *STy = Entry.second;
340 if (containsScalableVectorValue(STy)) {
341 CheckFailed("Structs cannot contain scalable vectors", STy, &M);
342 Broken = true;
343 }
344 }
345
346 return !Broken;
347 }
319348
320349 bool verify(const Function &F) {
321350 assert(F.getParent() == &M &&
385414 visitModuleCommandLines(M);
386415
387416 verifyCompileUnits();
417
418 verifyTypes(M);
388419
389420 verifyDeoptimizeCallingConvs();
390421 DISubprogramAttachments.clear();
612643 });
613644 }
614645
646 // Check for a scalable vector type, making sure to look through arrays and
647 // structs. Pointers to scalable vectors don't count, since we know what the
648 // size of a pointer is.
649 static bool containsScalableVectorValueRecursive(const Type *Ty,
650 SmallVectorImpl &Visited) {
651 if (is_contained(Visited, Ty))
652 return false;
653
654 Visited.push_back(Ty);
655
656 if (auto *VTy = dyn_cast(Ty))
657 return VTy->isScalable();
658
659 if (auto *ATy = dyn_cast(Ty))
660 return containsScalableVectorValueRecursive(ATy->getElementType(), Visited);
661
662 if (auto *STy = dyn_cast(Ty))
663 for (Type *EltTy : STy->elements())
664 if (containsScalableVectorValueRecursive(EltTy, Visited))
665 return true;
666
667 return false;
668 }
669
670 bool Verifier::containsScalableVectorValue(const Type *Ty) {
671 SmallVector VisitedList = {};
672 return containsScalableVectorValueRecursive(Ty, VisitedList);
673 }
674
615675 void Verifier::visitGlobalVariable(const GlobalVariable &GV) {
616676 if (GV.hasInitializer()) {
617677 Assert(GV.getInitializer()->getType() == GV.getValueType(),
689749 AssertDI(false, "!dbg attachment of global variable must be a "
690750 "DIGlobalVariableExpression");
691751 }
752
753 // Scalable vectors cannot be global variables, since we don't know
754 // the runtime size. Need to look inside structs/arrays to find the
755 // underlying element type as well.
756 if (containsScalableVectorValue(GV.getValueType()))
757 CheckFailed("Globals cannot contain scalable vectors", &GV);
692758
693759 if (!GV.hasInitializer()) {
694760 visitGlobalValue(GV);
916916 ; CHECK: %t7 = alloca x86_mmx
917917 %t8 = alloca %opaquety*
918918 ; CHECK: %t8 = alloca %opaquety*
919 %t9 = alloca <4 x i32>
920 ; CHECK: %t9 = alloca <4 x i32>
921 %t10 = alloca
922 ; CHECK: %t10 = alloca
919923
920924 ret void
921925 }
0 ; RUN: not opt -S -verify < %s 2>&1 | FileCheck %s
1
2 ;; Arrays and Structs cannot contain scalable vectors, since we don't
3 ;; know the size at compile time and the container types need to have
4 ;; a known size.
5
6 ; CHECK-DAG: Arrays cannot contain scalable vectors
7 ; CHECK-DAG: [2 x { i32, }]; ModuleID = ''
8 ; CHECK-DAG: Arrays cannot contain scalable vectors
9 ; CHECK-DAG: [4 x ]; ModuleID = ''
10 ; CHECK-DAG: Arrays cannot contain scalable vectors
11 ; CHECK-DAG: [2 x ]; ModuleID = ''
12 ; CHECK-DAG: Structs cannot contain scalable vectors
13 ; CHECK-DAG: { i64, [4 x ] }; ModuleID = ''
14 ; CHECK-DAG: Structs cannot contain scalable vectors
15 ; CHECK-DAG: { i32, }; ModuleID = ''
16 ; CHECK-DAG: Structs cannot contain scalable vectors
17 ; CHECK-DAG: { , }; ModuleID = ''
18 ; CHECK-DAG: Structs cannot contain scalable vectors
19 ; CHECK-DAG: %sty = type { i64, }; ModuleID = ''
20
21 %sty = type { i64, }
22
23 define void @scalable_aggregates() {
24 %array = alloca [2 x ]
25 %struct = alloca { , }
26 %named_struct = alloca %sty
27 %s_in_a = alloca [2 x { i32, } ]
28 %a_in_s = alloca { i64, [4 x ] }
29 ret void
30 }
0 ; RUN: not opt -S -verify < %s 2>&1 | FileCheck %s
1
2 ;; Global variables cannot be scalable vectors, since we don't
3 ;; know the size at compile time.
4
5 ; CHECK: Globals cannot contain scalable vectors
6 ; CHECK-NEXT: * @ScalableVecGlobal
7 @ScalableVecGlobal = global zeroinitializer
8
9 ; CHECK: Globals cannot contain scalable vectors
10 ; CHECK-NEXT: [64 x ]* @ScalableVecGlobalArray
11 @ScalableVecGlobalArray = global [64 x ] zeroinitializer
12
13 ; CHECK: Globals cannot contain scalable vectors
14 ; CHECK-NEXT: { , }* @ScalableVecGlobalStruct
15 @ScalableVecGlobalStruct = global { , } zeroinitializer
16
17 ; CHECK: Globals cannot contain scalable vectors
18 ; CHECK-NEXT: { [4 x i32], [2 x { , }] }* @ScalableVecMixed
19 @ScalableVecMixed = global { [4 x i32], [2 x { , }]} zeroinitializer
20
21 ;; Global _pointers_ to scalable vectors are fine
22 ; CHECK-NOT: Globals cannot contain scalable vectors
23 @ScalableVecPtr = global * zeroinitializer
3636 ValueHandleTest.cpp
3737 ValueMapTest.cpp
3838 ValueTest.cpp
39 VectorTypesTest.cpp
3940 VerifierTest.cpp
4041 WaymarkTest.cpp
4142 )
0 //===--- llvm/unittest/IR/VectorTypesTest.cpp - vector types unit tests ---===//
1 //
2 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
3 // See https://llvm.org/LICENSE.txt for license information.
4 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5 //
6 //===----------------------------------------------------------------------===//
7
8 #include "llvm/IR/DerivedTypes.h"
9 #include "llvm/IR/LLVMContext.h"
10 #include "llvm/Support/ScalableSize.h"
11 #include "gtest/gtest.h"
12 using namespace llvm;
13
14 namespace {
15 TEST(VectorTypesTest, FixedLength) {
16 LLVMContext Ctx;
17
18 Type *Int16Ty = Type::getInt16Ty(Ctx);
19 Type *Int32Ty = Type::getInt32Ty(Ctx);
20 Type *Int64Ty = Type::getInt64Ty(Ctx);
21 Type *Float64Ty = Type::getDoubleTy(Ctx);
22
23 VectorType *V8Int32Ty = VectorType::get(Int32Ty, 8);
24 ASSERT_FALSE(V8Int32Ty->isScalable());
25 EXPECT_EQ(V8Int32Ty->getNumElements(), 8U);
26 EXPECT_EQ(V8Int32Ty->getElementType()->getScalarSizeInBits(), 32U);
27
28 VectorType *V8Int16Ty = VectorType::get(Int16Ty, {8, false});
29 ASSERT_FALSE(V8Int16Ty->isScalable());
30 EXPECT_EQ(V8Int16Ty->getNumElements(), 8U);
31 EXPECT_EQ(V8Int16Ty->getElementType()->getScalarSizeInBits(), 16U);
32
33 ElementCount EltCnt(4, false);
34 VectorType *V4Int64Ty = VectorType::get(Int64Ty, EltCnt);
35 ASSERT_FALSE(V4Int64Ty->isScalable());
36 EXPECT_EQ(V4Int64Ty->getNumElements(), 4U);
37 EXPECT_EQ(V4Int64Ty->getElementType()->getScalarSizeInBits(), 64U);
38
39 VectorType *V2Int64Ty = VectorType::get(Int64Ty, EltCnt/2);
40 ASSERT_FALSE(V2Int64Ty->isScalable());
41 EXPECT_EQ(V2Int64Ty->getNumElements(), 2U);
42 EXPECT_EQ(V2Int64Ty->getElementType()->getScalarSizeInBits(), 64U);
43
44 VectorType *V8Int64Ty = VectorType::get(Int64Ty, EltCnt*2);
45 ASSERT_FALSE(V8Int64Ty->isScalable());
46 EXPECT_EQ(V8Int64Ty->getNumElements(), 8U);
47 EXPECT_EQ(V8Int64Ty->getElementType()->getScalarSizeInBits(), 64U);
48
49 VectorType *V4Float64Ty = VectorType::get(Float64Ty, EltCnt);
50 ASSERT_FALSE(V4Float64Ty->isScalable());
51 EXPECT_EQ(V4Float64Ty->getNumElements(), 4U);
52 EXPECT_EQ(V4Float64Ty->getElementType()->getScalarSizeInBits(), 64U);
53
54 VectorType *ExtTy = VectorType::getExtendedElementVectorType(V8Int16Ty);
55 EXPECT_EQ(ExtTy, V8Int32Ty);
56 ASSERT_FALSE(ExtTy->isScalable());
57 EXPECT_EQ(ExtTy->getNumElements(), 8U);
58 EXPECT_EQ(ExtTy->getElementType()->getScalarSizeInBits(), 32U);
59
60 VectorType *TruncTy = VectorType::getTruncatedElementVectorType(V8Int32Ty);
61 EXPECT_EQ(TruncTy, V8Int16Ty);
62 ASSERT_FALSE(TruncTy->isScalable());
63 EXPECT_EQ(TruncTy->getNumElements(), 8U);
64 EXPECT_EQ(TruncTy->getElementType()->getScalarSizeInBits(), 16U);
65
66 VectorType *HalvedTy = VectorType::getHalfElementsVectorType(V4Int64Ty);
67 EXPECT_EQ(HalvedTy, V2Int64Ty);
68 ASSERT_FALSE(HalvedTy->isScalable());
69 EXPECT_EQ(HalvedTy->getNumElements(), 2U);
70 EXPECT_EQ(HalvedTy->getElementType()->getScalarSizeInBits(), 64U);
71
72 VectorType *DoubledTy = VectorType::getDoubleElementsVectorType(V4Int64Ty);
73 EXPECT_EQ(DoubledTy, V8Int64Ty);
74 ASSERT_FALSE(DoubledTy->isScalable());
75 EXPECT_EQ(DoubledTy->getNumElements(), 8U);
76 EXPECT_EQ(DoubledTy->getElementType()->getScalarSizeInBits(), 64U);
77
78 VectorType *ConvTy = VectorType::getInteger(V4Float64Ty);
79 EXPECT_EQ(ConvTy, V4Int64Ty);
80 ASSERT_FALSE(ConvTy->isScalable());
81 EXPECT_EQ(ConvTy->getNumElements(), 4U);
82 EXPECT_EQ(ConvTy->getElementType()->getScalarSizeInBits(), 64U);
83
84 EltCnt = V8Int64Ty->getElementCount();
85 EXPECT_EQ(EltCnt.Min, 8U);
86 ASSERT_FALSE(EltCnt.Scalable);
87 }
88
89 TEST(VectorTypesTest, Scalable) {
90 LLVMContext Ctx;
91
92 Type *Int16Ty = Type::getInt16Ty(Ctx);
93 Type *Int32Ty = Type::getInt32Ty(Ctx);
94 Type *Int64Ty = Type::getInt64Ty(Ctx);
95 Type *Float64Ty = Type::getDoubleTy(Ctx);
96
97 VectorType *ScV8Int32Ty = VectorType::get(Int32Ty, 8, true);
98 ASSERT_TRUE(ScV8Int32Ty->isScalable());
99 EXPECT_EQ(ScV8Int32Ty->getNumElements(), 8U);
100 EXPECT_EQ(ScV8Int32Ty->getElementType()->getScalarSizeInBits(), 32U);
101
102 VectorType *ScV8Int16Ty = VectorType::get(Int16Ty, {8, true});
103 ASSERT_TRUE(ScV8Int16Ty->isScalable());
104 EXPECT_EQ(ScV8Int16Ty->getNumElements(), 8U);
105 EXPECT_EQ(ScV8Int16Ty->getElementType()->getScalarSizeInBits(), 16U);
106
107 ElementCount EltCnt(4, true);
108 VectorType *ScV4Int64Ty = VectorType::get(Int64Ty, EltCnt);
109 ASSERT_TRUE(ScV4Int64Ty->isScalable());
110 EXPECT_EQ(ScV4Int64Ty->getNumElements(), 4U);
111 EXPECT_EQ(ScV4Int64Ty->getElementType()->getScalarSizeInBits(), 64U);
112
113 VectorType *ScV2Int64Ty = VectorType::get(Int64Ty, EltCnt/2);
114 ASSERT_TRUE(ScV2Int64Ty->isScalable());
115 EXPECT_EQ(ScV2Int64Ty->getNumElements(), 2U);
116 EXPECT_EQ(ScV2Int64Ty->getElementType()->getScalarSizeInBits(), 64U);
117
118 VectorType *ScV8Int64Ty = VectorType::get(Int64Ty, EltCnt*2);
119 ASSERT_TRUE(ScV8Int64Ty->isScalable());
120 EXPECT_EQ(ScV8Int64Ty->getNumElements(), 8U);
121 EXPECT_EQ(ScV8Int64Ty->getElementType()->getScalarSizeInBits(), 64U);
122
123 VectorType *ScV4Float64Ty = VectorType::get(Float64Ty, EltCnt);
124 ASSERT_TRUE(ScV4Float64Ty->isScalable());
125 EXPECT_EQ(ScV4Float64Ty->getNumElements(), 4U);
126 EXPECT_EQ(ScV4Float64Ty->getElementType()->getScalarSizeInBits(), 64U);
127
128 VectorType *ExtTy = VectorType::getExtendedElementVectorType(ScV8Int16Ty);
129 EXPECT_EQ(ExtTy, ScV8Int32Ty);
130 ASSERT_TRUE(ExtTy->isScalable());
131 EXPECT_EQ(ExtTy->getNumElements(), 8U);
132 EXPECT_EQ(ExtTy->getElementType()->getScalarSizeInBits(), 32U);
133
134 VectorType *TruncTy = VectorType::getTruncatedElementVectorType(ScV8Int32Ty);
135 EXPECT_EQ(TruncTy, ScV8Int16Ty);
136 ASSERT_TRUE(TruncTy->isScalable());
137 EXPECT_EQ(TruncTy->getNumElements(), 8U);
138 EXPECT_EQ(TruncTy->getElementType()->getScalarSizeInBits(), 16U);
139
140 VectorType *HalvedTy = VectorType::getHalfElementsVectorType(ScV4Int64Ty);
141 EXPECT_EQ(HalvedTy, ScV2Int64Ty);
142 ASSERT_TRUE(HalvedTy->isScalable());
143 EXPECT_EQ(HalvedTy->getNumElements(), 2U);
144 EXPECT_EQ(HalvedTy->getElementType()->getScalarSizeInBits(), 64U);
145
146 VectorType *DoubledTy = VectorType::getDoubleElementsVectorType(ScV4Int64Ty);
147 EXPECT_EQ(DoubledTy, ScV8Int64Ty);
148 ASSERT_TRUE(DoubledTy->isScalable());
149 EXPECT_EQ(DoubledTy->getNumElements(), 8U);
150 EXPECT_EQ(DoubledTy->getElementType()->getScalarSizeInBits(), 64U);
151
152 VectorType *ConvTy = VectorType::getInteger(ScV4Float64Ty);
153 EXPECT_EQ(ConvTy, ScV4Int64Ty);
154 ASSERT_TRUE(ConvTy->isScalable());
155 EXPECT_EQ(ConvTy->getNumElements(), 4U);
156 EXPECT_EQ(ConvTy->getElementType()->getScalarSizeInBits(), 64U);
157
158 EltCnt = ScV8Int64Ty->getElementCount();
159 EXPECT_EQ(EltCnt.Min, 8U);
160 ASSERT_TRUE(EltCnt.Scalable);
161 }
162
163 } // end anonymous namespace