assert(E && "No function transformations should introduce *new* "
"call edges! Any new calls should be modeled as "
"promoted existing ref edges!");
- RetainedEdges.insert(&CalleeN);
+ bool Inserted = RetainedEdges.insert(&CalleeN).second;
+ (void)Inserted;
+ assert(Inserted && "We should never visit a function twice.");
if (!E->isCall())
PromotedRefTargets.insert(&CalleeN);
}
assert(E && "No function transformations should introduce *new* ref "
"edges! Any new ref edges would require IPO which "
"function passes aren't allowed to do!");
- RetainedEdges.insert(&RefereeN);
+ bool Inserted = RetainedEdges.insert(&RefereeN).second;
+ (void)Inserted;
+ assert(Inserted && "We should never visit a function twice.");
if (E->isCall())
DemotedCallTargets.insert(&RefereeN);
};
// Include synthetic reference edges to known, defined lib functions.
for (auto *F : G.getLibFunctions())
- VisitRef(*F);
+ // While the list of lib functions doesn't have repeats, don't re-visit
+ // anything handled above.
+ if (!Visited.count(F))
+ VisitRef(*F);
// First remove all of the edges that are no longer present in this function.
// We have to build a list of dead targets first and then remove them as the
;
; Also check that it can handle inlining *removing* a libcall entirely.
;
-; RUN: opt -passes='cgscc(inline,function(instcombine))' -S < %s | FileCheck %s
+; Finally, we include some recursive patterns and forced analysis invaliadtion
+; that can trigger infinite CGSCC refinement if not handled correctly.
+;
+; RUN: opt -passes='cgscc(inline,function(instcombine,invalidate<all>))' -S < %s | FileCheck %s
define i8* @wibble(i8* %arg1, i8* %arg2) {
; CHECK-LABEL: define i8* @wibble(
%shr = and i32 %and2, 65280
ret i32 %shr
}
+
+define i64 @write(i32 %i, i8* %p, i64 %j) {
+entry:
+ %val = call i64 @write_wrapper(i32 %i, i8* %p, i64 %j) noinline
+ ret i64 %val
+}
+
+define i64 @write_wrapper(i32 %i, i8* %p, i64 %j) {
+entry:
+ %val = call i64 @write(i32 %i, i8* %p, i64 %j) noinline
+ ret i64 %val
+}