[RPOFuncAttrs] Fix norecurse detection
authorArthur Eubanks <aeubanks@google.com>
Fri, 17 Jun 2022 22:59:53 +0000 (15:59 -0700)
committerArthur Eubanks <aeubanks@google.com>
Sat, 18 Jun 2022 19:20:10 +0000 (12:20 -0700)
We wanted to check if all uses of the function are direct calls, but the
code didn't account for passing the function as a parameter.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D128104

llvm/lib/Transforms/IPO/FunctionAttrs.cpp
llvm/test/Transforms/FunctionAttrs/norecurse.ll

index 360a37f112ea6bf4b1db1503fea25ffe1030fe3a..769cad60c06d5a680e67478335296423e7ae85a1 100644 (file)
@@ -2014,12 +2014,13 @@ static bool addNoRecurseAttrsTopDown(Function &F) {
   // this function could be recursively (indirectly) called. Note that this
   // also detects if F is directly recursive as F is not yet marked as
   // a norecurse function.
-  for (auto *U : F.users()) {
-    auto *I = dyn_cast<Instruction>(U);
+  for (auto &U : F.uses()) {
+    auto *I = dyn_cast<Instruction>(U.getUser());
     if (!I)
       return false;
     CallBase *CB = dyn_cast<CallBase>(I);
-    if (!CB || !CB->getParent()->getParent()->doesNotRecurse())
+    if (!CB || !CB->isCallee(&U) ||
+        !CB->getParent()->getParent()->doesNotRecurse())
       return false;
   }
   F.setDoesNotRecurse();
index b1130b93d23d7643ca5d6ac76b2416bc843772a0..7baa7034aaa4b1c229a947787db995d321675788 100644 (file)
@@ -99,7 +99,9 @@ define void @p() norecurse {
 }
 
 ; CHECK: Function Attrs
-; CHECK-SAME: norecurse nosync readnone
+; CHECK-NOT: norecurse
+; CHECK-SAME: nosync readnone
+; CHECK-NOT: norecurse
 ; CHECK-NEXT: define internal i32 @escapes_as_parameter
 define internal i32 @escapes_as_parameter(ptr %p) {
   %a = call i32 @k()