diff options
-rw-r--r-- | llvm/include/llvm/CodeGen/LowLevelType.h | 1 | ||||
-rw-r--r-- | llvm/unittests/CodeGen/CMakeLists.txt | 1 | ||||
-rw-r--r-- | llvm/unittests/CodeGen/LowLevelTypeTest.cpp | 198 |
3 files changed, 200 insertions, 0 deletions
diff --git a/llvm/include/llvm/CodeGen/LowLevelType.h b/llvm/include/llvm/CodeGen/LowLevelType.h index d2fde627469..165a171bfb4 100644 --- a/llvm/include/llvm/CodeGen/LowLevelType.h +++ b/llvm/include/llvm/CodeGen/LowLevelType.h @@ -49,6 +49,7 @@ public: /// \brief get a low-level scalar or aggregate "bag of bits". static LLT scalar(unsigned SizeInBits) { + assert(SizeInBits > 0 && "invalid scalar size"); return LLT{Scalar, 1, SizeInBits}; } diff --git a/llvm/unittests/CodeGen/CMakeLists.txt b/llvm/unittests/CodeGen/CMakeLists.txt index dd6bb0c4bab..b9e4c4a50ad 100644 --- a/llvm/unittests/CodeGen/CMakeLists.txt +++ b/llvm/unittests/CodeGen/CMakeLists.txt @@ -5,6 +5,7 @@ set(LLVM_LINK_COMPONENTS set(CodeGenSources DIEHashTest.cpp + LowLevelTypeTest.cpp ) add_llvm_unittest(CodeGenTests diff --git a/llvm/unittests/CodeGen/LowLevelTypeTest.cpp b/llvm/unittests/CodeGen/LowLevelTypeTest.cpp new file mode 100644 index 00000000000..37245bcf6f4 --- /dev/null +++ b/llvm/unittests/CodeGen/LowLevelTypeTest.cpp @@ -0,0 +1,198 @@ +//===- llvm/unittest/CodeGen/GlobalISel/LowLevelTypeTest.cpp --------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/CodeGen/LowLevelType.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Type.h" +#include "gtest/gtest.h" + +using namespace llvm; + +// Define a pretty printer to help debugging when things go wrong. +namespace llvm { +std::ostream & +operator<<(std::ostream &OS, const llvm::LLT Ty) { + std::string Repr; + raw_string_ostream SS{Repr}; + Ty.print(SS); + OS << SS.str(); + return OS; +} +} + +namespace { + +TEST(LowLevelTypeTest, Scalar) { + LLVMContext C; + + for (unsigned S : {1U, 17U, 32U, 64U, 0xfffffU}) { + const LLT Ty = LLT::scalar(S); + const LLT HalfTy = Ty.halfScalarSize(); + const LLT DoubleTy = Ty.doubleScalarSize(); + + // Test kind. + for (const LLT TestTy : {Ty, HalfTy, DoubleTy}) { + ASSERT_TRUE(TestTy.isValid()); + ASSERT_TRUE(TestTy.isScalar()); + ASSERT_TRUE(TestTy.isSized()); + + ASSERT_FALSE(TestTy.isPointer()); + ASSERT_FALSE(TestTy.isVector()); + } + + // Test sizes. + EXPECT_EQ(S, Ty.getSizeInBits()); + EXPECT_EQ(S, Ty.getScalarSizeInBits()); + + // Is it OK to half an odd-sized scalar? It currently is. + EXPECT_EQ(S/2, HalfTy.getSizeInBits()); + EXPECT_EQ(S/2, HalfTy.getScalarSizeInBits()); + + EXPECT_EQ(S*2, DoubleTy.getSizeInBits()); + EXPECT_EQ(S*2, DoubleTy.getScalarSizeInBits()); + + // Test equality operators. + EXPECT_TRUE(Ty == Ty); + + // Test Type->LLT conversion. + const Type *IRTy = IntegerType::get(C, S); + EXPECT_EQ(Ty, LLT(*IRTy)); + } +} + +TEST(LowLevelTypeTest, Vector) { + LLVMContext C; + + for (unsigned S : {1U, 17U, 32U, 64U, 0xfffU}) { + for (uint16_t Elts : {2U, 3U, 4U, 32U, 0xffU}) { + const LLT STy = LLT::scalar(S); + const LLT VTy = LLT::vector(Elts, S); + + // Test the alternative vector(). + { + const LLT VSTy = LLT::vector(Elts, STy); + EXPECT_EQ(VTy, VSTy); + } + + // Test getElementType(). + EXPECT_EQ(STy, VTy.getElementType()); + + const LLT HalfSzTy = VTy.halfScalarSize(); + const LLT DoubleSzTy = VTy.doubleScalarSize(); + + // halfElements requires an even number of elements. + const LLT HalfEltIfEvenTy = ((Elts % 2) == 0) ? VTy.halfElements() : VTy; + const LLT DoubleEltTy = VTy.doubleElements(); + + // Test kind. + for (const LLT TestTy : {VTy, HalfSzTy, DoubleSzTy, DoubleEltTy}) { + ASSERT_TRUE(TestTy.isValid()); + ASSERT_TRUE(TestTy.isSized()); + ASSERT_TRUE(TestTy.isVector()); + + ASSERT_FALSE(TestTy.isScalar()); + ASSERT_FALSE(TestTy.isPointer()); + } + + // Test halving elements to a scalar. + { + ASSERT_TRUE(HalfEltIfEvenTy.isValid()); + ASSERT_TRUE(HalfEltIfEvenTy.isSized()); + ASSERT_FALSE(HalfEltIfEvenTy.isPointer()); + if (Elts > 2) { + ASSERT_TRUE(HalfEltIfEvenTy.isVector()); + } else { + ASSERT_FALSE(HalfEltIfEvenTy.isVector()); + EXPECT_EQ(STy, HalfEltIfEvenTy); + } + } + + + // Test sizes. + EXPECT_EQ(S * Elts, VTy.getSizeInBits()); + EXPECT_EQ(S, VTy.getScalarSizeInBits()); + EXPECT_EQ(Elts, VTy.getNumElements()); + + EXPECT_EQ((S / 2) * Elts, HalfSzTy.getSizeInBits()); + EXPECT_EQ(S / 2, HalfSzTy.getScalarSizeInBits()); + EXPECT_EQ(Elts, HalfSzTy.getNumElements()); + + EXPECT_EQ((S * 2) * Elts, DoubleSzTy.getSizeInBits()); + EXPECT_EQ(S * 2, DoubleSzTy.getScalarSizeInBits()); + EXPECT_EQ(Elts, DoubleSzTy.getNumElements()); + + if ((Elts % 2) == 0) { + EXPECT_EQ(S * (Elts / 2), HalfEltIfEvenTy.getSizeInBits()); + EXPECT_EQ(S, HalfEltIfEvenTy.getScalarSizeInBits()); + if (Elts > 2) + EXPECT_EQ(Elts / 2, HalfEltIfEvenTy.getNumElements()); + } + + EXPECT_EQ(S * (Elts * 2), DoubleEltTy.getSizeInBits()); + EXPECT_EQ(S, DoubleEltTy.getScalarSizeInBits()); + EXPECT_EQ(Elts * 2, DoubleEltTy.getNumElements()); + + // Test equality operators. + EXPECT_TRUE(VTy == VTy); + + // Test Type->LLT conversion. + Type *IRSTy = IntegerType::get(C, S); + const Type *IRTy = VectorType::get(IRSTy, Elts); + EXPECT_EQ(VTy, LLT(*IRTy)); + } + } +} + +TEST(LowLevelTypeTest, Pointer) { + LLVMContext C; + + for (unsigned AS : {0U, 1U, 127U, 0xffffU}) { + const LLT Ty = LLT::pointer(AS); + + // Test kind. + ASSERT_TRUE(Ty.isValid()); + ASSERT_TRUE(Ty.isPointer()); + + ASSERT_FALSE(Ty.isSized()); + ASSERT_FALSE(Ty.isScalar()); + ASSERT_FALSE(Ty.isVector()); + + // Test addressspace. + EXPECT_EQ(AS, Ty.getAddressSpace()); + + // Test equality operators. + EXPECT_TRUE(Ty == Ty); + + // Test Type->LLT conversion. + const Type *IRTy = PointerType::get(IntegerType::get(C, 8), AS); + EXPECT_EQ(Ty, LLT(*IRTy)); + } +} + +TEST(LowLevelTypeTest, Invalid) { + const LLT Ty; + + ASSERT_FALSE(Ty.isValid()); + ASSERT_FALSE(Ty.isScalar()); + ASSERT_FALSE(Ty.isSized()); + ASSERT_FALSE(Ty.isPointer()); + ASSERT_FALSE(Ty.isVector()); +} + +TEST(LowLevelTypeTest, Unsized) { + const LLT Ty = LLT::unsized(); + + ASSERT_TRUE(Ty.isValid()); + ASSERT_FALSE(Ty.isScalar()); + ASSERT_FALSE(Ty.isSized()); + ASSERT_FALSE(Ty.isPointer()); + ASSERT_FALSE(Ty.isVector()); +} +} |