diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp --- a/llvm/lib/Transforms/Utils/InlineFunction.cpp +++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp @@ -1068,15 +1068,41 @@ SmallPtrSet ObjSet; SmallVector Scopes, NoAliases; + bool ObjNotIdentified = false; SmallSetVector NAPtrArgs; for (const Value *V : PtrArgs) { SmallVector Objects; getUnderlyingObjects(V, Objects, /* LI = */ nullptr); + // It is not guaranteed that getUnderlyingObjects produce identifiable + // object. In this case, try a second walk starting from previous + // result. If the end result is different, it is possible that first + // walk exited early due to MaxLookup limit. + if (!all_of(Objects, isIdentifiedObject)) { + SmallVector MoreObjects; + DenseMap Objs; + for (const Value *V : Objects) + getUnderlyingObjects(V, MoreObjects, /* LI = */ nullptr); + + for (const Value *V : Objects) + Objs[V] = true; + + for (const Value *V : MoreObjects) + if (Objs.find(V) == Objs.end()) { + ObjNotIdentified = true; + break; + } + } + for (const Value *O : Objects) ObjSet.insert(O); } + // Be conservative since getUnderlyingObjects stopped the walk in the + // middle. + if (ObjNotIdentified) + continue; + // Figure out if we're derived from anything that is not a noalias // argument. bool CanDeriveViaCapture = false, UsesAliasingPtr = false; diff --git a/llvm/test/Transforms/Inline/inline-noalias.ll b/llvm/test/Transforms/Inline/inline-noalias.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/Inline/inline-noalias.ll @@ -0,0 +1,23 @@ +; RUN: opt < %s -passes=inline -S | FileCheck %s + +define i32 @caller(ptr %p) { + %v = call i32 @callee(ptr %p) + ret i32 %v +} + +define internal i32 @callee(ptr noalias %p) { + %p.8 = getelementptr i8, ptr %p, i64 8 +; CHECK: %v.i = load i32, ptr %p.8.i, align 4, !alias.scope ![[ALIAS0:[0-9]+]] + %v = load i32, ptr %p.8 + %p.1 = getelementptr i8, ptr %p, i64 1 + %p.2 = getelementptr i8, ptr %p.1, i64 1 + %p.3 = getelementptr i8, ptr %p.2, i64 1 + %p.4 = getelementptr i8, ptr %p.3, i64 1 + %p.5 = getelementptr i8, ptr %p.4, i64 1 + %p.6 = getelementptr i8, ptr %p.5, i64 1 + %p.7 = getelementptr i8, ptr %p.6, i64 1 + %p.8.alias = getelementptr i8, ptr %p.7, i64 1 +; CHECK-NOT: store i32 42, ptr %p.8.alias.i, align 4, !noalias ![[ALIAS0:[0-9]+]] + store i32 42, ptr %p.8.alias + ret i32 %v +}