mirror of
https://github.com/RPCSX/llvm.git
synced 2025-02-02 10:32:56 +00: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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@83353 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
454e957979
commit
ea5ed00ea3
@ -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)
|
||||
|
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user