Fix http://llvm.org/PR5116 by rolling back r60822. This passes `make unittests
authorJeffrey Yasskin <jyasskin@google.com>
Tue, 6 Oct 2009 00:35:55 +0000 (00:35 +0000)
committerJeffrey Yasskin <jyasskin@google.com>
Tue, 6 Oct 2009 00:35:55 +0000 (00:35 +0000)
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

lib/ExecutionEngine/JIT/JITEmitter.cpp
unittests/ExecutionEngine/JIT/JITTest.cpp

index 590846bfded0b4f6ecd78da889520f47a4be4e48..85483564eb5c36cfe5ae793918fff4bea2dd5faa 100644 (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)
index 9e70a548ef4c53cce9a95d73df1d59c46271c81e..ee27dee39bee5e9290c10dccc09ed9e0f6080fe6 100644 (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.