Skip to content

Commit ee41e32

Browse files
committed
[FunctionAttrs] Don't bail out on unknown calls
When inferring attributes, we should not bail out early on unknown calls (such as virtual calls), as we may still have call-site attributes that can be used for inference. Fixes #150817.
1 parent 166493d commit ee41e32

File tree

5 files changed

+19
-37
lines changed

5 files changed

+19
-37
lines changed

llvm/lib/Transforms/IPO/FunctionAttrs.cpp

Lines changed: 11 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1863,7 +1863,6 @@ void AttributeInferer::run(const SCCNodeSet &SCCNodes,
18631863

18641864
struct SCCNodesResult {
18651865
SCCNodeSet SCCNodes;
1866-
bool HasUnknownCall;
18671866
};
18681867

18691868
} // end anonymous namespace
@@ -2087,11 +2086,13 @@ static void addNoRecurseAttrs(const SCCNodeSet &SCCNodes,
20872086
for (auto &BB : *F)
20882087
for (auto &I : BB.instructionsWithoutDebug())
20892088
if (auto *CB = dyn_cast<CallBase>(&I)) {
2089+
if (CB->hasFnAttr(Attribute::NoRecurse))
2090+
continue;
2091+
20902092
Function *Callee = CB->getCalledFunction();
20912093
if (!Callee || Callee == F ||
2092-
(!Callee->doesNotRecurse() &&
2093-
!(Callee->isDeclaration() &&
2094-
Callee->hasFnAttribute(Attribute::NoCallback))))
2094+
!(Callee->isDeclaration() &&
2095+
Callee->hasFnAttribute(Attribute::NoCallback)))
20952096
// Function calls a potentially recursive function.
20962097
return;
20972098
}
@@ -2227,29 +2228,13 @@ static void addWillReturn(const SCCNodeSet &SCCNodes,
22272228

22282229
static SCCNodesResult createSCCNodeSet(ArrayRef<Function *> Functions) {
22292230
SCCNodesResult Res;
2230-
Res.HasUnknownCall = false;
22312231
for (Function *F : Functions) {
22322232
if (!F || F->hasOptNone() || F->hasFnAttribute(Attribute::Naked) ||
22332233
F->isPresplitCoroutine()) {
2234-
// Treat any function we're trying not to optimize as if it were an
2235-
// indirect call and omit it from the node set used below.
2236-
Res.HasUnknownCall = true;
2234+
// Omit any functions we're trying not to optimize from the set.
22372235
continue;
22382236
}
2239-
// Track whether any functions in this SCC have an unknown call edge.
2240-
// Note: if this is ever a performance hit, we can common it with
2241-
// subsequent routines which also do scans over the instructions of the
2242-
// function.
2243-
if (!Res.HasUnknownCall) {
2244-
for (Instruction &I : instructions(*F)) {
2245-
if (auto *CB = dyn_cast<CallBase>(&I)) {
2246-
if (!CB->getCalledFunction()) {
2247-
Res.HasUnknownCall = true;
2248-
break;
2249-
}
2250-
}
2251-
}
2252-
}
2237+
22532238
Res.SCCNodes.insert(F);
22542239
}
22552240
return Res;
@@ -2282,15 +2267,10 @@ deriveAttrsInPostOrder(ArrayRef<Function *> Functions, AARGetterT &&AARGetter,
22822267
addColdAttrs(Nodes.SCCNodes, Changed);
22832268
addWillReturn(Nodes.SCCNodes, Changed);
22842269
addNoUndefAttrs(Nodes.SCCNodes, Changed);
2285-
2286-
// If we have no external nodes participating in the SCC, we can deduce some
2287-
// more precise attributes as well.
2288-
if (!Nodes.HasUnknownCall) {
2289-
addNoAliasAttrs(Nodes.SCCNodes, Changed);
2290-
addNonNullAttrs(Nodes.SCCNodes, Changed);
2291-
inferAttrsFromFunctionBodies(Nodes.SCCNodes, Changed);
2292-
addNoRecurseAttrs(Nodes.SCCNodes, Changed);
2293-
}
2270+
addNoAliasAttrs(Nodes.SCCNodes, Changed);
2271+
addNonNullAttrs(Nodes.SCCNodes, Changed);
2272+
inferAttrsFromFunctionBodies(Nodes.SCCNodes, Changed);
2273+
addNoRecurseAttrs(Nodes.SCCNodes, Changed);
22942274

22952275
// Finally, infer the maximal set of attributes from the ones we've inferred
22962276
// above. This is handling the cases where one attribute on a signature

llvm/test/Transforms/FunctionAttrs/noalias.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ define ptr @return_unknown_call(ptr %fn) {
235235
}
236236

237237
define ptr @return_unknown_noalias_call(ptr %fn) {
238-
; CHECK-LABEL: define ptr @return_unknown_noalias_call(
238+
; CHECK-LABEL: define noalias ptr @return_unknown_noalias_call(
239239
; CHECK-SAME: ptr readonly captures(none) [[FN:%.*]]) {
240240
; CHECK-NEXT: [[A:%.*]] = call noalias ptr [[FN]]()
241241
; CHECK-NEXT: ret ptr [[A]]

llvm/test/Transforms/FunctionAttrs/nonnull.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1412,7 +1412,7 @@ define ptr @unknown_func(ptr %fn) {
14121412
}
14131413

14141414
define ptr @unknown_nonnull_func(ptr %fn) {
1415-
; FNATTRS-LABEL: define ptr @unknown_nonnull_func(
1415+
; FNATTRS-LABEL: define nonnull ptr @unknown_nonnull_func(
14161416
; FNATTRS-SAME: ptr readonly captures(none) [[FN:%.*]]) {
14171417
; FNATTRS-NEXT: [[RES:%.*]] = call nonnull ptr [[FN]]()
14181418
; FNATTRS-NEXT: ret ptr [[RES]]

llvm/test/Transforms/FunctionAttrs/norecurse.ll

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,9 +258,10 @@ define void @unknown_call(ptr %fn) {
258258
}
259259

260260
define void @unknown_norecurse_call(ptr %fn) {
261+
; FNATTRS: Function Attrs: norecurse
261262
; FNATTRS-LABEL: define {{[^@]+}}@unknown_norecurse_call
262-
; FNATTRS-SAME: (ptr readonly captures(none) [[FN:%.*]]) {
263-
; FNATTRS-NEXT: call void [[FN]]() #[[ATTR7:[0-9]+]]
263+
; FNATTRS-SAME: (ptr readonly captures(none) [[FN:%.*]]) #[[ATTR7:[0-9]+]] {
264+
; FNATTRS-NEXT: call void [[FN]]() #[[ATTR7]]
264265
; FNATTRS-NEXT: ret void
265266
;
266267
; ATTRIBUTOR-LABEL: define {{[^@]+}}@unknown_norecurse_call

llvm/test/Transforms/FunctionAttrs/nounwind.ll

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -418,9 +418,10 @@ define void @unknown_call(ptr %fn) {
418418
}
419419

420420
define void @unknown_nounwind_call(ptr %fn) {
421+
; FNATTRS: Function Attrs: nounwind
421422
; FNATTRS-LABEL: define {{[^@]+}}@unknown_nounwind_call
422-
; FNATTRS-SAME: (ptr readonly captures(none) [[FN:%.*]]) {
423-
; FNATTRS-NEXT: call void [[FN]]() #[[ATTR2:[0-9]+]]
423+
; FNATTRS-SAME: (ptr readonly captures(none) [[FN:%.*]]) #[[ATTR2:[0-9]+]] {
424+
; FNATTRS-NEXT: call void [[FN]]() #[[ATTR2]]
424425
; FNATTRS-NEXT: ret void
425426
;
426427
; ATTRIBUTOR: Function Attrs: nounwind

0 commit comments

Comments
 (0)