[test][AliasAnalysis] Add some baseline tests in preparation for getModRefInfoMask().
authorPatrick Walton <pcwalton@fb.com>
Fri, 28 Oct 2022 19:42:01 +0000 (12:42 -0700)
committerPatrick Walton <pcwalton@fb.com>
Sat, 29 Oct 2022 22:08:54 +0000 (15:08 -0700)
This commit adds some tests in preparation for D136659, which allows alias
analysis to treat locally-invariant memory pointed to by readonly noalias
pointers the same as globally-invariant memory in some cases. The existing
behavior for these tests is marked as expected and will be changed when that
diff lands.

Differential Revision: https://reviews.llvm.org/D136993

llvm/test/Analysis/BasicAA/constant-memory.ll
llvm/test/Transforms/InstCombine/memcpy-from-global.ll
llvm/test/Transforms/InstCombine/store.ll

index 487d3c6..6ef875d 100644 (file)
@@ -4,6 +4,8 @@
 
 declare void @dummy()
 
+declare void @foo(ptr)
+
 ; FIXME: This could be NoModRef
 ; CHECK-LABEL: Function: basic
 ; CHECK: Just Ref: Ptr: i32* @c        <->  call void @dummy()
@@ -31,3 +33,65 @@ loop:
 exit:
   ret void
 }
+
+; Tests that readonly noalias doesn't imply !Mod yet.
+;
+; CHECK-LABEL: Function: readonly_noalias
+; CHECK: Both ModRef: Ptr: i32* %p <->  call void @foo(ptr %p)
+define void @readonly_noalias(ptr readonly noalias %p) {
+    call void @foo(ptr %p)
+    load i32, ptr %p
+    ret void
+}
+
+; Tests that readnone noalias doesn't imply !Mod yet.
+;
+; CHECK-LABEL: Function: readnone_noalias
+; CHECK: Both ModRef: Ptr: i32* %p <->  call void @foo(ptr %p)
+define void @readnone_noalias(ptr readnone noalias %p) {
+    call void @foo(ptr %p)
+    load i32, ptr %p
+    ret void
+}
+
+; Tests that writeonly noalias doesn't imply !Ref (since it's still possible
+; to read from the object through other pointers if the pointer wasn't
+; written).
+;
+; CHECK-LABEL: Function: writeonly_noalias
+; CHECK: Both ModRef: Ptr: i32* %p <->  call void @foo(ptr %p)
+define void @writeonly_noalias(ptr writeonly noalias %p) {
+    call void @foo(ptr %p)
+    load i32, ptr %p
+    ret void
+}
+
+; Tests that readonly doesn't imply !Mod without noalias.
+;
+; CHECK-LABEL: Function: just_readonly
+; CHECK: Both ModRef: Ptr: i32* %p <->  call void @foo(ptr %p)
+define void @just_readonly(ptr readonly %p) {
+    call void @foo(ptr %p)
+    load i32, ptr %p
+    ret void
+}
+
+; Tests that readnone doesn't imply !Mod without noalias.
+;
+; CHECK-LABEL: Function: just_readnone
+; CHECK: Both ModRef: Ptr: i32* %p <->  call void @foo(ptr %p)
+define void @just_readnone(ptr readnone %p) {
+    call void @foo(ptr %p)
+    load i32, ptr %p
+    ret void
+}
+
+; Tests that writeonly doesn't imply !Ref.
+;
+; CHECK-LABEL: Function: just_writeonly
+; CHECK: Both ModRef: Ptr: i32* %p <->  call void @foo(ptr %p)
+define void @just_writeonly(ptr writeonly %p) {
+    call void @foo(ptr %p)
+    load i32, ptr %p
+    ret void
+}
index 4e1c88f..4790139 100644 (file)
@@ -338,4 +338,32 @@ entry:
   ret float %r
 }
 
+; Tests that we can't eliminate allocas copied from readonly noalias pointers yet.
+define void @memcpy_from_readonly_noalias(ptr readonly noalias align 8 dereferenceable(124) %arg) {
+; CHECK-LABEL: @memcpy_from_readonly_noalias(
+; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca [[T:%.*]], align 8
+; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 8 dereferenceable(124) [[ALLOCA]], ptr noundef nonnull align 8 dereferenceable(124) [[ARG:%.*]], i64 124, i1 false)
+; CHECK-NEXT:    call void @bar(ptr nonnull [[ALLOCA]]) #[[ATTR3]]
+; CHECK-NEXT:    ret void
+;
+  %alloca = alloca %T, align 8
+  call void @llvm.memcpy.p0.p0.i64(ptr %alloca, ptr %arg, i64 124, i1 false)
+  call void @bar(ptr %alloca) readonly
+  ret void
+}
+
+; Tests that we don't eliminate allocas copied from readonly pointers without noalias.
+define void @memcpy_from_just_readonly(ptr readonly align 8 dereferenceable(124) %arg) {
+; CHECK-LABEL: @memcpy_from_just_readonly(
+; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca [[T:%.*]], align 8
+; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 8 dereferenceable(124) [[ALLOCA]], ptr noundef nonnull align 8 dereferenceable(124) [[ARG:%.*]], i64 124, i1 false)
+; CHECK-NEXT:    call void @bar(ptr nonnull [[ALLOCA]]) #[[ATTR3]]
+; CHECK-NEXT:    ret void
+;
+  %alloca = alloca %T, align 8
+  call void @llvm.memcpy.p0.p0.i64(ptr %alloca, ptr %arg, i64 124, i1 false)
+  call void @bar(ptr %alloca) readonly
+  ret void
+}
+
 attributes #0 = { null_pointer_is_valid }
index cceea25..7cbe91b 100644 (file)
@@ -336,6 +336,16 @@ define void @store_to_constant() {
   ret void
 }
 
+; We can't delete stores to readonly noalias pointers yet.
+define void @store_to_readonly_noalias(ptr readonly noalias %0) {
+; CHECK-LABEL: @store_to_readonly_noalias(
+; CHECK-NEXT:    store i32 3, ptr [[TMP0:%.*]], align 4
+; CHECK-NEXT:    ret void
+;
+  store i32 3, ptr %0, align 4
+  ret void
+}
+
 !0 = !{!4, !4, i64 0}
 !1 = !{!"omnipotent char", !2}
 !2 = !{!"Simple C/C++ TBAA"}