llvm.org GIT mirror llvm / 3ec873e
[SVE][IR] Scalable Vector IR Type with pr42210 fix Recommit of D32530 with a few small changes: - Stopped recursively walking through aggregates in the verifier, so that we don't impose too much overhead on large modules under LTO (see PR42210). - Changed tests to match; the errors are slightly different since they only report the array or struct that actually contains a scalable vector, rather than all aggregates which contain one in a nested member. - Corrected an older comment Reviewers: thakis, rengolin, sdesmalen Reviewed By: sdesmalen Differential Revision: https://reviews.llvm.org/D63321 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@363658 91177308-0d34-0410-b5e6-96231b3b80d8 Graham Hunter 30 days ago
19 changed file(s) with 447 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
27342737 A vector type is a simple derived type that represents a vector of
27352738 elements. Vector types are used when multiple primitive data are
27362739 operated in parallel using a single instruction (SIMD). A vector type
2737 requires a size (number of elements) and an underlying primitive data
2738 type. Vector types are considered :ref:`first class `.
2740 requires a size (number of elements), an underlying primitive data type,
2741 and a scalable property to represent vectors where the exact hardware
2742 vector length is unknown at compile time. Vector types are considered
2743 :ref:`first class `.
27392744
27402745 :Syntax:
27412746
27422747 ::
27432748
2744 < <# elements> x >
2749 < <# elements> x > ; Fixed-length vector
2750 < vscale x <# elements> x > ; Scalable vector
27452751
27462752 The number of elements is a constant integer value larger than 0;
27472753 elementtype may be any integer, floating-point or pointer type. Vectors
2748 of size zero are not allowed.
2754 of size zero are not allowed. For scalable vectors, the total number of
2755 elements is a constant multiple (called vscale) of the specified number
2756 of elements; vscale is a positive integer that is unknown at compile time
2757 and the same hardware-dependent constant for all scalable vectors at run
2758 time. The size of a specific scalable vector type is thus constant within
2759 IR, even if the exact size in bytes cannot be determined until run time.
27492760
27502761 :Examples:
27512762
2752 +-------------------+--------------------------------------------------+
2753 | ``<4 x i32>`` | Vector of 4 32-bit integer values. |
2754 +-------------------+--------------------------------------------------+
2755 | ``<8 x float>`` | Vector of 8 32-bit floating-point values. |
2756 +-------------------+--------------------------------------------------+
2757 | ``<2 x i64>`` | Vector of 2 64-bit integer values. |
2758 +-------------------+--------------------------------------------------+
2759 | ``<4 x i64*>`` | Vector of 4 pointers to 64-bit integer values. |
2760 +-------------------+--------------------------------------------------+
2763 +------------------------+----------------------------------------------------+
2764 | ``<4 x i32>`` | Vector of 4 32-bit integer values. |
2765 +------------------------+----------------------------------------------------+
2766 | ``<8 x float>`` | Vector of 8 32-bit floating-point values. |
2767 +------------------------+----------------------------------------------------+
2768 | ``<2 x i64>`` | Vector of 2 64-bit integer values. |
2769 +------------------------+----------------------------------------------------+
2770 | ``<4 x i64*>`` | Vector of 4 pointers to 64-bit integer values. |
2771 +------------------------+----------------------------------------------------+
2772 | ```` | Vector with a multiple of 4 32-bit integer values. |
2773 +------------------------+----------------------------------------------------+
27612774
27622775 .. _t_label:
27632776
81538166 ::
81548167
81558168 = extractelement > , ; yields
8169 = extractelement > , ; yields
81568170
81578171 Overview:
81588172 """""""""
81738187
81748188 The result is a scalar of the same type as the element type of ``val``.
81758189 Its value is the value at position ``idx`` of ``val``. If ``idx``
8176 exceeds the length of ``val``, the result is a
8190 exceeds the length of ``val`` for a fixed-length vector, the result is a
8191 :ref:`poison value `. For a scalable vector, if the value
8192 of ``idx`` exceeds the runtime length of the vector, the result is a
81778193 :ref:`poison value `.
81788194
81798195 Example:
81948210 ::
81958211
81968212 = insertelement > , , ; yields >
8213 = insertelement > , , ; yields >
81978214
81988215 Overview:
81998216 """""""""
82158232
82168233 The result is a vector of the same type as ``val``. Its element values
82178234 are those of ``val`` except at position ``idx``, where it gets the value
8218 ``elt``. If ``idx`` exceeds the length of ``val``, the result
8235 ``elt``. If ``idx`` exceeds the length of ``val`` for a fixed-length vector,
8236 the result is a :ref:`poison value `. For a scalable vector,
8237 if the value of ``idx`` exceeds the runtime length of the vector, the result
82198238 is a :ref:`poison value `.
82208239
82218240 Example:
82368255 ::
82378256
82388257 = shufflevector > , > , ; yields >
8258 = shufflevector > , > v2, ; yields >
82398259
82408260 Overview:
82418261 """""""""
82668286 undef. If any element of the mask operand is undef, that element of the
82678287 result is undef. If the shuffle mask selects an undef element from one
82688288 of the input vectors, the resulting element is undef.
8289
8290 For scalable vectors, the only valid mask values at present are
8291 ``zeroinitializer`` and ``undef``, since we cannot write all indices as
8292 literals for a vector with a length unknown at compile time.
82698293
82708294 Example:
82718295 """"""""
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 /// 'vscale x' 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
27422742 /// Type
27432743 /// ::= '[' APSINTVAL 'x' Types ']'
27442744 /// ::= '<' APSINTVAL 'x' Types '>'
2745 /// ::= '<' 'vscale' 'x' APSINTVAL 'x' Types '>'
27452746 bool LLParser::ParseArrayVectorType(Type *&Result, bool isVector) {
2747 bool Scalable = false;
2748
2749 if (isVector && Lex.getKind() == lltok::kw_vscale) {
2750 Lex.Lex(); // consume the 'vscale'
2751 if (ParseToken(lltok::kw_x, "expected 'x' after vscale"))
2752 return true;
2753
2754 Scalable = true;
2755 }
2756
27462757 if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned() ||
27472758 Lex.getAPSIntVal().getBitWidth() > 64)
27482759 return TokError("expected number in address space");
27692780 return Error(SizeLoc, "size too large for vector");
27702781 if (!VectorType::isValidElementType(EltTy))
27712782 return Error(TypeLoc, "invalid vector element type");
2772 Result = VectorType::get(EltTy, unsigned(Size));
2783 Result = VectorType::get(EltTy, unsigned(Size), Scalable);
27732784 } else {
27742785 if (!ArrayType::isValidElementType(EltTy))
27752786 return Error(TypeLoc, "invalid array element type");
3636 bar, // |
3737 colon, // :
3838
39 kw_vscale,
3940 kw_x,
4041 kw_true,
4142 kw_false,
17741774 return error("Invalid type");
17751775 ResultTy = ArrayType::get(ResultTy, Record[0]);
17761776 break;
1777 case bitc::TYPE_CODE_VECTOR: // VECTOR: [numelts, eltty]
1777 case bitc::TYPE_CODE_VECTOR: // VECTOR: [numelts, eltty] or
1778 // [numelts, eltty, scalable]
17781779 if (Record.size() < 2)
17791780 return error("Invalid record");
17801781 if (Record[0] == 0)
17821783 ResultTy = getTypeByID(Record[1]);
17831784 if (!ResultTy || !StructType::isValidElementType(ResultTy))
17841785 return error("Invalid type");
1785 ResultTy = VectorType::get(ResultTy, Record[0]);
1786 bool Scalable = Record.size() > 2 ? Record[2] : false;
1787 ResultTy = VectorType::get(ResultTy, Record[0], Scalable);
17861788 break;
17871789 }
17881790
937937 }
938938 case Type::VectorTyID: {
939939 VectorType *VT = cast(T);
940 // VECTOR [numelts, eltty]
940 // VECTOR [numelts, eltty] or
941 // [numelts, eltty, scalable]
941942 Code = bitc::TYPE_CODE_VECTOR;
942943 TypeVals.push_back(VT->getNumElements());
943944 TypeVals.push_back(VE.getTypeID(VT->getElementType()));
945 if (VT->isScalable())
946 TypeVals.push_back(VT->isScalable());
944947 break;
945948 }
946949 }
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"
317318
318319 bool hasBrokenDebugInfo() const { return BrokenDebugInfo; }
319320
321 void verifyTypes() {
322 LLVMContext &Ctx = M.getContext();
323 for (auto &Entry : Ctx.pImpl->ArrayTypes) {
324 Type *EltTy = Entry.second->getElementType();
325 if (auto *VTy = dyn_cast(EltTy))
326 if (VTy->isScalable())
327 CheckFailed("Arrays cannot contain scalable vectors",
328 Entry.second, &M);
329 }
330
331 for (StructType* STy : Ctx.pImpl->AnonStructTypes)
332 for (Type *EltTy : STy->elements())
333 if (auto *VTy = dyn_cast(EltTy))
334 if (VTy->isScalable())
335 CheckFailed("Structs cannot contain scalable vectors", STy, &M);
336
337 for (auto &Entry : Ctx.pImpl->NamedStructTypes) {
338 StructType *STy = Entry.second;
339 for (Type *EltTy : STy->elements())
340 if (auto *VTy = dyn_cast(EltTy))
341 if (VTy->isScalable())
342 CheckFailed("Structs cannot contain scalable vectors", STy, &M);
343 }
344 }
345
320346 bool verify(const Function &F) {
321347 assert(F.getParent() == &M &&
322348 "An instance of this class only works with a specific module!");
385411 visitModuleCommandLines(M);
386412
387413 verifyCompileUnits();
414
415 verifyTypes();
388416
389417 verifyDeoptimizeCallingConvs();
390418 DISubprogramAttachments.clear();
690718 "DIGlobalVariableExpression");
691719 }
692720
721 // Scalable vectors cannot be global variables, since we don't know
722 // the runtime size. If the global is a struct or an array containing
723 // scalable vectors, that will be caught be verifyTypes instead.
724 if (auto *VTy = dyn_cast(GV.getValueType()))
725 if (VTy->isScalable())
726 CheckFailed("Globals cannot contain scalable vectors", &GV);
727
693728 if (!GV.hasInitializer()) {
694729 visitGlobalValue(GV);
695730 return;
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: [4 x ]; ModuleID = ''
8 ; CHECK-DAG: Arrays cannot contain scalable vectors
9 ; CHECK-DAG: [2 x ]; ModuleID = ''
10 ; CHECK-DAG: Structs cannot contain scalable vectors
11 ; CHECK-DAG: { i32, }; ModuleID = ''
12 ;; CHECK-DAG: Structs cannot contain scalable vectors
13 ; CHECK-DAG: { , }; ModuleID = ''
14 ; CHECK-DAG: Structs cannot contain scalable vectors
15 ; CHECK-DAG: %sty = type { i64, }; ModuleID = ''
16
17 %sty = type { i64, }
18
19 define void @scalable_aggregates() {
20 %array = alloca [2 x ]
21 %struct = alloca { , }
22 %named_struct = alloca %sty
23 %s_in_a = alloca [2 x { i32, } ]
24 %a_in_s = alloca { i64, [4 x ] }
25 ret void
26 }
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 ;; Global _pointers_ to scalable vectors are fine
10 ; CHECK-NOT: Globals cannot contain scalable vectors
11 @ScalableVecPtr = global * zeroinitializer
12
13 ;; The following errors don't explicitly mention global variables, but
14 ;; do still guarantee that the error will be caught.
15 ; CHECK-DAG: Arrays cannot contain scalable vectors
16 ; CHECK-DAG: [64 x ]; ModuleID = ''
17 @ScalableVecGlobalArray = global [64 x ] zeroinitializer
18
19 ; CHECK-DAG: Structs cannot contain scalable vectors
20 ; CHECK-DAG: { , }; ModuleID = ''
21 @ScalableVecGlobalStruct = global { , } zeroinitializer
22
23 ; CHECK-DAG: Structs cannot contain scalable vectors
24 ; CHECK-DAG { , }; ModuleID = ''
25 @ScalableVecMixed = global { [4 x i32], [2 x { , }]} 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