<div dir="ltr">No failures reported yet. I'm going to head off for the night, but will leave this test in for now: the last of the bugs may have been fixed, or they may only show up on long-running testers. If/when it starts failing please feel free to revert and I will look over any failure logs tomorrow.<div><br></div><div>-- Lang.</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, May 4, 2021 at 8:54 PM Lang Hames via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><br>
Author: Lang Hames<br>
Date: 2021-05-04T20:46:00-07:00<br>
New Revision: f2018d6c16d118779d35f3705c74a31c1855ca56<br>
<br>
URL: <a href="https://github.com/llvm/llvm-project/commit/f2018d6c16d118779d35f3705c74a31c1855ca56" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/commit/f2018d6c16d118779d35f3705c74a31c1855ca56</a><br>
DIFF: <a href="https://github.com/llvm/llvm-project/commit/f2018d6c16d118779d35f3705c74a31c1855ca56.diff" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/commit/f2018d6c16d118779d35f3705c74a31c1855ca56.diff</a><br>
<br>
LOG: [ORC] Reintroduce the ORC C API test.<br>
<br>
This test was removed in 51495fd285 due to broken bots. Its reintroduction is<br>
expected to trigger failures on some builders. The test has been modified to<br>
print error messages in full, which should aid in tracking these down.<br>
<br>
Added: <br>
llvm/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp<br>
<br>
Modified: <br>
llvm/unittests/ExecutionEngine/Orc/CMakeLists.txt<br>
<br>
Removed: <br>
<br>
<br>
<br>
################################################################################<br>
diff --git a/llvm/unittests/ExecutionEngine/Orc/CMakeLists.txt b/llvm/unittests/ExecutionEngine/Orc/CMakeLists.txt<br>
index d205d53829aa..505692233ebe 100644<br>
--- a/llvm/unittests/ExecutionEngine/Orc/CMakeLists.txt<br>
+++ b/llvm/unittests/ExecutionEngine/Orc/CMakeLists.txt<br>
@@ -17,6 +17,7 @@ add_llvm_unittest(OrcJITTests<br>
IndirectionUtilsTest.cpp<br>
JITTargetMachineBuilderTest.cpp<br>
LazyCallThroughAndReexportsTest.cpp<br>
+ OrcCAPITest.cpp<br>
OrcTestCommon.cpp<br>
QueueChannel.cpp<br>
ResourceTrackerTest.cpp<br>
<br>
diff --git a/llvm/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp b/llvm/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp<br>
new file mode 100644<br>
index 000000000000..50a2ee459ac2<br>
--- /dev/null<br>
+++ b/llvm/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp<br>
@@ -0,0 +1,328 @@<br>
+//===--- OrcCAPITest.cpp - Unit tests for the OrcJIT v2 C API ---*- C++ -*-===//<br>
+//<br>
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.<br>
+// See <a href="https://llvm.org/LICENSE.txt" rel="noreferrer" target="_blank">https://llvm.org/LICENSE.txt</a> for license information.<br>
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#include "llvm-c/Core.h"<br>
+#include "llvm-c/Error.h"<br>
+#include "llvm-c/LLJIT.h"<br>
+#include "llvm-c/Orc.h"<br>
+#include "gtest/gtest.h"<br>
+<br>
+#include "llvm/ADT/Triple.h"<br>
+#include <string><br>
+<br>
+using namespace llvm;<br>
+<br>
+// OrcCAPITestBase contains several helper methods and pointers for unit tests<br>
+// written for the LLVM-C API. It provides the following helpers:<br>
+//<br>
+// 1. Jit: an LLVMOrcLLJIT instance which is freed upon test exit<br>
+// 2. ExecutionSession: the LLVMOrcExecutionSession for the JIT<br>
+// 3. MainDylib: the main JITDylib for the LLJIT instance<br>
+// 4. materializationUnitFn: function pointer to an empty function, used for<br>
+// materialization unit testing<br>
+// 5. definitionGeneratorFn: function pointer for a basic<br>
+// LLVMOrcCAPIDefinitionGeneratorTryToGenerateFunction<br>
+// 6. createTestModule: helper method for creating a basic thread-safe-module<br>
+class OrcCAPITestBase : public testing::Test {<br>
+protected:<br>
+ LLVMOrcLLJITRef Jit = nullptr;<br>
+ LLVMOrcExecutionSessionRef ExecutionSession = nullptr;<br>
+ LLVMOrcJITDylibRef MainDylib = nullptr;<br>
+<br>
+public:<br>
+ static void SetUpTestCase() {<br>
+ LLVMInitializeNativeTarget();<br>
+ LLVMInitializeNativeAsmParser();<br>
+ LLVMInitializeNativeAsmPrinter();<br>
+<br>
+ // Attempt to set up a JIT instance once to verify that we can.<br>
+ LLVMOrcJITTargetMachineBuilderRef JTMB = nullptr;<br>
+ if (LLVMErrorRef E = LLVMOrcJITTargetMachineBuilderDetectHost(&JTMB)) {<br>
+ // If setup fails then disable these tests.<br>
+ LLVMConsumeError(E);<br>
+ TargetSupported = false;<br>
+ return;<br>
+ }<br>
+<br>
+ // Capture the target triple. We'll use it for both verification that<br>
+ // this target is *supposed* to be supported, and error messages in<br>
+ // the case that it fails anyway.<br>
+ char *TT = LLVMOrcJITTargetMachineBuilderGetTargetTriple(JTMB);<br>
+ TargetTriple = TT;<br>
+ LLVMOrcJITTargetMachineBuilderDisposeTargetTriple(JTMB, TT);<br>
+<br>
+ if (!isSupported(TargetTriple)) {<br>
+ // If this triple isn't supported then bail out.<br>
+ TargetSupported = false;<br>
+ LLVMOrcDisposeJITTargetMachineBuilder(JTMB);<br>
+ return;<br>
+ }<br>
+<br>
+ LLVMOrcLLJITBuilderRef Builder = LLVMOrcCreateLLJITBuilder();<br>
+ LLVMOrcLLJITBuilderSetJITTargetMachineBuilder(Builder, JTMB);<br>
+ LLVMOrcLLJITRef J;<br>
+ if (LLVMErrorRef E = LLVMOrcCreateLLJIT(&J, Builder)) {<br>
+ // If setup fails then disable these tests.<br>
+ TargetSupported = false;<br>
+ LLVMConsumeError(E);<br>
+ return;<br>
+ }<br>
+<br>
+ LLVMOrcDisposeLLJIT(J);<br>
+ TargetSupported = true;<br>
+ }<br>
+<br>
+ void SetUp() override {<br>
+ if (!TargetSupported)<br>
+ return;<br>
+<br>
+ LLVMOrcJITTargetMachineBuilderRef JTMB = nullptr;<br>
+ LLVMErrorRef E1 = LLVMOrcJITTargetMachineBuilderDetectHost(&JTMB);<br>
+ assert(E1 == LLVMErrorSuccess && "Expected call to detect host to succeed");<br>
+<br>
+ LLVMOrcLLJITBuilderRef Builder = LLVMOrcCreateLLJITBuilder();<br>
+ LLVMOrcLLJITBuilderSetJITTargetMachineBuilder(Builder, JTMB);<br>
+ LLVMErrorRef E2 = LLVMOrcCreateLLJIT(&Jit, Builder);<br>
+ assert(E2 == LLVMErrorSuccess &&<br>
+ "Expected call to create LLJIT to succeed");<br>
+ ExecutionSession = LLVMOrcLLJITGetExecutionSession(Jit);<br>
+ MainDylib = LLVMOrcLLJITGetMainJITDylib(Jit);<br>
+ }<br>
+ void TearDown() override {<br>
+ LLVMOrcDisposeLLJIT(Jit);<br>
+ Jit = nullptr;<br>
+ }<br>
+<br>
+protected:<br>
+ static bool isSupported(StringRef Triple) {<br>
+ // TODO: Print error messages in failure logs, use them to audit this list.<br>
+ // Some architectures may be unsupportable or missing key components, but<br>
+ // some may just be failing due to bugs in this testcase.<br>
+ if (Triple.startswith("armv7") || Triple.startswith("armv8l"))<br>
+ return false;<br>
+ return true;<br>
+ }<br>
+<br>
+ static void materializationUnitFn() {}<br>
+ // Stub definition generator, where all Names are materialized from the<br>
+ // materializationUnitFn() test function and defined into the JIT Dylib<br>
+ static LLVMErrorRef<br>
+ definitionGeneratorFn(LLVMOrcDefinitionGeneratorRef G, void *Ctx,<br>
+ LLVMOrcLookupStateRef *LS, LLVMOrcLookupKind K,<br>
+ LLVMOrcJITDylibRef JD, LLVMOrcJITDylibLookupFlags F,<br>
+ LLVMOrcCLookupSet Names, size_t NamesCount) {<br>
+ for (size_t I = 0; I < NamesCount; I++) {<br>
+ LLVMOrcCLookupSetElement Element = Names[I];<br>
+ LLVMOrcJITTargetAddress Addr =<br>
+ (LLVMOrcJITTargetAddress)(&materializationUnitFn);<br>
+ LLVMJITSymbolFlags Flags = {LLVMJITSymbolGenericFlagsWeak, 0};<br>
+ LLVMJITEvaluatedSymbol Sym = {Addr, Flags};<br>
+ LLVMOrcRetainSymbolStringPoolEntry(Element.Name);<br>
+ LLVMJITCSymbolMapPair Pair = {Element.Name, Sym};<br>
+ LLVMJITCSymbolMapPair Pairs[] = {Pair};<br>
+ LLVMOrcMaterializationUnitRef MU = LLVMOrcAbsoluteSymbols(Pairs, 1);<br>
+ LLVMErrorRef Err = LLVMOrcJITDylibDefine(JD, MU);<br>
+ if (Err)<br>
+ return Err;<br>
+ }<br>
+ return LLVMErrorSuccess;<br>
+ }<br>
+ // create a test LLVM IR module containing a function named "sum" which has<br>
+ // returns the sum of its two parameters<br>
+ static LLVMOrcThreadSafeModuleRef createTestModule() {<br>
+ LLVMOrcThreadSafeContextRef TSC = LLVMOrcCreateNewThreadSafeContext();<br>
+ LLVMContextRef Ctx = LLVMOrcThreadSafeContextGetContext(TSC);<br>
+ LLVMModuleRef Mod = LLVMModuleCreateWithNameInContext("test", Ctx);<br>
+ {<br>
+ LLVMTypeRef Int32Ty = LLVMInt32TypeInContext(Ctx);<br>
+ LLVMTypeRef ParamTys[] = {Int32Ty, Int32Ty};<br>
+ LLVMTypeRef TestFnTy = LLVMFunctionType(Int32Ty, ParamTys, 2, 0);<br>
+ LLVMValueRef TestFn = LLVMAddFunction(Mod, "sum", TestFnTy);<br>
+ LLVMBuilderRef IRBuilder = LLVMCreateBuilderInContext(Ctx);<br>
+ LLVMBasicBlockRef EntryBB = LLVMAppendBasicBlock(TestFn, "entry");<br>
+ LLVMPositionBuilderAtEnd(IRBuilder, EntryBB);<br>
+ LLVMValueRef Arg1 = LLVMGetParam(TestFn, 0);<br>
+ LLVMValueRef Arg2 = LLVMGetParam(TestFn, 1);<br>
+ LLVMValueRef Sum = LLVMBuildAdd(IRBuilder, Arg1, Arg2, "");<br>
+ LLVMBuildRet(IRBuilder, Sum);<br>
+ LLVMDisposeBuilder(IRBuilder);<br>
+ }<br>
+ LLVMOrcThreadSafeModuleRef TSM = LLVMOrcCreateNewThreadSafeModule(Mod, TSC);<br>
+ LLVMOrcDisposeThreadSafeContext(TSC);<br>
+ return TSM;<br>
+ }<br>
+<br>
+ static std::string TargetTriple;<br>
+ static bool TargetSupported;<br>
+};<br>
+<br>
+std::string OrcCAPITestBase::TargetTriple;<br>
+bool OrcCAPITestBase::TargetSupported = false;<br>
+<br>
+// Consumes the given error ref and returns the string error message.<br>
+static std::string toString(LLVMErrorRef E) {<br>
+ char *ErrMsg = LLVMGetErrorMessage(E);<br>
+ std::string Result(ErrMsg);<br>
+ LLVMDisposeErrorMessage(ErrMsg);<br>
+ return Result;<br>
+}<br>
+<br>
+TEST_F(OrcCAPITestBase, SymbolStringPoolUniquing) {<br>
+ if (!Jit) {<br>
+ // TODO: Use GTEST_SKIP() when GTest is updated to version 1.10.0<br>
+ return;<br>
+ }<br>
+<br>
+ LLVMOrcSymbolStringPoolEntryRef E1 =<br>
+ LLVMOrcExecutionSessionIntern(ExecutionSession, "aaa");<br>
+ LLVMOrcSymbolStringPoolEntryRef E2 =<br>
+ LLVMOrcExecutionSessionIntern(ExecutionSession, "aaa");<br>
+ LLVMOrcSymbolStringPoolEntryRef E3 =<br>
+ LLVMOrcExecutionSessionIntern(ExecutionSession, "bbb");<br>
+ const char *SymbolName = LLVMOrcSymbolStringPoolEntryStr(E1);<br>
+ ASSERT_EQ(E1, E2) << "String pool entries are not unique";<br>
+ ASSERT_NE(E1, E3) << "Unique symbol pool entries are equal";<br>
+ ASSERT_STREQ("aaa", SymbolName) << "String value of symbol is not equal";<br>
+ LLVMOrcReleaseSymbolStringPoolEntry(E1);<br>
+ LLVMOrcReleaseSymbolStringPoolEntry(E2);<br>
+ LLVMOrcReleaseSymbolStringPoolEntry(E3);<br>
+}<br>
+<br>
+TEST_F(OrcCAPITestBase, JITDylibLookup) {<br>
+ if (!Jit) {<br>
+ // TODO: Use GTEST_SKIP() when GTest is updated to version 1.10.0<br>
+ return;<br>
+ }<br>
+ LLVMOrcJITDylibRef DoesNotExist =<br>
+ LLVMOrcExecutionSessionGetJITDylibByName(ExecutionSession, "test");<br>
+ ASSERT_FALSE(!!DoesNotExist);<br>
+ LLVMOrcJITDylibRef L1 =<br>
+ LLVMOrcExecutionSessionCreateBareJITDylib(ExecutionSession, "test");<br>
+ LLVMOrcJITDylibRef L2 =<br>
+ LLVMOrcExecutionSessionGetJITDylibByName(ExecutionSession, "test");<br>
+ ASSERT_EQ(L1, L2) << "Located JIT Dylib is not equal to original";<br>
+}<br>
+<br>
+TEST_F(OrcCAPITestBase, MaterializationUnitCreation) {<br>
+ if (!Jit) {<br>
+ // TODO: Use GTEST_SKIP() when GTest is updated to version 1.10.0<br>
+ return;<br>
+ }<br>
+<br>
+ LLVMOrcSymbolStringPoolEntryRef Name =<br>
+ LLVMOrcLLJITMangleAndIntern(Jit, "test");<br>
+ LLVMJITSymbolFlags Flags = {LLVMJITSymbolGenericFlagsWeak, 0};<br>
+ LLVMOrcJITTargetAddress Addr =<br>
+ (LLVMOrcJITTargetAddress)(&materializationUnitFn);<br>
+ LLVMJITEvaluatedSymbol Sym = {Addr, Flags};<br>
+ LLVMJITCSymbolMapPair Pair = {Name, Sym};<br>
+ LLVMJITCSymbolMapPair Pairs[] = {Pair};<br>
+ LLVMOrcMaterializationUnitRef MU = LLVMOrcAbsoluteSymbols(Pairs, 1);<br>
+ LLVMOrcJITDylibDefine(MainDylib, MU);<br>
+ LLVMOrcJITTargetAddress OutAddr;<br>
+ if (LLVMErrorRef E = LLVMOrcLLJITLookup(Jit, &OutAddr, "test"))<br>
+ FAIL() << "Failed to look up \"test\" symbol (triple = " << TargetTriple<br>
+ << "): " << toString(E);<br>
+ ASSERT_EQ(Addr, OutAddr);<br>
+}<br>
+<br>
+TEST_F(OrcCAPITestBase, DefinitionGenerators) {<br>
+ if (!Jit) {<br>
+ // TODO: Use GTEST_SKIP() when GTest is updated to version 1.10.0<br>
+ return;<br>
+ }<br>
+<br>
+ LLVMOrcDefinitionGeneratorRef Gen =<br>
+ LLVMOrcCreateCustomCAPIDefinitionGenerator(&definitionGeneratorFn,<br>
+ nullptr);<br>
+ LLVMOrcJITDylibAddGenerator(MainDylib, Gen);<br>
+ LLVMOrcJITTargetAddress OutAddr;<br>
+ if (LLVMErrorRef E = LLVMOrcLLJITLookup(Jit, &OutAddr, "test"))<br>
+ FAIL() << "The DefinitionGenerator did not create symbol \"test\" "<br>
+ << "(triple = " << TargetTriple << "): " << toString(E);<br>
+ LLVMOrcJITTargetAddress ExpectedAddr =<br>
+ (LLVMOrcJITTargetAddress)(&materializationUnitFn);<br>
+ ASSERT_EQ(ExpectedAddr, OutAddr);<br>
+}<br>
+<br>
+TEST_F(OrcCAPITestBase, ResourceTrackerDefinitionLifetime) {<br>
+ if (!Jit) {<br>
+ // TODO: Use GTEST_SKIP() when GTest is updated to version 1.10.0<br>
+ return;<br>
+ }<br>
+<br>
+ // This test case ensures that all symbols loaded into a JITDylib with a<br>
+ // ResourceTracker attached are cleared from the JITDylib once the RT is<br>
+ // removed.<br>
+ LLVMOrcResourceTrackerRef RT =<br>
+ LLVMOrcJITDylibCreateResourceTracker(MainDylib);<br>
+ LLVMOrcThreadSafeModuleRef TSM = createTestModule();<br>
+ if (LLVMErrorRef E = LLVMOrcLLJITAddLLVMIRModuleWithRT(Jit, RT, TSM))<br>
+ FAIL() << "Failed to add LLVM IR module to LLJIT (triple = " << TargetTriple<br>
+ << "): " << toString(E);<br>
+ LLVMOrcJITTargetAddress TestFnAddr;<br>
+ if (LLVMErrorRef E = LLVMOrcLLJITLookup(Jit, &TestFnAddr, "sum"))<br>
+ FAIL() << "Symbol \"sum\" was not added into JIT (triple = " << TargetTriple<br>
+ << "): " << toString(E);<br>
+ ASSERT_TRUE(!!TestFnAddr);<br>
+ LLVMOrcResourceTrackerRemove(RT);<br>
+ LLVMOrcJITTargetAddress OutAddr;<br>
+ LLVMErrorRef Err = LLVMOrcLLJITLookup(Jit, &OutAddr, "sum");<br>
+ ASSERT_TRUE(Err);<br>
+ LLVMConsumeError(Err);<br>
+<br>
+ ASSERT_FALSE(OutAddr);<br>
+ LLVMOrcReleaseResourceTracker(RT);<br>
+}<br>
+<br>
+TEST_F(OrcCAPITestBase, ResourceTrackerTransfer) {<br>
+ if (!Jit) {<br>
+ // TODO: Use GTEST_SKIP() when GTest is updated to version 1.10.0<br>
+ return;<br>
+ }<br>
+<br>
+ LLVMOrcResourceTrackerRef DefaultRT =<br>
+ LLVMOrcJITDylibGetDefaultResourceTracker(MainDylib);<br>
+ LLVMOrcResourceTrackerRef RT2 =<br>
+ LLVMOrcJITDylibCreateResourceTracker(MainDylib);<br>
+ LLVMOrcThreadSafeModuleRef TSM = createTestModule();<br>
+ if (LLVMErrorRef E = LLVMOrcLLJITAddLLVMIRModuleWithRT(Jit, DefaultRT, TSM))<br>
+ FAIL() << "Failed to add LLVM IR module to LLJIT (triple = " << TargetTriple<br>
+ << "): " << toString(E);<br>
+ LLVMOrcJITTargetAddress Addr;<br>
+ if (LLVMErrorRef E = LLVMOrcLLJITLookup(Jit, &Addr, "sum"))<br>
+ FAIL() << "Symbol \"sum\" was not added into JIT (triple = " << TargetTriple<br>
+ << "): " << toString(E);<br>
+ LLVMOrcResourceTrackerTransferTo(DefaultRT, RT2);<br>
+ LLVMErrorRef Err = LLVMOrcLLJITLookup(Jit, &Addr, "sum");<br>
+ ASSERT_FALSE(Err);<br>
+ LLVMOrcReleaseResourceTracker(RT2);<br>
+}<br>
+<br>
+TEST_F(OrcCAPITestBase, ExecutionTest) {<br>
+ if (!Jit) {<br>
+ // TODO: Use GTEST_SKIP() when GTest is updated to version 1.10.0<br>
+ return;<br>
+ }<br>
+<br>
+ using SumFunctionType = int32_t (*)(int32_t, int32_t);<br>
+<br>
+ // This test performs OrcJIT compilation of a simple sum module<br>
+ LLVMInitializeNativeAsmPrinter();<br>
+ LLVMOrcThreadSafeModuleRef TSM = createTestModule();<br>
+ if (LLVMErrorRef E = LLVMOrcLLJITAddLLVMIRModule(Jit, MainDylib, TSM))<br>
+ FAIL() << "Failed to add LLVM IR module to LLJIT (triple = " << TargetTriple<br>
+ << ")" << toString(E);<br>
+ LLVMOrcJITTargetAddress TestFnAddr;<br>
+ if (LLVMErrorRef E = LLVMOrcLLJITLookup(Jit, &TestFnAddr, "sum"))<br>
+ FAIL() << "Symbol \"sum\" was not added into JIT (triple = " << TargetTriple<br>
+ << "): " << toString(E);<br>
+ auto *SumFn = (SumFunctionType)(TestFnAddr);<br>
+ int32_t Result = SumFn(1, 1);<br>
+ ASSERT_EQ(2, Result);<br>
+}<br>
<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div>