diff options
author | Jeffrey Yasskin <jyasskin@google.com> | 2009-10-06 00:35:55 +0000 |
---|---|---|
committer | Jeffrey Yasskin <jyasskin@google.com> | 2009-10-06 00:35:55 +0000 |
commit | ea5ed00ea34fd3c687dd0fac9fd483d0174438e3 (patch) | |
tree | d07d203424716acc219b27fb6779bfd134bf5ca4 /unittests/ExecutionEngine | |
parent | 454e957979727bd29d75ec70623e50795f5824d9 (diff) | |
download | external_llvm-ea5ed00ea34fd3c687dd0fac9fd483d0174438e3.zip external_llvm-ea5ed00ea34fd3c687dd0fac9fd483d0174438e3.tar.gz external_llvm-ea5ed00ea34fd3c687dd0fac9fd483d0174438e3.tar.bz2 |
Fix http://llvm.org/PR5116 by rolling back r60822. This passes `make unittests
check-lit` on both x86-64 Linux and x86-32 Darwin.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@83353 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'unittests/ExecutionEngine')
-rw-r--r-- | unittests/ExecutionEngine/JIT/JITTest.cpp | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/unittests/ExecutionEngine/JIT/JITTest.cpp b/unittests/ExecutionEngine/JIT/JITTest.cpp index 9e70a54..ee27dee 100644 --- a/unittests/ExecutionEngine/JIT/JITTest.cpp +++ b/unittests/ExecutionEngine/JIT/JITTest.cpp @@ -22,6 +22,7 @@ #include "llvm/Module.h" #include "llvm/ModuleProvider.h" #include "llvm/Support/IRBuilder.h" +#include "llvm/Support/TypeBuilder.h" #include "llvm/Target/TargetSelect.h" #include "llvm/Type.h" @@ -44,6 +45,21 @@ Function *makeReturnGlobal(std::string Name, GlobalVariable *G, Module *M) { return F; } +class JITTest : public testing::Test { + protected: + virtual void SetUp() { + M = new Module("<main>", Context); + std::string Error; + TheJIT.reset(EngineBuilder(M).setEngineKind(EngineKind::JIT) + .setErrorStr(&Error).create()); + ASSERT_TRUE(TheJIT.get() != NULL) << Error; + } + + LLVMContext Context; + Module *M; // Owned by ExecutionEngine. + OwningPtr<ExecutionEngine> TheJIT; +}; + // 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 @@ -115,6 +131,43 @@ TEST(JIT, GlobalInFunction) { EXPECT_EQ(3, *GPtr); } +int PlusOne(int arg) { + return arg + 1; +} + +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 + // the address into a register and call through the register. The + // current JIT does this by allocating a stub for any far call. + // There was a bug in which the JIT tried to emit a direct call when + // the target was already in the JIT's global mappings and lazy + // compilation was disabled. + + Function *KnownFunction = Function::Create( + TypeBuilder<int(int), false>::get(Context), + GlobalValue::ExternalLinkage, "known", M); + TheJIT->addGlobalMapping(KnownFunction, (void*)(intptr_t)PlusOne); + + // int test() { return known(7); } + Function *TestFunction = Function::Create( + TypeBuilder<int(), false>::get(Context), + GlobalValue::ExternalLinkage, "test", M); + BasicBlock *Entry = BasicBlock::Create(Context, "entry", TestFunction); + IRBuilder<> Builder(Entry); + Value *result = Builder.CreateCall( + KnownFunction, + ConstantInt::get(TypeBuilder<int, false>::get(Context), 7)); + Builder.CreateRet(result); + + TheJIT->EnableDlsymStubs(false); + TheJIT->DisableLazyCompilation(); + int (*TestFunctionPtr)() = reinterpret_cast<int(*)()>( + (intptr_t)TheJIT->getPointerToFunction(TestFunction)); + // This used to crash in trying to call PlusOne(). + EXPECT_EQ(8, TestFunctionPtr()); +} + // 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 // behavior. |