[Inline] don't add noalias metadata for unknown objects.

The unidentified objects recognized in `getUnderlyingObjects` may
still alias to the noalias parameter because `getUnderlyingObjects`
may not check deep enough to get the underlying object because of
`MaxLookup`. The real underlying object for the unidentified object
 may still be the noalias parameter.

Originally Patched By: tingwang

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D127202
This commit is contained in:
Chen Zheng 2022-06-24 08:04:06 -04:00
parent b6b65403b3
commit 39fe49aa57
2 changed files with 18 additions and 7 deletions

View File

@ -1077,7 +1077,8 @@ static void AddAliasScopeMetadata(CallBase &CB, ValueToValueMapTy &VMap,
// Figure out if we're derived from anything that is not a noalias
// argument.
bool RequiresNoCaptureBefore = false, UsesAliasingPtr = false;
bool RequiresNoCaptureBefore = false, UsesAliasingPtr = false,
UsesUnknownObject = false;
for (const Value *V : ObjSet) {
// Is this value a constant that cannot be derived from any pointer
// value (we need to exclude constant expressions, for example, that
@ -1098,14 +1099,24 @@ static void AddAliasScopeMetadata(CallBase &CB, ValueToValueMapTy &VMap,
UsesAliasingPtr = true;
}
// If this is not some identified function-local object (which cannot
// directly alias a noalias argument), or some other argument (which,
// by definition, also cannot alias a noalias argument), then we could
// alias a noalias argument that has been captured).
if (!isa<Argument>(V) && !isIdentifiedFunctionLocal(V))
if (isEscapeSource(V)) {
// An escape source can only alias with a noalias argument if it has
// been captured beforehand.
RequiresNoCaptureBefore = true;
} else if (!isa<Argument>(V) && !isIdentifiedObject(V)) {
// If this is neither an escape source, nor some identified object
// (which cannot directly alias a noalias argument), nor some other
// argument (which, by definition, also cannot alias a noalias
// argument), conservatively do not make any assumptions.
UsesUnknownObject = true;
}
}
// Nothing we can do if the used underlying object cannot be reliably
// determined.
if (UsesUnknownObject)
continue;
// A function call can always get captured noalias pointers (via other
// parameters, globals, etc.).
if (IsFuncCall && !IsArgMemOnlyCall)

View File

@ -14,7 +14,7 @@ define i32 @caller(ptr %p) {
; CHECK-NEXT: [[P_6_I:%.*]] = getelementptr i8, ptr [[P_5_I]], i64 1
; CHECK-NEXT: [[P_7_I:%.*]] = getelementptr i8, ptr [[P_6_I]], i64 1
; CHECK-NEXT: [[P_8_ALIAS_I:%.*]] = getelementptr i8, ptr [[P_7_I]], i64 1
; CHECK-NEXT: store i32 42, ptr [[P_8_ALIAS_I]], align 4, !noalias !0
; CHECK-NEXT: store i32 42, ptr [[P_8_ALIAS_I]], align 4
; CHECK-NEXT: ret i32 [[V_I]]
;
%v = call i32 @callee(ptr %p)