[GlobalISel] Add unittests for LowLevelType.
authorAhmed Bougacha <ahmed.bougacha@gmail.com>
Fri, 29 Jul 2016 16:10:57 +0000 (16:10 +0000)
committerAhmed Bougacha <ahmed.bougacha@gmail.com>
Fri, 29 Jul 2016 16:10:57 +0000 (16:10 +0000)
llvm-svn: 277160

llvm/include/llvm/CodeGen/LowLevelType.h
llvm/unittests/CodeGen/CMakeLists.txt
llvm/unittests/CodeGen/LowLevelTypeTest.cpp [new file with mode: 0644]

index d2fde62..165a171 100644 (file)
@@ -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};
   }
 
index dd6bb0c..b9e4c4a 100644 (file)
@@ -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 (file)
index 0000000..37245bc
--- /dev/null
@@ -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());
+}
+}