diff --git a/llvm/test/Analysis/BasicAA/constant-memory.ll b/llvm/test/Analysis/BasicAA/constant-memory.ll --- a/llvm/test/Analysis/BasicAA/constant-memory.ll +++ b/llvm/test/Analysis/BasicAA/constant-memory.ll @@ -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 @@ 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 +} diff --git a/llvm/test/Transforms/InstCombine/memcpy-from-global.ll b/llvm/test/Transforms/InstCombine/memcpy-from-global.ll --- a/llvm/test/Transforms/InstCombine/memcpy-from-global.ll +++ b/llvm/test/Transforms/InstCombine/memcpy-from-global.ll @@ -338,4 +338,32 @@ 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 } diff --git a/llvm/test/Transforms/InstCombine/store.ll b/llvm/test/Transforms/InstCombine/store.ll --- a/llvm/test/Transforms/InstCombine/store.ll +++ b/llvm/test/Transforms/InstCombine/store.ll @@ -336,6 +336,16 @@ 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"}