llvm.org GIT mirror llvm / 7350033
Revert r361953 "[SVE][IR] Scalable Vector IR Type" This reverts commit f4fc01f8dd3a5dfd2060d1ad0df6b90e8351ddf7. It caused a 3-4x slowdown when doing thinlto links, PR42210. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362913 91177308-0d34-0410-b5e6-96231b3b80d8 Nico Weber a month ago
19 changed file(s) with 40 addition(s) and 480 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
27352732 A vector type is a simple derived type that represents a vector of
27362733 elements. Vector types are used when multiple primitive data are
27372734 operated in parallel using a single instruction (SIMD). A vector type
2738 requires a size (number of elements), an underlying primitive data type,
2739 and a scalable property to represent vectors where the exact hardware
2740 vector length is unknown at compile time. Vector types are considered
2741 :ref:`first class `.
2735 requires a size (number of elements) and an underlying primitive data
2736 type. Vector types are considered :ref:`first class `.
27422737
27432738 :Syntax:
27442739
27452740 ::
27462741
2747 < <# elements> x > ; Fixed-length vector
2748 < vscale x <# elements> x > ; Scalable vector
2742 < <# elements> x >
27492743
27502744 The number of elements is a constant integer value larger than 0;
27512745 elementtype may be any integer, floating-point or pointer type. Vectors
2752 of size zero are not allowed. For scalable vectors, the total number of
2753 elements is a constant multiple (called vscale) of the specified number
2754 of elements; vscale is a positive integer that is unknown at compile time
2755 and the same hardware-dependent constant for all scalable vectors at run
2756 time. The size of a specific scalable vector type is thus constant within
2757 IR, even if the exact size in bytes cannot be determined until run time.
2746 of size zero are not allowed.
27582747
27592748 :Examples:
27602749
2761 +------------------------+----------------------------------------------------+
2762 | ``<4 x i32>`` | Vector of 4 32-bit integer values. |
2763 +------------------------+----------------------------------------------------+
2764 | ``<8 x float>`` | Vector of 8 32-bit floating-point values. |
2765 +------------------------+----------------------------------------------------+
2766 | ``<2 x i64>`` | Vector of 2 64-bit integer values. |
2767 +------------------------+----------------------------------------------------+
2768 | ``<4 x i64*>`` | Vector of 4 pointers to 64-bit integer values. |
2769 +------------------------+----------------------------------------------------+
2770 | ```` | Vector with a multiple of 4 32-bit integer values. |
2771 +------------------------+----------------------------------------------------+
2750 +-------------------+--------------------------------------------------+
2751 | ``<4 x i32>`` | Vector of 4 32-bit integer values. |
2752 +-------------------+--------------------------------------------------+
2753 | ``<8 x float>`` | Vector of 8 32-bit floating-point values. |
2754 +-------------------+--------------------------------------------------+
2755 | ``<2 x i64>`` | Vector of 2 64-bit integer values. |
2756 +-------------------+--------------------------------------------------+
2757 | ``<4 x i64*>`` | Vector of 4 pointers to 64-bit integer values. |
2758 +-------------------+--------------------------------------------------+
27722759
27732760 .. _t_label:
27742761
81508137 ::
81518138
81528139 = extractelement > , ; yields
8153 = extractelement > , ; yields
81548140
81558141 Overview:
81568142 """""""""
81718157
81728158 The result is a scalar of the same type as the element type of ``val``.
81738159 Its value is the value at position ``idx`` of ``val``. If ``idx``
8174 exceeds the length of ``val`` for a fixed-length vector, the result is a
8175 :ref:`poison value `. For a scalable vector, if the value
8176 of ``idx`` exceeds the runtime length of the vector, the result is a
8160 exceeds the length of ``val``, the result is a
81778161 :ref:`poison value `.
81788162
81798163 Example:
81948178 ::
81958179
81968180 = insertelement > , , ; yields >
8197 = insertelement > , , ; yields >
81988181
81998182 Overview:
82008183 """""""""
82168199
82178200 The result is a vector of the same type as ``val``. Its element values
82188201 are those of ``val`` except at position ``idx``, where it gets the value
8219 ``elt``. If ``idx`` exceeds the length of ``val`` for a fixed-length vector,
8220 the result is a :ref:`poison value `. For a scalable vector,
8221 if the value of ``idx`` exceeds the runtime length of the vector, the result
8202 ``elt``. If ``idx`` exceeds the length of ``val``, the result
82228203 is a :ref:`poison value `.
82238204
82248205 Example:
82398220 ::
82408221
82418222 = shufflevector > , > , ; yields >
8242 = shufflevector > , > v2, ; yields >
82438223
82448224 Overview:
82458225 """""""""
82708250 undef. If any element of the mask operand is undef, that element of the
82718251 result is undef. If the shuffle mask selects an undef element from one
82728252 of the input vectors, the resulting element is undef.
8273
8274 For scalable vectors, the only valid mask values at present are
8275 ``zeroinitializer`` and ``undef``, since we cannot write all indices as
8276 literals for a vector with a length unknown at compile time.
82778253
82788254 Example:
82798255 """"""""
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 /// '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;
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,
17741774 return error("Invalid type");
17751775 ResultTy = ArrayType::get(ResultTy, Record[0]);
17761776 break;
1777 case bitc::TYPE_CODE_VECTOR: // VECTOR: [numelts, eltty] or
1778 // [numelts, eltty, scalable]
1777 case bitc::TYPE_CODE_VECTOR: // VECTOR: [numelts, eltty]
17791778 if (Record.size() < 2)
17801779 return error("Invalid record");
17811780 if (Record[0] == 0)
17831782 ResultTy = getTypeByID(Record[1]);
17841783 if (!ResultTy || !StructType::isValidElementType(ResultTy))
17851784 return error("Invalid type");
1786 bool Scalable = Record.size() > 2 ? Record[2] : false;
1787 ResultTy = VectorType::get(ResultTy, Record[0], Scalable);
1785 ResultTy = VectorType::get(ResultTy, Record[0]);
17881786 break;
17891787 }
17901788
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"
307306 TBAAVerifier TBAAVerifyHelper;
308307
309308 void checkAtomicMemAccessSize(Type *Ty, const Instruction *I);
310 static bool containsScalableVectorValue(const Type *Ty);
311309
312310 public:
313311 explicit Verifier(raw_ostream *OS, bool ShouldTreatBrokenDebugInfoAsError,
318316 }
319317
320318 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 }
348319
349320 bool verify(const Function &F) {
350321 assert(F.getParent() == &M &&
414385 visitModuleCommandLines(M);
415386
416387 verifyCompileUnits();
417
418 verifyTypes(M);
419388
420389 verifyDeoptimizeCallingConvs();
421390 DISubprogramAttachments.clear();
643612 });
644613 }
645614
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
675615 void Verifier::visitGlobalVariable(const GlobalVariable &GV) {
676616 if (GV.hasInitializer()) {
677617 Assert(GV.getInitializer()->getType() == GV.getValueType(),
749689 AssertDI(false, "!dbg attachment of global variable must be a "
750690 "DIGlobalVariableExpression");
751691 }
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);
758692
759693 if (!GV.hasInitializer()) {
760694 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
923919
924920 ret void
925921 }
+0
-31
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: [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
-24
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 ; 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
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