Skip to content

Conversation

@davemgreen
Copy link
Collaborator

@davemgreen davemgreen commented Apr 7, 2025

This is a much smaller, technically orthogonal patch similar to #134505. It
states that a extractvalue(Argument) can be treated like an Argument for alias
analysis, where the extractelement acts like a phi / copy. No inttoptr here. I'm
hoping for this operations this is perfectly sensible, but it is quite a
complex area.

@llvmbot llvmbot added the llvm:analysis Includes value tracking, cost tables and constant folding label Apr 7, 2025
@llvmbot
Copy link
Member

llvmbot commented Apr 7, 2025

@llvm/pr-subscribers-llvm-analysis

Author: David Green (davemgreen)

Changes

This is a much smaller, technically orthogonal patch similar to #134505. It
states that a extractvalue(Argument) can be treated like an Argument for alias
analysis, where the extractelement acts like a phi / copy. No inttoptr here. I'm
hoping for this operations this is perfectly sensible, but it is quite a
complex area.


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

2 Files Affected:

  • (modified) llvm/lib/Analysis/BasicAliasAnalysis.cpp (+12-2)
  • (modified) llvm/test/Analysis/BasicAA/noalias-inttoptr.ll (+48)
diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
index 4d1a95a0c4b43..12d9c8706a8e1 100644
--- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
@@ -1533,6 +1533,16 @@ AliasResult BasicAAResult::aliasPHI(const PHINode *PN, LocationSize PNSize,
   return Alias;
 }
 
+// Return true for an Argument or extractvalue(Argument). These are all known
+// to not alias with FunctionLocal objects and can come up from coerced function
+// arguments.
+static bool isArgumentOrArgumentLike(const Value *V) {
+  if (isa<Argument>(V))
+    return true;
+  auto *E = dyn_cast<ExtractValueInst>(V);
+  return E && isa<Argument>(E->getOperand(0));
+}
+
 /// Provides a bunch of ad-hoc rules to disambiguate in common cases, such as
 /// array references.
 AliasResult BasicAAResult::aliasCheck(const Value *V1, LocationSize V1Size,
@@ -1585,8 +1595,8 @@ AliasResult BasicAAResult::aliasCheck(const Value *V1, LocationSize V1Size,
 
     // Function arguments can't alias with things that are known to be
     // unambigously identified at the function level.
-    if ((isa<Argument>(O1) && isIdentifiedFunctionLocal(O2)) ||
-        (isa<Argument>(O2) && isIdentifiedFunctionLocal(O1)))
+    if ((isArgumentOrArgumentLike(O1) && isIdentifiedFunctionLocal(O2)) ||
+        (isArgumentOrArgumentLike(O2) && isIdentifiedFunctionLocal(O1)))
       return AliasResult::NoAlias;
 
     // If one pointer is the result of a call/invoke or load and the other is a
diff --git a/llvm/test/Analysis/BasicAA/noalias-inttoptr.ll b/llvm/test/Analysis/BasicAA/noalias-inttoptr.ll
index 24bbcc55b3202..cdfdb091f668f 100644
--- a/llvm/test/Analysis/BasicAA/noalias-inttoptr.ll
+++ b/llvm/test/Analysis/BasicAA/noalias-inttoptr.ll
@@ -58,3 +58,51 @@ define void @test5(i64 %Q_as_int) {
   store i8 1, ptr %Q
   ret void
 }
+
+; Verify that extractvalue of a coerced ptr argument array are NoAlias a function local object
+define void @test_extractvalue([2 x ptr] %Q.coerce) {
+  ; CHECK-LABEL: Function: test_extractvalue:
+  ; CHECK: NoAlias:    i8* %P, i8* %Q
+  %P = alloca i8
+  %Q = extractvalue [2 x ptr] %Q.coerce, 1
+  store i8 0, ptr %P
+  store i8 1, ptr %Q
+  ret void
+}
+
+; Same as test_extractvalue with an escape of %P
+define void @test_extractvalue_escape([2 x ptr] %Q.coerce) {
+  ; CHECK-LABEL: Function: test_extractvalue_escape:
+  ; CHECK: NoAlias:    i8* %P, i8* %Q
+  %P = alloca i8
+  call void @escape(ptr %P)
+  %Q = extractvalue [2 x ptr] %Q.coerce, 1
+  store i8 0, ptr %P
+  store i8 1, ptr %Q
+  ret void
+}
+
+; Verify that extractvalue of a coerced ptr argument array are NoAlias a function local object
+define void @test_extractvalue_int([2 x i64] %Q.coerce) {
+  ; CHECK-LABEL: Function: test_extractvalue_int:
+  ; CHECK: NoAlias:    i8* %P, i8* %Q
+  %P = alloca i8
+  %Q_as_int = extractvalue [2 x i64] %Q.coerce, 1
+  %Q = inttoptr i64 %Q_as_int to ptr
+  store i8 0, ptr %P
+  store i8 1, ptr %Q
+  ret void
+}
+
+; Same as test_extractvalue_int with an escape of %P
+define void @test_extractvalue_int_escape([2 x i64] %Q.coerce) {
+  ; CHECK-LABEL: Function: test_extractvalue_int_escape:
+  ; CHECK: MayAlias:    i8* %P, i8* %Q
+  %P = alloca i8
+  call void @escape(ptr %P)
+  %Q_as_int = extractvalue [2 x i64] %Q.coerce, 1
+  %Q = inttoptr i64 %Q_as_int to ptr
+  store i8 0, ptr %P
+  store i8 1, ptr %Q
+  ret void
+}
\ No newline at end of file

Copy link
Contributor

@nikic nikic left a comment

Choose a reason for hiding this comment

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

Yes, this case is fine. LGTM

Copy link
Member

@nunoplopes nunoplopes left a comment

Choose a reason for hiding this comment

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

LGTM too.

…n to function-local objects.

This is a much smaller, technically orthoganal patch similar to llvm#134505. It
states that a extractvalue(Argument) can be treated like an Argument for alias
analysis, where the extractelement acts like a phi / copy. No inttotr here. I'm
hoping for this operations this is perfectly sensible, but it is quite a
complex area.
@davemgreen
Copy link
Collaborator Author

Thanks.

@davemgreen davemgreen merged commit c23e1cb into llvm:main Apr 8, 2025
6 of 10 checks passed
@davemgreen davemgreen deleted the gh-aa-extractarg branch April 8, 2025 09:06
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.

4 participants