From adfa2145e5f3e362ad00ed667da9867caf19f441 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 18 Feb 2025 15:09:43 +0100 Subject: [PATCH] [AA] Consider extractvalue and extractelement as escape sources CaptureTracking considers insertions into aggregates and vectors as captures. As such, extractions from aggregates and vectors are escape sources. A non-escaping identified local cannot alias with the result of an extractvalue/extractelement. Fixes https://github.com/llvm/llvm-project/issues/126670. --- llvm/lib/Analysis/AliasAnalysis.cpp | 6 +++++ .../BasicAA/escape-source-aggregate.ll | 27 +++++++++++++++++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Analysis/AliasAnalysis.cpp b/llvm/lib/Analysis/AliasAnalysis.cpp index 58297accc7f1f..aa72fb844ef32 100644 --- a/llvm/lib/Analysis/AliasAnalysis.cpp +++ b/llvm/lib/Analysis/AliasAnalysis.cpp @@ -859,6 +859,12 @@ bool llvm::isEscapeSource(const Value *V) { if (isa(V)) return true; + // Capture tracking considers insertions into aggregates and vectors as + // captures. As such, extractions from aggregates and vectors are escape + // sources. + if (isa(V)) + return true; + // Same for inttoptr constant expressions. if (auto *CE = dyn_cast(V)) if (CE->getOpcode() == Instruction::IntToPtr) diff --git a/llvm/test/Analysis/BasicAA/escape-source-aggregate.ll b/llvm/test/Analysis/BasicAA/escape-source-aggregate.ll index cef11b94f3873..872715f31011d 100644 --- a/llvm/test/Analysis/BasicAA/escape-source-aggregate.ll +++ b/llvm/test/Analysis/BasicAA/escape-source-aggregate.ll @@ -2,8 +2,9 @@ declare { ptr, i1 } @get_struct() declare <2 x ptr> @get_vec() +declare void @escape(ptr) -; CHECK: MayAlias: i32* %a, i32* %extract +; CHECK: NoAlias: i32* %a, i32* %extract define i32 @test_extractvalue() { %a = alloca i32 %call = call { ptr, i1 } @get_struct() @@ -13,7 +14,7 @@ define i32 @test_extractvalue() { ret i32 %v } -; CHECK: MayAlias: i32* %a, i32* %extract +; CHECK: NoAlias: i32* %a, i32* %extract define i32 @test_extractelement() { %a = alloca i32 %call = call <2 x ptr> @get_vec() @@ -22,3 +23,25 @@ define i32 @test_extractelement() { %v = load i32, ptr %a ret i32 %v } + +; CHECK: MayAlias: i32* %a, i32* %extract +define i32 @test_extractvalue_escape() { + %a = alloca i32 + call void @escape(ptr %a) + %call = call { ptr, i1 } @get_struct() + %extract = extractvalue { ptr, i1 } %call, 0 + store i32 0, ptr %extract + %v = load i32, ptr %a + ret i32 %v +} + +; CHECK: MayAlias: i32* %a, i32* %extract +define i32 @test_extractelement_escape() { + %a = alloca i32 + call void @escape(ptr %a) + %call = call <2 x ptr> @get_vec() + %extract = extractelement <2 x ptr> %call, i32 0 + store i32 0, ptr %extract + %v = load i32, ptr %a + ret i32 %v +}