[llvm] r374042 - [SVE][IR] Scalable Vector size queries and IR instruction support

Graham Hunter via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 8 05:53:55 PDT 2019


Author: huntergr
Date: Tue Oct  8 05:53:54 2019
New Revision: 374042

URL: http://llvm.org/viewvc/llvm-project?rev=374042&view=rev
Log:
[SVE][IR] Scalable Vector size queries and IR instruction support

* Adds a TypeSize struct to represent the known minimum size of a type
  along with a flag to indicate that the runtime size is a integer multiple
  of that size
* Converts existing size query functions from Type.h and DataLayout.h to
  return a TypeSize result
* Adds convenience methods (including a transparent conversion operator
  to uint64_t) so that most existing code 'just works' as if the return
  values were still scalars.
* Uses the new size queries along with ElementCount to ensure that all
  supported instructions used with scalable vectors can be constructed
  in IR.

Reviewers: hfinkel, lattner, rkruppe, greened, rovka, rengolin, sdesmalen

Reviewed By: rovka, sdesmalen

Differential Revision: https://reviews.llvm.org/D53137

Added:
    llvm/trunk/include/llvm/Support/TypeSize.h
    llvm/trunk/test/Other/scalable-vectors-core-ir.ll
Removed:
    llvm/trunk/include/llvm/Support/ScalableSize.h
Modified:
    llvm/trunk/include/llvm/ADT/DenseMapInfo.h
    llvm/trunk/include/llvm/IR/DataLayout.h
    llvm/trunk/include/llvm/IR/DerivedTypes.h
    llvm/trunk/include/llvm/IR/InstrTypes.h
    llvm/trunk/include/llvm/IR/Type.h
    llvm/trunk/include/llvm/Support/MachineValueType.h
    llvm/trunk/lib/Analysis/InlineCost.cpp
    llvm/trunk/lib/CodeGen/Analysis.cpp
    llvm/trunk/lib/IR/DataLayout.cpp
    llvm/trunk/lib/IR/Instructions.cpp
    llvm/trunk/lib/IR/Type.cpp
    llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp
    llvm/trunk/lib/Transforms/Scalar/SROA.cpp
    llvm/trunk/unittests/CodeGen/ScalableVectorMVTsTest.cpp
    llvm/trunk/unittests/IR/VectorTypesTest.cpp

Modified: llvm/trunk/include/llvm/ADT/DenseMapInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/DenseMapInfo.h?rev=374042&r1=374041&r2=374042&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/DenseMapInfo.h (original)
+++ llvm/trunk/include/llvm/ADT/DenseMapInfo.h Tue Oct  8 05:53:54 2019
@@ -17,7 +17,7 @@
 #include "llvm/ADT/Hashing.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/PointerLikeTypeTraits.h"
-#include "llvm/Support/ScalableSize.h"
+#include "llvm/Support/TypeSize.h"
 #include <cassert>
 #include <cstddef>
 #include <cstdint>

Modified: llvm/trunk/include/llvm/IR/DataLayout.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/DataLayout.h?rev=374042&r1=374041&r2=374042&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/DataLayout.h (original)
+++ llvm/trunk/include/llvm/IR/DataLayout.h Tue Oct  8 05:53:54 2019
@@ -30,6 +30,7 @@
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/Alignment.h"
+#include "llvm/Support/TypeSize.h"
 #include <cassert>
 #include <cstdint>
 #include <string>
@@ -437,23 +438,33 @@ public:
 
   /// Returns the number of bits necessary to hold the specified type.
   ///
+  /// If Ty is a scalable vector type, the scalable property will be set and
+  /// the runtime size will be a positive integer multiple of the base size.
+  ///
   /// For example, returns 36 for i36 and 80 for x86_fp80. The type passed must
   /// have a size (Type::isSized() must return true).
-  uint64_t getTypeSizeInBits(Type *Ty) const;
+  TypeSize getTypeSizeInBits(Type *Ty) const;
 
   /// Returns the maximum number of bytes that may be overwritten by
   /// storing the specified type.
   ///
+  /// If Ty is a scalable vector type, the scalable property will be set and
+  /// the runtime size will be a positive integer multiple of the base size.
+  ///
   /// For example, returns 5 for i36 and 10 for x86_fp80.
-  uint64_t getTypeStoreSize(Type *Ty) const {
-    return (getTypeSizeInBits(Ty) + 7) / 8;
+  TypeSize getTypeStoreSize(Type *Ty) const {
+    auto BaseSize = getTypeSizeInBits(Ty);
+    return { (BaseSize.getKnownMinSize() + 7) / 8, BaseSize.isScalable() };
   }
 
   /// Returns the maximum number of bits that may be overwritten by
   /// storing the specified type; always a multiple of 8.
   ///
+  /// If Ty is a scalable vector type, the scalable property will be set and
+  /// the runtime size will be a positive integer multiple of the base size.
+  ///
   /// For example, returns 40 for i36 and 80 for x86_fp80.
-  uint64_t getTypeStoreSizeInBits(Type *Ty) const {
+  TypeSize getTypeStoreSizeInBits(Type *Ty) const {
     return 8 * getTypeStoreSize(Ty);
   }
 
@@ -468,9 +479,12 @@ public:
   /// Returns the offset in bytes between successive objects of the
   /// specified type, including alignment padding.
   ///
+  /// If Ty is a scalable vector type, the scalable property will be set and
+  /// the runtime size will be a positive integer multiple of the base size.
+  ///
   /// This is the amount that alloca reserves for this type. For example,
   /// returns 12 or 16 for x86_fp80, depending on alignment.
-  uint64_t getTypeAllocSize(Type *Ty) const {
+  TypeSize getTypeAllocSize(Type *Ty) const {
     // Round up to the next alignment boundary.
     return alignTo(getTypeStoreSize(Ty), getABITypeAlignment(Ty));
   }
@@ -478,9 +492,12 @@ public:
   /// Returns the offset in bits between successive objects of the
   /// specified type, including alignment padding; always a multiple of 8.
   ///
+  /// If Ty is a scalable vector type, the scalable property will be set and
+  /// the runtime size will be a positive integer multiple of the base size.
+  ///
   /// This is the amount that alloca reserves for this type. For example,
   /// returns 96 or 128 for x86_fp80, depending on alignment.
-  uint64_t getTypeAllocSizeInBits(Type *Ty) const {
+  TypeSize getTypeAllocSizeInBits(Type *Ty) const {
     return 8 * getTypeAllocSize(Ty);
   }
 
@@ -598,13 +615,13 @@ private:
 
 // The implementation of this method is provided inline as it is particularly
 // well suited to constant folding when called on a specific Type subclass.
-inline uint64_t DataLayout::getTypeSizeInBits(Type *Ty) const {
+inline TypeSize DataLayout::getTypeSizeInBits(Type *Ty) const {
   assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
   switch (Ty->getTypeID()) {
   case Type::LabelTyID:
-    return getPointerSizeInBits(0);
+    return TypeSize::Fixed(getPointerSizeInBits(0));
   case Type::PointerTyID:
-    return getPointerSizeInBits(Ty->getPointerAddressSpace());
+    return TypeSize::Fixed(getPointerSizeInBits(Ty->getPointerAddressSpace()));
   case Type::ArrayTyID: {
     ArrayType *ATy = cast<ArrayType>(Ty);
     return ATy->getNumElements() *
@@ -612,26 +629,30 @@ inline uint64_t DataLayout::getTypeSizeI
   }
   case Type::StructTyID:
     // Get the layout annotation... which is lazily created on demand.
-    return getStructLayout(cast<StructType>(Ty))->getSizeInBits();
+    return TypeSize::Fixed(
+                        getStructLayout(cast<StructType>(Ty))->getSizeInBits());
   case Type::IntegerTyID:
-    return Ty->getIntegerBitWidth();
+    return TypeSize::Fixed(Ty->getIntegerBitWidth());
   case Type::HalfTyID:
-    return 16;
+    return TypeSize::Fixed(16);
   case Type::FloatTyID:
-    return 32;
+    return TypeSize::Fixed(32);
   case Type::DoubleTyID:
   case Type::X86_MMXTyID:
-    return 64;
+    return TypeSize::Fixed(64);
   case Type::PPC_FP128TyID:
   case Type::FP128TyID:
-    return 128;
+    return TypeSize::Fixed(128);
   // In memory objects this is always aligned to a higher boundary, but
   // only 80 bits contain information.
   case Type::X86_FP80TyID:
-    return 80;
+    return TypeSize::Fixed(80);
   case Type::VectorTyID: {
     VectorType *VTy = cast<VectorType>(Ty);
-    return VTy->getNumElements() * getTypeSizeInBits(VTy->getElementType());
+    auto EltCnt = VTy->getElementCount();
+    uint64_t MinBits = EltCnt.Min *
+                        getTypeSizeInBits(VTy->getElementType()).getFixedSize();
+    return TypeSize(MinBits, EltCnt.Scalable);
   }
   default:
     llvm_unreachable("DataLayout::getTypeSizeInBits(): Unsupported type");

Modified: llvm/trunk/include/llvm/IR/DerivedTypes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/DerivedTypes.h?rev=374042&r1=374041&r2=374042&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/DerivedTypes.h (original)
+++ llvm/trunk/include/llvm/IR/DerivedTypes.h Tue Oct  8 05:53:54 2019
@@ -23,7 +23,7 @@
 #include "llvm/IR/Type.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/Compiler.h"
-#include "llvm/Support/ScalableSize.h"
+#include "llvm/Support/TypeSize.h"
 #include <cassert>
 #include <cstdint>
 

Modified: llvm/trunk/include/llvm/IR/InstrTypes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/InstrTypes.h?rev=374042&r1=374041&r2=374042&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/InstrTypes.h (original)
+++ llvm/trunk/include/llvm/IR/InstrTypes.h Tue Oct  8 05:53:54 2019
@@ -975,7 +975,7 @@ public:
   static Type* makeCmpResultType(Type* opnd_type) {
     if (VectorType* vt = dyn_cast<VectorType>(opnd_type)) {
       return VectorType::get(Type::getInt1Ty(opnd_type->getContext()),
-                             vt->getNumElements());
+                             vt->getElementCount());
     }
     return Type::getInt1Ty(opnd_type->getContext());
   }

Modified: llvm/trunk/include/llvm/IR/Type.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Type.h?rev=374042&r1=374041&r2=374042&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Type.h (original)
+++ llvm/trunk/include/llvm/IR/Type.h Tue Oct  8 05:53:54 2019
@@ -21,6 +21,7 @@
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/TypeSize.h"
 #include <cassert>
 #include <cstdint>
 #include <iterator>
@@ -281,12 +282,15 @@ public:
   /// This will return zero if the type does not have a size or is not a
   /// primitive type.
   ///
+  /// If this is a scalable vector type, the scalable property will be set and
+  /// the runtime size will be a positive integer multiple of the base size.
+  ///
   /// Note that this may not reflect the size of memory allocated for an
   /// instance of the type or the number of bytes that are written when an
   /// instance of the type is stored to memory. The DataLayout class provides
   /// additional query functions to provide this information.
   ///
-  unsigned getPrimitiveSizeInBits() const LLVM_READONLY;
+  TypeSize getPrimitiveSizeInBits() const LLVM_READONLY;
 
   /// If this is a vector type, return the getPrimitiveSizeInBits value for the
   /// element type. Otherwise return the getPrimitiveSizeInBits value for this

Modified: llvm/trunk/include/llvm/Support/MachineValueType.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/MachineValueType.h?rev=374042&r1=374041&r2=374042&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/MachineValueType.h (original)
+++ llvm/trunk/include/llvm/Support/MachineValueType.h Tue Oct  8 05:53:54 2019
@@ -17,7 +17,7 @@
 #include "llvm/ADT/iterator_range.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/MathExtras.h"
-#include "llvm/Support/ScalableSize.h"
+#include "llvm/Support/TypeSize.h"
 #include <cassert>
 
 namespace llvm {

Removed: llvm/trunk/include/llvm/Support/ScalableSize.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/ScalableSize.h?rev=374041&view=auto
==============================================================================
--- llvm/trunk/include/llvm/Support/ScalableSize.h (original)
+++ llvm/trunk/include/llvm/Support/ScalableSize.h (removed)
@@ -1,46 +0,0 @@
-//===- ScalableSize.h - Scalable vector size info ---------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides a struct that can be used to query the size of IR types
-// which may be scalable vectors. It provides convenience operators so that
-// it can be used in much the same way as a single scalar value.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_SCALABLESIZE_H
-#define LLVM_SUPPORT_SCALABLESIZE_H
-
-namespace llvm {
-
-class ElementCount {
-public:
-  unsigned Min;  // Minimum number of vector elements.
-  bool Scalable; // If true, NumElements is a multiple of 'Min' determined
-                 // at runtime rather than compile time.
-
-  ElementCount(unsigned Min, bool Scalable)
-  : Min(Min), Scalable(Scalable) {}
-
-  ElementCount operator*(unsigned RHS) {
-    return { Min * RHS, Scalable };
-  }
-  ElementCount operator/(unsigned RHS) {
-    return { Min / RHS, Scalable };
-  }
-
-  bool operator==(const ElementCount& RHS) const {
-    return Min == RHS.Min && Scalable == RHS.Scalable;
-  }
-  bool operator!=(const ElementCount& RHS) const {
-    return !(*this == RHS);
-  }
-};
-
-} // end namespace llvm
-
-#endif // LLVM_SUPPORT_SCALABLESIZE_H

Added: llvm/trunk/include/llvm/Support/TypeSize.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/TypeSize.h?rev=374042&view=auto
==============================================================================
--- llvm/trunk/include/llvm/Support/TypeSize.h (added)
+++ llvm/trunk/include/llvm/Support/TypeSize.h Tue Oct  8 05:53:54 2019
@@ -0,0 +1,200 @@
+//===- TypeSize.h - Wrapper around type sizes -------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides a struct that can be used to query the size of IR types
+// which may be scalable vectors. It provides convenience operators so that
+// it can be used in much the same way as a single scalar value.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_TYPESIZE_H
+#define LLVM_SUPPORT_TYPESIZE_H
+
+#include <tuple>
+
+namespace llvm {
+
+class ElementCount {
+public:
+  unsigned Min;  // Minimum number of vector elements.
+  bool Scalable; // If true, NumElements is a multiple of 'Min' determined
+                 // at runtime rather than compile time.
+
+  ElementCount(unsigned Min, bool Scalable)
+  : Min(Min), Scalable(Scalable) {}
+
+  ElementCount operator*(unsigned RHS) {
+    return { Min * RHS, Scalable };
+  }
+  ElementCount operator/(unsigned RHS) {
+    return { Min / RHS, Scalable };
+  }
+
+  bool operator==(const ElementCount& RHS) const {
+    return Min == RHS.Min && Scalable == RHS.Scalable;
+  }
+  bool operator!=(const ElementCount& RHS) const {
+    return !(*this == RHS);
+  }
+};
+
+// This class is used to represent the size of types. If the type is of fixed
+// size, it will represent the exact size. If the type is a scalable vector,
+// it will represent the known minimum size.
+class TypeSize {
+  uint64_t MinSize;   // The known minimum size.
+  bool IsScalable;    // If true, then the runtime size is an integer multiple
+                      // of MinSize.
+
+public:
+  constexpr TypeSize(uint64_t MinSize, bool Scalable)
+    : MinSize(MinSize), IsScalable(Scalable) {}
+
+  static constexpr TypeSize Fixed(uint64_t Size) {
+    return TypeSize(Size, /*IsScalable=*/false);
+  }
+
+  static constexpr TypeSize Scalable(uint64_t MinSize) {
+    return TypeSize(MinSize, /*IsScalable=*/true);
+  }
+
+  // Scalable vector types with the same minimum size as a fixed size type are
+  // not guaranteed to be the same size at runtime, so they are never
+  // considered to be equal.
+  friend bool operator==(const TypeSize &LHS, const TypeSize &RHS) {
+    return std::tie(LHS.MinSize, LHS.IsScalable) ==
+           std::tie(RHS.MinSize, RHS.IsScalable);
+  }
+
+  friend bool operator!=(const TypeSize &LHS, const TypeSize &RHS) {
+    return !(LHS == RHS);
+  }
+
+  // For many cases, size ordering between scalable and fixed size types cannot
+  // be determined at compile time, so such comparisons aren't allowed.
+  //
+  // e.g. <vscale x 2 x i16> could be bigger than <4 x i32> with a runtime
+  // vscale >= 5, equal sized with a vscale of 4, and smaller with
+  // a vscale <= 3.
+  //
+  // If the scalable flags match, just perform the requested comparison
+  // between the minimum sizes.
+  friend bool operator<(const TypeSize &LHS, const TypeSize &RHS) {
+    assert(LHS.IsScalable == RHS.IsScalable &&
+           "Ordering comparison of scalable and fixed types");
+
+    return LHS.MinSize < RHS.MinSize;
+  }
+
+  friend bool operator>(const TypeSize &LHS, const TypeSize &RHS) {
+    return RHS < LHS;
+  }
+
+  friend bool operator<=(const TypeSize &LHS, const TypeSize &RHS) {
+    return !(RHS < LHS);
+  }
+
+  friend bool operator>=(const TypeSize &LHS, const TypeSize& RHS) {
+    return !(LHS < RHS);
+  }
+
+  // Convenience operators to obtain relative sizes independently of
+  // the scalable flag.
+  TypeSize operator*(unsigned RHS) const {
+    return { MinSize * RHS, IsScalable };
+  }
+
+  friend TypeSize operator*(const unsigned LHS, const TypeSize &RHS) {
+    return { LHS * RHS.MinSize, RHS.IsScalable };
+  }
+
+  TypeSize operator/(unsigned RHS) const {
+    return { MinSize / RHS, IsScalable };
+  }
+
+  // Return the minimum size with the assumption that the size is exact.
+  // Use in places where a scalable size doesn't make sense (e.g. non-vector
+  // types, or vectors in backends which don't support scalable vectors)
+  uint64_t getFixedSize() const {
+    assert(!IsScalable && "Request for a fixed size on a scalable object");
+    return MinSize;
+  }
+
+  // Return the known minimum size. Use in places where the scalable property
+  // doesn't matter (e.g. determining alignment) or in conjunction with the
+  // isScalable method below.
+  uint64_t getKnownMinSize() const {
+    return MinSize;
+  }
+
+  // Return whether or not the size is scalable.
+  bool isScalable() const {
+    return IsScalable;
+  }
+
+  // Casts to a uint64_t if this is a fixed-width size.
+  //
+  // NOTE: This interface is obsolete and will be removed in a future version
+  // of LLVM in favour of calling getFixedSize() directly
+  operator uint64_t() const {
+    return getFixedSize();
+  }
+
+  // Additional convenience operators needed to avoid ambiguous parses
+  // TODO: Make uint64_t the default operator?
+  TypeSize operator*(uint64_t RHS) const {
+    return { MinSize * RHS, IsScalable };
+  }
+
+  TypeSize operator*(int RHS) const {
+    return { MinSize * RHS, IsScalable };
+  }
+
+  TypeSize operator*(int64_t RHS) const {
+    return { MinSize * RHS, IsScalable };
+  }
+
+  friend TypeSize operator*(const uint64_t LHS, const TypeSize &RHS) {
+    return { LHS * RHS.MinSize, RHS.IsScalable };
+  }
+
+  friend TypeSize operator*(const int LHS, const TypeSize &RHS) {
+    return { LHS * RHS.MinSize, RHS.IsScalable };
+  }
+
+  friend TypeSize operator*(const int64_t LHS, const TypeSize &RHS) {
+    return { LHS * RHS.MinSize, RHS.IsScalable };
+  }
+
+  TypeSize operator/(uint64_t RHS) const {
+    return { MinSize / RHS, IsScalable };
+  }
+
+  TypeSize operator/(int RHS) const {
+    return { MinSize / RHS, IsScalable };
+  }
+
+  TypeSize operator/(int64_t RHS) const {
+    return { MinSize / RHS, IsScalable };
+  }
+};
+
+/// Returns a TypeSize with a known minimum size that is the next integer
+/// (mod 2**64) that is greater than or equal to \p Value and is a multiple
+/// of \p Align. \p Align must be non-zero.
+///
+/// Similar to the alignTo functions in MathExtras.h
+inline TypeSize alignTo(TypeSize Size, uint64_t Align) {
+  assert(Align != 0u && "Align must be non-zero");
+  return {(Size.getKnownMinSize() + Align - 1) / Align * Align,
+          Size.isScalable()};
+}
+
+} // end namespace llvm
+
+#endif // LLVM_SUPPORT_TypeSize_H

Modified: llvm/trunk/lib/Analysis/InlineCost.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InlineCost.cpp?rev=374042&r1=374041&r2=374042&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/InlineCost.cpp (original)
+++ llvm/trunk/lib/Analysis/InlineCost.cpp Tue Oct  8 05:53:54 2019
@@ -436,7 +436,8 @@ bool CallAnalyzer::visitAlloca(AllocaIns
     if (auto *AllocSize = dyn_cast_or_null<ConstantInt>(Size)) {
       Type *Ty = I.getAllocatedType();
       AllocatedSize = SaturatingMultiplyAdd(
-          AllocSize->getLimitedValue(), DL.getTypeAllocSize(Ty), AllocatedSize);
+          AllocSize->getLimitedValue(), DL.getTypeAllocSize(Ty).getFixedSize(),
+          AllocatedSize);
       return Base::visitAlloca(I);
     }
   }
@@ -444,7 +445,8 @@ bool CallAnalyzer::visitAlloca(AllocaIns
   // Accumulate the allocated size.
   if (I.isStaticAlloca()) {
     Type *Ty = I.getAllocatedType();
-    AllocatedSize = SaturatingAdd(DL.getTypeAllocSize(Ty), AllocatedSize);
+    AllocatedSize = SaturatingAdd(DL.getTypeAllocSize(Ty).getFixedSize(),
+                                  AllocatedSize);
   }
 
   // We will happily inline static alloca instructions.

Modified: llvm/trunk/lib/CodeGen/Analysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/Analysis.cpp?rev=374042&r1=374041&r2=374042&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/Analysis.cpp (original)
+++ llvm/trunk/lib/CodeGen/Analysis.cpp Tue Oct  8 05:53:54 2019
@@ -309,7 +309,8 @@ static const Value *getNoopInput(const V
         NoopInput = Op;
     } else if (isa<TruncInst>(I) &&
                TLI.allowTruncateForTailCall(Op->getType(), I->getType())) {
-      DataBits = std::min(DataBits, I->getType()->getPrimitiveSizeInBits());
+      DataBits = std::min((uint64_t)DataBits,
+                         I->getType()->getPrimitiveSizeInBits().getFixedSize());
       NoopInput = Op;
     } else if (auto CS = ImmutableCallSite(I)) {
       const Value *ReturnedOp = CS.getReturnedArgOperand();

Modified: llvm/trunk/lib/IR/DataLayout.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/DataLayout.cpp?rev=374042&r1=374041&r2=374042&view=diff
==============================================================================
--- llvm/trunk/lib/IR/DataLayout.cpp (original)
+++ llvm/trunk/lib/IR/DataLayout.cpp Tue Oct  8 05:53:54 2019
@@ -29,6 +29,7 @@
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/MathExtras.h"
+#include "llvm/Support/TypeSize.h"
 #include <algorithm>
 #include <cassert>
 #include <cstdint>
@@ -745,7 +746,10 @@ Align DataLayout::getAlignment(Type *Ty,
     llvm_unreachable("Bad type for getAlignment!!!");
   }
 
-  return getAlignmentInfo(AlignType, getTypeSizeInBits(Ty), abi_or_pref, Ty);
+  // If we're dealing with a scalable vector, we just need the known minimum
+  // size for determining alignment. If not, we'll get the exact size.
+  return getAlignmentInfo(AlignType, getTypeSizeInBits(Ty).getKnownMinSize(),
+                          abi_or_pref, Ty);
 }
 
 unsigned DataLayout::getABITypeAlignment(Type *Ty) const {

Modified: llvm/trunk/lib/IR/Instructions.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Instructions.cpp?rev=374042&r1=374041&r2=374042&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Instructions.cpp (original)
+++ llvm/trunk/lib/IR/Instructions.cpp Tue Oct  8 05:53:54 2019
@@ -38,6 +38,7 @@
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/MathExtras.h"
+#include "llvm/Support/TypeSize.h"
 #include <algorithm>
 #include <cassert>
 #include <cstdint>
@@ -1792,7 +1793,7 @@ ShuffleVectorInst::ShuffleVectorInst(Val
                                      const Twine &Name,
                                      Instruction *InsertBefore)
 : Instruction(VectorType::get(cast<VectorType>(V1->getType())->getElementType(),
-                cast<VectorType>(Mask->getType())->getNumElements()),
+                cast<VectorType>(Mask->getType())->getElementCount()),
               ShuffleVector,
               OperandTraits<ShuffleVectorInst>::op_begin(this),
               OperandTraits<ShuffleVectorInst>::operands(this),
@@ -1809,7 +1810,7 @@ ShuffleVectorInst::ShuffleVectorInst(Val
                                      const Twine &Name,
                                      BasicBlock *InsertAtEnd)
 : Instruction(VectorType::get(cast<VectorType>(V1->getType())->getElementType(),
-                cast<VectorType>(Mask->getType())->getNumElements()),
+                cast<VectorType>(Mask->getType())->getElementCount()),
               ShuffleVector,
               OperandTraits<ShuffleVectorInst>::op_begin(this),
               OperandTraits<ShuffleVectorInst>::operands(this),
@@ -2982,8 +2983,8 @@ bool CastInst::isCastable(Type *SrcTy, T
       }
 
   // Get the bit sizes, we'll need these
-  unsigned SrcBits = SrcTy->getPrimitiveSizeInBits();   // 0 for ptr
-  unsigned DestBits = DestTy->getPrimitiveSizeInBits(); // 0 for ptr
+  auto SrcBits = SrcTy->getPrimitiveSizeInBits();   // 0 for ptr
+  auto DestBits = DestTy->getPrimitiveSizeInBits(); // 0 for ptr
 
   // Run through the possibilities ...
   if (DestTy->isIntegerTy()) {               // Casting to integral
@@ -3030,7 +3031,7 @@ bool CastInst::isBitCastable(Type *SrcTy
 
   if (VectorType *SrcVecTy = dyn_cast<VectorType>(SrcTy)) {
     if (VectorType *DestVecTy = dyn_cast<VectorType>(DestTy)) {
-      if (SrcVecTy->getNumElements() == DestVecTy->getNumElements()) {
+      if (SrcVecTy->getElementCount() == DestVecTy->getElementCount()) {
         // An element by element cast. Valid if casting the elements is valid.
         SrcTy = SrcVecTy->getElementType();
         DestTy = DestVecTy->getElementType();
@@ -3044,12 +3045,12 @@ bool CastInst::isBitCastable(Type *SrcTy
     }
   }
 
-  unsigned SrcBits = SrcTy->getPrimitiveSizeInBits();   // 0 for ptr
-  unsigned DestBits = DestTy->getPrimitiveSizeInBits(); // 0 for ptr
+  auto SrcBits = SrcTy->getPrimitiveSizeInBits();   // 0 for ptr
+  auto DestBits = DestTy->getPrimitiveSizeInBits(); // 0 for ptr
 
   // Could still have vectors of pointers if the number of elements doesn't
   // match
-  if (SrcBits == 0 || DestBits == 0)
+  if (SrcBits.getKnownMinSize() == 0 || DestBits.getKnownMinSize() == 0)
     return false;
 
   if (SrcBits != DestBits)

Modified: llvm/trunk/lib/IR/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Type.cpp?rev=374042&r1=374041&r2=374042&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Type.cpp (original)
+++ llvm/trunk/lib/IR/Type.cpp Tue Oct  8 05:53:54 2019
@@ -26,6 +26,7 @@
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/TypeSize.h"
 #include <cassert>
 #include <utility>
 
@@ -111,18 +112,22 @@ bool Type::isEmptyTy() const {
   return false;
 }
 
-unsigned Type::getPrimitiveSizeInBits() const {
+TypeSize Type::getPrimitiveSizeInBits() const {
   switch (getTypeID()) {
-  case Type::HalfTyID: return 16;
-  case Type::FloatTyID: return 32;
-  case Type::DoubleTyID: return 64;
-  case Type::X86_FP80TyID: return 80;
-  case Type::FP128TyID: return 128;
-  case Type::PPC_FP128TyID: return 128;
-  case Type::X86_MMXTyID: return 64;
-  case Type::IntegerTyID: return cast<IntegerType>(this)->getBitWidth();
-  case Type::VectorTyID:  return cast<VectorType>(this)->getBitWidth();
-  default: return 0;
+  case Type::HalfTyID: return TypeSize::Fixed(16);
+  case Type::FloatTyID: return TypeSize::Fixed(32);
+  case Type::DoubleTyID: return TypeSize::Fixed(64);
+  case Type::X86_FP80TyID: return TypeSize::Fixed(80);
+  case Type::FP128TyID: return TypeSize::Fixed(128);
+  case Type::PPC_FP128TyID: return TypeSize::Fixed(128);
+  case Type::X86_MMXTyID: return TypeSize::Fixed(64);
+  case Type::IntegerTyID:
+    return TypeSize::Fixed(cast<IntegerType>(this)->getBitWidth());
+  case Type::VectorTyID: {
+    const VectorType *VTy = cast<VectorType>(this);
+    return TypeSize(VTy->getBitWidth(), VTy->isScalable());
+  }
+  default: return TypeSize::Fixed(0);
   }
 }
 

Modified: llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp?rev=374042&r1=374041&r2=374042&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp Tue Oct  8 05:53:54 2019
@@ -8526,7 +8526,7 @@ bool AArch64TargetLowering::isExtFreeImp
       // Get the shift amount based on the scaling factor:
       // log2(sizeof(IdxTy)) - log2(8).
       uint64_t ShiftAmt =
-          countTrailingZeros(DL.getTypeStoreSizeInBits(IdxTy)) - 3;
+        countTrailingZeros(DL.getTypeStoreSizeInBits(IdxTy).getFixedSize()) - 3;
       // Is the constant foldable in the shift of the addressing mode?
       // I.e., shift amount is between 1 and 4 inclusive.
       if (ShiftAmt == 0 || ShiftAmt > 4)

Modified: llvm/trunk/lib/Transforms/Scalar/SROA.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SROA.cpp?rev=374042&r1=374041&r2=374042&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/SROA.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/SROA.cpp Tue Oct  8 05:53:54 2019
@@ -959,14 +959,16 @@ private:
       std::tie(UsedI, I) = Uses.pop_back_val();
 
       if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
-        Size = std::max(Size, DL.getTypeStoreSize(LI->getType()));
+        Size = std::max(Size,
+                        DL.getTypeStoreSize(LI->getType()).getFixedSize());
         continue;
       }
       if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
         Value *Op = SI->getOperand(0);
         if (Op == UsedI)
           return SI;
-        Size = std::max(Size, DL.getTypeStoreSize(Op->getType()));
+        Size = std::max(Size,
+                        DL.getTypeStoreSize(Op->getType()).getFixedSize());
         continue;
       }
 

Added: llvm/trunk/test/Other/scalable-vectors-core-ir.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/scalable-vectors-core-ir.ll?rev=374042&view=auto
==============================================================================
--- llvm/trunk/test/Other/scalable-vectors-core-ir.ll (added)
+++ llvm/trunk/test/Other/scalable-vectors-core-ir.ll Tue Oct  8 05:53:54 2019
@@ -0,0 +1,393 @@
+; RUN: opt -S -verify < %s | FileCheck %s
+target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64--linux-gnu"
+
+;; Check supported instructions are accepted without dropping 'vscale'.
+;; Same order as the LangRef
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Unary Operations
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+
+define <vscale x 2 x double> @fneg(<vscale x 2 x double> %val) {
+; CHECK-LABEL: @fneg
+; CHECK: %r = fneg <vscale x 2 x double> %val
+; CHECK-NEXT: ret <vscale x 2 x double> %r
+  %r = fneg <vscale x 2 x double> %val
+  ret <vscale x 2 x double> %r
+}
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Binary Operations
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+define <vscale x 8 x i16> @add(<vscale x 8 x i16> %a, <vscale x 8 x i16> %b) {
+; CHECK-LABEL: @add
+; CHECK: %r = add <vscale x 8 x i16> %a, %b
+; CHECK-NEXT: ret <vscale x 8 x i16> %r
+  %r = add <vscale x 8 x i16> %a, %b
+  ret <vscale x 8 x i16> %r
+}
+
+define <vscale x 4 x float> @fadd(<vscale x 4 x float> %a, <vscale x 4 x float> %b) {
+; CHECK-LABEL: @fadd
+; CHECK: %r = fadd <vscale x 4 x float> %a, %b
+; CHECK-NEXT: ret <vscale x 4 x float> %r
+  %r = fadd <vscale x 4 x float> %a, %b
+  ret <vscale x 4 x float> %r
+}
+
+define <vscale x 4 x i32> @sub(<vscale x 4 x i32> %a, <vscale x 4 x i32> %b) {
+; CHECK-LABEL: @sub
+; CHECK: %r = sub <vscale x 4 x i32> %a, %b
+; CHECK-NEXT: ret <vscale x 4 x i32> %r
+  %r = sub <vscale x 4 x i32> %a, %b
+  ret <vscale x 4 x i32> %r
+}
+
+define <vscale x 4 x float> @fsub(<vscale x 4 x float> %a, <vscale x 4 x float> %b) {
+; CHECK-LABEL: @fsub
+; CHECK: %r = fsub <vscale x 4 x float> %a, %b
+; CHECK-NEXT: ret <vscale x 4 x float> %r
+  %r = fsub <vscale x 4 x float> %a, %b
+  ret <vscale x 4 x float> %r
+}
+
+define <vscale x 4 x i32> @mul(<vscale x 4 x i32> %a, <vscale x 4 x i32> %b) {
+; CHECK-LABEL: @mul
+; CHECK: %r = mul <vscale x 4 x i32> %a, %b
+; CHECK-NEXT: ret <vscale x 4 x i32> %r
+  %r = mul <vscale x 4 x i32> %a, %b
+  ret <vscale x 4 x i32> %r
+}
+
+define <vscale x 4 x float> @fmul(<vscale x 4 x float> %a, <vscale x 4 x float> %b) {
+; CHECK-LABEL: @fmul
+; CHECK: %r = fmul <vscale x 4 x float> %a, %b
+; CHECK-NEXT: ret <vscale x 4 x float> %r
+  %r = fmul <vscale x 4 x float> %a, %b
+  ret <vscale x 4 x float> %r
+}
+
+define <vscale x 4 x i32> @udiv(<vscale x 4 x i32> %a, <vscale x 4 x i32> %b) {
+; CHECK-LABEL: @udiv
+; CHECK: %r = udiv <vscale x 4 x i32> %a, %b
+; CHECK-NEXT: ret <vscale x 4 x i32> %r
+  %r = udiv <vscale x 4 x i32> %a, %b
+  ret <vscale x 4 x i32> %r
+}
+
+define <vscale x 4 x i32> @sdiv(<vscale x 4 x i32> %a, <vscale x 4 x i32> %b) {
+; CHECK-LABEL: @sdiv
+; CHECK: %r = sdiv <vscale x 4 x i32> %a, %b
+; CHECK-NEXT: ret <vscale x 4 x i32> %r
+  %r = sdiv <vscale x 4 x i32> %a, %b
+  ret <vscale x 4 x i32> %r
+}
+
+define <vscale x 4 x float> @fdiv(<vscale x 4 x float> %a, <vscale x 4 x float> %b) {
+; CHECK-LABEL: @fdiv
+; CHECK: %r = fdiv <vscale x 4 x float> %a, %b
+; CHECK-NEXT: ret <vscale x 4 x float> %r
+  %r = fdiv <vscale x 4 x float> %a, %b
+  ret <vscale x 4 x float> %r
+}
+
+define <vscale x 4 x i32> @urem(<vscale x 4 x i32> %a, <vscale x 4 x i32> %b) {
+; CHECK-LABEL: @urem
+; CHECK: %r = urem <vscale x 4 x i32> %a, %b
+; CHECK-NEXT: ret <vscale x 4 x i32> %r
+  %r = urem <vscale x 4 x i32> %a, %b
+  ret <vscale x 4 x i32> %r
+}
+
+define <vscale x 4 x i32> @srem(<vscale x 4 x i32> %a, <vscale x 4 x i32> %b) {
+; CHECK-LABEL: @srem
+; CHECK: %r = srem <vscale x 4 x i32> %a, %b
+; CHECK-NEXT: ret <vscale x 4 x i32> %r
+  %r = srem <vscale x 4 x i32> %a, %b
+  ret <vscale x 4 x i32> %r
+}
+
+define <vscale x 4 x float> @frem(<vscale x 4 x float> %a, <vscale x 4 x float> %b) {
+; CHECK-LABEL: @frem
+; CHECK: %r = frem <vscale x 4 x float> %a, %b
+; CHECK-NEXT: ret <vscale x 4 x float> %r
+  %r = frem <vscale x 4 x float> %a, %b
+  ret <vscale x 4 x float> %r
+}
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Bitwise Binary Operations
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+define <vscale x 4 x i32> @shl(<vscale x 4 x i32> %a, <vscale x 4 x i32> %b) {
+; CHECK-LABEL: @shl
+; CHECK: %r = shl <vscale x 4 x i32> %a, %b
+; CHECK-NEXT: ret <vscale x 4 x i32> %r
+  %r = shl <vscale x 4 x i32> %a, %b
+  ret <vscale x 4 x i32> %r
+}
+
+define <vscale x 4 x i32> @lshr(<vscale x 4 x i32> %a, <vscale x 4 x i32> %b) {
+; CHECK-LABEL: @lshr
+; CHECK: %r = lshr <vscale x 4 x i32> %a, %b
+; CHECK-NEXT: ret <vscale x 4 x i32> %r
+  %r = lshr <vscale x 4 x i32> %a, %b
+  ret <vscale x 4 x i32> %r
+}
+
+define <vscale x 4 x i32> @ashr(<vscale x 4 x i32> %a, <vscale x 4 x i32> %b) {
+; CHECK-LABEL: @ashr
+; CHECK: %r = ashr <vscale x 4 x i32> %a, %b
+; CHECK-NEXT: ret <vscale x 4 x i32> %r
+  %r = ashr <vscale x 4 x i32> %a, %b
+  ret <vscale x 4 x i32> %r
+}
+
+define <vscale x 4 x i32> @and(<vscale x 4 x i32> %a, <vscale x 4 x i32> %b) {
+; CHECK-LABEL: @and
+; CHECK: %r = and <vscale x 4 x i32> %a, %b
+; CHECK-NEXT: ret <vscale x 4 x i32> %r
+  %r = and <vscale x 4 x i32> %a, %b
+  ret <vscale x 4 x i32> %r
+}
+
+define <vscale x 4 x i32> @or(<vscale x 4 x i32> %a, <vscale x 4 x i32> %b) {
+; CHECK-LABEL: @or
+; CHECK: %r = or <vscale x 4 x i32> %a, %b
+; CHECK-NEXT: ret <vscale x 4 x i32> %r
+  %r = or <vscale x 4 x i32> %a, %b
+  ret <vscale x 4 x i32> %r
+}
+
+define <vscale x 4 x i32> @xor(<vscale x 4 x i32> %a, <vscale x 4 x i32> %b) {
+; CHECK-LABEL: @xor
+; CHECK: %r = xor <vscale x 4 x i32> %a, %b
+; CHECK-NEXT: ret <vscale x 4 x i32> %r
+  %r = xor <vscale x 4 x i32> %a, %b
+  ret <vscale x 4 x i32> %r
+}
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Vector Operations
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+define i64 @extractelement(<vscale x 2 x i64> %val) {
+; CHECK-LABEL: @extractelement
+; CHECK: %r = extractelement <vscale x 2 x i64> %val, i32 0
+; CHECK-NEXT: ret i64 %r
+  %r = extractelement <vscale x 2 x i64> %val, i32 0
+  ret i64 %r
+}
+
+define <vscale x 16 x i8> @insertelement(<vscale x 16 x i8> %vec, i8 %ins) {
+; CHECK-LABEL: @insertelement
+; CHECK: %r = insertelement <vscale x 16 x i8> %vec, i8 %ins, i32 0
+; CHECK-NEXT: ret <vscale x 16 x i8> %r
+  %r = insertelement <vscale x 16 x i8> %vec, i8 %ins, i32 0
+  ret <vscale x 16 x i8> %r
+}
+
+define <vscale x 8 x half> @shufflevector(half %val) {
+; CHECK-LABEL: @shufflevector
+; CHECK: %insvec = insertelement <vscale x 8 x half> undef, half %val, i32 0
+; CHECK-NEXT: %r = shufflevector <vscale x 8 x half> %insvec, <vscale x 8 x half> undef, <vscale x 8 x i32> zeroinitializer
+; CHECK-NEXT: ret <vscale x 8 x half> %r
+  %insvec = insertelement <vscale x 8 x half> undef, half %val, i32 0
+  %r = shufflevector <vscale x 8 x half> %insvec, <vscale x 8 x half> undef, <vscale x 8 x i32> zeroinitializer
+  ret <vscale x 8 x half> %r
+}
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Memory Access and Addressing Operations
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+define void @alloca() {
+; CHECK-LABEL: @alloca
+; CHECK: %vec = alloca <vscale x 4 x i32>
+; CHECK-NEXT: ret void
+  %vec = alloca <vscale x 4 x i32>
+  ret void
+}
+
+define <vscale x 2 x double> @load(<vscale x 2 x double>* %ptr) {
+; CHECK-LABEL: @load
+; CHECK: %r = load <vscale x 2 x double>, <vscale x 2 x double>* %ptr
+; CHECK-NEXT: ret <vscale x 2 x double> %r
+  %r = load <vscale x 2 x double>, <vscale x 2 x double>* %ptr
+  ret <vscale x 2 x double> %r
+}
+
+define void @store(<vscale x 4 x i32> %data, <vscale x 4 x i32>* %ptr) {
+; CHECK-LABEL: @store
+; CHECK: store <vscale x 4 x i32> %data, <vscale x 4 x i32>* %ptr
+; CHECK-NEXT: ret void
+  store <vscale x 4 x i32> %data, <vscale x 4 x i32>* %ptr
+  ret void
+}
+
+define <vscale x 4 x float>* @getelementptr(<vscale x 4 x float>* %base) {
+; CHECK-LABEL: @getelementptr
+; CHECK: %r = getelementptr <vscale x 4 x float>, <vscale x 4 x float>* %base, i64 0
+; CHECK-NEXT: ret <vscale x 4 x float>* %r
+  %r = getelementptr <vscale x 4 x float>, <vscale x 4 x float>* %base, i64 0
+  ret <vscale x 4 x float>* %r
+}
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Conversion Operations
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+define <vscale x 4 x i32> @truncto(<vscale x 4 x i64> %val) {
+; CHECK-LABEL: @truncto
+; CHECK: %r = trunc <vscale x 4 x i64> %val to <vscale x 4 x i32>
+; CHECK-NEXT: ret <vscale x 4 x i32> %r
+  %r = trunc <vscale x 4 x i64> %val to <vscale x 4 x i32>
+  ret <vscale x 4 x i32> %r
+}
+
+define <vscale x 2 x i64> @zextto(<vscale x 2 x i16> %val) {
+; CHECK-LABEL: @zextto
+; CHECK: %r = zext <vscale x 2 x i16> %val to <vscale x 2 x i64>
+; CHECK-NEXT: ret <vscale x 2 x i64> %r
+  %r = zext <vscale x 2 x i16> %val to <vscale x 2 x i64>
+  ret <vscale x 2 x i64> %r
+}
+
+define <vscale x 4 x i32> @sextto(<vscale x 4 x i8> %val) {
+; CHECK-LABEL: @sextto
+; CHECK: %r = sext <vscale x 4 x i8> %val to <vscale x 4 x i32>
+; CHECK-NEXT: ret <vscale x 4 x i32> %r
+  %r = sext <vscale x 4 x i8> %val to <vscale x 4 x i32>
+  ret <vscale x 4 x i32> %r
+}
+
+define <vscale x 4 x half> @fptruncto(<vscale x 4 x float> %val) {
+; CHECK-LABEL: @fptruncto
+; CHECK: %r = fptrunc <vscale x 4 x float> %val to <vscale x 4 x half>
+; CHECK-NEXT: ret <vscale x 4 x half> %r
+  %r = fptrunc <vscale x 4 x float> %val to <vscale x 4 x half>
+  ret <vscale x 4 x half> %r
+}
+
+define <vscale x 2 x double> @fpextto(<vscale x 2 x half> %val) {
+; CHECK-LABEL: @fpextto
+; CHECK: %r = fpext <vscale x 2 x half> %val to <vscale x 2 x double>
+; CHECK-NEXT: ret <vscale x 2 x double> %r
+  %r = fpext <vscale x 2 x half> %val to <vscale x 2 x double>
+  ret <vscale x 2 x double> %r
+}
+
+define <vscale x 4 x i32> @fptouito(<vscale x 4 x float> %val) {
+; CHECK-LABEL: @fptoui
+; CHECK: %r = fptoui <vscale x 4 x float> %val to <vscale x 4 x i32>
+; CHECK-NEXT: ret <vscale x 4 x i32> %r
+  %r = fptoui <vscale x 4 x float> %val to <vscale x 4 x i32>
+  ret <vscale x 4 x i32> %r
+}
+
+define <vscale x 4 x i32> @fptosito(<vscale x 4 x float> %val) {
+; CHECK-LABEL: @fptosi
+; CHECK: %r = fptosi <vscale x 4 x float> %val to <vscale x 4 x i32>
+; CHECK-NEXT: ret <vscale x 4 x i32> %r
+  %r = fptosi <vscale x 4 x float> %val to <vscale x 4 x i32>
+  ret <vscale x 4 x i32> %r
+}
+
+define <vscale x 4 x float> @uitofpto(<vscale x 4 x i32> %val) {
+; CHECK-LABEL: @uitofp
+; CHECK: %r = uitofp <vscale x 4 x i32> %val to <vscale x 4 x float>
+; CHECK-NEXT: ret <vscale x 4 x float> %r
+  %r = uitofp <vscale x 4 x i32> %val to <vscale x 4 x float>
+  ret <vscale x 4 x float> %r
+}
+
+define <vscale x 4 x float> @sitofpto(<vscale x 4 x i32> %val) {
+; CHECK-LABEL: @sitofp
+; CHECK: %r = sitofp <vscale x 4 x i32> %val to <vscale x 4 x float>
+; CHECK-NEXT: ret <vscale x 4 x float> %r
+  %r = sitofp <vscale x 4 x i32> %val to <vscale x 4 x float>
+  ret <vscale x 4 x float> %r
+}
+
+define <vscale x 2 x i64> @ptrtointto(<vscale x 2 x i32*> %val) {
+; CHECK-LABEL: @ptrtointto
+; CHECK: %r = ptrtoint <vscale x 2 x i32*> %val to <vscale x 2 x i64>
+; CHECK-NEXT: ret <vscale x 2 x i64> %r
+  %r = ptrtoint <vscale x 2 x i32*> %val to <vscale x 2 x i64>
+  ret <vscale x 2 x i64> %r
+}
+
+define <vscale x 2 x i32*> @inttoptrto(<vscale x 2 x i64> %val) {
+; CHECK-LABEL: @inttoptrto
+; CHECK: %r = inttoptr <vscale x 2 x i64> %val to <vscale x 2 x i32*>
+; CHECK-NEXT: ret <vscale x 2 x i32*> %r
+  %r = inttoptr <vscale x 2 x i64> %val to <vscale x 2 x i32*>
+  ret <vscale x 2 x i32*> %r
+}
+
+define <vscale x 2 x i64> @bitcastto(<vscale x 2 x double> %a) {
+; CHECK-LABEL: @bitcast
+; CHECK: %r = bitcast <vscale x 2 x double> %a to <vscale x 2 x i64>
+; CHECK-NEXT: ret <vscale x 2 x i64> %r
+  %r = bitcast <vscale x 2 x double> %a to <vscale x 2 x i64>
+  ret <vscale x 2 x i64> %r
+}
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Other Operations
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+define <vscale x 4 x i1> @icmp(<vscale x 4 x i32> %a, <vscale x 4 x i32> %b) {
+; CHECK-LABEL: @icmp
+; CHECK: %r = icmp eq <vscale x 4 x i32> %a, %b
+; CHECK-NEXT: ret <vscale x 4 x i1> %r
+  %r = icmp eq <vscale x 4 x i32> %a, %b
+  ret <vscale x 4 x i1> %r
+}
+
+define <vscale x 4 x i1> @fcmp(<vscale x 4 x float> %a, <vscale x 4 x float> %b) {
+; CHECK-LABEL: @fcmp
+; CHECK: %r = fcmp une <vscale x 4 x float> %a, %b
+; CHECK-NEXT: ret <vscale x 4 x i1> %r
+  %r = fcmp une <vscale x 4 x float> %a, %b
+  ret <vscale x 4 x i1> %r
+}
+
+define <vscale x 16 x i8> @phi(<vscale x 16 x i8> %a, i32 %val) {
+; CHECK-LABEL: @phi
+; CHECK: %r = phi <vscale x 16 x i8> [ %a, %entry ], [ %added, %iszero ]
+; CHECK-NEXT: ret <vscale x 16 x i8> %r
+entry:
+  %cmp = icmp eq i32 %val, 0
+  br i1 %cmp, label %iszero, label %end
+
+iszero:
+  %ins = insertelement <vscale x 16 x i8> undef, i8 1, i32 0
+  %splatone = shufflevector <vscale x 16 x i8> %ins, <vscale x 16 x i8> undef, <vscale x 16 x i32> zeroinitializer
+  %added = add <vscale x 16 x i8> %a, %splatone
+  br label %end
+
+end:
+  %r = phi <vscale x 16 x i8> [ %a, %entry ], [ %added, %iszero ]
+  ret <vscale x 16 x i8> %r
+}
+
+define <vscale x 8 x half> @select(<vscale x 8 x half> %a, <vscale x 8 x half> %b, <vscale x 8 x i1> %sval) {
+; CHECK-LABEL: @select
+; CHECK: %r = select <vscale x 8 x i1> %sval, <vscale x 8 x half> %a, <vscale x 8 x half> %b
+; CHECK-NEXT: ret <vscale x 8 x half> %r
+  %r = select <vscale x 8 x i1> %sval, <vscale x 8 x half> %a, <vscale x 8 x half> %b
+  ret <vscale x 8 x half> %r
+}
+
+declare <vscale x 4 x i32> @callee(<vscale x 4 x i32>)
+define <vscale x 4 x i32> @call(<vscale x 4 x i32> %val) {
+; CHECK-LABEL: @call
+; CHECK: %r = call <vscale x 4 x i32> @callee(<vscale x 4 x i32> %val)
+; CHECK-NEXT: ret <vscale x 4 x i32> %r
+  %r = call <vscale x 4 x i32> @callee(<vscale x 4 x i32> %val)
+  ret <vscale x 4 x i32> %r
+}
\ No newline at end of file

Modified: llvm/trunk/unittests/CodeGen/ScalableVectorMVTsTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/CodeGen/ScalableVectorMVTsTest.cpp?rev=374042&r1=374041&r2=374042&view=diff
==============================================================================
--- llvm/trunk/unittests/CodeGen/ScalableVectorMVTsTest.cpp (original)
+++ llvm/trunk/unittests/CodeGen/ScalableVectorMVTsTest.cpp Tue Oct  8 05:53:54 2019
@@ -10,7 +10,7 @@
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/Support/MachineValueType.h"
-#include "llvm/Support/ScalableSize.h"
+#include "llvm/Support/TypeSize.h"
 #include "gtest/gtest.h"
 
 using namespace llvm;

Modified: llvm/trunk/unittests/IR/VectorTypesTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/VectorTypesTest.cpp?rev=374042&r1=374041&r2=374042&view=diff
==============================================================================
--- llvm/trunk/unittests/IR/VectorTypesTest.cpp (original)
+++ llvm/trunk/unittests/IR/VectorTypesTest.cpp Tue Oct  8 05:53:54 2019
@@ -6,9 +6,10 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/LLVMContext.h"
-#include "llvm/Support/ScalableSize.h"
+#include "llvm/Support/TypeSize.h"
 #include "gtest/gtest.h"
 using namespace llvm;
 
@@ -161,4 +162,117 @@ TEST(VectorTypesTest, Scalable) {
   ASSERT_TRUE(EltCnt.Scalable);
 }
 
+TEST(VectorTypesTest, FixedLenComparisons) {
+  LLVMContext Ctx;
+  DataLayout DL("");
+
+  Type *Int32Ty = Type::getInt32Ty(Ctx);
+  Type *Int64Ty = Type::getInt64Ty(Ctx);
+
+  VectorType *V2Int32Ty = VectorType::get(Int32Ty, 2);
+  VectorType *V4Int32Ty = VectorType::get(Int32Ty, 4);
+
+  VectorType *V2Int64Ty = VectorType::get(Int64Ty, 2);
+
+  TypeSize V2I32Len = V2Int32Ty->getPrimitiveSizeInBits();
+  EXPECT_EQ(V2I32Len.getKnownMinSize(), 64U);
+  EXPECT_FALSE(V2I32Len.isScalable());
+
+  EXPECT_LT(V2Int32Ty->getPrimitiveSizeInBits(),
+            V4Int32Ty->getPrimitiveSizeInBits());
+  EXPECT_GT(V2Int64Ty->getPrimitiveSizeInBits(),
+            V2Int32Ty->getPrimitiveSizeInBits());
+  EXPECT_EQ(V4Int32Ty->getPrimitiveSizeInBits(),
+            V2Int64Ty->getPrimitiveSizeInBits());
+  EXPECT_NE(V2Int32Ty->getPrimitiveSizeInBits(),
+            V2Int64Ty->getPrimitiveSizeInBits());
+
+  // Check that a fixed-only comparison works for fixed size vectors.
+  EXPECT_EQ(V2Int64Ty->getPrimitiveSizeInBits().getFixedSize(),
+            V4Int32Ty->getPrimitiveSizeInBits().getFixedSize());
+
+  // Check the DataLayout interfaces.
+  EXPECT_EQ(DL.getTypeSizeInBits(V2Int64Ty),
+            DL.getTypeSizeInBits(V4Int32Ty));
+  EXPECT_EQ(DL.getTypeSizeInBits(V2Int32Ty), 64U);
+  EXPECT_EQ(DL.getTypeSizeInBits(V2Int64Ty), 128U);
+  EXPECT_EQ(DL.getTypeStoreSize(V2Int64Ty),
+            DL.getTypeStoreSize(V4Int32Ty));
+  EXPECT_NE(DL.getTypeStoreSizeInBits(V2Int32Ty),
+            DL.getTypeStoreSizeInBits(V2Int64Ty));
+  EXPECT_EQ(DL.getTypeStoreSizeInBits(V2Int32Ty), 64U);
+  EXPECT_EQ(DL.getTypeStoreSize(V2Int64Ty), 16U);
+  EXPECT_EQ(DL.getTypeAllocSize(V4Int32Ty),
+            DL.getTypeAllocSize(V2Int64Ty));
+  EXPECT_NE(DL.getTypeAllocSizeInBits(V2Int32Ty),
+            DL.getTypeAllocSizeInBits(V2Int64Ty));
+  EXPECT_EQ(DL.getTypeAllocSizeInBits(V4Int32Ty), 128U);
+  EXPECT_EQ(DL.getTypeAllocSize(V2Int32Ty), 8U);
+  ASSERT_TRUE(DL.typeSizeEqualsStoreSize(V4Int32Ty));
+}
+
+TEST(VectorTypesTest, ScalableComparisons) {
+  LLVMContext Ctx;
+  DataLayout DL("");
+
+  Type *Int32Ty = Type::getInt32Ty(Ctx);
+  Type *Int64Ty = Type::getInt64Ty(Ctx);
+
+  VectorType *ScV2Int32Ty = VectorType::get(Int32Ty, {2, true});
+  VectorType *ScV4Int32Ty = VectorType::get(Int32Ty, {4, true});
+
+  VectorType *ScV2Int64Ty = VectorType::get(Int64Ty, {2, true});
+
+  TypeSize ScV2I32Len = ScV2Int32Ty->getPrimitiveSizeInBits();
+  EXPECT_EQ(ScV2I32Len.getKnownMinSize(), 64U);
+  EXPECT_TRUE(ScV2I32Len.isScalable());
+
+  EXPECT_LT(ScV2Int32Ty->getPrimitiveSizeInBits(),
+            ScV4Int32Ty->getPrimitiveSizeInBits());
+  EXPECT_GT(ScV2Int64Ty->getPrimitiveSizeInBits(),
+            ScV2Int32Ty->getPrimitiveSizeInBits());
+  EXPECT_EQ(ScV4Int32Ty->getPrimitiveSizeInBits(),
+            ScV2Int64Ty->getPrimitiveSizeInBits());
+  EXPECT_NE(ScV2Int32Ty->getPrimitiveSizeInBits(),
+            ScV2Int64Ty->getPrimitiveSizeInBits());
+
+  // Check the DataLayout interfaces.
+  EXPECT_EQ(DL.getTypeSizeInBits(ScV2Int64Ty),
+            DL.getTypeSizeInBits(ScV4Int32Ty));
+  EXPECT_EQ(DL.getTypeSizeInBits(ScV2Int32Ty).getKnownMinSize(), 64U);
+  EXPECT_EQ(DL.getTypeStoreSize(ScV2Int64Ty),
+            DL.getTypeStoreSize(ScV4Int32Ty));
+  EXPECT_NE(DL.getTypeStoreSizeInBits(ScV2Int32Ty),
+            DL.getTypeStoreSizeInBits(ScV2Int64Ty));
+  EXPECT_EQ(DL.getTypeStoreSizeInBits(ScV2Int32Ty).getKnownMinSize(), 64U);
+  EXPECT_EQ(DL.getTypeStoreSize(ScV2Int64Ty).getKnownMinSize(), 16U);
+  EXPECT_EQ(DL.getTypeAllocSize(ScV4Int32Ty),
+            DL.getTypeAllocSize(ScV2Int64Ty));
+  EXPECT_NE(DL.getTypeAllocSizeInBits(ScV2Int32Ty),
+            DL.getTypeAllocSizeInBits(ScV2Int64Ty));
+  EXPECT_EQ(DL.getTypeAllocSizeInBits(ScV4Int32Ty).getKnownMinSize(), 128U);
+  EXPECT_EQ(DL.getTypeAllocSize(ScV2Int32Ty).getKnownMinSize(), 8U);
+  ASSERT_TRUE(DL.typeSizeEqualsStoreSize(ScV4Int32Ty));
+}
+
+TEST(VectorTypesTest, CrossComparisons) {
+  LLVMContext Ctx;
+
+  Type *Int32Ty = Type::getInt32Ty(Ctx);
+
+  VectorType *V4Int32Ty = VectorType::get(Int32Ty, {4, false});
+  VectorType *ScV4Int32Ty = VectorType::get(Int32Ty, {4, true});
+
+  // Even though the minimum size is the same, a scalable vector could be
+  // larger so we don't consider them to be the same size.
+  EXPECT_NE(V4Int32Ty->getPrimitiveSizeInBits(),
+            ScV4Int32Ty->getPrimitiveSizeInBits());
+  // If we are only checking the minimum, then they are the same size.
+  EXPECT_EQ(V4Int32Ty->getPrimitiveSizeInBits().getKnownMinSize(),
+            ScV4Int32Ty->getPrimitiveSizeInBits().getKnownMinSize());
+
+  // We can't use ordering comparisons (<,<=,>,>=) between scalable and
+  // non-scalable vector sizes.
+}
+
 } // end anonymous namespace




More information about the llvm-commits mailing list