summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-c-test/echo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-c-test/echo.cpp')
-rw-r--r--llvm/tools/llvm-c-test/echo.cpp78
1 files changed, 76 insertions, 2 deletions
diff --git a/llvm/tools/llvm-c-test/echo.cpp b/llvm/tools/llvm-c-test/echo.cpp
index 73da1ee8b21..8341b11aa45 100644
--- a/llvm/tools/llvm-c-test/echo.cpp
+++ b/llvm/tools/llvm-c-test/echo.cpp
@@ -939,7 +939,7 @@ AliasDecl:
if (!Begin) {
if (End != nullptr)
report_fatal_error("Range has an end but no beginning");
- goto NamedMDDecl;
+ goto GlobalIFuncDecl;
}
Cur = Begin;
@@ -967,6 +967,41 @@ AliasDecl:
Cur = Next;
}
+GlobalIFuncDecl:
+ Begin = LLVMGetFirstGlobalIFunc(Src);
+ End = LLVMGetLastGlobalIFunc(Src);
+ if (!Begin) {
+ if (End != nullptr)
+ report_fatal_error("Range has an end but no beginning");
+ goto NamedMDDecl;
+ }
+
+ Cur = Begin;
+ Next = nullptr;
+ while (true) {
+ size_t NameLen;
+ const char *Name = LLVMGetValueName2(Cur, &NameLen);
+ if (LLVMGetNamedGlobalIFunc(M, Name, NameLen))
+ report_fatal_error("Global ifunc already cloned");
+ LLVMTypeRef CurType = TypeCloner(M).Clone(LLVMGlobalGetValueType(Cur));
+ // FIXME: Allow NULL resolver.
+ LLVMAddGlobalIFunc(M, Name, NameLen,
+ CurType, /*addressSpace*/ 0, LLVMGetUndef(CurType));
+
+ Next = LLVMGetNextGlobalIFunc(Cur);
+ if (Next == nullptr) {
+ if (Cur != End)
+ report_fatal_error("");
+ break;
+ }
+
+ LLVMValueRef Prev = LLVMGetPreviousGlobalIFunc(Next);
+ if (Prev != Cur)
+ report_fatal_error("Next.Previous global is not Current");
+
+ Cur = Next;
+ }
+
NamedMDDecl:
LLVMNamedMDNodeRef BeginMD = LLVMGetFirstNamedMetadata(Src);
LLVMNamedMDNodeRef EndMD = LLVMGetLastNamedMetadata(Src);
@@ -1114,7 +1149,7 @@ AliasClone:
if (!Begin) {
if (End != nullptr)
report_fatal_error("Range has an end but no beginning");
- goto NamedMDClone;
+ goto GlobalIFuncClone;
}
Cur = Begin;
@@ -1147,6 +1182,45 @@ AliasClone:
Cur = Next;
}
+GlobalIFuncClone:
+ Begin = LLVMGetFirstGlobalIFunc(Src);
+ End = LLVMGetLastGlobalIFunc(Src);
+ if (!Begin) {
+ if (End != nullptr)
+ report_fatal_error("Range has an end but no beginning");
+ goto NamedMDClone;
+ }
+
+ Cur = Begin;
+ Next = nullptr;
+ while (true) {
+ size_t NameLen;
+ const char *Name = LLVMGetValueName2(Cur, &NameLen);
+ LLVMValueRef IFunc = LLVMGetNamedGlobalIFunc(M, Name, NameLen);
+ if (!IFunc)
+ report_fatal_error("Global ifunc must have been declared already");
+
+ if (LLVMValueRef Resolver = LLVMGetGlobalIFuncResolver(Cur)) {
+ LLVMSetGlobalIFuncResolver(IFunc, clone_constant(Resolver, M));
+ }
+
+ LLVMSetLinkage(IFunc, LLVMGetLinkage(Cur));
+ LLVMSetUnnamedAddress(IFunc, LLVMGetUnnamedAddress(Cur));
+
+ Next = LLVMGetNextGlobalIFunc(Cur);
+ if (Next == nullptr) {
+ if (Cur != End)
+ report_fatal_error("Last global alias does not match End");
+ break;
+ }
+
+ LLVMValueRef Prev = LLVMGetPreviousGlobalIFunc(Next);
+ if (Prev != Cur)
+ report_fatal_error("Next.Previous global alias is not Current");
+
+ Cur = Next;
+ }
+
NamedMDClone:
LLVMNamedMDNodeRef BeginMD = LLVMGetFirstNamedMetadata(Src);
LLVMNamedMDNodeRef EndMD = LLVMGetLastNamedMetadata(Src);
OpenPOWER on IntegriCloud