summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Homerding <homerdin@gmail.com>2019-07-08 15:57:56 +0000
committerBrian Homerding <homerdin@gmail.com>2019-07-08 15:57:56 +0000
commitb4b21d807e4f47f1f87b05fddf6bb3167b14476e (patch)
tree2ca1fdfcf72d73e5d6245cbd845c3f372e0a9dc9
parentb52a0c0cc88f0d66ae8ea770f92ed3448aee88a7 (diff)
downloadbcm5719-llvm-b4b21d807e4f47f1f87b05fddf6bb3167b14476e.tar.gz
bcm5719-llvm-b4b21d807e4f47f1f87b05fddf6bb3167b14476e.zip
Add, and infer, a nofree function attribute
This patch adds a function attribute, nofree, to indicate that a function does not, directly or indirectly, call a memory-deallocation function (e.g., free, C++'s operator delete). Reviewers: jdoerfert Differential Revision: https://reviews.llvm.org/D49165 llvm-svn: 365336
-rw-r--r--llvm/docs/LangRef.rst8
-rw-r--r--llvm/include/llvm/Analysis/MemoryBuiltins.h13
-rw-r--r--llvm/include/llvm/Analysis/TargetLibraryInfo.def9
-rw-r--r--llvm/include/llvm/Bitcode/LLVMBitCodes.h1
-rw-r--r--llvm/include/llvm/IR/Attributes.td3
-rw-r--r--llvm/include/llvm/IR/Function.h8
-rw-r--r--llvm/lib/Analysis/MemoryBuiltins.cpp55
-rw-r--r--llvm/lib/AsmParser/LLLexer.cpp1
-rw-r--r--llvm/lib/AsmParser/LLParser.cpp1
-rw-r--r--llvm/lib/AsmParser/LLToken.h1
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp4
-rw-r--r--llvm/lib/Bitcode/Writer/BitcodeWriter.cpp2
-rw-r--r--llvm/lib/IR/Attributes.cpp2
-rw-r--r--llvm/lib/IR/Verifier.cpp1
-rw-r--r--llvm/lib/Transforms/IPO/FunctionAttrs.cpp56
-rw-r--r--llvm/lib/Transforms/Utils/BuildLibCalls.cpp11
-rw-r--r--llvm/lib/Transforms/Utils/CodeExtractor.cpp1
-rw-r--r--llvm/test/Analysis/TypeBasedAliasAnalysis/functionattrs.ll4
-rw-r--r--llvm/test/Bitcode/attributes.ll10
-rw-r--r--llvm/test/CodeGen/AMDGPU/inline-attr.ll6
-rw-r--r--llvm/test/CodeGen/X86/no-plt-libcalls.ll2
-rw-r--r--llvm/test/Feature/OperandBundles/function-attrs.ll7
-rw-r--r--llvm/test/Transforms/FunctionAttrs/atomic.ll2
-rw-r--r--llvm/test/Transforms/FunctionAttrs/nofree.ll113
-rw-r--r--llvm/test/Transforms/FunctionAttrs/operand-bundles-scc.ll2
-rw-r--r--llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll16
-rw-r--r--llvm/test/Transforms/InferFunctionAttrs/annotate.ll579
-rw-r--r--llvm/test/Transforms/InferFunctionAttrs/norecurse_debug.ll2
-rw-r--r--llvm/test/Transforms/LICM/strlen.ll2
-rw-r--r--llvm/test/Transforms/LoopIdiom/basic.ll2
30 files changed, 593 insertions, 331 deletions
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 8325e08e180..ae266629a64 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -1453,6 +1453,14 @@ example:
duplicated by inlining. That implies that the function has
internal linkage and only has one call site, so the original
call is dead after inlining.
+``nofree``
+ This function attribute indicates that the function does not, directly or
+ indirectly, call a memory-deallocation function (free, for example). As a
+ result, uncaptured pointers that are known to be dereferenceable prior to a
+ call to a function with the ``nofree`` attribute are still known to be
+ dereferenceable after the call (the capturing condition is necessary in
+ environments where the function might communicate the pointer to another thread
+ which then deallocates the memory).
``noimplicitfloat``
This attributes disables implicit floating-point instructions.
``noinline``
diff --git a/llvm/include/llvm/Analysis/MemoryBuiltins.h b/llvm/include/llvm/Analysis/MemoryBuiltins.h
index 9a5c77d2c1b..49f9e58ffad 100644
--- a/llvm/include/llvm/Analysis/MemoryBuiltins.h
+++ b/llvm/include/llvm/Analysis/MemoryBuiltins.h
@@ -18,6 +18,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Analysis/TargetFolder.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/IR/CallSite.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InstVisitor.h"
@@ -83,6 +84,15 @@ bool isMallocOrCallocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
bool isAllocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
bool LookThroughBitCast = false);
+/// Tests if a value is a call or invoke to a library function that
+/// reallocates memory (e.g., realloc).
+bool isReallocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
+ bool LookThroughBitCast = false);
+
+/// Tests if a function is a call or invoke to a library function that
+/// reallocates memory (e.g., realloc).
+bool isReallocLikeFn(const Function *F, const TargetLibraryInfo *TLI);
+
//===----------------------------------------------------------------------===//
// malloc Call Utility Functions.
//
@@ -134,6 +144,9 @@ inline CallInst *extractCallocCall(Value *I, const TargetLibraryInfo *TLI) {
// free Call Utility Functions.
//
+/// isLibFreeFunction - Returns true if the function is a builtin free()
+bool isLibFreeFunction(const Function *F, const LibFunc TLIFn);
+
/// isFreeCall - Returns non-null if the value is a call to the builtin free()
const CallInst *isFreeCall(const Value *I, const TargetLibraryInfo *TLI);
diff --git a/llvm/include/llvm/Analysis/TargetLibraryInfo.def b/llvm/include/llvm/Analysis/TargetLibraryInfo.def
index bbccca4ca66..afed404f04c 100644
--- a/llvm/include/llvm/Analysis/TargetLibraryInfo.def
+++ b/llvm/include/llvm/Analysis/TargetLibraryInfo.def
@@ -11,6 +11,15 @@
// Which is defined depends on whether TLI_DEFINE_ENUM is defined or
// TLI_DEFINE_STRING is defined. Only one should be defined at a time.
+// NOTE: The nofree attribute is added to Libfuncs which are not
+// listed as free or realloc functions in MemoryBuiltins.cpp
+//
+// When adding a function which frees memory include the LibFunc
+// in lib/Analysis/MemoryBuiltins.cpp "isLibFreeFunction".
+//
+// When adding a LibFunc which reallocates memory include the LibFunc
+// in lib/Analysis/MemoryBuiltins.cpp "AllocationFnData[]".
+
#if !(defined(TLI_DEFINE_ENUM) || defined(TLI_DEFINE_STRING))
#error "Must define TLI_DEFINE_ENUM or TLI_DEFINE_STRING for TLI .def."
#elif defined(TLI_DEFINE_ENUM) && defined(TLI_DEFINE_STRING)
diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
index 5f3f7b1bd37..3ec0b383d54 100644
--- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h
+++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
@@ -629,6 +629,7 @@ enum AttributeKindCodes {
ATTR_KIND_SPECULATIVE_LOAD_HARDENING = 59,
ATTR_KIND_IMMARG = 60,
ATTR_KIND_WILLRETURN = 61,
+ ATTR_KIND_NOFREE = 62
};
enum ComdatSelectionKindCodes {
diff --git a/llvm/include/llvm/IR/Attributes.td b/llvm/include/llvm/IR/Attributes.td
index 96dd915bca0..694a23a8045 100644
--- a/llvm/include/llvm/IR/Attributes.td
+++ b/llvm/include/llvm/IR/Attributes.td
@@ -85,6 +85,9 @@ def NoCapture : EnumAttr<"nocapture">;
/// Call cannot be duplicated.
def NoDuplicate : EnumAttr<"noduplicate">;
+/// Function does not deallocate memory.
+def NoFree : EnumAttr<"nofree">;
+
/// Disable implicit floating point insts.
def NoImplicitFloat : EnumAttr<"noimplicitfloat">;
diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h
index b93541cbb16..7fa61e12f43 100644
--- a/llvm/include/llvm/IR/Function.h
+++ b/llvm/include/llvm/IR/Function.h
@@ -564,6 +564,14 @@ public:
addFnAttr(Attribute::Speculatable);
}
+ /// Determine if the call might deallocate memory.
+ bool doesNotFreeMemory() const {
+ return onlyReadsMemory() || hasFnAttribute(Attribute::NoFree);
+ }
+ void setDoesNotFreeMemory() {
+ addFnAttr(Attribute::NoFree);
+ }
+
/// Determine if the function is known not to recurse, directly or
/// indirectly.
bool doesNotRecurse() const {
diff --git a/llvm/lib/Analysis/MemoryBuiltins.cpp b/llvm/lib/Analysis/MemoryBuiltins.cpp
index 08254266482..d73419fad6a 100644
--- a/llvm/lib/Analysis/MemoryBuiltins.cpp
+++ b/llvm/lib/Analysis/MemoryBuiltins.cpp
@@ -263,6 +263,19 @@ bool llvm::isAllocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
return getAllocationData(V, AllocLike, TLI, LookThroughBitCast).hasValue();
}
+/// Tests if a value is a call or invoke to a library function that
+/// reallocates memory (e.g., realloc).
+bool llvm::isReallocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
+ bool LookThroughBitCast) {
+ return getAllocationData(V, ReallocLike, TLI, LookThroughBitCast).hasValue();
+}
+
+/// Tests if a functions is a call or invoke to a library function that
+/// reallocates memory (e.g., realloc).
+bool llvm::isReallocLikeFn(const Function *F, const TargetLibraryInfo *TLI) {
+ return getAllocationDataForFunction(F, ReallocLike, TLI).hasValue();
+}
+
/// extractMallocCall - Returns the corresponding CallInst if the instruction
/// is a malloc call. Since CallInst::CreateMalloc() only creates calls, we
/// ignore InvokeInst here.
@@ -358,19 +371,8 @@ const CallInst *llvm::extractCallocCall(const Value *I,
return isCallocLikeFn(I, TLI) ? cast<CallInst>(I) : nullptr;
}
-/// isFreeCall - Returns non-null if the value is a call to the builtin free()
-const CallInst *llvm::isFreeCall(const Value *I, const TargetLibraryInfo *TLI) {
- bool IsNoBuiltinCall;
- const Function *Callee =
- getCalledFunction(I, /*LookThroughBitCast=*/false, IsNoBuiltinCall);
- if (Callee == nullptr || IsNoBuiltinCall)
- return nullptr;
-
- StringRef FnName = Callee->getName();
- LibFunc TLIFn;
- if (!TLI || !TLI->getLibFunc(FnName, TLIFn) || !TLI->has(TLIFn))
- return nullptr;
-
+/// isLibFreeFunction - Returns true if the function is a builtin free()
+bool llvm::isLibFreeFunction(const Function *F, const LibFunc TLIFn) {
unsigned ExpectedNumParams;
if (TLIFn == LibFunc_free ||
TLIFn == LibFunc_ZdlPv || // operator delete(void*)
@@ -401,22 +403,39 @@ const CallInst *llvm::isFreeCall(const Value *I, const TargetLibraryInfo *TLI) {
TLIFn == LibFunc_ZdlPvSt11align_val_tRKSt9nothrow_t) // delete[](void*, align_val_t, nothrow)
ExpectedNumParams = 3;
else
- return nullptr;
+ return false;
// Check free prototype.
// FIXME: workaround for PR5130, this will be obsolete when a nobuiltin
// attribute will exist.
- FunctionType *FTy = Callee->getFunctionType();
+ FunctionType *FTy = F->getFunctionType();
if (!FTy->getReturnType()->isVoidTy())
- return nullptr;
+ return false;
if (FTy->getNumParams() != ExpectedNumParams)
+ return false;
+ if (FTy->getParamType(0) != Type::getInt8PtrTy(F->getContext()))
+ return false;
+
+ return true;
+}
+
+/// isFreeCall - Returns non-null if the value is a call to the builtin free()
+const CallInst *llvm::isFreeCall(const Value *I, const TargetLibraryInfo *TLI) {
+ bool IsNoBuiltinCall;
+ const Function *Callee =
+ getCalledFunction(I, /*LookThroughBitCast=*/false, IsNoBuiltinCall);
+ if (Callee == nullptr || IsNoBuiltinCall)
return nullptr;
- if (FTy->getParamType(0) != Type::getInt8PtrTy(Callee->getContext()))
+
+ StringRef FnName = Callee->getName();
+ LibFunc TLIFn;
+ if (!TLI || !TLI->getLibFunc(FnName, TLIFn) || !TLI->has(TLIFn))
return nullptr;
- return dyn_cast<CallInst>(I);
+ return isLibFreeFunction(Callee, TLIFn) ? dyn_cast<CallInst>(I) : nullptr;
}
+
//===----------------------------------------------------------------------===//
// Utility functions to compute size of objects.
//
diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp
index a23afac27b7..5bc628dac1f 100644
--- a/llvm/lib/AsmParser/LLLexer.cpp
+++ b/llvm/lib/AsmParser/LLLexer.cpp
@@ -650,6 +650,7 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(nobuiltin);
KEYWORD(nocapture);
KEYWORD(noduplicate);
+ KEYWORD(nofree);
KEYWORD(noimplicitfloat);
KEYWORD(noinline);
KEYWORD(norecurse);
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 085f3bd2999..1256e632551 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -1280,6 +1280,7 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B,
case lltok::kw_naked: B.addAttribute(Attribute::Naked); break;
case lltok::kw_nobuiltin: B.addAttribute(Attribute::NoBuiltin); break;
case lltok::kw_noduplicate: B.addAttribute(Attribute::NoDuplicate); break;
+ case lltok::kw_nofree: B.addAttribute(Attribute::NoFree); break;
case lltok::kw_noimplicitfloat:
B.addAttribute(Attribute::NoImplicitFloat); break;
case lltok::kw_noinline: B.addAttribute(Attribute::NoInline); break;
diff --git a/llvm/lib/AsmParser/LLToken.h b/llvm/lib/AsmParser/LLToken.h
index 8b0118e6942..a6a81865cb7 100644
--- a/llvm/lib/AsmParser/LLToken.h
+++ b/llvm/lib/AsmParser/LLToken.h
@@ -195,6 +195,7 @@ enum Kind {
kw_nobuiltin,
kw_nocapture,
kw_noduplicate,
+ kw_nofree,
kw_noimplicitfloat,
kw_noinline,
kw_norecurse,
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index a339f6eb710..0ba76f0f371 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -1278,6 +1278,8 @@ static uint64_t getRawAttributeMask(Attribute::AttrKind Val) {
return 1ULL << 61;
case Attribute::WillReturn:
return 1ULL << 62;
+ case Attribute::NoFree:
+ return 1ULL << 63;
case Attribute::Dereferenceable:
llvm_unreachable("dereferenceable attribute not supported in raw format");
break;
@@ -1442,6 +1444,8 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) {
return Attribute::NoCapture;
case bitc::ATTR_KIND_NO_DUPLICATE:
return Attribute::NoDuplicate;
+ case bitc::ATTR_KIND_NOFREE:
+ return Attribute::NoFree;
case bitc::ATTR_KIND_NO_IMPLICIT_FLOAT:
return Attribute::NoImplicitFloat;
case bitc::ATTR_KIND_NO_INLINE:
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index 547889f82c7..65b9e0bb6a1 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -639,6 +639,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
return bitc::ATTR_KIND_NO_CAPTURE;
case Attribute::NoDuplicate:
return bitc::ATTR_KIND_NO_DUPLICATE;
+ case Attribute::NoFree:
+ return bitc::ATTR_KIND_NOFREE;
case Attribute::NoImplicitFloat:
return bitc::ATTR_KIND_NO_IMPLICIT_FLOAT;
case Attribute::NoInline:
diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp
index 99fc447c5af..0073eda0838 100644
--- a/llvm/lib/IR/Attributes.cpp
+++ b/llvm/lib/IR/Attributes.cpp
@@ -321,6 +321,8 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
return "nocapture";
if (hasAttribute(Attribute::NoDuplicate))
return "noduplicate";
+ if (hasAttribute(Attribute::NoFree))
+ return "nofree";
if (hasAttribute(Attribute::NoImplicitFloat))
return "noimplicitfloat";
if (hasAttribute(Attribute::NoInline))
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index b0464346557..2655e3ce81e 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -1497,6 +1497,7 @@ static bool isFuncOnlyAttr(Attribute::AttrKind Kind) {
case Attribute::NoCfCheck:
case Attribute::NoUnwind:
case Attribute::NoInline:
+ case Attribute::NoFree:
case Attribute::AlwaysInline:
case Attribute::OptimizeForSize:
case Attribute::StackProtect:
diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
index 9e95e796da6..a3fb7d1d57a 100644
--- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
@@ -27,6 +27,7 @@
#include "llvm/Analysis/CallGraphSCCPass.h"
#include "llvm/Analysis/CaptureTracking.h"
#include "llvm/Analysis/LazyCallGraph.h"
+#include "llvm/Analysis/MemoryBuiltins.h"
#include "llvm/Analysis/MemoryLocation.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/Argument.h"
@@ -75,6 +76,7 @@ STATISTIC(NumNoAlias, "Number of function returns marked noalias");
STATISTIC(NumNonNullReturn, "Number of function returns marked nonnull");
STATISTIC(NumNoRecurse, "Number of functions marked as norecurse");
STATISTIC(NumNoUnwind, "Number of functions marked as nounwind");
+STATISTIC(NumNoFree, "Number of functions marked as nofree");
// FIXME: This is disabled by default to avoid exposing security vulnerabilities
// in C/C++ code compiled by clang:
@@ -88,6 +90,10 @@ static cl::opt<bool> DisableNoUnwindInference(
"disable-nounwind-inference", cl::Hidden,
cl::desc("Stop inferring nounwind attribute during function-attrs pass"));
+static cl::opt<bool> DisableNoFreeInference(
+ "disable-nofree-inference", cl::Hidden,
+ cl::desc("Stop inferring nofree attribute during function-attrs pass"));
+
namespace {
using SCCNodeSet = SmallSetVector<Function *, 8>;
@@ -1227,6 +1233,25 @@ static bool InstrBreaksNonThrowing(Instruction &I, const SCCNodeSet &SCCNodes) {
return true;
}
+/// Helper for NoFree inference predicate InstrBreaksAttribute.
+static bool InstrBreaksNoFree(Instruction &I, const SCCNodeSet &SCCNodes) {
+ CallSite CS(&I);
+ if (!CS)
+ return false;
+
+ Function *Callee = CS.getCalledFunction();
+ if (!Callee)
+ return true;
+
+ if (Callee->doesNotFreeMemory())
+ return false;
+
+ if (SCCNodes.count(Callee) > 0)
+ return false;
+
+ return true;
+}
+
/// Infer attributes from all functions in the SCC by scanning every
/// instruction for compliance to the attribute assumptions. Currently it
/// does:
@@ -1280,6 +1305,29 @@ static bool inferAttrsFromFunctionBodies(const SCCNodeSet &SCCNodes) {
},
/* RequiresExactDefinition= */ true});
+ if (!DisableNoFreeInference)
+ // Request to infer nofree attribute for all the functions in the SCC if
+ // every callsite within the SCC does not directly or indirectly free
+ // memory (except for calls to functions within the SCC). Note that nofree
+ // attribute suffers from derefinement - results may change depending on
+ // how functions are optimized. Thus it can be inferred only from exact
+ // definitions.
+ AI.registerAttrInference(AttributeInferer::InferenceDescriptor{
+ Attribute::NoFree,
+ // Skip functions known not to free memory.
+ [](const Function &F) { return F.doesNotFreeMemory(); },
+ // Instructions that break non-deallocating assumption.
+ [SCCNodes](Instruction &I) {
+ return InstrBreaksNoFree(I, SCCNodes);
+ },
+ [](Function &F) {
+ LLVM_DEBUG(dbgs()
+ << "Adding nofree attr to fn " << F.getName() << "\n");
+ F.setDoesNotFreeMemory();
+ ++NumNoFree;
+ },
+ /* RequiresExactDefinition= */ true});
+
// Perform all the requested attribute inference actions.
return AI.run(SCCNodes);
}
@@ -1322,7 +1370,8 @@ static bool addNoRecurseAttrs(const SCCNodeSet &SCCNodes) {
}
template <typename AARGetterT>
-static bool deriveAttrsInPostOrder(SCCNodeSet &SCCNodes, AARGetterT &&AARGetter,
+static bool deriveAttrsInPostOrder(SCCNodeSet &SCCNodes,
+ AARGetterT &&AARGetter,
bool HasUnknownCall) {
bool Changed = false;
@@ -1353,6 +1402,11 @@ PreservedAnalyses PostOrderFunctionAttrsPass::run(LazyCallGraph::SCC &C,
FunctionAnalysisManager &FAM =
AM.getResult<FunctionAnalysisManagerCGSCCProxy>(C, CG).getManager();
+ const ModuleAnalysisManager &MAM =
+ AM.getResult<ModuleAnalysisManagerCGSCCProxy>(C, CG).getManager();
+ assert(C.size() > 0 && "Cannot handle an empty SCC!");
+ Module &M = *C.begin()->getFunction().getParent();
+
// We pass a lambda into functions to wire them up to the analysis manager
// for getting function analyses.
auto AARGetter = [&](Function &F) -> AAResults & {
diff --git a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
index d486d915998..27f110e24f9 100644
--- a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
@@ -22,6 +22,7 @@
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
+#include "llvm/Analysis/MemoryBuiltins.h"
using namespace llvm;
@@ -120,6 +121,13 @@ static bool setNonLazyBind(Function &F) {
return true;
}
+static bool setDoesNotFreeMemory(Function &F) {
+ if (F.hasFnAttribute(Attribute::NoFree))
+ return false;
+ F.addFnAttr(Attribute::NoFree);
+ return true;
+}
+
bool llvm::inferLibFuncAttributes(Module *M, StringRef Name,
const TargetLibraryInfo &TLI) {
Function *F = M->getFunction(Name);
@@ -135,6 +143,9 @@ bool llvm::inferLibFuncAttributes(Function &F, const TargetLibraryInfo &TLI) {
bool Changed = false;
+ if(!isLibFreeFunction(&F, TheLibFunc) && !isReallocLikeFn(&F, &TLI))
+ Changed |= setDoesNotFreeMemory(F);
+
if (F.getParent() != nullptr && F.getParent()->getRtLibUseGOT())
Changed |= setNonLazyBind(F);
diff --git a/llvm/lib/Transforms/Utils/CodeExtractor.cpp b/llvm/lib/Transforms/Utils/CodeExtractor.cpp
index 23a404c11a6..c9e9033d9c1 100644
--- a/llvm/lib/Transforms/Utils/CodeExtractor.cpp
+++ b/llvm/lib/Transforms/Utils/CodeExtractor.cpp
@@ -814,6 +814,7 @@ Function *CodeExtractor::constructFunction(const ValueSet &inputs,
case Attribute::InlineHint:
case Attribute::MinSize:
case Attribute::NoDuplicate:
+ case Attribute::NoFree:
case Attribute::NoImplicitFloat:
case Attribute::NoInline:
case Attribute::NonLazyBind:
diff --git a/llvm/test/Analysis/TypeBasedAliasAnalysis/functionattrs.ll b/llvm/test/Analysis/TypeBasedAliasAnalysis/functionattrs.ll
index e2b7c971dd8..63df6bd8400 100644
--- a/llvm/test/Analysis/TypeBasedAliasAnalysis/functionattrs.ll
+++ b/llvm/test/Analysis/TypeBasedAliasAnalysis/functionattrs.ll
@@ -73,11 +73,11 @@ declare void @callee(i32* %p) nounwind
declare void @llvm.memcpy.p0i8.p0i8.i64(i8*, i8*, i64, i1) nounwind
; CHECK: attributes #0 = { norecurse nounwind readnone }
-; CHECK: attributes #1 = { norecurse nounwind writeonly }
+; CHECK: attributes #1 = { nofree norecurse nounwind writeonly }
; CHECK: attributes #2 = { nounwind readonly }
; CHECK: attributes #3 = { nounwind }
; CHECK: attributes #4 = { nounwind readnone }
-; CHECK: attributes #5 = { norecurse nounwind }
+; CHECK: attributes #5 = { nofree norecurse nounwind }
; CHECK: attributes #6 = { argmemonly nounwind }
; Root note.
diff --git a/llvm/test/Bitcode/attributes.ll b/llvm/test/Bitcode/attributes.ll
index 3aac9ee64ce..84630cd4bf8 100644
--- a/llvm/test/Bitcode/attributes.ll
+++ b/llvm/test/Bitcode/attributes.ll
@@ -204,7 +204,7 @@ define void @f34()
; CHECK: define void @f34()
{
call void @nobuiltin() nobuiltin
-; CHECK: call void @nobuiltin() #37
+; CHECK: call void @nobuiltin() #38
ret void;
}
@@ -357,6 +357,11 @@ define void @f60() willreturn
ret void
}
+; CHECK: define void @f61() #37
+define void @f61() nofree {
+ ret void
+}
+
; CHECK: attributes #0 = { noreturn }
; CHECK: attributes #1 = { nounwind }
; CHECK: attributes #2 = { readnone }
@@ -394,4 +399,5 @@ define void @f60() willreturn
; CHECK: attributes #34 = { sanitize_hwaddress }
; CHECK: attributes #35 = { shadowcallstack }
; CHECK: attributes #36 = { willreturn }
-; CHECK: attributes #37 = { nobuiltin }
+; CHECK: attributes #37 = { nofree }
+; CHECK: attributes #38 = { nobuiltin }
diff --git a/llvm/test/CodeGen/AMDGPU/inline-attr.ll b/llvm/test/CodeGen/AMDGPU/inline-attr.ll
index 6f6b5f4c0b0..b44138d107a 100644
--- a/llvm/test/CodeGen/AMDGPU/inline-attr.ll
+++ b/llvm/test/CodeGen/AMDGPU/inline-attr.ll
@@ -7,13 +7,13 @@
; GCN: %mul.i = fmul float %load, 1.500000e+01
; UNSAFE: attributes #0 = { norecurse nounwind readnone "less-precise-fpmad"="true" "no-infs-fp-math"="true" "no-nans-fp-math"="true" "unsafe-fp-math"="true" }
-; UNSAFE: attributes #1 = { norecurse nounwind "less-precise-fpmad"="true" "no-infs-fp-math"="true" "no-nans-fp-math"="true" "unsafe-fp-math"="true" }
+; UNSAFE: attributes #1 = { nofree norecurse nounwind "less-precise-fpmad"="true" "no-infs-fp-math"="true" "no-nans-fp-math"="true" "unsafe-fp-math"="true" }
; NOINFS: attributes #0 = { norecurse nounwind readnone "no-infs-fp-math"="true" }
-; NOINFS: attributes #1 = { norecurse nounwind "less-precise-fpmad"="false" "no-infs-fp-math"="true" "no-nans-fp-math"="false" "unsafe-fp-math"="false" }
+; NOINFS: attributes #1 = { nofree norecurse nounwind "less-precise-fpmad"="false" "no-infs-fp-math"="true" "no-nans-fp-math"="false" "unsafe-fp-math"="false" }
; NONANS: attributes #0 = { norecurse nounwind readnone "no-nans-fp-math"="true" }
-; NONANS: attributes #1 = { norecurse nounwind "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="true" "unsafe-fp-math"="false" }
+; NONANS: attributes #1 = { nofree norecurse nounwind "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="true" "unsafe-fp-math"="false" }
define float @foo(float %x) #0 {
entry:
diff --git a/llvm/test/CodeGen/X86/no-plt-libcalls.ll b/llvm/test/CodeGen/X86/no-plt-libcalls.ll
index 795ad57f9a5..876c8f10e42 100644
--- a/llvm/test/CodeGen/X86/no-plt-libcalls.ll
+++ b/llvm/test/CodeGen/X86/no-plt-libcalls.ll
@@ -12,7 +12,7 @@ define void @printf_call() {
ret void
}
-; CHECK: Function Attrs: nounwind nonlazybind
+; CHECK: Function Attrs: nofree nounwind nonlazybind
; CHECK-NEXT: declare i32 @puts(i8* nocapture readonly)
!llvm.module.flags = !{!0}
diff --git a/llvm/test/Feature/OperandBundles/function-attrs.ll b/llvm/test/Feature/OperandBundles/function-attrs.ll
index 808f396fed8..6e1b2550399 100644
--- a/llvm/test/Feature/OperandBundles/function-attrs.ll
+++ b/llvm/test/Feature/OperandBundles/function-attrs.ll
@@ -6,7 +6,7 @@ declare void @f_readnone() readnone
define void @test_0(i32* %x) {
; FunctionAttrs must not infer readonly / readnone for %x
-; CHECK-LABEL: define void @test_0(i32* %x) {
+; CHECK-LABEL: define void @test_0(i32* %x) #2 {
entry:
; CHECK: call void @f_readonly() [ "foo"(i32* %x) ]
call void @f_readonly() [ "foo"(i32* %x) ]
@@ -16,7 +16,7 @@ define void @test_0(i32* %x) {
define void @test_1(i32* %x) {
; FunctionAttrs must not infer readonly / readnone for %x
-; CHECK-LABEL: define void @test_1(i32* %x) {
+; CHECK-LABEL: define void @test_1(i32* %x) #2 {
entry:
; CHECK: call void @f_readnone() [ "foo"(i32* %x) ]
call void @f_readnone() [ "foo"(i32* %x) ]
@@ -31,3 +31,6 @@ define void @test_2(i32* %x) {
call void @f_readonly() [ "deopt"(i32* %x) ]
ret void
}
+
+; CHECK: attributes #2 = { nofree }
+
diff --git a/llvm/test/Transforms/FunctionAttrs/atomic.ll b/llvm/test/Transforms/FunctionAttrs/atomic.ll
index af87a28770e..35de0ce800d 100644
--- a/llvm/test/Transforms/FunctionAttrs/atomic.ll
+++ b/llvm/test/Transforms/FunctionAttrs/atomic.ll
@@ -21,4 +21,4 @@ entry:
}
; CHECK: attributes #0 = { norecurse nounwind readnone ssp uwtable }
-; CHECK: attributes #1 = { norecurse nounwind ssp uwtable }
+; CHECK: attributes #1 = { nofree norecurse nounwind ssp uwtable }
diff --git a/llvm/test/Transforms/FunctionAttrs/nofree.ll b/llvm/test/Transforms/FunctionAttrs/nofree.ll
new file mode 100644
index 00000000000..e72ff2f5325
--- /dev/null
+++ b/llvm/test/Transforms/FunctionAttrs/nofree.ll
@@ -0,0 +1,113 @@
+; RUN: opt < %s -functionattrs -S | FileCheck %s
+; RUN: opt < %s -passes=function-attrs -S | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; CHECK: define void @_Z4foo1Pi(i32* nocapture readnone %a) local_unnamed_addr #0 {
+define void @_Z4foo1Pi(i32* nocapture readnone %a) local_unnamed_addr #0 {
+entry:
+ tail call void @_Z3extv()
+ ret void
+}
+
+declare void @_Z3extv() local_unnamed_addr
+
+; CHECK: define void @_Z4foo2Pi(i32* nocapture %a) local_unnamed_addr #1 {
+define void @_Z4foo2Pi(i32* nocapture %a) local_unnamed_addr #1 {
+entry:
+ %0 = bitcast i32* %a to i8*
+ tail call void @free(i8* %0) #2
+ ret void
+}
+
+declare void @free(i8* nocapture) local_unnamed_addr #2
+
+; CHECK: define i32 @_Z4foo3Pi(i32* nocapture readonly %a) local_unnamed_addr #3 {
+define i32 @_Z4foo3Pi(i32* nocapture readonly %a) local_unnamed_addr #3 {
+entry:
+ %0 = load i32, i32* %a, align 4
+ ret i32 %0
+}
+
+; CHECK: define double @_Z4foo4Pd(double* nocapture readonly %a) local_unnamed_addr #1 {
+define double @_Z4foo4Pd(double* nocapture readonly %a) local_unnamed_addr #1 {
+entry:
+ %0 = load double, double* %a, align 8
+ %call = tail call double @cos(double %0) #2
+ ret double %call
+}
+
+declare double @cos(double) local_unnamed_addr #2
+
+; CHECK: define noalias i32* @_Z4foo5Pm(i64* nocapture readonly %a) local_unnamed_addr #1 {
+define noalias i32* @_Z4foo5Pm(i64* nocapture readonly %a) local_unnamed_addr #1 {
+entry:
+ %0 = load i64, i64* %a, align 8
+ %call = tail call noalias i8* @malloc(i64 %0) #2
+ %1 = bitcast i8* %call to i32*
+ ret i32* %1
+}
+
+declare noalias i8* @malloc(i64) local_unnamed_addr #2
+
+; CHECK: define noalias i64* @_Z4foo6Pm(i64* nocapture %a) local_unnamed_addr #1 {
+define noalias i64* @_Z4foo6Pm(i64* nocapture %a) local_unnamed_addr #1 {
+entry:
+ %0 = bitcast i64* %a to i8*
+ %1 = load i64, i64* %a, align 8
+ %call = tail call i8* @realloc(i8* %0, i64 %1) #2
+ %2 = bitcast i8* %call to i64*
+ ret i64* %2
+}
+
+declare noalias i8* @realloc(i8* nocapture, i64) local_unnamed_addr #2
+
+; CHECK: define void @_Z4foo7Pi(i32* %a) local_unnamed_addr #1 {
+define void @_Z4foo7Pi(i32* %a) local_unnamed_addr #1 {
+entry:
+ %isnull = icmp eq i32* %a, null
+ br i1 %isnull, label %delete.end, label %delete.notnull
+
+delete.notnull: ; preds = %entry
+ %0 = bitcast i32* %a to i8*
+ tail call void @_ZdlPv(i8* %0) #5
+ br label %delete.end
+
+delete.end: ; preds = %delete.notnull, %entry
+ ret void
+}
+
+declare void @_ZdlPv(i8*) local_unnamed_addr #4
+
+; CHECK: define void @_Z4foo8Pi(i32* %a) local_unnamed_addr #1 {
+define void @_Z4foo8Pi(i32* %a) local_unnamed_addr #1 {
+entry:
+ %isnull = icmp eq i32* %a, null
+ br i1 %isnull, label %delete.end, label %delete.notnull
+
+delete.notnull: ; preds = %entry
+ %0 = bitcast i32* %a to i8*
+ tail call void @_ZdaPv(i8* %0) #5
+ br label %delete.end
+
+delete.end: ; preds = %delete.notnull, %entry
+ ret void
+}
+
+declare void @_ZdaPv(i8*) local_unnamed_addr #4
+
+attributes #0 = { uwtable }
+attributes #1 = { nounwind uwtable }
+attributes #2 = { nounwind }
+attributes #3 = { norecurse nounwind readonly uwtable }
+attributes #4 = { nobuiltin nounwind }
+attributes #5 = { builtin nounwind }
+
+; CHECK: attributes #0 = { uwtable }
+; CHECK: attributes #1 = { nounwind uwtable }
+; CHECK: attributes #2 = { nounwind }
+; CHECK: attributes #3 = { norecurse nounwind readonly uwtable }
+; CHECK: attributes #4 = { nobuiltin nounwind }
+; CHECK: attributes #5 = { builtin nounwind }
+
diff --git a/llvm/test/Transforms/FunctionAttrs/operand-bundles-scc.ll b/llvm/test/Transforms/FunctionAttrs/operand-bundles-scc.ll
index 69808a83c6d..4ad195ea2b5 100644
--- a/llvm/test/Transforms/FunctionAttrs/operand-bundles-scc.ll
+++ b/llvm/test/Transforms/FunctionAttrs/operand-bundles-scc.ll
@@ -14,4 +14,4 @@ define void @g() {
}
-; CHECK: attributes #0 = { nounwind }
+; CHECK: attributes #0 = { nofree nounwind }
diff --git a/llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll b/llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll
index 0828db35fd2..be190b7c4d3 100644
--- a/llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll
+++ b/llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll
@@ -30,7 +30,7 @@
;
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
-; CHECK: Function Attrs: nounwind
+; CHECK: Function Attrs: nofree nounwind
; CHECK-NEXT: define i32* @external_ret2_nrw(i32* %n0, i32* %r0, i32* %w0)
define i32* @external_ret2_nrw(i32* %n0, i32* %r0, i32* %w0) {
entry:
@@ -41,7 +41,7 @@ entry:
ret i32* %call3
}
-; CHECK: Function Attrs: nounwind
+; CHECK: Function Attrs: nofree nounwind
; CHECK-NEXT: define internal i32* @internal_ret0_nw(i32* %n0, i32* %w0)
define internal i32* @internal_ret0_nw(i32* %n0, i32* %w0) {
entry:
@@ -70,7 +70,7 @@ return: ; preds = %if.end, %if.then
ret i32* %retval.0
}
-; CHECK: Function Attrs: nounwind
+; CHECK: Function Attrs: nofree nounwind
; CHECK-NEXT: define internal i32* @internal_ret1_rrw(i32* %r0, i32* %r1, i32* %w0)
define internal i32* @internal_ret1_rrw(i32* %r0, i32* %r1, i32* %w0) {
entry:
@@ -102,7 +102,7 @@ return: ; preds = %if.end, %if.then
ret i32* %retval.0
}
-; CHECK: Function Attrs: norecurse nounwind
+; CHECK: Function Attrs: nofree norecurse nounwind
; CHECK-NEXT: define i32* @external_sink_ret2_nrw(i32* readnone %n0, i32* nocapture readonly %r0, i32* returned %w0)
define i32* @external_sink_ret2_nrw(i32* %n0, i32* %r0, i32* %w0) {
entry:
@@ -121,7 +121,7 @@ return: ; preds = %if.end, %if.then
ret i32* %w0
}
-; CHECK: Function Attrs: nounwind
+; CHECK: Function Attrs: nofree nounwind
; CHECK-NEXT: define internal i32* @internal_ret1_rw(i32* %r0, i32* %w0)
define internal i32* @internal_ret1_rw(i32* %r0, i32* %w0) {
entry:
@@ -147,7 +147,7 @@ return: ; preds = %if.end, %if.then
ret i32* %retval.0
}
-; CHECK: Function Attrs: nounwind
+; CHECK: Function Attrs: nofree nounwind
; CHECK-NEXT: define i32* @external_source_ret2_nrw(i32* %n0, i32* %r0, i32* %w0)
define i32* @external_source_ret2_nrw(i32* %n0, i32* %r0, i32* %w0) {
entry:
@@ -160,6 +160,6 @@ entry:
; for a subset relation.
;
; CHECK-NOT: attributes #
-; CHECK: attributes #{{.*}} = { nounwind }
-; CHECK: attributes #{{.*}} = { norecurse nounwind }
+; CHECK: attributes #{{.*}} = { nofree nounwind }
+; CHECK: attributes #{{.*}} = { nofree norecurse nounwind }
; CHECK-NOT: attributes #
diff --git a/llvm/test/Transforms/InferFunctionAttrs/annotate.ll b/llvm/test/Transforms/InferFunctionAttrs/annotate.ll
index 02278161345..cb446476400 100644
--- a/llvm/test/Transforms/InferFunctionAttrs/annotate.ll
+++ b/llvm/test/Transforms/InferFunctionAttrs/annotate.ll
@@ -5,14 +5,14 @@
; RUN: opt < %s -mtriple=nvptx -inferattrs -S | FileCheck -check-prefix=CHECK-NVPTX %s
; operator new routines
-declare i8* @_Znwj(i64)
-; CHECK: declare noalias nonnull i8* @_Znwj(i64)
+declare i8* @_Znwj(i64 )
+; CHECK: declare noalias nonnull i8* @_Znwj(i64) [[G0:#[0-9]+]]
declare i8* @_Znwm(i64)
-; CHECK: declare noalias nonnull i8* @_Znwm(i64)
+; CHECK: declare noalias nonnull i8* @_Znwm(i64) [[G0]]
declare i32 @__nvvm_reflect(i8*)
; CHECK-NVPTX: declare i32 @__nvvm_reflect(i8*) [[G0:#[0-9]+]]
-; CHECK-NVPTX: attributes [[G0]] = { nounwind readnone }
+; CHECK-NVPTX: attributes [[G0]] = { nofree nounwind readnone }
; Check all the libc functions (thereby also exercising the prototype check).
@@ -160,244 +160,244 @@ declare double @__sinpi(double)
; CHECK: declare float @__sinpif(float)
declare float @__sinpif(float)
-; CHECK: declare i32 @abs(i32)
+; CHECK: declare i32 @abs(i32) [[G0]]
declare i32 @abs(i32)
-; CHECK: declare i32 @access(i8* nocapture readonly, i32) [[G0:#[0-9]+]]
+; CHECK: declare i32 @access(i8* nocapture readonly, i32) [[G1:#[0-9]+]]
declare i32 @access(i8*, i32)
-; CHECK: declare double @acos(double)
+; CHECK: declare double @acos(double) [[G0]]
declare double @acos(double)
-; CHECK: declare float @acosf(float)
+; CHECK: declare float @acosf(float) [[G0]]
declare float @acosf(float)
-; CHECK: declare double @acosh(double)
+; CHECK: declare double @acosh(double) [[G0]]
declare double @acosh(double)
-; CHECK: declare float @acoshf(float)
+; CHECK: declare float @acoshf(float) [[G0]]
declare float @acoshf(float)
-; CHECK: declare x86_fp80 @acoshl(x86_fp80)
+; CHECK: declare x86_fp80 @acoshl(x86_fp80) [[G0]]
declare x86_fp80 @acoshl(x86_fp80)
-; CHECK: declare x86_fp80 @acosl(x86_fp80)
+; CHECK: declare x86_fp80 @acosl(x86_fp80) [[G0]]
declare x86_fp80 @acosl(x86_fp80)
-; CHECK: declare double @asin(double)
+; CHECK: declare double @asin(double) [[G0]]
declare double @asin(double)
-; CHECK: declare float @asinf(float)
+; CHECK: declare float @asinf(float) [[G0]]
declare float @asinf(float)
-; CHECK: declare double @asinh(double)
+; CHECK: declare double @asinh(double) [[G0]]
declare double @asinh(double)
-; CHECK: declare float @asinhf(float)
+; CHECK: declare float @asinhf(float) [[G0]]
declare float @asinhf(float)
-; CHECK: declare x86_fp80 @asinhl(x86_fp80)
+; CHECK: declare x86_fp80 @asinhl(x86_fp80) [[G0]]
declare x86_fp80 @asinhl(x86_fp80)
-; CHECK: declare x86_fp80 @asinl(x86_fp80)
+; CHECK: declare x86_fp80 @asinl(x86_fp80) [[G0]]
declare x86_fp80 @asinl(x86_fp80)
-; CHECK: declare double @atan(double)
+; CHECK: declare double @atan(double) [[G0]]
declare double @atan(double)
-; CHECK: declare double @atan2(double, double)
+; CHECK: declare double @atan2(double, double) [[G0]]
declare double @atan2(double, double)
-; CHECK: declare float @atan2f(float, float)
+; CHECK: declare float @atan2f(float, float) [[G0]]
declare float @atan2f(float, float)
-; CHECK: declare x86_fp80 @atan2l(x86_fp80, x86_fp80)
+; CHECK: declare x86_fp80 @atan2l(x86_fp80, x86_fp80) [[G0]]
declare x86_fp80 @atan2l(x86_fp80, x86_fp80)
-; CHECK: declare float @atanf(float)
+; CHECK: declare float @atanf(float) [[G0]]
declare float @atanf(float)
-; CHECK: declare double @atanh(double)
+; CHECK: declare double @atanh(double) [[G0]]
declare double @atanh(double)
-; CHECK: declare float @atanhf(float)
+; CHECK: declare float @atanhf(float) [[G0]]
declare float @atanhf(float)
-; CHECK: declare x86_fp80 @atanhl(x86_fp80)
+; CHECK: declare x86_fp80 @atanhl(x86_fp80) [[G0]]
declare x86_fp80 @atanhl(x86_fp80)
-; CHECK: declare x86_fp80 @atanl(x86_fp80)
+; CHECK: declare x86_fp80 @atanl(x86_fp80) [[G0]]
declare x86_fp80 @atanl(x86_fp80)
-; CHECK: declare double @atof(i8* nocapture) [[G1:#[0-9]+]]
+; CHECK: declare double @atof(i8* nocapture) [[G2:#[0-9]+]]
declare double @atof(i8*)
-; CHECK: declare i32 @atoi(i8* nocapture) [[G1]]
+; CHECK: declare i32 @atoi(i8* nocapture) [[G2]]
declare i32 @atoi(i8*)
-; CHECK: declare i64 @atol(i8* nocapture) [[G1]]
+; CHECK: declare i64 @atol(i8* nocapture) [[G2]]
declare i64 @atol(i8*)
-; CHECK: declare i64 @atoll(i8* nocapture) [[G1]]
+; CHECK: declare i64 @atoll(i8* nocapture) [[G2]]
declare i64 @atoll(i8*)
-; CHECK-DARWIN: declare i32 @bcmp(i8* nocapture, i8* nocapture, i64) [[G1]]
-; CHECK-LINUX: declare i32 @bcmp(i8* nocapture, i8* nocapture, i64) [[G1]]
-; CHECK-UNKNOWN-NOT: declare i32 @bcmp(i8* nocapture, i8* nocapture, i64) [[G1]]
-; CHECK-NVPTX-NOT: declare i32 @bcmp(i8* nocapture, i8* nocapture, i64) [[G1]]
+; CHECK-DARWIN: declare i32 @bcmp(i8* nocapture, i8* nocapture, i64) [[G2]]
+; CHECK-LINUX: declare i32 @bcmp(i8* nocapture, i8* nocapture, i64) [[G2]]
+; CHECK-UNKNOWN-NOT: declare i32 @bcmp(i8* nocapture, i8* nocapture, i64) [[G2]]
+; CHECK-NVPTX-NOT: declare i32 @bcmp(i8* nocapture, i8* nocapture, i64) [[G2]]
declare i32 @bcmp(i8*, i8*, i64)
-; CHECK: declare void @bcopy(i8* nocapture readonly, i8* nocapture, i64) [[G0]]
+; CHECK: declare void @bcopy(i8* nocapture readonly, i8* nocapture, i64) [[G1]]
declare void @bcopy(i8*, i8*, i64)
-; CHECK: declare void @bzero(i8* nocapture, i64) [[G0]]
+; CHECK: declare void @bzero(i8* nocapture, i64) [[G1]]
declare void @bzero(i8*, i64)
-; CHECK: declare noalias i8* @calloc(i64, i64) [[G0]]
+; CHECK: declare noalias i8* @calloc(i64, i64) [[G1]]
declare i8* @calloc(i64, i64)
-; CHECK: declare double @cbrt(double)
+; CHECK: declare double @cbrt(double) [[G0]]
declare double @cbrt(double)
-; CHECK: declare float @cbrtf(float)
+; CHECK: declare float @cbrtf(float) [[G0]]
declare float @cbrtf(float)
-; CHECK: declare x86_fp80 @cbrtl(x86_fp80)
+; CHECK: declare x86_fp80 @cbrtl(x86_fp80) [[G0]]
declare x86_fp80 @cbrtl(x86_fp80)
-; CHECK: declare double @ceil(double)
+; CHECK: declare double @ceil(double) [[G0]]
declare double @ceil(double)
-; CHECK: declare float @ceilf(float)
+; CHECK: declare float @ceilf(float) [[G0]]
declare float @ceilf(float)
-; CHECK: declare x86_fp80 @ceill(x86_fp80)
+; CHECK: declare x86_fp80 @ceill(x86_fp80) [[G0]]
declare x86_fp80 @ceill(x86_fp80)
-; CHECK: declare i32 @chmod(i8* nocapture readonly, i16 zeroext) [[G0]]
+; CHECK: declare i32 @chmod(i8* nocapture readonly, i16 zeroext) [[G1]]
declare i32 @chmod(i8*, i16 zeroext)
-; CHECK: declare i32 @chown(i8* nocapture readonly, i32, i32) [[G0]]
+; CHECK: declare i32 @chown(i8* nocapture readonly, i32, i32) [[G1]]
declare i32 @chown(i8*, i32, i32)
-; CHECK: declare void @clearerr(%opaque* nocapture) [[G0]]
+; CHECK: declare void @clearerr(%opaque* nocapture) [[G1]]
declare void @clearerr(%opaque*)
-; CHECK: declare i32 @closedir(%opaque* nocapture) [[G0]]
+; CHECK: declare i32 @closedir(%opaque* nocapture) [[G1]]
declare i32 @closedir(%opaque*)
-; CHECK: declare double @copysign(double, double)
+; CHECK: declare double @copysign(double, double) [[G0]]
declare double @copysign(double, double)
-; CHECK: declare float @copysignf(float, float)
+; CHECK: declare float @copysignf(float, float) [[G0]]
declare float @copysignf(float, float)
-; CHECK: declare x86_fp80 @copysignl(x86_fp80, x86_fp80)
+; CHECK: declare x86_fp80 @copysignl(x86_fp80, x86_fp80) [[G0]]
declare x86_fp80 @copysignl(x86_fp80, x86_fp80)
-; CHECK: declare double @cos(double)
+; CHECK: declare double @cos(double) [[G0]]
declare double @cos(double)
-; CHECK: declare float @cosf(float)
+; CHECK: declare float @cosf(float) [[G0]]
declare float @cosf(float)
-; CHECK: declare double @cosh(double)
+; CHECK: declare double @cosh(double) [[G0]]
declare double @cosh(double)
-; CHECK: declare float @coshf(float)
+; CHECK: declare float @coshf(float) [[G0]]
declare float @coshf(float)
-; CHECK: declare x86_fp80 @coshl(x86_fp80)
+; CHECK: declare x86_fp80 @coshl(x86_fp80) [[G0]]
declare x86_fp80 @coshl(x86_fp80)
-; CHECK: declare x86_fp80 @cosl(x86_fp80)
+; CHECK: declare x86_fp80 @cosl(x86_fp80) [[G0]]
declare x86_fp80 @cosl(x86_fp80)
-; CHECK: declare i8* @ctermid(i8* nocapture) [[G0]]
+; CHECK: declare i8* @ctermid(i8* nocapture) [[G1]]
declare i8* @ctermid(i8*)
-; CHECK: declare double @exp(double)
+; CHECK: declare double @exp(double) [[G0]]
declare double @exp(double)
-; CHECK: declare double @exp2(double)
+; CHECK: declare double @exp2(double) [[G0]]
declare double @exp2(double)
-; CHECK: declare float @exp2f(float)
+; CHECK: declare float @exp2f(float) [[G0]]
declare float @exp2f(float)
-; CHECK: declare x86_fp80 @exp2l(x86_fp80)
+; CHECK: declare x86_fp80 @exp2l(x86_fp80) [[G0]]
declare x86_fp80 @exp2l(x86_fp80)
-; CHECK: declare float @expf(float)
+; CHECK: declare float @expf(float) [[G0]]
declare float @expf(float)
-; CHECK: declare x86_fp80 @expl(x86_fp80)
+; CHECK: declare x86_fp80 @expl(x86_fp80) [[G0]]
declare x86_fp80 @expl(x86_fp80)
-; CHECK: declare double @expm1(double)
+; CHECK: declare double @expm1(double) [[G0]]
declare double @expm1(double)
-; CHECK: declare float @expm1f(float)
+; CHECK: declare float @expm1f(float) [[G0]]
declare float @expm1f(float)
-; CHECK: declare x86_fp80 @expm1l(x86_fp80)
+; CHECK: declare x86_fp80 @expm1l(x86_fp80) [[G0]]
declare x86_fp80 @expm1l(x86_fp80)
-; CHECK: declare double @fabs(double)
+; CHECK: declare double @fabs(double) [[G0]]
declare double @fabs(double)
-; CHECK: declare float @fabsf(float)
+; CHECK: declare float @fabsf(float) [[G0]]
declare float @fabsf(float)
-; CHECK: declare x86_fp80 @fabsl(x86_fp80)
+; CHECK: declare x86_fp80 @fabsl(x86_fp80) [[G0]]
declare x86_fp80 @fabsl(x86_fp80)
-; CHECK: declare i32 @fclose(%opaque* nocapture) [[G0]]
+; CHECK: declare i32 @fclose(%opaque* nocapture) [[G1]]
declare i32 @fclose(%opaque*)
-; CHECK: declare noalias %opaque* @fdopen(i32, i8* nocapture readonly) [[G0]]
+; CHECK: declare noalias %opaque* @fdopen(i32, i8* nocapture readonly) [[G1]]
declare %opaque* @fdopen(i32, i8*)
-; CHECK: declare i32 @feof(%opaque* nocapture) [[G0]]
+; CHECK: declare i32 @feof(%opaque* nocapture) [[G1]]
declare i32 @feof(%opaque*)
-; CHECK: declare i32 @ferror(%opaque* nocapture) [[G1]]
+; CHECK: declare i32 @ferror(%opaque* nocapture) [[G2]]
declare i32 @ferror(%opaque*)
-; CHECK: declare i32 @fflush(%opaque* nocapture) [[G0]]
+; CHECK: declare i32 @fflush(%opaque* nocapture) [[G1]]
declare i32 @fflush(%opaque*)
-; CHECK: declare i32 @ffs(i32)
+; CHECK: declare i32 @ffs(i32) [[G0]]
declare i32 @ffs(i32)
-; CHECK: declare i32 @ffsl(i64)
+; CHECK: declare i32 @ffsl(i64) [[G0]]
declare i32 @ffsl(i64)
-; CHECK: declare i32 @ffsll(i64)
+; CHECK: declare i32 @ffsll(i64) [[G0]]
declare i32 @ffsll(i64)
-; CHECK: declare i32 @fgetc(%opaque* nocapture) [[G0]]
+; CHECK: declare i32 @fgetc(%opaque* nocapture) [[G1]]
declare i32 @fgetc(%opaque*)
-; CHECK: declare i32 @fgetpos(%opaque* nocapture, i64* nocapture) [[G0]]
+; CHECK: declare i32 @fgetpos(%opaque* nocapture, i64* nocapture) [[G1]]
declare i32 @fgetpos(%opaque*, i64*)
-; CHECK: declare i8* @fgets(i8*, i32, %opaque* nocapture) [[G0]]
+; CHECK: declare i8* @fgets(i8*, i32, %opaque* nocapture) [[G1]]
declare i8* @fgets(i8*, i32, %opaque*)
-; CHECK: declare i32 @fileno(%opaque* nocapture) [[G0]]
+; CHECK: declare i32 @fileno(%opaque* nocapture) [[G1]]
declare i32 @fileno(%opaque*)
-; CHECK: declare void @flockfile(%opaque* nocapture) [[G0]]
+; CHECK: declare void @flockfile(%opaque* nocapture) [[G1]]
declare void @flockfile(%opaque*)
-; CHECK: declare double @floor(double)
+; CHECK: declare double @floor(double) [[G0]]
declare double @floor(double)
-; CHECK: declare float @floorf(float)
+; CHECK: declare float @floorf(float) [[G0]]
declare float @floorf(float)
-; CHECK: declare x86_fp80 @floorl(x86_fp80)
+; CHECK: declare x86_fp80 @floorl(x86_fp80) [[G0]]
declare x86_fp80 @floorl(x86_fp80)
; CHECK: declare i32 @fls(i32)
@@ -409,607 +409,608 @@ declare i32 @flsl(i64)
; CHECK: declare i32 @flsll(i64)
declare i32 @flsll(i64)
-; CHECK: declare double @fmax(double, double)
+; CHECK: declare double @fmax(double, double) [[G0]]
declare double @fmax(double, double)
-; CHECK: declare float @fmaxf(float, float)
+; CHECK: declare float @fmaxf(float, float) [[G0]]
declare float @fmaxf(float, float)
-; CHECK: declare x86_fp80 @fmaxl(x86_fp80, x86_fp80)
+; CHECK: declare x86_fp80 @fmaxl(x86_fp80, x86_fp80) [[G0]]
declare x86_fp80 @fmaxl(x86_fp80, x86_fp80)
-; CHECK: declare double @fmin(double, double)
+; CHECK: declare double @fmin(double, double) [[G0]]
declare double @fmin(double, double)
-; CHECK: declare float @fminf(float, float)
+; CHECK: declare float @fminf(float, float) [[G0]]
declare float @fminf(float, float)
-; CHECK: declare x86_fp80 @fminl(x86_fp80, x86_fp80)
+; CHECK: declare x86_fp80 @fminl(x86_fp80, x86_fp80) [[G0]]
declare x86_fp80 @fminl(x86_fp80, x86_fp80)
-; CHECK: declare double @fmod(double, double)
+; CHECK: declare double @fmod(double, double) [[G0]]
declare double @fmod(double, double)
-; CHECK: declare float @fmodf(float, float)
+; CHECK: declare float @fmodf(float, float) [[G0]]
declare float @fmodf(float, float)
-; CHECK: declare x86_fp80 @fmodl(x86_fp80, x86_fp80)
+; CHECK: declare x86_fp80 @fmodl(x86_fp80, x86_fp80) [[G0]]
declare x86_fp80 @fmodl(x86_fp80, x86_fp80)
-; CHECK: declare noalias %opaque* @fopen(i8* nocapture readonly, i8* nocapture readonly) [[G0]]
+; CHECK: declare noalias %opaque* @fopen(i8* nocapture readonly, i8* nocapture readonly) [[G1]]
declare %opaque* @fopen(i8*, i8*)
-; CHECK: declare i32 @fprintf(%opaque* nocapture, i8* nocapture readonly, ...) [[G0]]
+; CHECK: declare i32 @fprintf(%opaque* nocapture, i8* nocapture readonly, ...) [[G1]]
declare i32 @fprintf(%opaque*, i8*, ...)
-; CHECK: declare i32 @fputc(i32, %opaque* nocapture) [[G0]]
+; CHECK: declare i32 @fputc(i32, %opaque* nocapture) [[G1]]
declare i32 @fputc(i32, %opaque*)
-; CHECK: declare i32 @fputs(i8* nocapture readonly, %opaque* nocapture) [[G0]]
+; CHECK: declare i32 @fputs(i8* nocapture readonly, %opaque* nocapture) [[G1]]
declare i32 @fputs(i8*, %opaque*)
-; CHECK: declare i64 @fread(i8* nocapture, i64, i64, %opaque* nocapture) [[G0]]
+; CHECK: declare i64 @fread(i8* nocapture, i64, i64, %opaque* nocapture) [[G1]]
declare i64 @fread(i8*, i64, i64, %opaque*)
-; CHECK: declare void @free(i8* nocapture) [[G0]]
+; CHECK: declare void @free(i8* nocapture) [[G3:#[0-9]+]]
declare void @free(i8*)
-; CHECK: declare double @frexp(double, i32* nocapture) [[G0]]
+; CHECK: declare double @frexp(double, i32* nocapture) [[G1]]
declare double @frexp(double, i32*)
-; CHECK: declare float @frexpf(float, i32* nocapture) [[G0]]
+; CHECK: declare float @frexpf(float, i32* nocapture) [[G1]]
declare float @frexpf(float, i32*)
-; CHECK: declare x86_fp80 @frexpl(x86_fp80, i32* nocapture) [[G0]]
+; CHECK: declare x86_fp80 @frexpl(x86_fp80, i32* nocapture) [[G1]]
declare x86_fp80 @frexpl(x86_fp80, i32*)
-; CHECK: declare i32 @fscanf(%opaque* nocapture, i8* nocapture readonly, ...) [[G0]]
+; CHECK: declare i32 @fscanf(%opaque* nocapture, i8* nocapture readonly, ...) [[G1]]
declare i32 @fscanf(%opaque*, i8*, ...)
-; CHECK: declare i32 @fseek(%opaque* nocapture, i64, i32) [[G0]]
+; CHECK: declare i32 @fseek(%opaque* nocapture, i64, i32) [[G1]]
declare i32 @fseek(%opaque*, i64, i32)
-; CHECK: declare i32 @fseeko(%opaque* nocapture, i64, i32) [[G0]]
+; CHECK: declare i32 @fseeko(%opaque* nocapture, i64, i32) [[G1]]
declare i32 @fseeko(%opaque*, i64, i32)
-; CHECK-LINUX: declare i32 @fseeko64(%opaque* nocapture, i64, i32) [[G0]]
+; CHECK-LINUX: declare i32 @fseeko64(%opaque* nocapture, i64, i32) [[G1]]
declare i32 @fseeko64(%opaque*, i64, i32)
-; CHECK: declare i32 @fsetpos(%opaque* nocapture, i64*) [[G0]]
+; CHECK: declare i32 @fsetpos(%opaque* nocapture, i64*) [[G1]]
declare i32 @fsetpos(%opaque*, i64*)
-; CHECK: declare i32 @fstat(i32, %opaque* nocapture) [[G0]]
+; CHECK: declare i32 @fstat(i32, %opaque* nocapture) [[G1]]
declare i32 @fstat(i32, %opaque*)
-; CHECK-LINUX: declare i32 @fstat64(i32, %opaque* nocapture) [[G0]]
+; CHECK-LINUX: declare i32 @fstat64(i32, %opaque* nocapture) [[G1]]
declare i32 @fstat64(i32, %opaque*)
-; CHECK: declare i32 @fstatvfs(i32, %opaque* nocapture) [[G0]]
+; CHECK: declare i32 @fstatvfs(i32, %opaque* nocapture) [[G1]]
declare i32 @fstatvfs(i32, %opaque*)
-; CHECK-LINUX: declare i32 @fstatvfs64(i32, %opaque* nocapture) [[G0]]
+; CHECK-LINUX: declare i32 @fstatvfs64(i32, %opaque* nocapture) [[G1]]
declare i32 @fstatvfs64(i32, %opaque*)
-; CHECK: declare i64 @ftell(%opaque* nocapture) [[G0]]
+; CHECK: declare i64 @ftell(%opaque* nocapture) [[G1]]
declare i64 @ftell(%opaque*)
-; CHECK: declare i64 @ftello(%opaque* nocapture) [[G0]]
+; CHECK: declare i64 @ftello(%opaque* nocapture) [[G1]]
declare i64 @ftello(%opaque*)
-; CHECK-LINUX: declare i64 @ftello64(%opaque* nocapture) [[G0]]
+; CHECK-LINUX: declare i64 @ftello64(%opaque* nocapture) [[G1]]
declare i64 @ftello64(%opaque*)
-; CHECK: declare i32 @ftrylockfile(%opaque* nocapture) [[G0]]
+; CHECK: declare i32 @ftrylockfile(%opaque* nocapture) [[G1]]
declare i32 @ftrylockfile(%opaque*)
-; CHECK: declare void @funlockfile(%opaque* nocapture) [[G0]]
+; CHECK: declare void @funlockfile(%opaque* nocapture) [[G1]]
declare void @funlockfile(%opaque*)
-; CHECK: declare i64 @fwrite(i8* nocapture, i64, i64, %opaque* nocapture) [[G0]]
+; CHECK: declare i64 @fwrite(i8* nocapture, i64, i64, %opaque* nocapture) [[G1]]
declare i64 @fwrite(i8*, i64, i64, %opaque*)
-; CHECK: declare i32 @getc(%opaque* nocapture) [[G0]]
+; CHECK: declare i32 @getc(%opaque* nocapture) [[G1]]
declare i32 @getc(%opaque*)
-; CHECK: declare i32 @getc_unlocked(%opaque* nocapture) [[G0]]
+; CHECK: declare i32 @getc_unlocked(%opaque* nocapture) [[G1]]
declare i32 @getc_unlocked(%opaque*)
-; CHECK: declare i32 @getchar()
+; CHECK: declare i32 @getchar() [[G1]]
declare i32 @getchar()
-; CHECK: declare i32 @getchar_unlocked()
+; CHECK: declare i32 @getchar_unlocked() [[G1]]
declare i32 @getchar_unlocked()
-; CHECK: declare i8* @getenv(i8* nocapture) [[G1]]
+; CHECK: declare i8* @getenv(i8* nocapture) [[G2]]
declare i8* @getenv(i8*)
-; CHECK: declare i32 @getitimer(i32, %opaque* nocapture) [[G0]]
+; CHECK: declare i32 @getitimer(i32, %opaque* nocapture) [[G1]]
declare i32 @getitimer(i32, %opaque*)
-; CHECK: declare i32 @getlogin_r(i8* nocapture, i64) [[G0]]
+; CHECK: declare i32 @getlogin_r(i8* nocapture, i64) [[G1]]
declare i32 @getlogin_r(i8*, i64)
-; CHECK: declare %opaque* @getpwnam(i8* nocapture readonly) [[G0]]
+; CHECK: declare %opaque* @getpwnam(i8* nocapture readonly) [[G1]]
declare %opaque* @getpwnam(i8*)
-; CHECK: declare i8* @gets(i8*)
+; CHECK: declare i8* @gets(i8*) [[G1]]
declare i8* @gets(i8*)
-; CHECK: declare i32 @gettimeofday(%opaque* nocapture, i8* nocapture) [[G0]]
+; CHECK: declare i32 @gettimeofday(%opaque* nocapture, i8* nocapture) [[G1]]
declare i32 @gettimeofday(%opaque*, i8*)
-; CHECK: declare i32 @isascii(i32)
+; CHECK: declare i32 @isascii(i32) [[G0]]
declare i32 @isascii(i32)
-; CHECK: declare i32 @isdigit(i32)
+; CHECK: declare i32 @isdigit(i32) [[G0]]
declare i32 @isdigit(i32)
-; CHECK: declare i64 @labs(i64)
+; CHECK: declare i64 @labs(i64) [[G0]]
declare i64 @labs(i64)
-; CHECK: declare i32 @lchown(i8* nocapture readonly, i32, i32) [[G0]]
+; CHECK: declare i32 @lchown(i8* nocapture readonly, i32, i32) [[G1]]
declare i32 @lchown(i8*, i32, i32)
-; CHECK: declare double @ldexp(double, i32)
+; CHECK: declare double @ldexp(double, i32) [[G0]]
declare double @ldexp(double, i32)
-; CHECK: declare float @ldexpf(float, i32)
+; CHECK: declare float @ldexpf(float, i32) [[G0]]
declare float @ldexpf(float, i32)
-; CHECK: declare x86_fp80 @ldexpl(x86_fp80, i32)
+; CHECK: declare x86_fp80 @ldexpl(x86_fp80, i32) [[G0]]
declare x86_fp80 @ldexpl(x86_fp80, i32)
-; CHECK: declare i64 @llabs(i64)
+; CHECK: declare i64 @llabs(i64) [[G0]]
declare i64 @llabs(i64)
-; CHECK: declare double @log(double)
+; CHECK: declare double @log(double) [[G0]]
declare double @log(double)
-; CHECK: declare double @log10(double)
+; CHECK: declare double @log10(double) [[G0]]
declare double @log10(double)
-; CHECK: declare float @log10f(float)
+; CHECK: declare float @log10f(float) [[G0]]
declare float @log10f(float)
-; CHECK: declare x86_fp80 @log10l(x86_fp80)
+; CHECK: declare x86_fp80 @log10l(x86_fp80) [[G0]]
declare x86_fp80 @log10l(x86_fp80)
-; CHECK: declare double @log1p(double)
+; CHECK: declare double @log1p(double) [[G0]]
declare double @log1p(double)
-; CHECK: declare float @log1pf(float)
+; CHECK: declare float @log1pf(float) [[G0]]
declare float @log1pf(float)
-; CHECK: declare x86_fp80 @log1pl(x86_fp80)
+; CHECK: declare x86_fp80 @log1pl(x86_fp80) [[G0]]
declare x86_fp80 @log1pl(x86_fp80)
-; CHECK: declare double @log2(double)
+; CHECK: declare double @log2(double) [[G0]]
declare double @log2(double)
-; CHECK: declare float @log2f(float)
+; CHECK: declare float @log2f(float) [[G0]]
declare float @log2f(float)
-; CHECK: declare x86_fp80 @log2l(x86_fp80)
+; CHECK: declare x86_fp80 @log2l(x86_fp80) [[G0]]
declare x86_fp80 @log2l(x86_fp80)
-; CHECK: declare double @logb(double)
+; CHECK: declare double @logb(double) [[G0]]
declare double @logb(double)
-; CHECK: declare float @logbf(float)
+; CHECK: declare float @logbf(float) [[G0]]
declare float @logbf(float)
-; CHECK: declare x86_fp80 @logbl(x86_fp80)
+; CHECK: declare x86_fp80 @logbl(x86_fp80) [[G0]]
declare x86_fp80 @logbl(x86_fp80)
-; CHECK: declare float @logf(float)
+; CHECK: declare float @logf(float) [[G0]]
declare float @logf(float)
-; CHECK: declare x86_fp80 @logl(x86_fp80)
+; CHECK: declare x86_fp80 @logl(x86_fp80) [[G0]]
declare x86_fp80 @logl(x86_fp80)
-; CHECK: declare i32 @lstat(i8* nocapture readonly, %opaque* nocapture) [[G0]]
+; CHECK: declare i32 @lstat(i8* nocapture readonly, %opaque* nocapture) [[G1]]
declare i32 @lstat(i8*, %opaque*)
-; CHECK-LINUX: declare i32 @lstat64(i8* nocapture readonly, %opaque* nocapture) [[G0]]
+; CHECK-LINUX: declare i32 @lstat64(i8* nocapture readonly, %opaque* nocapture) [[G1]]
declare i32 @lstat64(i8*, %opaque*)
-; CHECK: declare noalias i8* @malloc(i64) [[G0]]
+; CHECK: declare noalias i8* @malloc(i64) [[G1]]
declare i8* @malloc(i64)
-; CHECK-LINUX: declare noalias i8* @memalign(i64, i64)
+; CHECK-LINUX: declare noalias i8* @memalign(i64, i64) [[G0]]
declare i8* @memalign(i64, i64)
-; CHECK: declare i8* @memccpy(i8*, i8* nocapture readonly, i32, i64) [[G0]]
+; CHECK: declare i8* @memccpy(i8*, i8* nocapture readonly, i32, i64) [[G1]]
declare i8* @memccpy(i8*, i8*, i32, i64)
-; CHECK: declare i8* @memchr(i8*, i32, i64) [[G1]]
+; CHECK: declare i8* @memchr(i8*, i32, i64) [[G2]]
declare i8* @memchr(i8*, i32, i64)
-; CHECK: declare i32 @memcmp(i8* nocapture, i8* nocapture, i64) [[G1]]
+; CHECK: declare i32 @memcmp(i8* nocapture, i8* nocapture, i64) [[G2]]
declare i32 @memcmp(i8*, i8*, i64)
-; CHECK: declare i8* @memcpy(i8* returned, i8* nocapture readonly, i64) [[G0]]
+; CHECK: declare i8* @memcpy(i8* returned, i8* nocapture readonly, i64) [[G1]]
declare i8* @memcpy(i8*, i8*, i64)
-; CHECK: declare i8* @mempcpy(i8*, i8* nocapture readonly, i64) [[G0]]
+; CHECK: declare i8* @mempcpy(i8*, i8* nocapture readonly, i64) [[G1]]
declare i8* @mempcpy(i8*, i8*, i64)
-; CHECK: declare i8* @memmove(i8* returned, i8* nocapture readonly, i64) [[G0]]
+; CHECK: declare i8* @memmove(i8* returned, i8* nocapture readonly, i64) [[G1]]
declare i8* @memmove(i8*, i8*, i64)
-; CHECK: declare i8* @memset(i8*, i32, i64)
+; CHECK: declare i8* @memset(i8*, i32, i64) [[G0]]
declare i8* @memset(i8*, i32, i64)
-; CHECK: declare i32 @mkdir(i8* nocapture readonly, i16 zeroext) [[G0]]
+; CHECK: declare i32 @mkdir(i8* nocapture readonly, i16 zeroext) [[G1]]
declare i32 @mkdir(i8*, i16 zeroext)
-; CHECK: declare i64 @mktime(%opaque* nocapture) [[G0]]
+; CHECK: declare i64 @mktime(%opaque* nocapture) [[G1]]
declare i64 @mktime(%opaque*)
-; CHECK: declare double @modf(double, double* nocapture) [[G0]]
+; CHECK: declare double @modf(double, double* nocapture) [[G1]]
declare double @modf(double, double*)
-; CHECK: declare float @modff(float, float* nocapture) [[G0]]
+; CHECK: declare float @modff(float, float* nocapture) [[G1]]
declare float @modff(float, float*)
-; CHECK: declare x86_fp80 @modfl(x86_fp80, x86_fp80* nocapture) [[G0]]
+; CHECK: declare x86_fp80 @modfl(x86_fp80, x86_fp80* nocapture) [[G1]]
declare x86_fp80 @modfl(x86_fp80, x86_fp80*)
-; CHECK: declare double @nearbyint(double)
+; CHECK: declare double @nearbyint(double) [[G0]]
declare double @nearbyint(double)
-; CHECK: declare float @nearbyintf(float)
+; CHECK: declare float @nearbyintf(float) [[G0]]
declare float @nearbyintf(float)
-; CHECK: declare x86_fp80 @nearbyintl(x86_fp80)
+; CHECK: declare x86_fp80 @nearbyintl(x86_fp80) [[G0]]
declare x86_fp80 @nearbyintl(x86_fp80)
-; CHECK: declare i32 @open(i8* nocapture readonly, i32, ...)
+; CHECK: declare i32 @open(i8* nocapture readonly, i32, ...) [[G0]]
declare i32 @open(i8*, i32, ...)
-; CHECK-LINUX: declare i32 @open64(i8* nocapture readonly, i32, ...)
+; CHECK-LINUX: declare i32 @open64(i8* nocapture readonly, i32, ...) [[G0]]
declare i32 @open64(i8*, i32, ...)
-; CHECK: declare noalias %opaque* @opendir(i8* nocapture readonly) [[G0]]
+; CHECK: declare noalias %opaque* @opendir(i8* nocapture readonly) [[G1]]
declare %opaque* @opendir(i8*)
-; CHECK: declare i32 @pclose(%opaque* nocapture) [[G0]]
+; CHECK: declare i32 @pclose(%opaque* nocapture) [[G1]]
declare i32 @pclose(%opaque*)
-; CHECK: declare void @perror(i8* nocapture readonly) [[G0]]
+; CHECK: declare void @perror(i8* nocapture readonly) [[G1]]
declare void @perror(i8*)
-; CHECK: declare noalias %opaque* @popen(i8* nocapture readonly, i8* nocapture readonly) [[G0]]
+; CHECK: declare noalias %opaque* @popen(i8* nocapture readonly, i8* nocapture readonly) [[G1]]
declare %opaque* @popen(i8*, i8*)
-; CHECK: declare i32 @posix_memalign(i8**, i64, i64)
+; CHECK: declare i32 @posix_memalign(i8**, i64, i64) [[G0]]
declare i32 @posix_memalign(i8**, i64, i64)
-; CHECK: declare double @pow(double, double)
+; CHECK: declare double @pow(double, double) [[G0]]
declare double @pow(double, double)
-; CHECK: declare float @powf(float, float)
+; CHECK: declare float @powf(float, float) [[G0]]
declare float @powf(float, float)
-; CHECK: declare x86_fp80 @powl(x86_fp80, x86_fp80)
+; CHECK: declare x86_fp80 @powl(x86_fp80, x86_fp80) [[G0]]
declare x86_fp80 @powl(x86_fp80, x86_fp80)
-; CHECK: declare i64 @pread(i32, i8* nocapture, i64, i64)
+; CHECK: declare i64 @pread(i32, i8* nocapture, i64, i64) [[G0]]
declare i64 @pread(i32, i8*, i64, i64)
-; CHECK: declare i32 @printf(i8* nocapture readonly, ...) [[G0]]
+; CHECK: declare i32 @printf(i8* nocapture readonly, ...) [[G1]]
declare i32 @printf(i8*, ...)
-; CHECK: declare i32 @putc(i32, %opaque* nocapture) [[G0]]
+; CHECK: declare i32 @putc(i32, %opaque* nocapture) [[G1]]
declare i32 @putc(i32, %opaque*)
-; CHECK: declare i32 @putchar(i32)
+; CHECK: declare i32 @putchar(i32) [[G1]]
declare i32 @putchar(i32)
-; CHECK: declare i32 @putchar_unlocked(i32)
+; CHECK: declare i32 @putchar_unlocked(i32) [[G1]]
declare i32 @putchar_unlocked(i32)
-; CHECK: declare i32 @puts(i8* nocapture readonly) [[G0]]
+; CHECK: declare i32 @puts(i8* nocapture readonly) [[G1]]
declare i32 @puts(i8*)
-; CHECK: declare i64 @pwrite(i32, i8* nocapture readonly, i64, i64)
+; CHECK: declare i64 @pwrite(i32, i8* nocapture readonly, i64, i64) [[G0]]
declare i64 @pwrite(i32, i8*, i64, i64)
-; CHECK: declare void @qsort(i8*, i64, i64, i32 (i8*, i8*)* nocapture)
+; CHECK: declare void @qsort(i8*, i64, i64, i32 (i8*, i8*)* nocapture) [[G0]]
declare void @qsort(i8*, i64, i64, i32 (i8*, i8*)*)
-; CHECK: declare i64 @read(i32, i8* nocapture, i64)
+; CHECK: declare i64 @read(i32, i8* nocapture, i64) [[G0]]
declare i64 @read(i32, i8*, i64)
-; CHECK: declare i64 @readlink(i8* nocapture readonly, i8* nocapture, i64) [[G0]]
+; CHECK: declare i64 @readlink(i8* nocapture readonly, i8* nocapture, i64) [[G1]]
declare i64 @readlink(i8*, i8*, i64)
-; CHECK: declare noalias i8* @realloc(i8* nocapture, i64) [[G0]]
+; CHECK: declare noalias i8* @realloc(i8* nocapture, i64) [[G3]]
declare i8* @realloc(i8*, i64)
; CHECK: declare i8* @reallocf(i8*, i64)
declare i8* @reallocf(i8*, i64)
-; CHECK: declare i8* @realpath(i8* nocapture readonly, i8*)
+; CHECK: declare i8* @realpath(i8* nocapture readonly, i8*) [[G1]]
declare i8* @realpath(i8*, i8*)
-; CHECK: declare i32 @remove(i8* nocapture readonly) [[G0]]
+; CHECK: declare i32 @remove(i8* nocapture readonly) [[G1]]
declare i32 @remove(i8*)
-; CHECK: declare i32 @rename(i8* nocapture readonly, i8* nocapture readonly) [[G0]]
+; CHECK: declare i32 @rename(i8* nocapture readonly, i8* nocapture readonly) [[G1]]
declare i32 @rename(i8*, i8*)
-; CHECK: declare void @rewind(%opaque* nocapture) [[G0]]
+; CHECK: declare void @rewind(%opaque* nocapture) [[G1]]
declare void @rewind(%opaque*)
-; CHECK: declare double @rint(double)
+; CHECK: declare double @rint(double) [[G0]]
declare double @rint(double)
-; CHECK: declare float @rintf(float)
+; CHECK: declare float @rintf(float) [[G0]]
declare float @rintf(float)
-; CHECK: declare x86_fp80 @rintl(x86_fp80)
+; CHECK: declare x86_fp80 @rintl(x86_fp80) [[G0]]
declare x86_fp80 @rintl(x86_fp80)
-; CHECK: declare i32 @rmdir(i8* nocapture readonly) [[G0]]
+; CHECK: declare i32 @rmdir(i8* nocapture readonly) [[G1]]
declare i32 @rmdir(i8*)
-; CHECK: declare double @round(double)
+; CHECK: declare double @round(double) [[G0]]
declare double @round(double)
-; CHECK: declare float @roundf(float)
+; CHECK: declare float @roundf(float) [[G0]]
declare float @roundf(float)
-; CHECK: declare x86_fp80 @roundl(x86_fp80)
+; CHECK: declare x86_fp80 @roundl(x86_fp80) [[G0]]
declare x86_fp80 @roundl(x86_fp80)
-; CHECK: declare i32 @scanf(i8* nocapture readonly, ...) [[G0]]
+; CHECK: declare i32 @scanf(i8* nocapture readonly, ...) [[G1]]
declare i32 @scanf(i8*, ...)
-; CHECK: declare void @setbuf(%opaque* nocapture, i8*) [[G0]]
+; CHECK: declare void @setbuf(%opaque* nocapture, i8*) [[G1]]
declare void @setbuf(%opaque*, i8*)
-; CHECK: declare i32 @setitimer(i32, %opaque* nocapture readonly, %opaque* nocapture) [[G0]]
+; CHECK: declare i32 @setitimer(i32, %opaque* nocapture readonly, %opaque* nocapture) [[G1]]
declare i32 @setitimer(i32, %opaque*, %opaque*)
-; CHECK: declare i32 @setvbuf(%opaque* nocapture, i8*, i32, i64) [[G0]]
+; CHECK: declare i32 @setvbuf(%opaque* nocapture, i8*, i32, i64) [[G1]]
declare i32 @setvbuf(%opaque*, i8*, i32, i64)
-; CHECK: declare double @sin(double)
+; CHECK: declare double @sin(double) [[G0]]
declare double @sin(double)
-; CHECK: declare float @sinf(float)
+; CHECK: declare float @sinf(float) [[G0]]
declare float @sinf(float)
-; CHECK: declare double @sinh(double)
+; CHECK: declare double @sinh(double) [[G0]]
declare double @sinh(double)
-; CHECK: declare float @sinhf(float)
+; CHECK: declare float @sinhf(float) [[G0]]
declare float @sinhf(float)
-; CHECK: declare x86_fp80 @sinhl(x86_fp80)
+; CHECK: declare x86_fp80 @sinhl(x86_fp80) [[G0]]
declare x86_fp80 @sinhl(x86_fp80)
-; CHECK: declare x86_fp80 @sinl(x86_fp80)
+; CHECK: declare x86_fp80 @sinl(x86_fp80) [[G0]]
declare x86_fp80 @sinl(x86_fp80)
-; CHECK: declare i32 @snprintf(i8* nocapture, i64, i8* nocapture readonly, ...) [[G0]]
+; CHECK: declare i32 @snprintf(i8* nocapture, i64, i8* nocapture readonly, ...) [[G1]]
declare i32 @snprintf(i8*, i64, i8*, ...)
-; CHECK: declare i32 @sprintf(i8* nocapture, i8* nocapture readonly, ...) [[G0]]
+; CHECK: declare i32 @sprintf(i8* nocapture, i8* nocapture readonly, ...) [[G1]]
declare i32 @sprintf(i8*, i8*, ...)
-; CHECK: declare double @sqrt(double)
+; CHECK: declare double @sqrt(double) [[G0]]
declare double @sqrt(double)
-; CHECK: declare float @sqrtf(float)
+; CHECK: declare float @sqrtf(float) [[G0]]
declare float @sqrtf(float)
-; CHECK: declare x86_fp80 @sqrtl(x86_fp80)
+; CHECK: declare x86_fp80 @sqrtl(x86_fp80) [[G0]]
declare x86_fp80 @sqrtl(x86_fp80)
-; CHECK: declare i32 @sscanf(i8* nocapture readonly, i8* nocapture readonly, ...) [[G0]]
+; CHECK: declare i32 @sscanf(i8* nocapture readonly, i8* nocapture readonly, ...) [[G1]]
declare i32 @sscanf(i8*, i8*, ...)
-; CHECK: declare i32 @stat(i8* nocapture readonly, %opaque* nocapture) [[G0]]
+; CHECK: declare i32 @stat(i8* nocapture readonly, %opaque* nocapture) [[G1]]
declare i32 @stat(i8*, %opaque*)
-; CHECK-LINUX: declare i32 @stat64(i8* nocapture readonly, %opaque* nocapture) [[G0]]
+; CHECK-LINUX: declare i32 @stat64(i8* nocapture readonly, %opaque* nocapture) [[G1]]
declare i32 @stat64(i8*, %opaque*)
-; CHECK: declare i32 @statvfs(i8* nocapture readonly, %opaque* nocapture) [[G0]]
+; CHECK: declare i32 @statvfs(i8* nocapture readonly, %opaque* nocapture) [[G1]]
declare i32 @statvfs(i8*, %opaque*)
-; CHECK-LINUX: declare i32 @statvfs64(i8* nocapture readonly, %opaque* nocapture) [[G0]]
+; CHECK-LINUX: declare i32 @statvfs64(i8* nocapture readonly, %opaque* nocapture) [[G1]]
declare i32 @statvfs64(i8*, %opaque*)
-; CHECK: declare i8* @stpcpy(i8*, i8* nocapture readonly) [[G0]]
+; CHECK: declare i8* @stpcpy(i8*, i8* nocapture readonly) [[G1]]
declare i8* @stpcpy(i8*, i8*)
-; CHECK: declare i8* @stpncpy(i8*, i8* nocapture readonly, i64) [[G0]]
+; CHECK: declare i8* @stpncpy(i8*, i8* nocapture readonly, i64) [[G1]]
declare i8* @stpncpy(i8*, i8*, i64)
-; CHECK: declare i32 @strcasecmp(i8* nocapture, i8* nocapture) [[G1]]
+; CHECK: declare i32 @strcasecmp(i8* nocapture, i8* nocapture) [[G2]]
declare i32 @strcasecmp(i8*, i8*)
-; CHECK: declare i8* @strcat(i8* returned, i8* nocapture readonly) [[G0]]
+; CHECK: declare i8* @strcat(i8* returned, i8* nocapture readonly) [[G1]]
declare i8* @strcat(i8*, i8*)
-; CHECK: declare i8* @strchr(i8*, i32) [[G1]]
+; CHECK: declare i8* @strchr(i8*, i32) [[G2]]
declare i8* @strchr(i8*, i32)
-; CHECK: declare i32 @strcmp(i8* nocapture, i8* nocapture) [[G1]]
+; CHECK: declare i32 @strcmp(i8* nocapture, i8* nocapture) [[G2]]
declare i32 @strcmp(i8*, i8*)
-; CHECK: declare i32 @strcoll(i8* nocapture, i8* nocapture) [[G1]]
+; CHECK: declare i32 @strcoll(i8* nocapture, i8* nocapture) [[G2]]
declare i32 @strcoll(i8*, i8*)
-; CHECK: declare i8* @strcpy(i8* returned, i8* nocapture readonly) [[G0]]
+; CHECK: declare i8* @strcpy(i8* returned, i8* nocapture readonly) [[G1]]
declare i8* @strcpy(i8*, i8*)
-; CHECK: declare i64 @strcspn(i8* nocapture, i8* nocapture) [[G1]]
+; CHECK: declare i64 @strcspn(i8* nocapture, i8* nocapture) [[G2]]
declare i64 @strcspn(i8*, i8*)
-; CHECK: declare noalias i8* @strdup(i8* nocapture readonly) [[G0]]
+; CHECK: declare noalias i8* @strdup(i8* nocapture readonly) [[G1]]
declare i8* @strdup(i8*)
-; CHECK: declare i64 @strlen(i8* nocapture) [[G2:#[0-9]+]]
+; CHECK: declare i64 @strlen(i8* nocapture) [[G4:#[0-9]+]]
declare i64 @strlen(i8*)
-; CHECK: declare i32 @strncasecmp(i8* nocapture, i8* nocapture, i64) [[G1]]
+; CHECK: declare i32 @strncasecmp(i8* nocapture, i8* nocapture, i64) [[G2]]
declare i32 @strncasecmp(i8*, i8*, i64)
-; CHECK: declare i8* @strncat(i8* returned, i8* nocapture readonly, i64) [[G0]]
+; CHECK: declare i8* @strncat(i8* returned, i8* nocapture readonly, i64) [[G1]]
declare i8* @strncat(i8*, i8*, i64)
-; CHECK: declare i32 @strncmp(i8* nocapture, i8* nocapture, i64) [[G1]]
+; CHECK: declare i32 @strncmp(i8* nocapture, i8* nocapture, i64) [[G2]]
declare i32 @strncmp(i8*, i8*, i64)
-; CHECK: declare i8* @strncpy(i8* returned, i8* nocapture readonly, i64) [[G0]]
+; CHECK: declare i8* @strncpy(i8* returned, i8* nocapture readonly, i64) [[G1]]
declare i8* @strncpy(i8*, i8*, i64)
-; CHECK: declare noalias i8* @strndup(i8* nocapture readonly, i64) [[G0]]
+; CHECK: declare noalias i8* @strndup(i8* nocapture readonly, i64) [[G1]]
declare i8* @strndup(i8*, i64)
-; CHECK: declare i64 @strnlen(i8*, i64)
+; CHECK: declare i64 @strnlen(i8*, i64) [[G0]]
declare i64 @strnlen(i8*, i64)
-; CHECK: declare i8* @strpbrk(i8*, i8* nocapture) [[G1]]
+; CHECK: declare i8* @strpbrk(i8*, i8* nocapture) [[G2]]
declare i8* @strpbrk(i8*, i8*)
-; CHECK: declare i8* @strrchr(i8*, i32) [[G1]]
+; CHECK: declare i8* @strrchr(i8*, i32) [[G2]]
declare i8* @strrchr(i8*, i32)
-; CHECK: declare i64 @strspn(i8* nocapture, i8* nocapture) [[G1]]
+; CHECK: declare i64 @strspn(i8* nocapture, i8* nocapture) [[G2]]
declare i64 @strspn(i8*, i8*)
-; CHECK: declare i8* @strstr(i8*, i8* nocapture) [[G1]]
+; CHECK: declare i8* @strstr(i8*, i8* nocapture) [[G2]]
declare i8* @strstr(i8*, i8*)
-; CHECK: declare double @strtod(i8* readonly, i8** nocapture) [[G0]]
+; CHECK: declare double @strtod(i8* readonly, i8** nocapture) [[G1]]
declare double @strtod(i8*, i8**)
-; CHECK: declare float @strtof(i8* readonly, i8** nocapture) [[G0]]
+; CHECK: declare float @strtof(i8* readonly, i8** nocapture) [[G1]]
declare float @strtof(i8*, i8**)
-; CHECK: declare i8* @strtok(i8*, i8* nocapture readonly) [[G0]]
+; CHECK: declare i8* @strtok(i8*, i8* nocapture readonly) [[G1]]
declare i8* @strtok(i8*, i8*)
-; CHECK: declare i8* @strtok_r(i8*, i8* nocapture readonly, i8**) [[G0]]
+; CHECK: declare i8* @strtok_r(i8*, i8* nocapture readonly, i8**) [[G1]]
declare i8* @strtok_r(i8*, i8*, i8**)
-; CHECK: declare i64 @strtol(i8* readonly, i8** nocapture, i32) [[G0]]
+; CHECK: declare i64 @strtol(i8* readonly, i8** nocapture, i32) [[G1]]
declare i64 @strtol(i8*, i8**, i32)
-; CHECK: declare x86_fp80 @strtold(i8* readonly, i8** nocapture) [[G0]]
+; CHECK: declare x86_fp80 @strtold(i8* readonly, i8** nocapture) [[G1]]
declare x86_fp80 @strtold(i8*, i8**)
-; CHECK: declare i64 @strtoll(i8* readonly, i8** nocapture, i32) [[G0]]
+; CHECK: declare i64 @strtoll(i8* readonly, i8** nocapture, i32) [[G1]]
declare i64 @strtoll(i8*, i8**, i32)
-; CHECK: declare i64 @strtoul(i8* readonly, i8** nocapture, i32) [[G0]]
+; CHECK: declare i64 @strtoul(i8* readonly, i8** nocapture, i32) [[G1]]
declare i64 @strtoul(i8*, i8**, i32)
-; CHECK: declare i64 @strtoull(i8* readonly, i8** nocapture, i32) [[G0]]
+; CHECK: declare i64 @strtoull(i8* readonly, i8** nocapture, i32) [[G1]]
declare i64 @strtoull(i8*, i8**, i32)
-; CHECK: declare i64 @strxfrm(i8* nocapture, i8* nocapture readonly, i64) [[G0]]
+; CHECK: declare i64 @strxfrm(i8* nocapture, i8* nocapture readonly, i64) [[G1]]
declare i64 @strxfrm(i8*, i8*, i64)
-; CHECK: declare i32 @system(i8* nocapture readonly)
+; CHECK: declare i32 @system(i8* nocapture readonly) [[G0]]
declare i32 @system(i8*)
-; CHECK: declare double @tan(double)
+; CHECK: declare double @tan(double) [[G0]]
declare double @tan(double)
-; CHECK: declare float @tanf(float)
+; CHECK: declare float @tanf(float) [[G0]]
declare float @tanf(float)
-; CHECK: declare double @tanh(double)
+; CHECK: declare double @tanh(double) [[G0]]
declare double @tanh(double)
-; CHECK: declare float @tanhf(float)
+; CHECK: declare float @tanhf(float) [[G0]]
declare float @tanhf(float)
-; CHECK: declare x86_fp80 @tanhl(x86_fp80)
+; CHECK: declare x86_fp80 @tanhl(x86_fp80) [[G0]]
declare x86_fp80 @tanhl(x86_fp80)
-; CHECK: declare x86_fp80 @tanl(x86_fp80)
+; CHECK: declare x86_fp80 @tanl(x86_fp80) [[G0]]
declare x86_fp80 @tanl(x86_fp80)
-; CHECK: declare i64 @times(%opaque* nocapture) [[G0]]
+; CHECK: declare i64 @times(%opaque* nocapture) [[G1]]
declare i64 @times(%opaque*)
-; CHECK: declare noalias %opaque* @tmpfile() [[G0]]
+; CHECK: declare noalias %opaque* @tmpfile() [[G1]]
declare %opaque* @tmpfile()
-; CHECK-LINUX: declare noalias %opaque* @tmpfile64() [[G0]]
+; CHECK-LINUX: declare noalias %opaque* @tmpfile64() [[G1]]
declare %opaque* @tmpfile64()
-; CHECK: declare i32 @toascii(i32)
+; CHECK: declare i32 @toascii(i32) [[G0]]
declare i32 @toascii(i32)
-; CHECK: declare double @trunc(double)
+; CHECK: declare double @trunc(double) [[G0]]
declare double @trunc(double)
-; CHECK: declare float @truncf(float)
+; CHECK: declare float @truncf(float) [[G0]]
declare float @truncf(float)
-; CHECK: declare x86_fp80 @truncl(x86_fp80)
+; CHECK: declare x86_fp80 @truncl(x86_fp80) [[G0]]
declare x86_fp80 @truncl(x86_fp80)
-; CHECK: declare i32 @uname(%opaque* nocapture) [[G0]]
+; CHECK: declare i32 @uname(%opaque* nocapture) [[G1]]
declare i32 @uname(%opaque*)
-; CHECK: declare i32 @ungetc(i32, %opaque* nocapture) [[G0]]
+; CHECK: declare i32 @ungetc(i32, %opaque* nocapture) [[G1]]
declare i32 @ungetc(i32, %opaque*)
-; CHECK: declare i32 @unlink(i8* nocapture readonly) [[G0]]
+; CHECK: declare i32 @unlink(i8* nocapture readonly) [[G1]]
declare i32 @unlink(i8*)
-; CHECK: declare i32 @unsetenv(i8* nocapture readonly) [[G0]]
+; CHECK: declare i32 @unsetenv(i8* nocapture readonly) [[G1]]
declare i32 @unsetenv(i8*)
-; CHECK: declare i32 @utime(i8* nocapture readonly, %opaque* nocapture readonly) [[G0]]
+; CHECK: declare i32 @utime(i8* nocapture readonly, %opaque* nocapture readonly) [[G1]]
declare i32 @utime(i8*, %opaque*)
-; CHECK: declare i32 @utimes(i8* nocapture readonly, %opaque* nocapture readonly) [[G0]]
+; CHECK: declare i32 @utimes(i8* nocapture readonly, %opaque* nocapture readonly) [[G1]]
declare i32 @utimes(i8*, %opaque*)
-; CHECK: declare noalias i8* @valloc(i64) [[G0]]
+; CHECK: declare noalias i8* @valloc(i64) [[G1]]
declare i8* @valloc(i64)
-; CHECK: declare i32 @vfprintf(%opaque* nocapture, i8* nocapture readonly, %opaque*) [[G0]]
+; CHECK: declare i32 @vfprintf(%opaque* nocapture, i8* nocapture readonly, %opaque*) [[G1]]
declare i32 @vfprintf(%opaque*, i8*, %opaque*)
-; CHECK: declare i32 @vfscanf(%opaque* nocapture, i8* nocapture readonly, %opaque*) [[G0]]
+; CHECK: declare i32 @vfscanf(%opaque* nocapture, i8* nocapture readonly, %opaque*) [[G1]]
declare i32 @vfscanf(%opaque*, i8*, %opaque*)
-; CHECK: declare i32 @vprintf(i8* nocapture readonly, %opaque*) [[G0]]
+; CHECK: declare i32 @vprintf(i8* nocapture readonly, %opaque*) [[G1]]
declare i32 @vprintf(i8*, %opaque*)
-; CHECK: declare i32 @vscanf(i8* nocapture readonly, %opaque*) [[G0]]
+; CHECK: declare i32 @vscanf(i8* nocapture readonly, %opaque*) [[G1]]
declare i32 @vscanf(i8*, %opaque*)
-; CHECK: declare i32 @vsnprintf(i8* nocapture, i64, i8* nocapture readonly, %opaque*) [[G0]]
+; CHECK: declare i32 @vsnprintf(i8* nocapture, i64, i8* nocapture readonly, %opaque*) [[G1]]
declare i32 @vsnprintf(i8*, i64, i8*, %opaque*)
-; CHECK: declare i32 @vsprintf(i8* nocapture, i8* nocapture readonly, %opaque*) [[G0]]
+; CHECK: declare i32 @vsprintf(i8* nocapture, i8* nocapture readonly, %opaque*) [[G1]]
declare i32 @vsprintf(i8*, i8*, %opaque*)
-; CHECK: declare i32 @vsscanf(i8* nocapture readonly, i8* nocapture readonly, %opaque*) [[G0]]
+; CHECK: declare i32 @vsscanf(i8* nocapture readonly, i8* nocapture readonly, %opaque*) [[G1]]
declare i32 @vsscanf(i8*, i8*, %opaque*)
-; CHECK: declare i64 @write(i32, i8* nocapture readonly, i64)
+; CHECK: declare i64 @write(i32, i8* nocapture readonly, i64) [[G0]]
declare i64 @write(i32, i8*, i64)
; memset_pattern16 isn't available everywhere.
-; CHECK-DARWIN: declare void @memset_pattern16(i8* nocapture, i8* nocapture readonly, i64) [[G3:#[0-9]+]]
+; CHECK-DARWIN: declare void @memset_pattern16(i8* nocapture, i8* nocapture readonly, i64) [[G5:#[0-9]+]]
declare void @memset_pattern16(i8*, i8*, i64)
-
-; CHECK: attributes [[G0]] = { nounwind }
-; CHECK: attributes [[G1]] = { nounwind readonly }
-; CHECK: attributes [[G2]] = { argmemonly nounwind readonly }
-; CHECK-DARWIN: attributes [[G3]] = { argmemonly }
+; CHECK: attributes [[G0]] = { nofree }
+; CHECK: attributes [[G1]] = { nofree nounwind }
+; CHECK: attributes [[G2]] = { nofree nounwind readonly }
+; CHECK: attributes [[G3]] = { nounwind }
+; CHECK: attributes [[G4]] = { argmemonly nofree nounwind readonly }
+; CHECK-DARWIN: attributes [[G5]] = { argmemonly nofree }
diff --git a/llvm/test/Transforms/InferFunctionAttrs/norecurse_debug.ll b/llvm/test/Transforms/InferFunctionAttrs/norecurse_debug.ll
index 575bbac5e5a..8ac037a7799 100644
--- a/llvm/test/Transforms/InferFunctionAttrs/norecurse_debug.ll
+++ b/llvm/test/Transforms/InferFunctionAttrs/norecurse_debug.ll
@@ -52,5 +52,5 @@ attributes #1 = { nounwind readnone speculatable }
!28 = !DILocation(line: 9, column: 18, scope: !2)
!29 = !DILocation(line: 10, column: 1, scope: !2)
-; CHECK: attributes #0 = { norecurse nounwind }
+; CHECK: attributes #0 = { nofree norecurse nounwind }
; CHECK-NOT foo.coefficient1
diff --git a/llvm/test/Transforms/LICM/strlen.ll b/llvm/test/Transforms/LICM/strlen.ll
index 27d51c8394d..82b3374184d 100644
--- a/llvm/test/Transforms/LICM/strlen.ll
+++ b/llvm/test/Transforms/LICM/strlen.ll
@@ -13,7 +13,7 @@ loop:
}
; CHECK: declare i64 @strlen(i8* nocapture) #0
-; CHECK: attributes #0 = { argmemonly nounwind readonly }
+; CHECK: attributes #0 = { argmemonly nofree nounwind readonly }
declare i64 @strlen(i8*)
diff --git a/llvm/test/Transforms/LoopIdiom/basic.ll b/llvm/test/Transforms/LoopIdiom/basic.ll
index 076e0224b81..89d8dab0d68 100644
--- a/llvm/test/Transforms/LoopIdiom/basic.ll
+++ b/llvm/test/Transforms/LoopIdiom/basic.ll
@@ -709,4 +709,4 @@ exit:
; Validate that "memset_pattern" has the proper attributes.
; CHECK: declare void @memset_pattern16(i8* nocapture, i8* nocapture readonly, i64) [[ATTRS:#[0-9]+]]
-; CHECK: [[ATTRS]] = { argmemonly }
+; CHECK: [[ATTRS]] = { argmemonly nofree }
OpenPOWER on IntegriCloud