[llvm] r290581 - [LCG] Teach the LazyCallGraph to handle visiting the blockaddress
Chandler Carruth via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 26 21:00:46 PST 2016
Author: chandlerc
Date: Mon Dec 26 23:00:45 2016
New Revision: 290581
URL: http://llvm.org/viewvc/llvm-project?rev=290581&view=rev
Log:
[LCG] Teach the LazyCallGraph to handle visiting the blockaddress
constant expression and to correctly form function reference edges
through them without crashing because one of the operands (the
`BasicBlock` isn't actually a constant despite being an operand of
a constant).
Modified:
llvm/trunk/include/llvm/Analysis/LazyCallGraph.h
llvm/trunk/unittests/Analysis/LazyCallGraphTest.cpp
Modified: llvm/trunk/include/llvm/Analysis/LazyCallGraph.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/LazyCallGraph.h?rev=290581&r1=290580&r2=290581&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/LazyCallGraph.h (original)
+++ llvm/trunk/include/llvm/Analysis/LazyCallGraph.h Mon Dec 26 23:00:45 2016
@@ -44,6 +44,7 @@
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
@@ -973,6 +974,15 @@ public:
continue;
}
+ if (BlockAddress *BA = dyn_cast<BlockAddress>(C)) {
+ // The blockaddress constant expression is a weird special case, we
+ // can't generically walk its operands the way we do for all other
+ // constants.
+ if (Visited.insert(BA->getFunction()).second)
+ Worklist.push_back(BA->getFunction());
+ continue;
+ }
+
for (Value *Op : C->operand_values())
if (Visited.insert(cast<Constant>(Op)).second)
Worklist.push_back(cast<Constant>(Op));
Modified: llvm/trunk/unittests/Analysis/LazyCallGraphTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Analysis/LazyCallGraphTest.cpp?rev=290581&r1=290580&r2=290581&view=diff
==============================================================================
--- llvm/trunk/unittests/Analysis/LazyCallGraphTest.cpp (original)
+++ llvm/trunk/unittests/Analysis/LazyCallGraphTest.cpp Mon Dec 26 23:00:45 2016
@@ -2016,4 +2016,35 @@ TEST(LazyCallGraphTest, InternalRefEdgeT
EXPECT_EQ(&AC, &RC[4]);
}
+// Test for IR containing constants using blockaddress constant expressions.
+// These are truly unique constructs: constant expressions with non-constant
+// operands.
+TEST(LazyCallGraphTest, HandleBlockAddress) {
+ LLVMContext Context;
+ std::unique_ptr<Module> M =
+ parseAssembly(Context, "define void @f() {\n"
+ "entry:\n"
+ " ret void\n"
+ "bb:\n"
+ " unreachable\n"
+ "}\n"
+ "define void @g(i8** %ptr) {\n"
+ "entry:\n"
+ " store i8* blockaddress(@f, %bb), i8** %ptr\n"
+ " ret void\n"
+ "}\n");
+ LazyCallGraph CG(*M);
+
+ auto I = CG.postorder_ref_scc_begin();
+ LazyCallGraph::RefSCC &FRC = *I++;
+ LazyCallGraph::RefSCC &GRC = *I++;
+ EXPECT_EQ(CG.postorder_ref_scc_end(), I);
+
+ LazyCallGraph::Node &F = *CG.lookup(lookupFunction(*M, "f"));
+ LazyCallGraph::Node &G = *CG.lookup(lookupFunction(*M, "g"));
+ EXPECT_EQ(&FRC, CG.lookupRefSCC(F));
+ EXPECT_EQ(&GRC, CG.lookupRefSCC(G));
+ EXPECT_TRUE(GRC.isParentOf(FRC));
+}
+
}
More information about the llvm-commits
mailing list