llvm.org GIT mirror llvm / e7f98a9
[Lint] Don't warn about noalias argument aliasing if other argument is byval Summary: When using byval, the data is effectively copied as part of the call anyway, so we aren't actually passing the pointer and thus there is no reason to issue a warning. Reviewers: rnk Reviewed By: rnk Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D40118 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@321478 91177308-0d34-0410-b5e6-96231b3b80d8 Mikael Holmen 2 years ago
2 changed file(s) with 58 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
264264 // Check that noalias arguments don't alias other arguments. This is
265265 // not fully precise because we don't know the sizes of the dereferenced
266266 // memory regions.
267 if (Formal->hasNoAliasAttr() && Actual->getType()->isPointerTy())
268 for (CallSite::arg_iterator BI = CS.arg_begin(); BI != AE; ++BI)
267 if (Formal->hasNoAliasAttr() && Actual->getType()->isPointerTy()) {
268 AttributeList PAL = CS.getAttributes();
269 unsigned ArgNo = 0;
270 for (CallSite::arg_iterator BI = CS.arg_begin(); BI != AE; ++BI) {
271 // Skip ByVal arguments since they will be memcpy'd to the callee's
272 // stack so we're not really passing the pointer anyway.
273 if (PAL.hasParamAttribute(ArgNo++, Attribute::ByVal))
274 continue;
269275 if (AI != BI && (*BI)->getType()->isPointerTy()) {
270276 AliasResult Result = AA->alias(*AI, *BI);
271277 Assert(Result != MustAlias && Result != PartialAlias,
272278 "Unusual: noalias argument aliases another argument", &I);
273279 }
280 }
281 }
274282
275283 // Check that an sret argument points to valid memory.
276284 if (Formal->hasStructRetAttr() && Actual->getType()->isPointerTy()) {
0 ; RUN: opt < %s -lint -disable-output 2>&1 | FileCheck %s
1
2 %s = type { i8 }
3
4 ; Function Attrs: argmemonly nounwind
5 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture writeonly, i8* nocapture readonly, i32, i32, i1) #0
6
7 ; Function Attrs: argmemonly nounwind
8 declare void @llvm.memset.p0i8.i8.i32(i8* nocapture writeonly, i8, i32, i32, i1) #0
9
10 declare void @f1(%s* noalias nocapture sret, %s* nocapture readnone)
11
12 define void @f2() {
13 entry:
14 %c = alloca %s
15 %tmp = alloca %s
16 %0 = bitcast %s* %c to i8*
17 %1 = bitcast %s* %tmp to i8*
18 call void @llvm.memset.p0i8.i8.i32(i8* %0, i8 0, i32 1, i32 1, i1 false)
19 call void @f1(%s* sret %c, %s* %c)
20 ret void
21 }
22
23 ; Lint should complain about us passing %c to both arguments since one of them
24 ; is noalias.
25 ; CHECK: Unusual: noalias argument aliases another argument
26 ; CHECK-NEXT: call void @f1(%s* sret %c, %s* %c)
27
28 declare void @f3(%s* noalias nocapture sret, %s* byval nocapture readnone)
29
30 define void @f4() {
31 entry:
32 %c = alloca %s
33 %tmp = alloca %s
34 %0 = bitcast %s* %c to i8*
35 %1 = bitcast %s* %tmp to i8*
36 call void @llvm.memset.p0i8.i8.i32(i8* %0, i8 0, i32 1, i32 1, i1 false)
37 call void @f3(%s* sret %c, %s* byval %c)
38 ret void
39 }
40
41 ; Lint should not complain about passing %c to both arguments even if one is
42 ; noalias, since the other one is byval, effectively copying the data to the
43 ; stack instead of passing the pointer itself.
44 ; CHECK-NOT: Unusual: noalias argument aliases another argument
45 ; CHECK-NOT: call void @f3(%s* sret %c, %s* %c)
46
47 attributes #0 = { argmemonly nounwind }