[PATCH] D115916: [funcattrs] Consistently treat calling a function pointer as a non-capturing read

Philip Reames via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 16 16:55:51 PST 2021


reames created this revision.
reames added reviewers: jdoerfert, anna, sstefan1, aeubanks, modimo.
Herald added subscribers: ormris, bollu, hiraditya, mcrosier.
reames requested review of this revision.
Herald added a project: LLVM.

We were being wildly inconsistent about what memory access was implied by an indirect function call.  Depending on the call site attributes, you could get anything from a read, to unknown, to none at all. (The last was a miscompile.)

We were also always traversing the uses of a readonly indirect call.  This is entirely unneeded as the indirect call does not capture.  The callee might capture itself internally, but that has no implications for this caller.  (See the nice explanation in the CaptureTracking comments if that case is confusing.)

Note that elsewhere in the same file, we were correctly computing the nocapture attribute for indirect calls.  The changed case only resulted in conservatism when computing memory attributes if say the return value was written to.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D115916

Files:
  llvm/lib/Transforms/IPO/FunctionAttrs.cpp
  llvm/test/Transforms/FunctionAttrs/nocapture.ll
  llvm/test/Transforms/FunctionAttrs/writeonly.ll


Index: llvm/test/Transforms/FunctionAttrs/writeonly.ll
===================================================================
--- llvm/test/Transforms/FunctionAttrs/writeonly.ll
+++ llvm/test/Transforms/FunctionAttrs/writeonly.ll
@@ -92,19 +92,19 @@
   ret void
 }
 
-; CHECK: define void @fptr_test1(i8* %p, void (i8*)* nocapture %f)
+; CHECK: define void @fptr_test1(i8* %p, void (i8*)* nocapture readonly %f)
 define void @fptr_test1(i8* %p, void (i8*)* %f) {
   call void %f(i8* %p)
   ret void
 }
 
-; CHECK: define void @fptr_test2(i8* %p, void (i8*)* nocapture %f)
+; CHECK: define void @fptr_test2(i8* %p, void (i8*)* nocapture readonly %f)
 define void @fptr_test2(i8* %p, void (i8*)* %f) {
   call void %f(i8* writeonly %p)
   ret void
 }
 
-; CHECK: define void @fptr_test3(i8* %p, void (i8*)* nocapture %f)
+; CHECK: define void @fptr_test3(i8* %p, void (i8*)* nocapture readonly %f)
 define void @fptr_test3(i8* %p, void (i8*)* %f) {
   call void %f(i8* %p) writeonly
   ret void
Index: llvm/test/Transforms/FunctionAttrs/nocapture.ll
===================================================================
--- llvm/test/Transforms/FunctionAttrs/nocapture.ll
+++ llvm/test/Transforms/FunctionAttrs/nocapture.ll
@@ -128,7 +128,7 @@
 }
 
 
-; FNATTR: define void @nc3(void ()* nocapture %p)
+; FNATTR: define void @nc3(void ()* nocapture readonly %p)
 define void @nc3(void ()* %p) {
 	call void %p()
 	ret void
@@ -141,7 +141,7 @@
 	ret void
 }
 
-; FNATTR: define void @nc5(void (i8*)* nocapture %f, i8* nocapture %p)
+; FNATTR: define void @nc5(void (i8*)* nocapture readonly %f, i8* nocapture %p)
 define void @nc5(void (i8*)* %f, i8* %p) {
 	call void %f(i8* %p) readonly nounwind
 	call void %f(i8* nocapture %p)
@@ -319,21 +319,21 @@
 
 declare void @capture(i8*)
 
-; FNATTR: define void @nocapture_fptr(i8* (i8*)* nocapture %f, i8* %p)
+; FNATTR: define void @nocapture_fptr(i8* (i8*)* nocapture readonly %f, i8* %p)
 define void @nocapture_fptr(i8* (i8*)* %f, i8* %p) {
   %res = call i8* %f(i8* %p)
   call void @capture(i8* %res)
   ret void
 }
 
-; FNATTR: define void @recurse_fptr(i8* (i8*)* nocapture %f, i8* %p)
+; FNATTR: define void @recurse_fptr(i8* (i8*)* nocapture readonly %f, i8* %p)
 define void @recurse_fptr(i8* (i8*)* %f, i8* %p) {
   %res = call i8* %f(i8* %p)
   store i8 0, i8* %res
   ret void
 }
 
-; FNATTR: define void @readnone_indirec(void (i8*)* nocapture readnone %f, i8* readnone %p)
+; FNATTR: define void @readnone_indirec(void (i8*)* nocapture readonly %f, i8* readnone %p)
 define void @readnone_indirec(void (i8*)* %f, i8* %p) {
   call void %f(i8* %p) readnone
   ret void
Index: llvm/lib/Transforms/IPO/FunctionAttrs.cpp
===================================================================
--- llvm/lib/Transforms/IPO/FunctionAttrs.cpp
+++ llvm/lib/Transforms/IPO/FunctionAttrs.cpp
@@ -702,6 +702,11 @@
       };
 
       CallBase &CB = cast<CallBase>(*I);
+      if (CB.isCallee(U)) {
+        IsRead = true;
+        Captures = false; // See comment in CaptureTracking for context
+        continue;
+      }
       if (CB.doesNotAccessMemory()) {
         AddUsersToWorklistIfCapturing();
         continue;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D115916.395035.patch
Type: text/x-patch
Size: 3161 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20211217/d2f6d341/attachment.bin>


More information about the llvm-commits mailing list