llvm.org GIT mirror llvm / 3f4d13d
[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). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@290581 91177308-0d34-0410-b5e6-96231b3b80d8 Chandler Carruth 2 years ago
2 changed file(s) with 42 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
4343 #include "llvm/ADT/iterator.h"
4444 #include "llvm/ADT/iterator_range.h"
4545 #include "llvm/IR/BasicBlock.h"
46 #include "llvm/IR/Constants.h"
4647 #include "llvm/IR/Function.h"
4748 #include "llvm/IR/Module.h"
4849 #include "llvm/IR/PassManager.h"
972973 continue;
973974 }
974975
976 if (BlockAddress *BA = dyn_cast(C)) {
977 // The blockaddress constant expression is a weird special case, we
978 // can't generically walk its operands the way we do for all other
979 // constants.
980 if (Visited.insert(BA->getFunction()).second)
981 Worklist.push_back(BA->getFunction());
982 continue;
983 }
984
975985 for (Value *Op : C->operand_values())
976986 if (Visited.insert(cast(Op)).second)
977987 Worklist.push_back(cast(Op));
20152015 EXPECT_EQ(&AC, &RC[4]);
20162016 }
20172017
2018 }
2018 // Test for IR containing constants using blockaddress constant expressions.
2019 // These are truly unique constructs: constant expressions with non-constant
2020 // operands.
2021 TEST(LazyCallGraphTest, HandleBlockAddress) {
2022 LLVMContext Context;
2023 std::unique_ptr M =
2024 parseAssembly(Context, "define void @f() {\n"
2025 "entry:\n"
2026 " ret void\n"
2027 "bb:\n"
2028 " unreachable\n"
2029 "}\n"
2030 "define void @g(i8** %ptr) {\n"
2031 "entry:\n"
2032 " store i8* blockaddress(@f, %bb), i8** %ptr\n"
2033 " ret void\n"
2034 "}\n");
2035 LazyCallGraph CG(*M);
2036
2037 auto I = CG.postorder_ref_scc_begin();
2038 LazyCallGraph::RefSCC &FRC = *I++;
2039 LazyCallGraph::RefSCC &GRC = *I++;
2040 EXPECT_EQ(CG.postorder_ref_scc_end(), I);
2041
2042 LazyCallGraph::Node &F = *CG.lookup(lookupFunction(*M, "f"));
2043 LazyCallGraph::Node &G = *CG.lookup(lookupFunction(*M, "g"));
2044 EXPECT_EQ(&FRC, CG.lookupRefSCC(F));
2045 EXPECT_EQ(&GRC, CG.lookupRefSCC(G));
2046 EXPECT_TRUE(GRC.isParentOf(FRC));
2047 }
2048
2049 }