summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Blaikie <dblaikie@gmail.com>2017-06-06 20:51:15 +0000
committerDavid Blaikie <dblaikie@gmail.com>2017-06-06 20:51:15 +0000
commit3aa7f8086331183bf8c6d4ff840699286f0ffd08 (patch)
tree0cbecb12eee62d6efb99afbd099315a171d4faaf
parent698655354d44ec8d1a9f9e205a73f65be2f86fc0 (diff)
GlobalsModRef+OptNone: Don't prove readnone/other properties from an optnone function
Seems like at least one reasonable interpretation of optnone is that the optimizer never "looks inside" a function. This fix is consistent with that interpretation. Specifically this came up in the situation: f3 calls f2 calls f1 f2 is always_inline f1 is optnone The application of readnone to f1 (& thus to f2) caused the inliner to kill the call to f2 as being trivially dead (without even checking the cost function, as it happens - not sure if that's also a bug). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@304833 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Analysis/GlobalsModRef.cpp17
-rw-r--r--unittests/Analysis/CMakeLists.txt1
-rw-r--r--unittests/Analysis/GlobalsModRefTest.cpp41
3 files changed, 56 insertions, 3 deletions
diff --git a/lib/Analysis/GlobalsModRef.cpp b/lib/Analysis/GlobalsModRef.cpp
index 33f00cb19b2..39c38798f3c 100644
--- a/lib/Analysis/GlobalsModRef.cpp
+++ b/lib/Analysis/GlobalsModRef.cpp
@@ -475,7 +475,10 @@ void GlobalsAAResult::AnalyzeCallGraph(CallGraph &CG, Module &M) {
const std::vector<CallGraphNode *> &SCC = *I;
assert(!SCC.empty() && "SCC with no functions?");
- if (!SCC[0]->getFunction() || !SCC[0]->getFunction()->isDefinitionExact()) {
+ Function *F = SCC[0]->getFunction();
+
+ if (!F || !F->isDefinitionExact() ||
+ F->hasFnAttribute(Attribute::OptimizeNone)) {
// Calls externally or not exact - can't say anything useful. Remove any
// existing function records (may have been created when scanning
// globals).
@@ -484,13 +487,12 @@ void GlobalsAAResult::AnalyzeCallGraph(CallGraph &CG, Module &M) {
continue;
}
- FunctionInfo &FI = FunctionInfos[SCC[0]->getFunction()];
+ FunctionInfo &FI = FunctionInfos[F];
bool KnowNothing = false;
// Collect the mod/ref properties due to called functions. We only compute
// one mod-ref set.
for (unsigned i = 0, e = SCC.size(); i != e && !KnowNothing; ++i) {
- Function *F = SCC[i]->getFunction();
if (!F) {
KnowNothing = true;
break;
@@ -545,6 +547,15 @@ void GlobalsAAResult::AnalyzeCallGraph(CallGraph &CG, Module &M) {
for (auto *Node : SCC) {
if (FI.getModRefInfo() == MRI_ModRef)
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);
+ continue;
+ }
+
for (Instruction &I : instructions(Node->getFunction())) {
if (FI.getModRefInfo() == MRI_ModRef)
break; // The mod/ref lattice saturates here.
diff --git a/unittests/Analysis/CMakeLists.txt b/unittests/Analysis/CMakeLists.txt
index 8082c54b9c6..ac8bca25d93 100644
--- a/unittests/Analysis/CMakeLists.txt
+++ b/unittests/Analysis/CMakeLists.txt
@@ -12,6 +12,7 @@ add_llvm_unittest(AnalysisTests
CallGraphTest.cpp
CFGTest.cpp
CGSCCPassManagerTest.cpp
+ GlobalsModRefTest.cpp
LazyCallGraphTest.cpp
LoopInfoTest.cpp
MemoryBuiltinsTest.cpp
diff --git a/unittests/Analysis/GlobalsModRefTest.cpp b/unittests/Analysis/GlobalsModRefTest.cpp
new file mode 100644
index 00000000000..da8b44d273f
--- /dev/null
+++ b/unittests/Analysis/GlobalsModRefTest.cpp
@@ -0,0 +1,41 @@
+//===--- GlobalsModRefTest.cpp - Mixed TBAA unit tests --------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/GlobalsModRef.h"
+#include "llvm/AsmParser/Parser.h"
+#include "llvm/Support/SourceMgr.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+TEST(GlobalsModRef, OptNone) {
+ StringRef Assembly = R"(
+ define void @f() optnone {
+ ret void
+ }
+ )";
+
+ LLVMContext Context;
+ SMDiagnostic Error;
+ auto M = parseAssemblyString(Assembly, Error, Context);
+ 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();
+
+ Triple Trip(M->getTargetTriple());
+ TargetLibraryInfoImpl TLII(Trip);
+ TargetLibraryInfo TLI(TLII);
+ llvm::CallGraph CG(*M);
+
+ auto AAR = GlobalsAAResult::analyzeModule(*M, TLI, CG);
+ EXPECT_EQ(FMRB_UnknownModRefBehavior, AAR.getModRefBehavior(&F));
+}