summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Blaikie <dblaikie@gmail.com>2017-06-07 21:37:39 +0000
committerDavid Blaikie <dblaikie@gmail.com>2017-06-07 21:37:39 +0000
commit96e2a9955b7874886eebe2a73ebec51beb22cb6d (patch)
tree31c9641f92c385b44738685c6699b1666ef67e29
parent6ed2765ff12725dc4604853d43387953281c0391 (diff)
GlobalsModRef: Ensure optnone+readonly/readnone attributes are respected
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@304945 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Analysis/GlobalsModRef.cpp13
-rw-r--r--unittests/Analysis/GlobalsModRefTest.cpp24
2 files changed, 24 insertions, 13 deletions
diff --git a/lib/Analysis/GlobalsModRef.cpp b/lib/Analysis/GlobalsModRef.cpp
index 39c38798f3c..4ef023379bb 100644
--- a/lib/Analysis/GlobalsModRef.cpp
+++ b/lib/Analysis/GlobalsModRef.cpp
@@ -477,8 +477,7 @@ void GlobalsAAResult::AnalyzeCallGraph(CallGraph &CG, Module &M) {
Function *F = SCC[0]->getFunction();
- if (!F || !F->isDefinitionExact() ||
- F->hasFnAttribute(Attribute::OptimizeNone)) {
+ if (!F || !F->isDefinitionExact()) {
// Calls externally or not exact - can't say anything useful. Remove any
// existing function records (may have been created when scanning
// globals).
@@ -498,7 +497,7 @@ void GlobalsAAResult::AnalyzeCallGraph(CallGraph &CG, Module &M) {
break;
}
- if (F->isDeclaration()) {
+ if (F->isDeclaration() || F->hasFnAttribute(Attribute::OptimizeNone)) {
// Try to get mod/ref behaviour from function attributes.
if (F->doesNotAccessMemory()) {
// Can't do better than that!
@@ -549,12 +548,10 @@ void GlobalsAAResult::AnalyzeCallGraph(CallGraph &CG, Module &M) {
break; // The mod/ref lattice saturates here.
// Don't prove any properties based on the implementation of an optnone
- // function.
- if (Node->getFunction()->hasFnAttribute(Attribute::OptimizeNone)) {
- FI.addModRefInfo(MRI_Ref);
- FI.addModRefInfo(MRI_Mod);
+ // function. Function attributes were already used as a best approximation
+ // above.
+ if (Node->getFunction()->hasFnAttribute(Attribute::OptimizeNone))
continue;
- }
for (Instruction &I : instructions(Node->getFunction())) {
if (FI.getModRefInfo() == MRI_ModRef)
diff --git a/unittests/Analysis/GlobalsModRefTest.cpp b/unittests/Analysis/GlobalsModRefTest.cpp
index da8b44d273f..323edc2cc17 100644
--- a/unittests/Analysis/GlobalsModRefTest.cpp
+++ b/unittests/Analysis/GlobalsModRefTest.cpp
@@ -16,7 +16,13 @@ using namespace llvm;
TEST(GlobalsModRef, OptNone) {
StringRef Assembly = R"(
- define void @f() optnone {
+ define void @f1() optnone {
+ ret void
+ }
+ define void @f2() optnone readnone {
+ ret void
+ }
+ define void @f3() optnone readonly {
ret void
}
)";
@@ -27,9 +33,14 @@ TEST(GlobalsModRef, OptNone) {
ASSERT_TRUE(M) << "Bad assembly?";
const auto &funcs = M->functions();
- ASSERT_NE(funcs.begin(), funcs.end());
- EXPECT_EQ(std::next(funcs.begin()), funcs.end());
- const Function &F = *funcs.begin();
+ auto I = funcs.begin();
+ ASSERT_NE(I, funcs.end());
+ const Function &F1 = *I;
+ ASSERT_NE(++I, funcs.end());
+ const Function &F2 = *I;
+ ASSERT_NE(++I, funcs.end());
+ const Function &F3 = *I;
+ EXPECT_EQ(++I, funcs.end());
Triple Trip(M->getTargetTriple());
TargetLibraryInfoImpl TLII(Trip);
@@ -37,5 +48,8 @@ TEST(GlobalsModRef, OptNone) {
llvm::CallGraph CG(*M);
auto AAR = GlobalsAAResult::analyzeModule(*M, TLI, CG);
- EXPECT_EQ(FMRB_UnknownModRefBehavior, AAR.getModRefBehavior(&F));
+
+ EXPECT_EQ(FMRB_UnknownModRefBehavior, AAR.getModRefBehavior(&F1));
+ EXPECT_EQ(FMRB_DoesNotAccessMemory, AAR.getModRefBehavior(&F2));
+ EXPECT_EQ(FMRB_OnlyReadsMemory, AAR.getModRefBehavior(&F3));
}