Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[AA][ScopedNoAliasAA] Returns ModRef when an alias exists #70159

Closed
wants to merge 2 commits into from

Conversation

DianQK
Copy link
Member

@DianQK DianQK commented Oct 25, 2023

Fixes #70158.

@llvmbot
Copy link
Collaborator

llvmbot commented Oct 25, 2023

@llvm/pr-subscribers-llvm-analysis

Author: DianQK (DianQK)

Changes

Fixes #70158.


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

2 Files Affected:

  • (modified) llvm/lib/Analysis/ScopedNoAliasAA.cpp (+4-8)
  • (added) llvm/test/Analysis/ScopedNoAliasAA/mod-ref.ll (+32)
diff --git a/llvm/lib/Analysis/ScopedNoAliasAA.cpp b/llvm/lib/Analysis/ScopedNoAliasAA.cpp
index 3815bdf49d59cea..619424873d54286 100644
--- a/llvm/lib/Analysis/ScopedNoAliasAA.cpp
+++ b/llvm/lib/Analysis/ScopedNoAliasAA.cpp
@@ -79,10 +79,8 @@ ModRefInfo ScopedNoAliasAAResult::getModRefInfo(const CallBase *Call,
     return ModRefInfo::ModRef;
 
   if (!mayAliasInScopes(Loc.AATags.Scope,
-                        Call->getMetadata(LLVMContext::MD_noalias)))
-    return ModRefInfo::NoModRef;
-
-  if (!mayAliasInScopes(Call->getMetadata(LLVMContext::MD_alias_scope),
+                        Call->getMetadata(LLVMContext::MD_noalias)) &&
+      !mayAliasInScopes(Call->getMetadata(LLVMContext::MD_alias_scope),
                         Loc.AATags.NoAlias))
     return ModRefInfo::NoModRef;
 
@@ -96,10 +94,8 @@ ModRefInfo ScopedNoAliasAAResult::getModRefInfo(const CallBase *Call1,
     return ModRefInfo::ModRef;
 
   if (!mayAliasInScopes(Call1->getMetadata(LLVMContext::MD_alias_scope),
-                        Call2->getMetadata(LLVMContext::MD_noalias)))
-    return ModRefInfo::NoModRef;
-
-  if (!mayAliasInScopes(Call2->getMetadata(LLVMContext::MD_alias_scope),
+                        Call2->getMetadata(LLVMContext::MD_noalias)) &&
+      !mayAliasInScopes(Call2->getMetadata(LLVMContext::MD_alias_scope),
                         Call1->getMetadata(LLVMContext::MD_noalias)))
     return ModRefInfo::NoModRef;
 
diff --git a/llvm/test/Analysis/ScopedNoAliasAA/mod-ref.ll b/llvm/test/Analysis/ScopedNoAliasAA/mod-ref.ll
new file mode 100644
index 000000000000000..d62f724c4539b42
--- /dev/null
+++ b/llvm/test/Analysis/ScopedNoAliasAA/mod-ref.ll
@@ -0,0 +1,32 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
+; RUN: opt -passes=gvn -S < %s | FileCheck %s
+
+declare void @use(i64)
+
+define i64 @foo(ptr noalias nocapture noundef align 8 dereferenceable(24) %p) {
+; CHECK-LABEL: define i64 @foo(
+; CHECK-SAME: ptr noalias nocapture noundef align 8 dereferenceable(24) [[P:%.*]]) {
+; CHECK-NEXT:    [[P1:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 16
+; CHECK-NEXT:    [[V1:%.*]] = load i64, ptr [[P1]], align 8
+; CHECK-NEXT:    call void @use(i64 [[V1]])
+; CHECK-NEXT:    [[P2:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8
+; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr noundef nonnull align 8 dereferenceable(16) [[P2]], i8 0, i64 16, i1 false), !alias.scope !0
+; CHECK-NEXT:    ret i64 0
+;
+  %p1 = getelementptr inbounds i8, ptr %p, i64 16
+  %v1 = load i64, ptr %p1, align 8
+  call void @use(i64 %v1)
+  %p2 = getelementptr inbounds i8, ptr %p, i64 8
+  call void @llvm.memset.p0.i64(ptr noundef nonnull align 8 dereferenceable(16) %p2, i8 0, i64 16, i1 false), !alias.scope !0
+  %v2 = load i64, ptr %p1, align 8, !noalias !0
+  ret i64 %v2
+}
+
+; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: write)
+declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg) #0
+
+attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: write) }
+
+!0 = !{!1}
+!1 = distinct !{!1, !2}
+!2 = distinct !{!2}

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.

It's sufficient to have !noalias on one instruction and !alias.scope on the other. You don't need both of them to have !noalias and !alias.scope.

See https://llvm.org/docs/LangRef.html#noalias-and-alias-scope-metadata for documentation and in particular:

When evaluating an aliasing query, if for some domain, the set of scopes with that domain in one instruction’s alias.scope list is a subset of (or equal to) the set of scopes for that domain in another instruction’s noalias list, then the two memory accesses are assumed not to alias.

@DianQK
Copy link
Member Author

DianQK commented Oct 27, 2023

It's sufficient to have !noalias on one instruction and !alias.scope on the other. You don't need both of them to have !noalias and !alias.scope.

See https://llvm.org/docs/LangRef.html#noalias-and-alias-scope-metadata for documentation and in particular:

When evaluating an aliasing query, if for some domain, the set of scopes with that domain in one instruction’s alias.scope list is a subset of (or equal to) the set of scopes for that domain in another instruction’s noalias list, then the two memory accesses are assumed not to alias.

Thanks, I get it. I'll keep looking for what the problem is.

@DianQK DianQK closed this Oct 27, 2023
@DianQK DianQK deleted the scoped-mod-ref branch October 27, 2023 00:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[ScopedNoAliasAA] Should ScopedNoAliasAA be more conservative in getting ModRef?
3 participants