[llvm] [FunctionAttrs] Only consider provenance capture in access attr inference (PR #138535)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Mon May 5 07:17:50 PDT 2025


https://github.com/nikic created https://github.com/llvm/llvm-project/pull/138535

For the purpose of inferring readonly/writeonly/readnone on arguments, we only care about provenance captures, not address captures.

>From b5d0f7b3aca880e678febce8acb22e7a67ad6d5a Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Mon, 5 May 2025 15:57:40 +0200
Subject: [PATCH] [FunctionAttrs] Only consider provenance capture in access
 attr inference

For the purpose of infering readonly/writeonly/readnone on the
arguments, we only care about provenance captures, not address
captures.
---
 llvm/lib/Transforms/IPO/FunctionAttrs.cpp       | 9 ++++-----
 llvm/test/Transforms/FunctionAttrs/nocapture.ll | 4 ++--
 2 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
index 74e8a849803d2..f918d7e059b63 100644
--- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
@@ -908,7 +908,7 @@ determinePointerAccessAttrs(Argument *A,
         for (Use &UU : CB.uses())
           if (Visited.insert(&UU).second)
             Worklist.push_back(&UU);
-      } else if (!CB.doesNotCapture(UseIndex)) {
+      } else if (capturesAnyProvenance(CB.getCaptureInfo(UseIndex))) {
         if (!CB.onlyReadsMemory())
           // If the callee can save a copy into other memory, then simply
           // scanning uses of the call is insufficient.  We have no way
@@ -1382,10 +1382,9 @@ static void addArgumentAttrs(const SCCNodeSet &SCCNodes,
       }
     }
 
-    // TODO(captures): Ignore address-only captures.
-    if (capturesAnything(CC)) {
-      // As the pointer may be captured, determine the pointer attributes
-      // looking at each argument individually.
+    if (capturesAnyProvenance(CC)) {
+      // As the pointer provenance may be captured, determine the pointer
+      // attributes looking at each argument individually.
       for (ArgumentGraphNode *N : ArgumentSCC) {
         if (DetermineAccessAttrsForSingleton(N->Definition))
           Changed.insert(N->Definition->getParent());
diff --git a/llvm/test/Transforms/FunctionAttrs/nocapture.ll b/llvm/test/Transforms/FunctionAttrs/nocapture.ll
index a5afa0ed365fb..9d6acc410de75 100644
--- a/llvm/test/Transforms/FunctionAttrs/nocapture.ll
+++ b/llvm/test/Transforms/FunctionAttrs/nocapture.ll
@@ -1234,7 +1234,7 @@ define void @dont_increase_existing_captures_scc2(ptr %p) {
 define void @addr_only_scc(ptr %p) {
 ; FNATTRS: Function Attrs: nofree nosync nounwind memory(write, argmem: read, inaccessiblemem: none)
 ; FNATTRS-LABEL: define void @addr_only_scc
-; FNATTRS-SAME: (ptr captures(address_is_null) [[P:%.*]]) #[[ATTR20:[0-9]+]] {
+; FNATTRS-SAME: (ptr readonly captures(address_is_null) [[P:%.*]]) #[[ATTR20:[0-9]+]] {
 ; FNATTRS-NEXT:    [[V:%.*]] = load i8, ptr [[P]], align 1
 ; FNATTRS-NEXT:    store i8 [[V]], ptr @g, align 1
 ; FNATTRS-NEXT:    call void @addr_only_scc2(ptr [[P]])
@@ -1257,7 +1257,7 @@ define void @addr_only_scc(ptr %p) {
 define void @addr_only_scc2(ptr %p) {
 ; FNATTRS: Function Attrs: nofree nosync nounwind memory(write, argmem: read, inaccessiblemem: none)
 ; FNATTRS-LABEL: define void @addr_only_scc2
-; FNATTRS-SAME: (ptr captures(address_is_null) [[P:%.*]]) #[[ATTR20]] {
+; FNATTRS-SAME: (ptr readonly captures(address_is_null) [[P:%.*]]) #[[ATTR20]] {
 ; FNATTRS-NEXT:    [[CMP:%.*]] = icmp ne ptr [[P]], null
 ; FNATTRS-NEXT:    br i1 [[CMP]], label [[IF:%.*]], label [[EXIT:%.*]]
 ; FNATTRS:       if:



More information about the llvm-commits mailing list