1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 11:02:59 +02:00

Fix http://llvm.org/PR5116 by rolling back r60822. This passes `make unittests

check-lit` on both x86-64 Linux and x86-32 Darwin.

llvm-svn: 83353
This commit is contained in:
Jeffrey Yasskin 2009-10-06 00:35:55 +00:00
parent 6a7f2ee022
commit 4b011e6a51
2 changed files with 54 additions and 1 deletions

View File

@ -644,7 +644,7 @@ void *JITEmitter::getPointerToGlobal(GlobalValue *V, void *Reference,
// If we have already compiled the function, return a pointer to its body.
Function *F = cast<Function>(V);
void *ResultPtr;
if (!DoesntNeedStub && !TheJIT->isLazyCompilationDisabled()) {
if (!DoesntNeedStub) {
// Return the function stub if it's already created.
ResultPtr = Resolver.getFunctionStubIfAvailable(F);
if (ResultPtr)

View File

@ -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.