llvm.org GIT mirror llvm / ee48043
[PM/LCG] Follow-up fix to r308088 to handle deletion of library functions. In the prior commit, we provide ordering to the LCG between functions and library function definitions that they might begin to call through transformations. But we still would delete these library functions from the call graph if they became dead during inlining. While this immediately crashed, it also exposed a loss of information. We shouldn't remove definitions of library functions that can still usefully participate in the LCG-powered CGSCC optimization process. If new call edges are formed, we want to have definitions to be called. We can still remove these functions if truly dead using global-dce, etc, but removing them during the CGSCC walk is premature. This fixes a crash in the new PM when optimizing some unusual libraries that end up with "internal" lib functions such as the code in the "R" language's libraries. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@308417 91177308-0d34-0410-b5e6-96231b3b80d8 Chandler Carruth 3 years ago
4 changed file(s) with 48 addition(s) and 7 deletion(s). Raw diff Collapse all Expand all
970970 ///
971971 /// These functions, because they are known to LLVM, can have calls
972972 /// introduced out of thin air from arbitrary IR.
973 ArrayRef getLibFunctions() const { return LibFunctions; }
973 ArrayRef getLibFunctions() const {
974 return LibFunctions.getArrayRef();
975 }
976
977 /// Test whether a function is a known and defined library function tracked by
978 /// the call graph.
979 ///
980 /// Because these functions are known to LLVM they are specially modeled in
981 /// the call graph and even when all IR-level references have been removed
982 /// remain active and reachable.
983 bool isLibFunction(Function &F) const { return LibFunctions.count(&F); }
974984
975985 ///@{
976986 /// \name Pre-SCC Mutation API
11091119 /// Defined functions that are also known library functions which the
11101120 /// optimizer can reason about and therefore might introduce calls to out of
11111121 /// thin air.
1112 SmallVector LibFunctions;
1122 SmallSetVector LibFunctions;
11131123
11141124 /// Helper to insert a new function, with an already looked-up entry in
11151125 /// the NodeMap.
143143 // synthesize reference edges to it to model the fact that LLVM can turn
144144 // arbitrary code into a library function call.
145145 if (isKnownLibFunction(F, TLI))
146 LibFunctions.push_back(&F);
146 LibFunctions.insert(&F);
147147
148148 if (F.hasLocalLinkage())
149149 continue;
16071607 assert(F.use_empty() &&
16081608 "This routine should only be called on trivially dead functions!");
16091609
1610 // We shouldn't remove library functions as they are never really dead while
1611 // the call graph is in use -- every function definition refers to them.
1612 assert(!isLibFunction(F) &&
1613 "Must not remove lib functions from the call graph!");
1614
16101615 auto NI = NodeMap.find(&F);
16111616 if (NI == NodeMap.end())
16121617 // Not in the graph at all!
908908 // To check this we also need to nuke any dead constant uses (perhaps
909909 // made dead by this operation on other functions).
910910 Callee.removeDeadConstantUsers();
911 if (Callee.use_empty()) {
911 if (Callee.use_empty() && !CG.isLibFunction(Callee)) {
912912 Calls.erase(
913913 std::remove_if(Calls.begin() + i + 1, Calls.end(),
914914 [&Callee](const std::pair &Call) {
0 ; Make sure that the CGSCC pass manager can handle when instcombine simplifies
11 ; one libcall into an unrelated libcall and update the call graph accordingly.
22 ;
3 ; RUN: opt -passes='cgscc(function(instcombine))' -S < %s | FileCheck %s
3 ; Also check that it can handle inlining *removing* a libcall entirely.
4 ;
5 ; RUN: opt -passes='cgscc(inline,function(instcombine))' -S < %s | FileCheck %s
46
57 define i8* @wibble(i8* %arg1, i8* %arg2) {
6 ; CHECK-LABLE: define @wibble(
8 ; CHECK-LABEL: define i8* @wibble(
79 bb:
810 %tmp = alloca [1024 x i8], align 16
911 %tmp2 = getelementptr inbounds [1024 x i8], [1024 x i8]* %tmp, i64 0, i64 0
1921 ; CHECK: ret
2022 }
2123
22 define i8* @strncpy(i8* %arg1, i8* %arg2, i64 %size) {
24 define i8* @strncpy(i8* %arg1, i8* %arg2, i64 %size) noinline {
2325 bb:
2426 %result = call i8* @my_special_strncpy(i8* %arg1, i8* %arg2, i64 %size)
2527 ret i8* %result
3234 declare i8* @__strncpy_chk(i8*, i8*, i64, i64)
3335
3436 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i32, i1)
37
38 ; Check that even when we completely remove a libcall we don't get the call
39 ; graph wrong once we handle libcalls in the call graph specially to address
40 ; the above case.
41 define i32 @hoge(i32* %arg1) {
42 ; CHECK-LABEL: define i32 @hoge(
43 bb:
44 %tmp41 = load i32*, i32** null
45 %tmp6 = load i32, i32* %arg1
46 %tmp7 = call i32 @ntohl(i32 %tmp6)
47 ; CHECK-NOT: call i32 @ntohl
48 ret i32 %tmp7
49 ; CHECK: ret i32
50 }
51
52 ; Even though this function is not used, it should be retained as it may be
53 ; used when doing further libcall transformations.
54 define internal i32 @ntohl(i32 %x) {
55 ; CHECK-LABEL: define internal i32 @ntohl(
56 entry:
57 %and2 = lshr i32 %x, 8
58 %shr = and i32 %and2, 65280
59 ret i32 %shr
60 }