From: Philip Reames Date: Thu, 23 Dec 2021 02:21:59 +0000 (-0800) Subject: [funcattrs] Use callsite param attributes from indirect calls when inferring access... X-Git-Tag: upstream/15.0.7~22348 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ee5d5e19f99db863fc3037eb125d8cfce3b2c5d8;p=platform%2Fupstream%2Fllvm.git [funcattrs] Use callsite param attributes from indirect calls when inferring access attributes Arguments to an indirect call is by definition outside the SCC, but there's no reason we can't use locally defined facts on the call site. This also has the nice effect of further simplifying the code. Differential Revision: https://reviews.llvm.org/D116118 --- diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp index 516d400..321d4a1 100644 --- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp +++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp @@ -710,22 +710,13 @@ determinePointerAccessAttrs(Argument *A, if (CB.doesNotAccessMemory()) continue; - Function *F = CB.getCalledFunction(); - if (!F) { - if (CB.onlyReadsMemory()) { - IsRead = true; - continue; - } - return Attribute::None; - } - - if (CB.isArgOperand(U) && UseIndex < F->arg_size() && - SCCNodes.count(F->getArg(UseIndex))) { - // This is an argument which is part of the speculative SCC. Note that - // only operands corresponding to formal arguments of the callee can - // participate in the speculation. - break; - } + if (Function *F = CB.getCalledFunction()) + if (CB.isArgOperand(U) && UseIndex < F->arg_size() && + SCCNodes.count(F->getArg(UseIndex))) + // This is an argument which is part of the speculative SCC. Note + // that only operands corresponding to formal arguments of the callee + // can participate in the speculation. + break; // The accessors used on call site here do the right thing for calls and // invokes with operand bundles. diff --git a/llvm/test/Transforms/FunctionAttrs/readattrs.ll b/llvm/test/Transforms/FunctionAttrs/readattrs.ll index 3ca0bc4..8ea47cf 100644 --- a/llvm/test/Transforms/FunctionAttrs/readattrs.ll +++ b/llvm/test/Transforms/FunctionAttrs/readattrs.ll @@ -146,3 +146,42 @@ define void @unsound_readonly(i8* %ignored, i8* %escaped_then_written) { store i8 0, i8* %addr.ld ret void } + + +; CHECK: define void @fptr_test1a(i8* nocapture readnone %p, void (i8*)* nocapture readonly %f) +define void @fptr_test1a(i8* %p, void (i8*)* %f) { + call void %f(i8* nocapture readnone %p) + ret void +} + +; CHECK: define void @fptr_test1b(i8* %p, void (i8*)* nocapture readonly %f) +define void @fptr_test1b(i8* %p, void (i8*)* %f) { + ; Can't infer readnone here because call might capture %p + call void %f(i8* readnone %p) + ret void +} + +; CHECK: define void @fptr_test1c(i8* readnone %p, void (i8*)* nocapture readonly %f) +define void @fptr_test1c(i8* %p, void (i8*)* %f) { + call void %f(i8* readnone %p) readonly + ret void +} + +; CHECK: define void @fptr_test2a(i8* nocapture readonly %p, void (i8*)* nocapture readonly %f) +define void @fptr_test2a(i8* %p, void (i8*)* %f) { + call void %f(i8* nocapture readonly %p) + ret void +} + +; CHECK: define void @fptr_test2b(i8* %p, void (i8*)* nocapture readonly %f) +define void @fptr_test2b(i8* %p, void (i8*)* %f) { + ; Can't infer readonly here because call might capture %p + call void %f(i8* readonly %p) + ret void +} + +; CHECK: define void @fptr_test2c(i8* readonly %p, void (i8*)* nocapture readonly %f) +define void @fptr_test2c(i8* %p, void (i8*)* %f) { + call void %f(i8* readonly %p) readonly + ret void +}