aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/InlineFunction.cpp
diff options
context:
space:
mode:
authorKrzysztof Pszeniczny <kpszeniczny@google.com>2024-05-26 18:05:13 +0200
committerGitHub <noreply@github.com>2024-05-26 18:05:13 +0200
commitcda5790e38af5da3ad455eddab36ef16bf3e8104 (patch)
tree822b2860f08d0e430f65a7c52a4e2b3fb8b0cd8a /llvm/lib/Transforms/Utils/InlineFunction.cpp
parenta4a436672a2c179274e07aeb68e9acd6f483a653 (diff)
downloadllvm-cda5790e38af5da3ad455eddab36ef16bf3e8104.zip
llvm-cda5790e38af5da3ad455eddab36ef16bf3e8104.tar.gz
llvm-cda5790e38af5da3ad455eddab36ef16bf3e8104.tar.bz2
[Inliner] Don't propagate memory attributes to byval params (#93381)
Memory restrictions for params to the inlined function do not apply to the copies logically made when that function further passes its own params as byval. In other words, imagine that `@foo()` calls `@bar(ptr readonly %p)` which in turn calls `@baz(ptr byval("...") %p)` (passing the same `%p`). This is fully legal - `baz` is allowed to modify its copy of the object referenced by `%p` because the argument is passed by value. However, when inlining `@bar` into `@foo`, we can't say that the callsite is now `@baz(ptr readonly byval("...") %p)`, as this would mean that `@baz` is not allowed to modify it's copy of the object pointed to by `%p`. LangRef says: "The copy is considered to belong to the caller not the callee (for example, readonly functions should not write to byval parameters)". This fixes a miscompile introduced by PR #89024 in a program in the Google codebase.
Diffstat (limited to 'llvm/lib/Transforms/Utils/InlineFunction.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/InlineFunction.cpp6
1 files changed, 6 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp
index 82daaed..7b846f2 100644
--- a/llvm/lib/Transforms/Utils/InlineFunction.cpp
+++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp
@@ -1389,6 +1389,12 @@ static void AddParamAndFnBasicAttributes(const CallBase &CB,
if (!Arg)
continue;
+ if (AL.hasParamAttr(I, Attribute::ByVal))
+ // It's unsound to propagate memory attributes to byval arguments.
+ // Even if CalledFunction doesn't e.g. write to the argument,
+ // the call to NewInnerCB may write to its by-value copy.
+ continue;
+
unsigned ArgNo = Arg->getArgNo();
// If so, propagate its access attributes.
AL = AL.addParamAttributes(Context, I, ValidParamAttrs[ArgNo]);