summaryrefslogtreecommitdiff
path: root/unittests
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2013-06-10 20:36:52 +0000
committerDimitry Andric <dim@FreeBSD.org>2013-06-10 20:36:52 +0000
commit59d6cff90eecf31cb3dd860c4e786674cfdd42eb (patch)
tree909310b2e05119d1d6efda049977042abbb58bb1 /unittests
parent4a16efa3e43e35f0cc9efe3a67f620f0017c3d36 (diff)
downloadsrc-test2-59d6cff90eecf31cb3dd860c4e786674cfdd42eb.tar.gz
src-test2-59d6cff90eecf31cb3dd860c4e786674cfdd42eb.zip
Notes
Diffstat (limited to 'unittests')
-rw-r--r--unittests/CMakeLists.txt1
-rw-r--r--unittests/DebugInfo/CMakeLists.txt13
-rw-r--r--unittests/DebugInfo/DWARFFormValueTest.cpp31
-rw-r--r--unittests/DebugInfo/Makefile16
-rw-r--r--unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp3
-rw-r--r--unittests/ExecutionEngine/JIT/JITTest.cpp34
-rw-r--r--unittests/ExecutionEngine/JIT/MultiJITTest.cpp8
-rw-r--r--unittests/ExecutionEngine/MCJIT/CMakeLists.txt2
-rw-r--r--unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp97
-rw-r--r--unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp240
-rw-r--r--unittests/ExecutionEngine/MCJIT/MCJITTestAPICommon.h77
-rw-r--r--unittests/ExecutionEngine/MCJIT/MCJITTestBase.h50
-rw-r--r--unittests/ExecutionEngine/Makefile5
-rw-r--r--unittests/IR/CMakeLists.txt2
-rw-r--r--unittests/IR/PatternMatch.cpp265
-rw-r--r--unittests/IR/ValueTest.cpp46
-rw-r--r--unittests/Makefile3
-rw-r--r--unittests/Support/CMakeLists.txt2
-rw-r--r--unittests/Support/CommandLineTest.cpp52
-rw-r--r--unittests/Support/CompressionTest.cpp68
-rw-r--r--unittests/Support/Path.cpp12
-rw-r--r--unittests/Support/ProgramTest.cpp89
-rw-r--r--unittests/Transforms/Utils/Cloning.cpp32
23 files changed, 1064 insertions, 84 deletions
diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt
index a3f8bf34e731..4b7e418cd180 100644
--- a/unittests/CMakeLists.txt
+++ b/unittests/CMakeLists.txt
@@ -13,3 +13,4 @@ add_subdirectory(Option)
add_subdirectory(Support)
add_subdirectory(Transforms)
add_subdirectory(IR)
+add_subdirectory(DebugInfo)
diff --git a/unittests/DebugInfo/CMakeLists.txt b/unittests/DebugInfo/CMakeLists.txt
new file mode 100644
index 000000000000..ec580b7f69a4
--- /dev/null
+++ b/unittests/DebugInfo/CMakeLists.txt
@@ -0,0 +1,13 @@
+set(LLVM_LINK_COMPONENTS
+ debuginfo
+ object
+ support
+ )
+
+set(DebugInfoSources
+ DWARFFormValueTest.cpp
+ )
+
+add_llvm_unittest(DebugInfoTests
+ ${DebugInfoSources}
+ )
diff --git a/unittests/DebugInfo/DWARFFormValueTest.cpp b/unittests/DebugInfo/DWARFFormValueTest.cpp
new file mode 100644
index 000000000000..04b859bdb9db
--- /dev/null
+++ b/unittests/DebugInfo/DWARFFormValueTest.cpp
@@ -0,0 +1,31 @@
+//===- llvm/unittest/DebugInfo/DWARFFormValueTest.cpp ---------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/DWARFFormValue.h"
+#include "llvm/Support/Dwarf.h"
+#include "gtest/gtest.h"
+using namespace llvm;
+using namespace dwarf;
+
+namespace {
+
+TEST(DWARFFormValue, FixedFormSizes) {
+ // Size of DW_FORM_addr and DW_FORM_ref_addr are equal in DWARF2,
+ // DW_FORM_ref_addr is always 4 bytes in DWARF32 starting from DWARF3.
+ const uint8_t *sizes = DWARFFormValue::getFixedFormSizes(4, 2);
+ EXPECT_EQ(sizes[DW_FORM_addr], sizes[DW_FORM_ref_addr]);
+ sizes = DWARFFormValue::getFixedFormSizes(8, 2);
+ EXPECT_EQ(sizes[DW_FORM_addr], sizes[DW_FORM_ref_addr]);
+ sizes = DWARFFormValue::getFixedFormSizes(8, 3);
+ EXPECT_EQ(4, sizes[DW_FORM_ref_addr]);
+ // Check that we don't have fixed form sizes for weird address sizes.
+ EXPECT_EQ(0, DWARFFormValue::getFixedFormSizes(16, 2));
+}
+
+} // end anonymous namespace
diff --git a/unittests/DebugInfo/Makefile b/unittests/DebugInfo/Makefile
new file mode 100644
index 000000000000..999ded90b0f6
--- /dev/null
+++ b/unittests/DebugInfo/Makefile
@@ -0,0 +1,16 @@
+##===- unittests/DebugInfo/Makefile ------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../..
+TESTNAME = DebugInfo
+LINK_COMPONENTS := debuginfo object support
+
+include $(LEVEL)/Makefile.config
+
+include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
diff --git a/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp b/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp
index 6ba8bc42d12c..87f482444f41 100644
--- a/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp
+++ b/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp
@@ -74,6 +74,8 @@ class JITEventListenerTest : public testing::Test {
const OwningPtr<ExecutionEngine> EE;
};
+// Tests on SystemZ disabled as we're running the old JIT
+#if !defined(__s390__)
Function *buildFunction(Module *M) {
Function *Result = Function::Create(
TypeBuilder<int32_t(int32_t), false>::get(getGlobalContext()),
@@ -224,6 +226,7 @@ TEST_F(JITEventListenerTest, MatchesMachineCodeInfo) {
EXPECT_EQ(1U, Listener.FreedEvents[0].Index);
EXPECT_EQ(F_addr, Listener.FreedEvents[0].Code);
}
+#endif
class JITEnvironment : public testing::Environment {
virtual void SetUp() {
diff --git a/unittests/ExecutionEngine/JIT/JITTest.cpp b/unittests/ExecutionEngine/JIT/JITTest.cpp
index 30dadc9f3e3b..e6f4cb9af25f 100644
--- a/unittests/ExecutionEngine/JIT/JITTest.cpp
+++ b/unittests/ExecutionEngine/JIT/JITTest.cpp
@@ -35,6 +35,9 @@ using namespace llvm;
namespace {
+// Tests on ARM, PowerPC and SystemZ disabled as we're running the old jit
+#if !defined(__arm__) && !defined(__powerpc__) && !defined(__s390__)
+
Function *makeReturnGlobal(std::string Name, GlobalVariable *G, Module *M) {
std::vector<Type*> params;
FunctionType *FTy = FunctionType::get(G->getType()->getElementType(),
@@ -231,9 +234,6 @@ class JITTest : public testing::Test {
OwningPtr<ExecutionEngine> TheJIT;
};
-// Tests on ARM and PowerPC disabled as we're running the old jit
-#if !defined(__arm__) && !defined(__powerpc__)
-
// Regression test for a bug. The JIT used to allocate globals inside the same
// memory block used for the function, and when the function code was freed,
// the global was left in the same place. This test allocates a function
@@ -302,8 +302,6 @@ TEST(JIT, GlobalInFunction) {
EXPECT_EQ(3, *GPtr);
}
-#endif // !defined(__arm__) && !defined(__powerpc__)
-
// Regression test for a bug. The JITEmitter wasn't checking to verify that
// it hadn't run out of space while generating the DWARF exception information
// for an emitted function.
@@ -348,8 +346,6 @@ int PlusOne(int arg) {
return arg + 1;
}
-// ARM and PowerPC tests disabled pending fix for PR10783.
-#if !defined(__arm__) && !defined(__powerpc__)
TEST_F(JITTest, FarCallToKnownFunction) {
// x86-64 can only make direct calls to functions within 32 bits of
// the current PC. To call anything farther away, we have to load
@@ -527,7 +523,6 @@ TEST_F(JITTest, ModuleDeletion) {
EXPECT_EQ(RJMM->startExceptionTableCalls.size(),
NumTablesDeallocated);
}
-#endif // !defined(__arm__) && !defined(__powerpc__)
// ARM, MIPS and PPC still emit stubs for calls since the target may be
// too far away to call directly. This #if can probably be removed when
@@ -573,9 +568,6 @@ TEST_F(JITTest, NoStubs) {
}
#endif // !ARM && !PPC
-// Tests on ARM and PowerPC disabled as we're running the old jit
-#if !defined(__arm__) && !defined(__powerpc__)
-
TEST_F(JITTest, FunctionPointersOutliveTheirCreator) {
TheJIT->DisableLazyCompilation(true);
LoadAssembly("define i8()* @get_foo_addr() { "
@@ -610,13 +602,9 @@ TEST_F(JITTest, FunctionPointersOutliveTheirCreator) {
#endif
}
-#endif //!defined(__arm__) && !defined(__powerpc__)
-
-// Tests on ARM and PowerPC disabled as we're running the old jit
-// In addition, ARM does not have an implementation
-// of replaceMachineCodeForFunction(), so recompileAndRelinkFunction
-// doesn't work.
-#if !defined(__arm__) && !defined(__powerpc__)
+// ARM does not have an implementation of replaceMachineCodeForFunction(),
+// so recompileAndRelinkFunction doesn't work.
+#if !defined(__arm__)
TEST_F(JITTest, FunctionIsRecompiledAndRelinked) {
Function *F = Function::Create(TypeBuilder<int(void), false>::get(Context),
GlobalValue::ExternalLinkage, "test", M);
@@ -647,7 +635,7 @@ TEST_F(JITTest, FunctionIsRecompiledAndRelinked) {
EXPECT_EQ(2, OrigFPtr())
<< "The old pointer's target should now jump to the new version";
}
-#endif // !defined(__arm__) && !defined(__powerpc__)
+#endif // !defined(__arm__)
} // anonymous namespace
// This variable is intentionally defined differently in the statically-compiled
@@ -657,9 +645,6 @@ extern "C" int32_t JITTest_AvailableExternallyGlobal;
int32_t JITTest_AvailableExternallyGlobal LLVM_ATTRIBUTE_USED = 42;
namespace {
-// Tests on ARM and PowerPC disabled as we're running the old jit
-#if !defined(__arm__) && !defined(__powerpc__)
-
TEST_F(JITTest, AvailableExternallyGlobalIsntEmitted) {
TheJIT->DisableLazyCompilation(true);
LoadAssembly("@JITTest_AvailableExternallyGlobal = "
@@ -676,7 +661,6 @@ TEST_F(JITTest, AvailableExternallyGlobalIsntEmitted) {
EXPECT_EQ(42, loader()) << "func should return 42 from the external global,"
<< " not 7 from the IR version.";
}
-#endif //!defined(__arm__) && !defined(__powerpc__)
} // anonymous namespace
// This function is intentionally defined differently in the statically-compiled
// program from the IR input to the JIT to assert that the JIT doesn't use its
@@ -687,8 +671,6 @@ extern "C" int32_t JITTest_AvailableExternallyFunction() {
}
namespace {
-// ARM and PowerPC tests disabled pending fix for PR10783.
-#if !defined(__arm__) && !defined(__powerpc__)
TEST_F(JITTest, AvailableExternallyFunctionIsntCompiled) {
TheJIT->DisableLazyCompilation(true);
LoadAssembly("define available_externally i32 "
@@ -844,7 +826,7 @@ TEST(LazyLoadedJITTest, EagerCompiledRecursionThroughGhost) {
(intptr_t)TheJIT->getPointerToFunction(recur1IR));
EXPECT_EQ(3, recur1(4));
}
-#endif // !defined(__arm__) && !defined(__powerpc__)
+#endif // !defined(__arm__) && !defined(__powerpc__) && !defined(__s390__)
// This code is copied from JITEventListenerTest, but it only runs once for all
// the tests in this directory. Everything seems fine, but that's strange
diff --git a/unittests/ExecutionEngine/JIT/MultiJITTest.cpp b/unittests/ExecutionEngine/JIT/MultiJITTest.cpp
index 53014672c268..4018cd5ce2f2 100644
--- a/unittests/ExecutionEngine/JIT/MultiJITTest.cpp
+++ b/unittests/ExecutionEngine/JIT/MultiJITTest.cpp
@@ -20,6 +20,9 @@ using namespace llvm;
namespace {
+// ARM, PowerPC and SystemZ tests disabled pending fix for PR10783.
+#if !defined(__arm__) && !defined(__powerpc__) && !defined(__s390__)
+
bool LoadAssemblyInto(Module *M, const char *assembly) {
SMDiagnostic Error;
bool success =
@@ -65,9 +68,6 @@ void createModule2(LLVMContext &Context2, Module *&M2, Function *&FooF2) {
FooF2 = M2->getFunction("foo2");
}
-// ARM and PowerPC tests disabled pending fix for PR10783.
-#if !defined(__arm__) && !defined(__powerpc__)
-
TEST(MultiJitTest, EagerMode) {
LLVMContext Context1;
Module *M1 = 0;
@@ -176,6 +176,6 @@ TEST(MultiJitTest, JitPool) {
#endif
EXPECT_TRUE(sa == fa);
}
-#endif // !defined(__arm__) && !defined(__powerpc__)
+#endif // !defined(__arm__) && !defined(__powerpc__) && !defined(__s390__)
} // anonymous namespace
diff --git a/unittests/ExecutionEngine/MCJIT/CMakeLists.txt b/unittests/ExecutionEngine/MCJIT/CMakeLists.txt
index c6b1f77e3e8b..922cb7efd5eb 100644
--- a/unittests/ExecutionEngine/MCJIT/CMakeLists.txt
+++ b/unittests/ExecutionEngine/MCJIT/CMakeLists.txt
@@ -9,7 +9,9 @@ set(LLVM_LINK_COMPONENTS
set(MCJITTestsSources
MCJITTest.cpp
+ MCJITCAPITest.cpp
MCJITMemoryManagerTest.cpp
+ MCJITObjectCacheTest.cpp
)
if(MSVC)
diff --git a/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp b/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp
new file mode 100644
index 000000000000..07ea1afe1a85
--- /dev/null
+++ b/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp
@@ -0,0 +1,97 @@
+//===- MCJITTest.cpp - Unit tests for the MCJIT ---------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This test suite verifies basic MCJIT functionality when invoked form the C
+// API.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm-c/Analysis.h"
+#include "llvm-c/Core.h"
+#include "llvm-c/ExecutionEngine.h"
+#include "llvm-c/Target.h"
+#include "llvm-c/Transforms/Scalar.h"
+#include "llvm/Support/Host.h"
+#include "MCJITTestAPICommon.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+class MCJITCAPITest : public testing::Test, public MCJITTestAPICommon {
+protected:
+ MCJITCAPITest() {
+ // The architectures below are known to be compatible with MCJIT as they
+ // are copied from test/ExecutionEngine/MCJIT/lit.local.cfg and should be
+ // kept in sync.
+ SupportedArchs.push_back(Triple::arm);
+ SupportedArchs.push_back(Triple::mips);
+ SupportedArchs.push_back(Triple::x86);
+ SupportedArchs.push_back(Triple::x86_64);
+
+ // The operating systems below are known to be sufficiently incompatible
+ // that they will fail the MCJIT C API tests.
+ UnsupportedOSs.push_back(Triple::Cygwin);
+ }
+};
+
+TEST_F(MCJITCAPITest, simple_function) {
+ SKIP_UNSUPPORTED_PLATFORM;
+
+ char *error = 0;
+
+ // Creates a function that returns 42, compiles it, and runs it.
+
+ LLVMModuleRef module = LLVMModuleCreateWithName("simple_module");
+
+ LLVMSetTarget(module, HostTriple.c_str());
+
+ LLVMValueRef function = LLVMAddFunction(
+ module, "simple_function", LLVMFunctionType(LLVMInt32Type(), 0, 0, 0));
+ LLVMSetFunctionCallConv(function, LLVMCCallConv);
+
+ LLVMBasicBlockRef entry = LLVMAppendBasicBlock(function, "entry");
+ LLVMBuilderRef builder = LLVMCreateBuilder();
+ LLVMPositionBuilderAtEnd(builder, entry);
+ LLVMBuildRet(builder, LLVMConstInt(LLVMInt32Type(), 42, 0));
+
+ LLVMVerifyModule(module, LLVMAbortProcessAction, &error);
+ LLVMDisposeMessage(error);
+
+ LLVMDisposeBuilder(builder);
+
+ LLVMMCJITCompilerOptions options;
+ LLVMInitializeMCJITCompilerOptions(&options, sizeof(options));
+ options.OptLevel = 2;
+
+ // Just ensure that this field still exists.
+ options.NoFramePointerElim = false;
+
+ LLVMExecutionEngineRef engine;
+ ASSERT_EQ(
+ 0, LLVMCreateMCJITCompilerForModule(&engine, module, &options,
+ sizeof(options), &error));
+
+ LLVMPassManagerRef pass = LLVMCreatePassManager();
+ LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), pass);
+ LLVMAddConstantPropagationPass(pass);
+ LLVMAddInstructionCombiningPass(pass);
+ LLVMRunPassManager(pass, module);
+ LLVMDisposePassManager(pass);
+
+ union {
+ void *raw;
+ int (*usable)();
+ } functionPointer;
+ functionPointer.raw = LLVMGetPointerToGlobal(engine, function);
+
+ EXPECT_EQ(42, functionPointer.usable());
+
+ LLVMDisposeExecutionEngine(engine);
+}
+
diff --git a/unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp b/unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp
new file mode 100644
index 000000000000..0061e30e7a54
--- /dev/null
+++ b/unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp
@@ -0,0 +1,240 @@
+//===- MCJITObjectCacheTest.cpp - Unit tests for MCJIT object caching -----===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/ExecutionEngine/JIT.h"
+#include "llvm/ExecutionEngine/MCJIT.h"
+#include "llvm/ExecutionEngine/ObjectCache.h"
+#include "llvm/ExecutionEngine/SectionMemoryManager.h"
+#include "MCJITTestBase.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+class TestObjectCache : public ObjectCache {
+public:
+ TestObjectCache() : DuplicateInserted(false) { }
+
+ virtual ~TestObjectCache() {
+ // Free any buffers we've allocated.
+ SmallVector<MemoryBuffer *, 2>::iterator it, end;
+ end = AllocatedBuffers.end();
+ for (it = AllocatedBuffers.begin(); it != end; ++it) {
+ delete *it;
+ }
+ AllocatedBuffers.clear();
+ }
+
+ virtual void notifyObjectCompiled(const Module *M, const MemoryBuffer *Obj) {
+ // If we've seen this module before, note that.
+ const std::string ModuleID = M->getModuleIdentifier();
+ if (ObjMap.find(ModuleID) != ObjMap.end())
+ DuplicateInserted = true;
+ // Store a copy of the buffer in our map.
+ ObjMap[ModuleID] = copyBuffer(Obj);
+ }
+
+ // Test-harness-specific functions
+ bool wereDuplicatesInserted() { return DuplicateInserted; }
+
+ bool wasModuleLookedUp(const Module *M) {
+ return ModulesLookedUp.find(M->getModuleIdentifier())
+ != ModulesLookedUp.end();
+ }
+
+ const MemoryBuffer* getObjectInternal(const Module* M) {
+ // Look for the module in our map.
+ const std::string ModuleID = M->getModuleIdentifier();
+ StringMap<const MemoryBuffer *>::iterator it = ObjMap.find(ModuleID);
+ if (it == ObjMap.end())
+ return 0;
+ return it->second;
+ }
+
+protected:
+ virtual const MemoryBuffer* getObject(const Module* M) {
+ const MemoryBuffer* BufferFound = getObjectInternal(M);
+ ModulesLookedUp.insert(M->getModuleIdentifier());
+ return BufferFound;
+ }
+
+private:
+ MemoryBuffer *copyBuffer(const MemoryBuffer *Buf) {
+ // Create a local copy of the buffer.
+ MemoryBuffer *NewBuffer = MemoryBuffer::getMemBufferCopy(Buf->getBuffer());
+ AllocatedBuffers.push_back(NewBuffer);
+ return NewBuffer;
+ }
+
+ StringMap<const MemoryBuffer *> ObjMap;
+ StringSet<> ModulesLookedUp;
+ SmallVector<MemoryBuffer *, 2> AllocatedBuffers;
+ bool DuplicateInserted;
+};
+
+class MCJITObjectCacheTest : public testing::Test, public MCJITTestBase {
+protected:
+
+ enum {
+ OriginalRC = 6,
+ ReplacementRC = 7
+ };
+
+ virtual void SetUp() {
+ M.reset(createEmptyModule("<main>"));
+ Main = insertMainFunction(M.get(), OriginalRC);
+ }
+
+ void compileAndRun(int ExpectedRC = OriginalRC) {
+ // This function shouldn't be called until after SetUp.
+ ASSERT_TRUE(0 != TheJIT);
+ ASSERT_TRUE(0 != Main);
+
+ TheJIT->finalizeObject();
+ void *vPtr = TheJIT->getPointerToFunction(Main);
+
+ static_cast<SectionMemoryManager*>(MM)->invalidateInstructionCache();
+
+ EXPECT_TRUE(0 != vPtr)
+ << "Unable to get pointer to main() from JIT";
+
+ int (*FuncPtr)(void) = (int(*)(void))(intptr_t)vPtr;
+ int returnCode = FuncPtr();
+ EXPECT_EQ(returnCode, ExpectedRC);
+ }
+
+ Function *Main;
+};
+
+TEST_F(MCJITObjectCacheTest, SetNullObjectCache) {
+ SKIP_UNSUPPORTED_PLATFORM;
+
+ createJIT(M.take());
+
+ TheJIT->setObjectCache(NULL);
+
+ compileAndRun();
+}
+
+
+TEST_F(MCJITObjectCacheTest, VerifyBasicObjectCaching) {
+ SKIP_UNSUPPORTED_PLATFORM;
+
+ OwningPtr<TestObjectCache> Cache(new TestObjectCache);
+
+ // Save a copy of the module pointer before handing it off to MCJIT.
+ const Module * SavedModulePointer = M.get();
+
+ createJIT(M.take());
+
+ TheJIT->setObjectCache(Cache.get());
+
+ // Verify that our object cache does not contain the module yet.
+ const MemoryBuffer *ObjBuffer = Cache->getObjectInternal(SavedModulePointer);
+ EXPECT_EQ(0, ObjBuffer);
+
+ compileAndRun();
+
+ // Verify that MCJIT tried to look-up this module in the cache.
+ EXPECT_TRUE(Cache->wasModuleLookedUp(SavedModulePointer));
+
+ // Verify that our object cache now contains the module.
+ ObjBuffer = Cache->getObjectInternal(SavedModulePointer);
+ EXPECT_TRUE(0 != ObjBuffer);
+
+ // Verify that the cache was only notified once.
+ EXPECT_FALSE(Cache->wereDuplicatesInserted());
+}
+
+TEST_F(MCJITObjectCacheTest, VerifyLoadFromCache) {
+ SKIP_UNSUPPORTED_PLATFORM;
+
+ OwningPtr<TestObjectCache> Cache(new TestObjectCache);
+
+ // Compile this module with an MCJIT engine
+ createJIT(M.take());
+ TheJIT->setObjectCache(Cache.get());
+ TheJIT->finalizeObject();
+
+ // Destroy the MCJIT engine we just used
+ TheJIT.reset();
+
+ // Create a new memory manager.
+ MM = new SectionMemoryManager;
+
+ // Create a new module and save it. Use a different return code so we can
+ // tell if MCJIT compiled this module or used the cache.
+ M.reset(createEmptyModule("<main>"));
+ Main = insertMainFunction(M.get(), ReplacementRC);
+ const Module * SecondModulePointer = M.get();
+
+ // Create a new MCJIT instance to load this module then execute it.
+ createJIT(M.take());
+ TheJIT->setObjectCache(Cache.get());
+ compileAndRun();
+
+ // Verify that MCJIT tried to look-up this module in the cache.
+ EXPECT_TRUE(Cache->wasModuleLookedUp(SecondModulePointer));
+
+ // Verify that MCJIT didn't try to cache this again.
+ EXPECT_FALSE(Cache->wereDuplicatesInserted());
+}
+
+TEST_F(MCJITObjectCacheTest, VerifyNonLoadFromCache) {
+ SKIP_UNSUPPORTED_PLATFORM;
+
+ OwningPtr<TestObjectCache> Cache(new TestObjectCache);
+
+ // Compile this module with an MCJIT engine
+ createJIT(M.take());
+ TheJIT->setObjectCache(Cache.get());
+ TheJIT->finalizeObject();
+
+ // Destroy the MCJIT engine we just used
+ TheJIT.reset();
+
+ // Create a new memory manager.
+ MM = new SectionMemoryManager;
+
+ // Create a new module and save it. Use a different return code so we can
+ // tell if MCJIT compiled this module or used the cache. Note that we use
+ // a new module name here so the module shouldn't be found in the cache.
+ M.reset(createEmptyModule("<not-main>"));
+ Main = insertMainFunction(M.get(), ReplacementRC);
+ const Module * SecondModulePointer = M.get();
+
+ // Create a new MCJIT instance to load this module then execute it.
+ createJIT(M.take());
+ TheJIT->setObjectCache(Cache.get());
+
+ // Verify that our object cache does not contain the module yet.
+ const MemoryBuffer *ObjBuffer = Cache->getObjectInternal(SecondModulePointer);
+ EXPECT_EQ(0, ObjBuffer);
+
+ // Run the function and look for the replacement return code.
+ compileAndRun(ReplacementRC);
+
+ // Verify that MCJIT tried to look-up this module in the cache.
+ EXPECT_TRUE(Cache->wasModuleLookedUp(SecondModulePointer));
+
+ // Verify that our object cache now contains the module.
+ ObjBuffer = Cache->getObjectInternal(SecondModulePointer);
+ EXPECT_TRUE(0 != ObjBuffer);
+
+ // Verify that MCJIT didn't try to cache this again.
+ EXPECT_FALSE(Cache->wereDuplicatesInserted());
+}
+
+} // Namespace
+
diff --git a/unittests/ExecutionEngine/MCJIT/MCJITTestAPICommon.h b/unittests/ExecutionEngine/MCJIT/MCJITTestAPICommon.h
new file mode 100644
index 000000000000..8160a186f413
--- /dev/null
+++ b/unittests/ExecutionEngine/MCJIT/MCJITTestAPICommon.h
@@ -0,0 +1,77 @@
+//===- MCJITTestBase.h - Common base class for MCJIT Unit tests ----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class implements functionality shared by both MCJIT C API tests, and
+// the C++ API tests.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MCJIT_TEST_API_COMMON_H
+#define MCJIT_TEST_API_COMMON_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/TargetSelect.h"
+
+// Used to skip tests on unsupported architectures and operating systems.
+// To skip a test, add this macro at the top of a test-case in a suite that
+// inherits from MCJITTestBase. See MCJITTest.cpp for examples.
+#define SKIP_UNSUPPORTED_PLATFORM \
+ do \
+ if (!ArchSupportsMCJIT() || !OSSupportsMCJIT()) \
+ return; \
+ while(0)
+
+namespace llvm {
+
+class MCJITTestAPICommon {
+protected:
+ MCJITTestAPICommon()
+ : HostTriple(sys::getProcessTriple())
+ {
+ InitializeNativeTarget();
+ InitializeNativeTargetAsmPrinter();
+
+#ifdef LLVM_ON_WIN32
+ // On Windows, generate ELF objects by specifying "-elf" in triple
+ HostTriple += "-elf";
+#endif // LLVM_ON_WIN32
+ HostTriple = Triple::normalize(HostTriple);
+ }
+
+ /// Returns true if the host architecture is known to support MCJIT
+ bool ArchSupportsMCJIT() {
+ Triple Host(HostTriple);
+ if (std::find(SupportedArchs.begin(), SupportedArchs.end(), Host.getArch())
+ == SupportedArchs.end()) {
+ return false;
+ }
+ return true;
+ }
+
+ /// Returns true if the host OS is known to support MCJIT
+ bool OSSupportsMCJIT() {
+ Triple Host(HostTriple);
+ if (std::find(UnsupportedOSs.begin(), UnsupportedOSs.end(), Host.getOS())
+ == UnsupportedOSs.end()) {
+ return true;
+ }
+ return false;
+ }
+
+ std::string HostTriple;
+ SmallVector<Triple::ArchType, 4> SupportedArchs;
+ SmallVector<Triple::OSType, 4> UnsupportedOSs;
+};
+
+} // namespace llvm
+
+#endif // MCJIT_TEST_API_COMMON_H
+
diff --git a/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h b/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h
index fc774abd6215..b0e98a88defc 100644
--- a/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h
+++ b/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h
@@ -17,8 +17,6 @@
#ifndef MCJIT_TEST_BASE_H
#define MCJIT_TEST_BASE_H
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/Config/config.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
@@ -28,21 +26,11 @@
#include "llvm/IR/Module.h"
#include "llvm/IR/TypeBuilder.h"
#include "llvm/Support/CodeGen.h"
-#include "llvm/Support/Host.h"
-#include "llvm/Support/TargetSelect.h"
-
-// Used to skip tests on unsupported architectures and operating systems.
-// To skip a test, add this macro at the top of a test-case in a suite that
-// inherits from MCJITTestBase. See MCJITTest.cpp for examples.
-#define SKIP_UNSUPPORTED_PLATFORM \
- do \
- if (!ArchSupportsMCJIT() || !OSSupportsMCJIT()) \
- return; \
- while(0);
+#include "MCJITTestAPICommon.h"
namespace llvm {
-class MCJITTestBase {
+class MCJITTestBase : public MCJITTestAPICommon {
protected:
MCJITTestBase()
@@ -52,17 +40,7 @@ protected:
, MArch("")
, Builder(Context)
, MM(new SectionMemoryManager)
- , HostTriple(sys::getProcessTriple())
{
- InitializeNativeTarget();
- InitializeNativeTargetAsmPrinter();
-
-#ifdef LLVM_ON_WIN32
- // On Windows, generate ELF objects by specifying "-elf" in triple
- HostTriple += "-elf";
-#endif // LLVM_ON_WIN32
- HostTriple = Triple::normalize(HostTriple);
-
// The architectures below are known to be compatible with MCJIT as they
// are copied from test/ExecutionEngine/MCJIT/lit.local.cfg and should be
// kept in sync.
@@ -78,26 +56,6 @@ protected:
UnsupportedOSs.push_back(Triple::Darwin);
}
- /// Returns true if the host architecture is known to support MCJIT
- bool ArchSupportsMCJIT() {
- Triple Host(HostTriple);
- if (std::find(SupportedArchs.begin(), SupportedArchs.end(), Host.getArch())
- == SupportedArchs.end()) {
- return false;
- }
- return true;
- }
-
- /// Returns true if the host OS is known to support MCJIT
- bool OSSupportsMCJIT() {
- Triple Host(HostTriple);
- if (std::find(UnsupportedOSs.begin(), UnsupportedOSs.end(), Host.getOS())
- == UnsupportedOSs.end()) {
- return true;
- }
- return false;
- }
-
Module *createEmptyModule(StringRef Name) {
Module * M = new Module(Name, Context);
M->setTargetTriple(Triple::normalize(HostTriple));
@@ -232,10 +190,6 @@ protected:
IRBuilder<> Builder;
JITMemoryManager *MM;
- std::string HostTriple;
- SmallVector<Triple::ArchType, 4> SupportedArchs;
- SmallVector<Triple::OSType, 4> UnsupportedOSs;
-
OwningPtr<Module> M;
};
diff --git a/unittests/ExecutionEngine/Makefile b/unittests/ExecutionEngine/Makefile
index c779a6a47c14..38e667ff9888 100644
--- a/unittests/ExecutionEngine/Makefile
+++ b/unittests/ExecutionEngine/Makefile
@@ -11,9 +11,10 @@ LEVEL = ../..
TESTNAME = ExecutionEngine
LINK_COMPONENTS :=interpreter
+include $(LEVEL)/Makefile.config
+
ifeq ($(TARGET_HAS_JIT),1)
- PARALLEL_DIRS = JIT MCJIT
+ PARALLEL_DIRS = JIT MCJIT
endif
-include $(LEVEL)/Makefile.config
include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
diff --git a/unittests/IR/CMakeLists.txt b/unittests/IR/CMakeLists.txt
index aed45979c069..c53043ef80e1 100644
--- a/unittests/IR/CMakeLists.txt
+++ b/unittests/IR/CMakeLists.txt
@@ -13,9 +13,11 @@ set(IRSources
MDBuilderTest.cpp
MetadataTest.cpp
PassManagerTest.cpp
+ PatternMatch.cpp
TypeBuilderTest.cpp
TypesTest.cpp
ValueMapTest.cpp
+ ValueTest.cpp
VerifierTest.cpp
WaymarkTest.cpp
)
diff --git a/unittests/IR/PatternMatch.cpp b/unittests/IR/PatternMatch.cpp
new file mode 100644
index 000000000000..7c6d8ce61586
--- /dev/null
+++ b/unittests/IR/PatternMatch.cpp
@@ -0,0 +1,265 @@
+//===---- llvm/unittest/IR/PatternMatch.cpp - PatternMatch unit tests ----===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/MDBuilder.h"
+#include "llvm/IR/Operator.h"
+#include "llvm/Support/NoFolder.h"
+#include "llvm/Support/PatternMatch.h"
+#include "gtest/gtest.h"
+
+using namespace llvm::PatternMatch;
+
+namespace llvm {
+namespace {
+
+/// Ordered floating point minimum/maximum tests.
+
+static void m_OrdFMin_expect_match_and_delete(Value *Cmp, Value *Select,
+ Value *L, Value *R) {
+ Value *MatchL, *MatchR;
+ EXPECT_TRUE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR)).match(Select));
+ EXPECT_EQ(L, MatchL);
+ EXPECT_EQ(R, MatchR);
+ delete Select;
+ delete Cmp;
+}
+
+static void m_OrdFMin_expect_nomatch_and_delete(Value *Cmp, Value *Select,
+ Value *L, Value *R) {
+ Value *MatchL, *MatchR;
+ EXPECT_FALSE(m_OrdFMin(m_Value(MatchL), m_Value(MatchR)).match(Select));
+ delete Select;
+ delete Cmp;
+}
+
+static void m_OrdFMax_expect_match_and_delete(Value *Cmp, Value *Select,
+ Value *L, Value *R) {
+ Value *MatchL, *MatchR;
+ EXPECT_TRUE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR)).match(Select));
+ EXPECT_EQ(L, MatchL);
+ EXPECT_EQ(R, MatchR);
+ delete Select;
+ delete Cmp;
+}
+
+static void m_OrdFMax_expect_nomatch_and_delete(Value *Cmp, Value *Select,
+ Value *L, Value *R) {
+ Value *MatchL, *MatchR;
+ EXPECT_FALSE(m_OrdFMax(m_Value(MatchL), m_Value(MatchR)).match(Select));
+ delete Select;
+ delete Cmp;
+}
+
+
+
+TEST(PatternMatchTest, FloatingPointOrderedMin) {
+ LLVMContext &C(getGlobalContext());
+ IRBuilder<true, NoFolder> Builder(C);
+
+ Type *FltTy = Builder.getFloatTy();
+ Value *L = ConstantFP::get(FltTy, 1.0);
+ Value *R = ConstantFP::get(FltTy, 2.0);
+
+ // Test OLT.
+ Value *Cmp = Builder.CreateFCmpOLT(L, R);
+ Value *Select = Builder.CreateSelect(Cmp, L, R);
+ m_OrdFMin_expect_match_and_delete(Cmp, Select, L, R);
+
+ // Test OLE.
+ Cmp = Builder.CreateFCmpOLE(L, R);
+ Select = Builder.CreateSelect(Cmp, L, R);
+ m_OrdFMin_expect_match_and_delete(Cmp, Select, L, R);
+
+ // Test no match on OGE.
+ Cmp = Builder.CreateFCmpOGE(L, R);
+ Select = Builder.CreateSelect(Cmp, L, R);
+ m_OrdFMin_expect_nomatch_and_delete(Cmp, Select, L, R);
+
+ // Test no match on OGT.
+ Cmp = Builder.CreateFCmpOGT(L, R);
+ Select = Builder.CreateSelect(Cmp, L, R);
+ m_OrdFMin_expect_nomatch_and_delete(Cmp, Select, L, R);
+
+ // Test match on OGE with inverted select.
+ Cmp = Builder.CreateFCmpOGE(L, R);
+ Select = Builder.CreateSelect(Cmp, R, L);
+ m_OrdFMin_expect_match_and_delete(Cmp, Select, L, R);
+
+ // Test match on OGT with inverted select.
+ Cmp = Builder.CreateFCmpOGT(L, R);
+ Select = Builder.CreateSelect(Cmp, R, L);
+ m_OrdFMin_expect_match_and_delete(Cmp, Select, L, R);
+}
+
+TEST(PatternMatchTest, FloatingPointOrderedMax) {
+ LLVMContext &C(getGlobalContext());
+ IRBuilder<true, NoFolder> Builder(C);
+
+ Type *FltTy = Builder.getFloatTy();
+ Value *L = ConstantFP::get(FltTy, 1.0);
+ Value *R = ConstantFP::get(FltTy, 2.0);
+
+ // Test OGT.
+ Value *Cmp = Builder.CreateFCmpOGT(L, R);
+ Value *Select = Builder.CreateSelect(Cmp, L, R);
+ m_OrdFMax_expect_match_and_delete(Cmp, Select, L, R);
+
+ // Test OGE.
+ Cmp = Builder.CreateFCmpOGE(L, R);
+ Select = Builder.CreateSelect(Cmp, L, R);
+ m_OrdFMax_expect_match_and_delete(Cmp, Select, L, R);
+
+ // Test no match on OLE.
+ Cmp = Builder.CreateFCmpOLE(L, R);
+ Select = Builder.CreateSelect(Cmp, L, R);
+ m_OrdFMax_expect_nomatch_and_delete(Cmp, Select, L, R);
+
+ // Test no match on OLT.
+ Cmp = Builder.CreateFCmpOLT(L, R);
+ Select = Builder.CreateSelect(Cmp, L, R);
+ m_OrdFMax_expect_nomatch_and_delete(Cmp, Select, L, R);
+
+ // Test match on OLE with inverted select.
+ Cmp = Builder.CreateFCmpOLE(L, R);
+ Select = Builder.CreateSelect(Cmp, R, L);
+ m_OrdFMax_expect_match_and_delete(Cmp, Select, L, R);
+
+ // Test match on OLT with inverted select.
+ Cmp = Builder.CreateFCmpOLT(L, R);
+ Select = Builder.CreateSelect(Cmp, R, L);
+ m_OrdFMax_expect_match_and_delete(Cmp, Select, L, R);
+}
+
+/// Unordered floating point minimum/maximum tests.
+
+static void m_UnordFMin_expect_match_and_delete(Value *Cmp, Value *Select,
+ Value *L, Value *R) {
+ Value *MatchL, *MatchR;
+ EXPECT_TRUE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR)).match(Select));
+ EXPECT_EQ(L, MatchL);
+ EXPECT_EQ(R, MatchR);
+ delete Select;
+ delete Cmp;
+}
+
+static void m_UnordFMin_expect_nomatch_and_delete(Value *Cmp, Value *Select,
+ Value *L, Value *R) {
+ Value *MatchL, *MatchR;
+ EXPECT_FALSE(m_UnordFMin(m_Value(MatchL), m_Value(MatchR)).match(Select));
+ delete Select;
+ delete Cmp;
+}
+
+static void m_UnordFMax_expect_match_and_delete(Value *Cmp, Value *Select,
+ Value *L, Value *R) {
+ Value *MatchL, *MatchR;
+ EXPECT_TRUE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR)).match(Select));
+ EXPECT_EQ(L, MatchL);
+ EXPECT_EQ(R, MatchR);
+ delete Select;
+ delete Cmp;
+}
+
+static void m_UnordFMax_expect_nomatch_and_delete(Value *Cmp, Value *Select,
+ Value *L, Value *R) {
+ Value *MatchL, *MatchR;
+ EXPECT_FALSE(m_UnordFMax(m_Value(MatchL), m_Value(MatchR)).match(Select));
+ delete Select;
+ delete Cmp;
+}
+
+TEST(PatternMatchTest, FloatingPointUnorderedMin) {
+ LLVMContext &C(getGlobalContext());
+ IRBuilder<true, NoFolder> Builder(C);
+
+ Type *FltTy = Builder.getFloatTy();
+ Value *L = ConstantFP::get(FltTy, 1.0);
+ Value *R = ConstantFP::get(FltTy, 2.0);
+
+ // Test ULT.
+ Value *Cmp = Builder.CreateFCmpULT(L, R);
+ Value *Select = Builder.CreateSelect(Cmp, L, R);
+ m_UnordFMin_expect_match_and_delete(Cmp, Select, L, R);
+
+ // Test ULE.
+ Cmp = Builder.CreateFCmpULE(L, R);
+ Select = Builder.CreateSelect(Cmp, L, R);
+ m_UnordFMin_expect_match_and_delete(Cmp, Select, L, R);
+
+ // Test no match on UGE.
+ Cmp = Builder.CreateFCmpUGE(L, R);
+ Select = Builder.CreateSelect(Cmp, L, R);
+ m_UnordFMin_expect_nomatch_and_delete(Cmp, Select, L, R);
+
+ // Test no match on UGT.
+ Cmp = Builder.CreateFCmpUGT(L, R);
+ Select = Builder.CreateSelect(Cmp, L, R);
+ m_UnordFMin_expect_nomatch_and_delete(Cmp, Select, L, R);
+
+ // Test match on UGE with inverted select.
+ Cmp = Builder.CreateFCmpUGE(L, R);
+ Select = Builder.CreateSelect(Cmp, R, L);
+ m_UnordFMin_expect_match_and_delete(Cmp, Select, L, R);
+
+ // Test match on UGT with inverted select.
+ Cmp = Builder.CreateFCmpUGT(L, R);
+ Select = Builder.CreateSelect(Cmp, R, L);
+ m_UnordFMin_expect_match_and_delete(Cmp, Select, L, R);
+}
+
+TEST(PatternMatchTest, FloatingPointUnorderedMax) {
+ LLVMContext &C(getGlobalContext());
+ IRBuilder<true, NoFolder> Builder(C);
+
+ Type *FltTy = Builder.getFloatTy();
+ Value *L = ConstantFP::get(FltTy, 1.0);
+ Value *R = ConstantFP::get(FltTy, 2.0);
+
+ // Test UGT.
+ Value *Cmp = Builder.CreateFCmpUGT(L, R);
+ Value *Select = Builder.CreateSelect(Cmp, L, R);
+ m_UnordFMax_expect_match_and_delete(Cmp, Select, L, R);
+
+ // Test UGE.
+ Cmp = Builder.CreateFCmpUGE(L, R);
+ Select = Builder.CreateSelect(Cmp, L, R);
+ m_UnordFMax_expect_match_and_delete(Cmp, Select, L, R);
+
+ // Test no match on ULE.
+ Cmp = Builder.CreateFCmpULE(L, R);
+ Select = Builder.CreateSelect(Cmp, L, R);
+ m_UnordFMax_expect_nomatch_and_delete(Cmp, Select, L, R);
+
+ // Test no match on ULT.
+ Cmp = Builder.CreateFCmpULT(L, R);
+ Select = Builder.CreateSelect(Cmp, L, R);
+ m_UnordFMax_expect_nomatch_and_delete(Cmp, Select, L, R);
+
+ // Test match on ULE with inverted select.
+ Cmp = Builder.CreateFCmpULE(L, R);
+ Select = Builder.CreateSelect(Cmp, R, L);
+ m_UnordFMax_expect_match_and_delete(Cmp, Select, L, R);
+
+ // Test match on ULT with inverted select.
+ Cmp = Builder.CreateFCmpULT(L, R);
+ Select = Builder.CreateSelect(Cmp, R, L);
+ m_UnordFMax_expect_match_and_delete(Cmp, Select, L, R);
+}
+
+} // anonymous namespace.
+} // llvm namespace.
diff --git a/unittests/IR/ValueTest.cpp b/unittests/IR/ValueTest.cpp
new file mode 100644
index 000000000000..52efb1a220aa
--- /dev/null
+++ b/unittests/IR/ValueTest.cpp
@@ -0,0 +1,46 @@
+//===- llvm/unittest/IR/ValueTest.cpp - Value unit tests ------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Assembly/Parser.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Value.h"
+#include "llvm/Support/SourceMgr.h"
+#include "gtest/gtest.h"
+using namespace llvm;
+
+namespace {
+
+TEST(ValueTest, UsedInBasicBlock) {
+ LLVMContext C;
+
+ const char *ModuleString = "define void @f(i32 %x, i32 %y) {\n"
+ "bb0:\n"
+ " %y1 = add i32 %y, 1\n"
+ " %y2 = add i32 %y, 1\n"
+ " %y3 = add i32 %y, 1\n"
+ " %y4 = add i32 %y, 1\n"
+ " %y5 = add i32 %y, 1\n"
+ " %y6 = add i32 %y, 1\n"
+ " %y7 = add i32 %y, 1\n"
+ " %y8 = add i32 %x, 1\n"
+ " ret void\n"
+ "}\n";
+ SMDiagnostic Err;
+ Module *M = ParseAssemblyString(ModuleString, NULL, Err, C);
+
+ Function *F = M->getFunction("f");
+
+ EXPECT_FALSE(F->isUsedInBasicBlock(F->begin()));
+ EXPECT_TRUE((++F->arg_begin())->isUsedInBasicBlock(F->begin()));
+ EXPECT_TRUE(F->arg_begin()->isUsedInBasicBlock(F->begin()));
+}
+
+} // end anonymous namespace
diff --git a/unittests/Makefile b/unittests/Makefile
index 926459ac08f8..61d60611be9c 100644
--- a/unittests/Makefile
+++ b/unittests/Makefile
@@ -9,7 +9,8 @@
LEVEL = ..
-PARALLEL_DIRS = ADT ExecutionEngine Support Transforms IR Analysis Bitcode
+PARALLEL_DIRS = ADT ExecutionEngine Support Transforms IR Analysis Bitcode \
+ DebugInfo
include $(LEVEL)/Makefile.common
diff --git a/unittests/Support/CMakeLists.txt b/unittests/Support/CMakeLists.txt
index b4b982f2ef23..e6cafbcaf158 100644
--- a/unittests/Support/CMakeLists.txt
+++ b/unittests/Support/CMakeLists.txt
@@ -10,6 +10,7 @@ add_llvm_unittest(SupportTests
BlockFrequencyTest.cpp
Casting.cpp
CommandLineTest.cpp
+ CompressionTest.cpp
ConstantRangeTest.cpp
DataExtractorTest.cpp
EndianTest.cpp
@@ -23,6 +24,7 @@ add_llvm_unittest(SupportTests
MemoryTest.cpp
Path.cpp
ProcessTest.cpp
+ ProgramTest.cpp
RegexTest.cpp
SwapByteOrderTest.cpp
TimeValue.cpp
diff --git a/unittests/Support/CommandLineTest.cpp b/unittests/Support/CommandLineTest.cpp
index 43c8cbd123b4..cd235d274e6c 100644
--- a/unittests/Support/CommandLineTest.cpp
+++ b/unittests/Support/CommandLineTest.cpp
@@ -41,6 +41,45 @@ class TempEnvVar {
const char *const name;
};
+cl::OptionCategory TestCategory("Test Options", "Description");
+cl::opt<int> TestOption("test-option", cl::desc("old description"));
+TEST(CommandLineTest, ModifyExisitingOption) {
+ const char Description[] = "New description";
+ const char ArgString[] = "new-test-option";
+ const char ValueString[] = "Integer";
+
+ StringMap<cl::Option*> Map;
+ cl::getRegisteredOptions(Map);
+
+ ASSERT_TRUE(Map.count("test-option") == 1) <<
+ "Could not find option in map.";
+
+ cl::Option *Retrieved = Map["test-option"];
+ ASSERT_EQ(&TestOption, Retrieved) << "Retrieved wrong option.";
+
+ ASSERT_EQ(&cl::GeneralCategory,Retrieved->Category) <<
+ "Incorrect default option category.";
+
+ Retrieved->setCategory(TestCategory);
+ ASSERT_EQ(&TestCategory,Retrieved->Category) <<
+ "Failed to modify option's option category.";
+
+ Retrieved->setDescription(Description);
+ ASSERT_STREQ(Retrieved->HelpStr, Description) <<
+ "Changing option description failed.";
+
+ Retrieved->setArgStr(ArgString);
+ ASSERT_STREQ(ArgString, Retrieved->ArgStr) <<
+ "Failed to modify option's Argument string.";
+
+ Retrieved->setValueStr(ValueString);
+ ASSERT_STREQ(Retrieved->ValueStr, ValueString) <<
+ "Failed to modify option's Value string.";
+
+ Retrieved->setHiddenFlag(cl::Hidden);
+ ASSERT_EQ(cl::Hidden, TestOption.getOptionHiddenFlag()) <<
+ "Failed to modify option's hidden flag.";
+}
#ifndef SKIP_ENVIRONMENT_TESTS
const char test_env_var[] = "LLVM_TEST_COMMAND_LINE_FLAGS";
@@ -55,6 +94,12 @@ TEST(CommandLineTest, ParseEnvironment) {
// This test used to make valgrind complain
// ("Conditional jump or move depends on uninitialised value(s)")
+//
+// Warning: Do not run any tests after this one that try to gain access to
+// registered command line options because this will likely result in a
+// SEGFAULT. This can occur because the cl::opt in the test below is declared
+// on the stack which will be destroyed after the test completes but the
+// command line system will still hold a pointer to a deallocated cl::Option.
TEST(CommandLineTest, ParseEnvironmentToLocalVar) {
// Put cl::opt on stack to check for proper initialization of fields.
cl::opt<std::string> EnvironmentTestOptionLocal("env-test-opt-local");
@@ -66,4 +111,11 @@ TEST(CommandLineTest, ParseEnvironmentToLocalVar) {
#endif // SKIP_ENVIRONMENT_TESTS
+TEST(CommandLineTest, UseOptionCategory) {
+ cl::opt<int> TestOption2("test-option", cl::cat(TestCategory));
+
+ ASSERT_EQ(&TestCategory,TestOption2.Category) << "Failed to assign Option "
+ "Category.";
+}
+
} // anonymous namespace
diff --git a/unittests/Support/CompressionTest.cpp b/unittests/Support/CompressionTest.cpp
new file mode 100644
index 000000000000..c8e2cd9f02b6
--- /dev/null
+++ b/unittests/Support/CompressionTest.cpp
@@ -0,0 +1,68 @@
+//===- llvm/unittest/Support/CompressionTest.cpp - Compression tests ------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements unit tests for the Compression functions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Compression.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Config/config.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+#if LLVM_ENABLE_ZLIB == 1 && HAVE_LIBZ
+
+void TestZlibCompression(StringRef Input, zlib::CompressionLevel Level) {
+ OwningPtr<MemoryBuffer> Compressed;
+ OwningPtr<MemoryBuffer> Uncompressed;
+ EXPECT_EQ(zlib::StatusOK, zlib::compress(Input, Compressed, Level));
+ // Check that uncompressed buffer is the same as original.
+ EXPECT_EQ(zlib::StatusOK, zlib::uncompress(Compressed->getBuffer(),
+ Uncompressed, Input.size()));
+ EXPECT_EQ(Input.size(), Uncompressed->getBufferSize());
+ EXPECT_EQ(0,
+ memcmp(Input.data(), Uncompressed->getBufferStart(), Input.size()));
+ if (Input.size() > 0) {
+ // Uncompression fails if expected length is too short.
+ EXPECT_EQ(zlib::StatusBufferTooShort,
+ zlib::uncompress(Compressed->getBuffer(), Uncompressed,
+ Input.size() - 1));
+ }
+}
+
+TEST(CompressionTest, Zlib) {
+ TestZlibCompression("", zlib::DefaultCompression);
+
+ TestZlibCompression("hello, world!", zlib::NoCompression);
+ TestZlibCompression("hello, world!", zlib::BestSizeCompression);
+ TestZlibCompression("hello, world!", zlib::BestSpeedCompression);
+ TestZlibCompression("hello, world!", zlib::DefaultCompression);
+
+ const size_t kSize = 1024;
+ char BinaryData[kSize];
+ for (size_t i = 0; i < kSize; ++i) {
+ BinaryData[i] = i & 255;
+ }
+ StringRef BinaryDataStr(BinaryData, kSize);
+
+ TestZlibCompression(BinaryDataStr, zlib::NoCompression);
+ TestZlibCompression(BinaryDataStr, zlib::BestSizeCompression);
+ TestZlibCompression(BinaryDataStr, zlib::BestSpeedCompression);
+ TestZlibCompression(BinaryDataStr, zlib::DefaultCompression);
+}
+
+#endif
+
+}
diff --git a/unittests/Support/Path.cpp b/unittests/Support/Path.cpp
index 45112597979c..eec8c62d8c84 100644
--- a/unittests/Support/Path.cpp
+++ b/unittests/Support/Path.cpp
@@ -298,12 +298,19 @@ TEST_F(FileSystemTest, DirectoryIteration) {
ASSERT_LT(z0, za1);
}
+const char elf[] = {0x7f, 'E', 'L', 'F', 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
+
TEST_F(FileSystemTest, Magic) {
struct type {
const char *filename;
const char *magic_str;
- size_t magic_str_len;
- } types [] = {{"magic.archive", "!<arch>\x0A", 8}};
+ size_t magic_str_len;
+ fs::file_magic magic;
+ } types [] = {
+ {"magic.archive", "!<arch>\x0A", 8, fs::file_magic::archive},
+ {"magic.elf", elf, sizeof(elf),
+ fs::file_magic::elf_relocatable}
+ };
// Create some files filled with magic.
for (type *i = types, *e = types + (sizeof(types) / sizeof(type)); i != e;
@@ -320,6 +327,7 @@ TEST_F(FileSystemTest, Magic) {
bool res = false;
ASSERT_NO_ERROR(fs::has_magic(file_pathname.c_str(), magic, res));
EXPECT_TRUE(res);
+ EXPECT_EQ(i->magic, fs::identify_magic(magic));
}
}
diff --git a/unittests/Support/ProgramTest.cpp b/unittests/Support/ProgramTest.cpp
new file mode 100644
index 000000000000..6cbb05454f80
--- /dev/null
+++ b/unittests/Support/ProgramTest.cpp
@@ -0,0 +1,89 @@
+//===- unittest/Support/ProgramTest.cpp -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Program.h"
+#include "gtest/gtest.h"
+
+#include <stdlib.h>
+#if defined(__APPLE__)
+# include <crt_externs.h>
+#elif !defined(_MSC_VER)
+// Forward declare environ in case it's not provided by stdlib.h.
+extern char **environ;
+#endif
+
+// From TestMain.cpp.
+extern const char *TestMainArgv0;
+
+namespace {
+
+using namespace llvm;
+using namespace sys;
+
+static cl::opt<std::string>
+ProgramTestStringArg1("program-test-string-arg1");
+static cl::opt<std::string>
+ProgramTestStringArg2("program-test-string-arg2");
+
+static void CopyEnvironment(std::vector<const char *> &out) {
+#ifdef __APPLE__
+ char **envp = *_NSGetEnviron();
+#else
+ // environ seems to work for Windows and most other Unices.
+ char **envp = environ;
+#endif
+ while (*envp != 0) {
+ out.push_back(*envp);
+ ++envp;
+ }
+}
+
+TEST(ProgramTest, CreateProcessTrailingSlash) {
+ if (getenv("LLVM_PROGRAM_TEST_CHILD")) {
+ if (ProgramTestStringArg1 == "has\\\\ trailing\\" &&
+ ProgramTestStringArg2 == "has\\\\ trailing\\") {
+ exit(0); // Success! The arguments were passed and parsed.
+ }
+ exit(1);
+ }
+
+ Path my_exe = Path::GetMainExecutable(TestMainArgv0, &ProgramTestStringArg1);
+ const char *argv[] = {
+ my_exe.c_str(),
+ "--gtest_filter=ProgramTest.CreateProcessTrailingSlashChild",
+ "-program-test-string-arg1", "has\\\\ trailing\\",
+ "-program-test-string-arg2", "has\\\\ trailing\\",
+ 0
+ };
+
+ // Add LLVM_PROGRAM_TEST_CHILD to the environment of the child.
+ std::vector<const char *> envp;
+ CopyEnvironment(envp);
+ envp.push_back("LLVM_PROGRAM_TEST_CHILD=1");
+ envp.push_back(0);
+
+ std::string error;
+ bool ExecutionFailed;
+ // Redirect stdout and stdin to NUL, but let stderr through.
+#ifdef LLVM_ON_WIN32
+ Path nul("NUL");
+#else
+ Path nul("/dev/null");
+#endif
+ const Path *redirects[] = { &nul, &nul, 0 };
+ int rc = Program::ExecuteAndWait(my_exe, argv, &envp[0], redirects,
+ /*secondsToWait=*/10, /*memoryLimit=*/0,
+ &error, &ExecutionFailed);
+ EXPECT_FALSE(ExecutionFailed) << error;
+ EXPECT_EQ(0, rc);
+}
+
+} // end anonymous namespace
diff --git a/unittests/Transforms/Utils/Cloning.cpp b/unittests/Transforms/Utils/Cloning.cpp
index cd304e720082..e19ae5bc2fb4 100644
--- a/unittests/Transforms/Utils/Cloning.cpp
+++ b/unittests/Transforms/Utils/Cloning.cpp
@@ -7,12 +7,15 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/IR/Instructions.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/Constant.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
+#include "llvm/Transforms/Utils/Cloning.h"
#include "gtest/gtest.h"
using namespace llvm;
@@ -143,4 +146,31 @@ TEST_F(CloneInstruction, Exact) {
EXPECT_TRUE(this->clone(SDiv)->isExact());
}
+TEST_F(CloneInstruction, Attributes) {
+ Type *ArgTy1[] = { Type::getInt32PtrTy(context) };
+ FunctionType *FT1 = FunctionType::get(Type::getVoidTy(context), ArgTy1, false);
+
+ Function *F1 = Function::Create(FT1, Function::ExternalLinkage);
+ BasicBlock *BB = BasicBlock::Create(context, "", F1);
+ IRBuilder<> Builder(BB);
+ Builder.CreateRetVoid();
+
+ Function *F2 = Function::Create(FT1, Function::ExternalLinkage);
+
+ Attribute::AttrKind AK[] = { Attribute::NoCapture };
+ AttributeSet AS = AttributeSet::get(context, 0, AK);
+ Argument *A = F1->arg_begin();
+ A->addAttr(AS);
+
+ SmallVector<ReturnInst*, 4> Returns;
+ ValueToValueMapTy VMap;
+ VMap[A] = UndefValue::get(A->getType());
+
+ CloneFunctionInto(F2, F1, VMap, false, Returns);
+ EXPECT_FALSE(F2->arg_begin()->hasNoCaptureAttr());
+
+ delete F1;
+ delete F2;
+}
+
}