diff --git a/clang/test/CodeGen/arm-cmse-attr.c b/clang/test/CodeGen/arm-cmse-attr.c --- a/clang/test/CodeGen/arm-cmse-attr.c +++ b/clang/test/CodeGen/arm-cmse-attr.c @@ -29,9 +29,9 @@ { } -// CHECK: define{{.*}} void @f1(void ()* nocapture %fptr) {{[^#]*}}#0 { +// CHECK: define{{.*}} void @f1(void ()* nocapture readonly %fptr) {{[^#]*}}#0 { // CHECK: call void %fptr() #2 -// CHECK: define{{.*}} void @f2(void ()* nocapture %fptr) {{[^#]*}}#0 { +// CHECK: define{{.*}} void @f2(void ()* nocapture readonly %fptr) {{[^#]*}}#0 { // CHECK: call void %fptr() #2 // CHECK: define{{.*}} void @f3() {{[^#]*}}#1 { // CHECK: define{{.*}} void @f4() {{[^#]*}}#1 { diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp --- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp +++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp @@ -702,6 +702,11 @@ }; CallBase &CB = cast(*I); + if (CB.isCallee(U)) { + IsRead = true; + Captures = false; // See comment in CaptureTracking for context + continue; + } if (CB.doesNotAccessMemory()) { AddUsersToWorklistIfCapturing(); continue; diff --git a/llvm/test/Transforms/FunctionAttrs/nocapture.ll b/llvm/test/Transforms/FunctionAttrs/nocapture.ll --- a/llvm/test/Transforms/FunctionAttrs/nocapture.ll +++ b/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 diff --git a/llvm/test/Transforms/FunctionAttrs/writeonly.ll b/llvm/test/Transforms/FunctionAttrs/writeonly.ll --- a/llvm/test/Transforms/FunctionAttrs/writeonly.ll +++ b/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