llvm.org GIT mirror llvm / a1a5ec6
Revert r363658 "[SVE][IR] Scalable Vector IR Type with pr42210 fix" We saw a 70% ThinLTO link time increase in Chromium for Android, see crbug.com/978817. Sounds like more of PR42210. > 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@364543 91177308-0d34-0410-b5e6-96231b3b80d8 Hans Wennborg a month ago
19 changed file(s) with 40 addition(s) and 447 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.
679676
680677 Syntax::
681678
27372734 A vector type is a simple derived type that represents a vector of
27382735 elements. Vector types are used when multiple primitive data are
27392736 operated in parallel using a single instruction (SIMD). A vector type
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 `.
2737 requires a size (number of elements) and an underlying primitive data
2738 type. Vector types are considered :ref:`first class `.
27442739
27452740 :Syntax:
27462741
27472742 ::
27482743
2749 < <# elements> x > ; Fixed-length vector
2750 < vscale x <# elements> x > ; Scalable vector
2744 < <# elements> x >
27512745
27522746 The number of elements is a constant integer value larger than 0;
27532747 elementtype may be any integer, floating-point or pointer type. Vectors
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.
2748 of size zero are not allowed.
27602749
27612750 :Examples:
27622751
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 +------------------------+----------------------------------------------------+
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 +-------------------+--------------------------------------------------+
27742761
27752762 .. _t_label:
27762763
81938180 ::
81948181
81958182 = extractelement > , ; yields
8196 = extractelement > , ; yields
81978183
81988184 Overview:
81998185 """""""""
82148200
82158201 The result is a scalar of the same type as the element type of ``val``.
82168202 Its value is the value at position ``idx`` of ``val``. If ``idx``
8217 exceeds the length of ``val`` for a fixed-length vector, the result is a
8218 :ref:`poison value `. For a scalable vector, if the value
8219 of ``idx`` exceeds the runtime length of the vector, the result is a
8203 exceeds the length of ``val``, the result is a
82208204 :ref:`poison value `.
82218205
82228206 Example:
82378221 ::
82388222
82398223 = insertelement > , , ; yields >
8240 = insertelement > , , ; yields >
82418224
82428225 Overview:
82438226 """""""""
82598242
82608243 The result is a vector of the same type as ``val``. Its element values
82618244 are those of ``val`` except at position ``idx``, where it gets the value
8262 ``elt``. If ``idx`` exceeds the length of ``val`` for a fixed-length vector,
8263 the result is a :ref:`poison value `. For a scalable vector,
8264 if the value of ``idx`` exceeds the runtime length of the vector, the result
8245 ``elt``. If ``idx`` exceeds the length of ``val``, the result
82658246 is a :ref:`poison value `.
82668247
82678248 Example:
82828263 ::
82838264
82848265 = shufflevector > , > , ; yields >
8285 = shufflevector > , > v2, ; yields >
82868266
82878267 Overview:
82888268 """""""""
83138293 undef. If any element of the mask operand is undef, that element of the
83148294 result is undef. If the shuffle mask selects an undef element from one
83158295 of the input vectors, the resulting element is undef.
8316
8317 For scalable vectors, the only valid mask values at present are
8318 ``zeroinitializer`` and ``undef``, since we cannot write all indices as
8319 literals for a vector with a length unknown at compile time.
83208296
83218297 Example:
83228298 """"""""
1616 #include "llvm/ADT/Hashing.h"
1717 #include "llvm/ADT/StringRef.h"
1818 #include "llvm/Support/PointerLikeTypeTraits.h"
19 #include "llvm/Support/ScalableSize.h"
2019 #include
2120 #include
2221 #include
268267 static bool isEqual(hash_code LHS, hash_code RHS) { return LHS == RHS; }
269268 };
270269
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
286270 } // end namespace llvm
287271
288272 #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"
2625 #include
2726 #include
2827
387386 SequentialType(const SequentialType &) = delete;
388387 SequentialType &operator=(const SequentialType &) = delete;
389388
390 /// For scalable vectors, this will return the minimum number of elements
391 /// in the vector.
392389 uint64_t getNumElements() const { return NumElements; }
393390 Type *getElementType() const { return ContainedType; }
394391
424421
425422 /// Class to represent vector types.
426423 class VectorType : public SequentialType {
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;
424 VectorType(Type *ElType, unsigned NumEl);
447425
448426 public:
449427 VectorType(const VectorType &) = delete;
450428 VectorType &operator=(const VectorType &) = delete;
451429
452430 /// This static method is the primary way to construct an VectorType.
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 }
431 static VectorType *get(Type *ElementType, unsigned NumElements);
458432
459433 /// This static method gets a VectorType with the same number of elements as
460434 /// the input type, and the element type is an integer type of the same width
463437 unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
464438 assert(EltBits && "Element size must be of a non-zero size");
465439 Type *EltTy = IntegerType::get(VTy->getContext(), EltBits);
466 return VectorType::get(EltTy, VTy->getElementCount());
440 return VectorType::get(EltTy, VTy->getNumElements());
467441 }
468442
469443 /// This static method is like getInteger except that the element types are
471445 static VectorType *getExtendedElementVectorType(VectorType *VTy) {
472446 unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
473447 Type *EltTy = IntegerType::get(VTy->getContext(), EltBits * 2);
474 return VectorType::get(EltTy, VTy->getElementCount());
448 return VectorType::get(EltTy, VTy->getNumElements());
475449 }
476450
477451 /// This static method is like getInteger except that the element types are
481455 assert((EltBits & 1) == 0 &&
482456 "Cannot truncate vector element with odd bit-width");
483457 Type *EltTy = IntegerType::get(VTy->getContext(), EltBits / 2);
484 return VectorType::get(EltTy, VTy->getElementCount());
458 return VectorType::get(EltTy, VTy->getNumElements());
485459 }
486460
487461 /// This static method returns a VectorType with half as many elements as the
488462 /// input type and the same element type.
489463 static VectorType *getHalfElementsVectorType(VectorType *VTy) {
490 auto EltCnt = VTy->getElementCount();
491 assert ((EltCnt.Min & 1) == 0 &&
464 unsigned NumElts = VTy->getNumElements();
465 assert ((NumElts & 1) == 0 &&
492466 "Cannot halve vector with odd number of elements.");
493 return VectorType::get(VTy->getElementType(), EltCnt/2);
467 return VectorType::get(VTy->getElementType(), NumElts/2);
494468 }
495469
496470 /// This static method returns a VectorType with twice as many elements as the
497471 /// input type and the same element type.
498472 static VectorType *getDoubleElementsVectorType(VectorType *VTy) {
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);
473 unsigned NumElts = VTy->getNumElements();
474 return VectorType::get(VTy->getElementType(), NumElts*2);
503475 }
504476
505477 /// Return true if the specified type is valid as a element type.
506478 static bool isValidElementType(Type *ElemTy);
507479
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.
480 /// Return the number of bits in the Vector type.
523481 /// Returns zero when the vector is a vector of pointers.
524482 unsigned getBitWidth() const {
525483 return getNumElements() * getElementType()->getPrimitiveSizeInBits();
533491
534492 unsigned Type::getVectorNumElements() const {
535493 return cast(this)->getNumElements();
536 }
537
538 bool Type::getVectorIsScalable() const {
539 return cast(this)->isScalable();
540494 }
541495
542496 /// Class to represent pointers.
365365 return ContainedTys[0];
366366 }
367367
368 inline bool getVectorIsScalable() const;
369368 inline unsigned getVectorNumElements() const;
370369 Type *getVectorElementType() const {
371370 assert(getTypeID() == VectorTyID);
+0
-43
include/llvm/Support/ScalableSize.h less more
None //===- 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);
710709 KEYWORD(x);
711710 KEYWORD(blockaddress);
712711
27422742 /// Type
27432743 /// ::= '[' APSINTVAL 'x' Types ']'
27442744 /// ::= '<' APSINTVAL 'x' Types '>'
2745 /// ::= '<' 'vscale' 'x' APSINTVAL 'x' Types '>'
27462745 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
27572746 if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned() ||
27582747 Lex.getAPSIntVal().getBitWidth() > 64)
27592748 return TokError("expected number in address space");
27802769 return Error(SizeLoc, "size too large for vector");
27812770 if (!VectorType::isValidElementType(EltTy))
27822771 return Error(TypeLoc, "invalid vector element type");
2783 Result = VectorType::get(EltTy, unsigned(Size), Scalable);
2772 Result = VectorType::get(EltTy, unsigned(Size));
27842773 } else {
27852774 if (!ArrayType::isValidElementType(EltTy))
27862775 return Error(TypeLoc, "invalid array element type");
3636 bar, // |
3737 colon, // :
3838
39 kw_vscale,
4039 kw_x,
4140 kw_true,
4241 kw_false,
18351835 return error("Invalid type");
18361836 ResultTy = ArrayType::get(ResultTy, Record[0]);
18371837 break;
1838 case bitc::TYPE_CODE_VECTOR: // VECTOR: [numelts, eltty] or
1839 // [numelts, eltty, scalable]
1838 case bitc::TYPE_CODE_VECTOR: // VECTOR: [numelts, eltty]
18401839 if (Record.size() < 2)
18411840 return error("Invalid record");
18421841 if (Record[0] == 0)
18441843 ResultTy = getTypeByID(Record[1]);
18451844 if (!ResultTy || !StructType::isValidElementType(ResultTy))
18461845 return error("Invalid type");
1847 bool Scalable = Record.size() > 2 ? Record[2] : false;
1848 ResultTy = VectorType::get(ResultTy, Record[0], Scalable);
1846 ResultTy = VectorType::get(ResultTy, Record[0]);
18491847 break;
18501848 }
18511849
937937 }
938938 case Type::VectorTyID: {
939939 VectorType *VT = cast(T);
940 // VECTOR [numelts, eltty] or
941 // [numelts, eltty, scalable]
940 // VECTOR [numelts, eltty]
942941 Code = bitc::TYPE_CODE_VECTOR;
943942 TypeVals.push_back(VT->getNumElements());
944943 TypeVals.push_back(VE.getTypeID(VT->getElementType()));
945 if (VT->isScalable())
946 TypeVals.push_back(VT->isScalable());
947944 break;
948945 }
949946 }
619619 }
620620 case Type::VectorTyID: {
621621 VectorType *PTy = cast(Ty);
622 OS << "<";
623 if (PTy->isScalable())
624 OS << "vscale x ";
625 OS << PTy->getNumElements() << " x ";
622 OS << "<" << PTy->getNumElements() << " x ";
626623 print(PTy->getElementType(), OS);
627624 OS << '>';
628625 return;
13331333 unsigned NamedStructTypesUniqueID = 0;
13341334
13351335 DenseMap, ArrayType*> ArrayTypes;
1336 DenseMapElementCount>, VectorType*> VectorTypes;
1336 DenseMapunsigned>, VectorType*> VectorTypes;
13371337 DenseMap PointerTypes; // Pointers in AddrSpace = 0
13381338 DenseMap, PointerType*> ASPointerTypes;
13391339
598598 // VectorType Implementation
599599 //===----------------------------------------------------------------------===//
600600
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");
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");
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, EC)];
612 ->VectorTypes[std::make_pair(ElementType, NumElements)];
613
613614 if (!Entry)
614 Entry = new (pImpl->Alloc) VectorType(ElementType, EC);
615 Entry = new (pImpl->Alloc) VectorType(ElementType, NumElements);
615616 return Entry;
616617 }
617618
4242 //
4343 //===----------------------------------------------------------------------===//
4444
45 #include "LLVMContextImpl.h"
4645 #include "llvm/IR/Verifier.h"
4746 #include "llvm/ADT/APFloat.h"
4847 #include "llvm/ADT/APInt.h"
318317
319318 bool hasBrokenDebugInfo() const { return BrokenDebugInfo; }
320319
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
346320 bool verify(const Function &F) {
347321 assert(F.getParent() == &M &&
348322 "An instance of this class only works with a specific module!");
411385 visitModuleCommandLines(M);
412386
413387 verifyCompileUnits();
414
415 verifyTypes();
416388
417389 verifyDeoptimizeCallingConvs();
418390 DISubprogramAttachments.clear();
718690 "DIGlobalVariableExpression");
719691 }
720692
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
728693 if (!GV.hasInitializer()) {
729694 visitGlobalValue(GV);
730695 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
923919
924920 ret void
925921 }
+0
-27
test/Verifier/scalable-aggregates.ll less more
None ; 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
-26
test/Verifier/scalable-global-vars.ll less more
None ; 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
4039 VerifierTest.cpp
4140 WaymarkTest.cpp
4241 )
+0
-164
unittests/IR/VectorTypesTest.cpp less more
None //===--- 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