Skip to content

Conversation

nikic
Copy link
Contributor

@nikic nikic commented Feb 18, 2025

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 #126670.

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 llvm#126670.
@llvmbot llvmbot added the llvm:analysis Includes value tracking, cost tables and constant folding label Feb 18, 2025
@llvmbot
Copy link
Member

llvmbot commented Feb 18, 2025

@llvm/pr-subscribers-llvm-analysis

Author: Nikita Popov (nikic)

Changes

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 #126670.


Full diff: https://github.com/llvm/llvm-project/pull/127640.diff

2 Files Affected:

  • (modified) llvm/lib/Analysis/AliasAnalysis.cpp (+6)
  • (modified) llvm/test/Analysis/BasicAA/escape-source-aggregate.ll (+25-2)
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<IntToPtrInst>(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<ExtractValueInst, ExtractElementInst>(V))
+    return true;
+
   // Same for inttoptr constant expressions.
   if (auto *CE = dyn_cast<ConstantExpr>(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
+}

Copy link
Contributor

@fhahn fhahn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM ,thanks

@nikic nikic merged commit 850062c into llvm:main Feb 19, 2025
10 checks passed
@nikic nikic deleted the escape-source-agg branch February 19, 2025 08:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
llvm:analysis Includes value tracking, cost tables and constant folding
Projects
None yet
Development

Successfully merging this pull request may close these issues.

try block prevents LLVM from identifying a throwing path is unreachable
3 participants