diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -4533,6 +4533,12 @@ if (OffsetZero && !GEP->hasAllZeroIndices()) return nullptr; AddWork(GEP->getPointerOperand()); + } else if (CallBase *CB = dyn_cast(V)) { + Value *Returned = CB->getReturnedArgOperand(); + if (Returned) + AddWork(Returned); + else + return nullptr; } else { return nullptr; } diff --git a/llvm/test/Instrumentation/HWAddressSanitizer/stack-safety-analysis.ll b/llvm/test/Instrumentation/HWAddressSanitizer/stack-safety-analysis.ll --- a/llvm/test/Instrumentation/HWAddressSanitizer/stack-safety-analysis.ll +++ b/llvm/test/Instrumentation/HWAddressSanitizer/stack-safety-analysis.ll @@ -164,8 +164,7 @@ ; SAFETY: call {{.*}}__hwasan_generate_tag ; SAFETY-NOT: call {{.*}}__hwasan_store ; NOSTACK-NOT: call {{.*}}__hwasan_generate_tag - ; TODO: Do not emit this store. - ; NOSTACK: call {{.*}}__hwasan_store + ; NOSTACK-NOT: call {{.*}}__hwasan_store %buf.sroa.0 = alloca i8, align 4 call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull %buf.sroa.0) %ptr = call i8* @retptr(i8* %buf.sroa.0) diff --git a/llvm/unittests/Analysis/ValueTrackingTest.cpp b/llvm/unittests/Analysis/ValueTrackingTest.cpp --- a/llvm/unittests/Analysis/ValueTrackingTest.cpp +++ b/llvm/unittests/Analysis/ValueTrackingTest.cpp @@ -2256,6 +2256,22 @@ ret void })", false, false}, + {R"( + declare i32* @retptr(i32* returned) + define void @test(i1 %cond) { + %a = alloca i32 + %r = call i32* @retptr(i32* %a) + ret void + })", + true, true}, + {R"( + declare i32* @fun(i32*) + define void @test(i1 %cond) { + %a = alloca i32 + %r = call i32* @fun(i32* %a) + ret void + })", + false, false}, }; TEST_P(FindAllocaForValueTest, findAllocaForValue) {