Taints the non-acquire RMW's store address with the load part
[oota-llvm.git] / unittests / ExecutionEngine / Orc / OrcCAPITest.cpp
1 //===--------------- OrcCAPITest.cpp - Unit tests Orc C API ---------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "OrcTestCommon.h"
11 #include "gtest/gtest.h"
12 #include "llvm-c/Core.h"
13 #include "llvm-c/OrcBindings.h"
14 #include "llvm-c/Target.h"
15 #include "llvm-c/TargetMachine.h"
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20
21 namespace llvm {
22
23 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
24
25 class OrcCAPIExecutionTest : public testing::Test, public OrcExecutionTest {
26 protected:
27   std::unique_ptr<Module> createTestModule(const Triple &TT) {
28     ModuleBuilder MB(getGlobalContext(), TT.str(), "");
29     Function *TestFunc = MB.createFunctionDecl<int()>("testFunc");
30     Function *Main = MB.createFunctionDecl<int(int, char*[])>("main");
31
32     Main->getBasicBlockList().push_back(BasicBlock::Create(getGlobalContext()));
33     IRBuilder<> B(&Main->back());
34     Value* Result = B.CreateCall(TestFunc);
35     B.CreateRet(Result);
36
37     return MB.takeModule();
38   }
39
40   typedef int (*MainFnTy)();
41
42   static int myTestFuncImpl() {
43     return 42;
44   }
45
46   static char *testFuncName;
47
48   static uint64_t myResolver(const char *Name, void *Ctx) {
49     if (!strncmp(Name, testFuncName, 8))
50       return (uint64_t)&myTestFuncImpl;
51     return 0;
52   }
53
54   struct CompileContext {
55     CompileContext() : Compiled(false) { }
56
57     OrcCAPIExecutionTest* APIExecTest;
58     std::unique_ptr<Module> M;
59     LLVMOrcModuleHandle H;
60     bool Compiled;
61   };
62
63   static LLVMOrcTargetAddress myCompileCallback(LLVMOrcJITStackRef JITStack,
64                                                 void *Ctx) {
65     CompileContext *CCtx = static_cast<CompileContext*>(Ctx);
66     auto *ET = CCtx->APIExecTest;
67     CCtx->M = ET->createTestModule(ET->TM->getTargetTriple());
68     CCtx->H = LLVMOrcAddEagerlyCompiledIR(JITStack, wrap(CCtx->M.get()),
69                                           myResolver, nullptr);
70     CCtx->Compiled = true;
71     LLVMOrcTargetAddress MainAddr = LLVMOrcGetSymbolAddress(JITStack, "main");
72     LLVMOrcSetIndirectStubPointer(JITStack, "foo", MainAddr);
73     return MainAddr;
74   }
75 };
76
77 char *OrcCAPIExecutionTest::testFuncName = nullptr;
78
79 TEST_F(OrcCAPIExecutionTest, TestEagerIRCompilation) {
80   if (!TM)
81     return;
82
83   LLVMOrcJITStackRef JIT =
84     LLVMOrcCreateInstance(wrap(TM.get()));
85
86   std::unique_ptr<Module> M = createTestModule(TM->getTargetTriple());
87
88   LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
89
90   LLVMOrcModuleHandle H =
91     LLVMOrcAddEagerlyCompiledIR(JIT, wrap(M.get()), myResolver, nullptr);
92   MainFnTy MainFn = (MainFnTy)LLVMOrcGetSymbolAddress(JIT, "main");
93   int Result = MainFn();
94   EXPECT_EQ(Result, 42)
95     << "Eagerly JIT'd code did not return expected result";
96
97   LLVMOrcRemoveModule(JIT, H);
98
99   LLVMOrcDisposeMangledSymbol(testFuncName);
100   LLVMOrcDisposeInstance(JIT);
101 }
102
103 TEST_F(OrcCAPIExecutionTest, TestLazyIRCompilation) {
104   if (!TM)
105     return;
106
107   LLVMOrcJITStackRef JIT =
108     LLVMOrcCreateInstance(wrap(TM.get()));
109
110   std::unique_ptr<Module> M = createTestModule(TM->getTargetTriple());
111
112   LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
113
114   LLVMOrcModuleHandle H =
115     LLVMOrcAddLazilyCompiledIR(JIT, wrap(M.get()), myResolver, nullptr);
116   MainFnTy MainFn = (MainFnTy)LLVMOrcGetSymbolAddress(JIT, "main");
117   int Result = MainFn();
118   EXPECT_EQ(Result, 42)
119     << "Lazily JIT'd code did not return expected result";
120
121   LLVMOrcRemoveModule(JIT, H);
122
123   LLVMOrcDisposeMangledSymbol(testFuncName);
124   LLVMOrcDisposeInstance(JIT);
125 }
126
127 TEST_F(OrcCAPIExecutionTest, TestDirectCallbacksAPI) {
128   if (!TM)
129     return;
130
131   LLVMOrcJITStackRef JIT =
132     LLVMOrcCreateInstance(wrap(TM.get()));
133
134   LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
135
136   CompileContext C;
137   C.APIExecTest = this;
138   LLVMOrcCreateIndirectStub(JIT, "foo",
139                             LLVMOrcCreateLazyCompileCallback(JIT,
140                                                              myCompileCallback,
141                                                              &C));
142   MainFnTy FooFn = (MainFnTy)LLVMOrcGetSymbolAddress(JIT, "foo");
143   int Result = FooFn();
144   EXPECT_TRUE(C.Compiled)
145     << "Function wasn't lazily compiled";
146   EXPECT_EQ(Result, 42)
147     << "Direct-callback JIT'd code did not return expected result";
148
149   C.Compiled = false;
150   FooFn();
151   EXPECT_FALSE(C.Compiled)
152     << "Direct-callback JIT'd code was JIT'd twice";
153
154   LLVMOrcRemoveModule(JIT, C.H);
155
156   LLVMOrcDisposeMangledSymbol(testFuncName);
157   LLVMOrcDisposeInstance(JIT);
158 }
159
160 } // namespace llvm