aboutsummaryrefslogtreecommitdiffstats
path: root/unittests/ExecutionEngine
diff options
context:
space:
mode:
authorJeffrey Yasskin <jyasskin@google.com>2009-10-06 00:35:55 +0000
committerJeffrey Yasskin <jyasskin@google.com>2009-10-06 00:35:55 +0000
commitea5ed00ea34fd3c687dd0fac9fd483d0174438e3 (patch)
treed07d203424716acc219b27fb6779bfd134bf5ca4 /unittests/ExecutionEngine
parent454e957979727bd29d75ec70623e50795f5824d9 (diff)
downloadexternal_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.cpp53
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.