[IR] Mark memset.* intrinsics as IntrWriteMem.

llvm.memset intrinsics do only write memory, but are missing
IntrWriteMem, so they doesNotReadMemory() returns false for them.

The test change is due to the test checking the fn attribute ids at the
call sites, which got bumped up due to a new combination with writeonly
appearing in the test file.

Reviewers: jdoerfert, reames, efriedma, nlopes, lebedev.ri

Reviewed By: jdoerfert

Differential Revision: https://reviews.llvm.org/D72789
This commit is contained in:
Florian Hahn 2020-01-16 10:25:29 +00:00
parent 736a380212
commit 0b21d55262
5 changed files with 43 additions and 28 deletions

View File

@ -519,8 +519,8 @@ def int_memmove : Intrinsic<[],
def int_memset : Intrinsic<[],
[llvm_anyptr_ty, llvm_i8_ty, llvm_anyint_ty,
llvm_i1_ty],
[IntrArgMemOnly, IntrWillReturn, NoCapture<0>, WriteOnly<0>,
ImmArg<3>]>;
[IntrWriteMem, IntrArgMemOnly, IntrWillReturn, NoCapture<0>,
WriteOnly<0>, ImmArg<3>]>;
// FIXME: Add version of these floating point intrinsics which allow non-default
// rounding modes and FP exception handling.
@ -1221,7 +1221,8 @@ def int_memmove_element_unordered_atomic
// @llvm.memset.element.unordered.atomic.*(dest, value, length, elementsize)
def int_memset_element_unordered_atomic
: Intrinsic<[], [ llvm_anyptr_ty, llvm_i8_ty, llvm_anyint_ty, llvm_i32_ty ],
[ IntrArgMemOnly, IntrWillReturn, NoCapture<0>, WriteOnly<0>, ImmArg<3> ]>;
[ IntrWriteMem, IntrArgMemOnly, IntrWillReturn, NoCapture<0>, WriteOnly<0>,
ImmArg<3> ]>;
//===------------------------ Reduction Intrinsics ------------------------===//
//

View File

@ -1,4 +1,4 @@
; RUN: opt < %s -basicaa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
; RUN: opt < %s -basicaa -aa-eval -print-all-alias-modref-info -S 2>&1 | FileCheck %s
target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:64-v128:32:128-a0:0:32-n32"
target triple = "arm-apple-ios"
@ -364,28 +364,42 @@ entry:
call void @an_argmemonly_func(i8* %q) #9 [ "unknown"() ]
ret void
; CHECK: Just Ref: Ptr: i8* %p <-> call void @a_readonly_func(i8* %p) #7 [ "unknown"() ]
; CHECK: Just Ref: Ptr: i8* %q <-> call void @a_readonly_func(i8* %p) #7 [ "unknown"() ]
; CHECK: NoModRef: Ptr: i8* %p <-> call void @an_inaccessiblememonly_func() #8 [ "unknown"() ]
; CHECK: NoModRef: Ptr: i8* %q <-> call void @an_inaccessiblememonly_func() #8 [ "unknown"() ]
; CHECK: NoModRef: Ptr: i8* %p <-> call void @an_inaccessibleorargmemonly_func(i8* %q) #9 [ "unknown"() ]
; CHECK: Both ModRef (MustAlias): Ptr: i8* %q <-> call void @an_inaccessibleorargmemonly_func(i8* %q) #9 [ "unknown"() ]
; CHECK: NoModRef: Ptr: i8* %p <-> call void @an_argmemonly_func(i8* %q) #10 [ "unknown"() ]
; CHECK: Both ModRef (MustAlias): Ptr: i8* %q <-> call void @an_argmemonly_func(i8* %q) #10 [ "unknown"() ]
; CHECK: Just Ref: call void @a_readonly_func(i8* %p) #7 [ "unknown"() ] <-> call void @an_inaccessiblememonly_func() #8 [ "unknown"() ]
; CHECK: Just Ref: call void @a_readonly_func(i8* %p) #7 [ "unknown"() ] <-> call void @an_inaccessibleorargmemonly_func(i8* %q) #9 [ "unknown"() ]
; CHECK: Just Ref: call void @a_readonly_func(i8* %p) #7 [ "unknown"() ] <-> call void @an_argmemonly_func(i8* %q) #10 [ "unknown"() ]
; CHECK: Both ModRef: call void @an_inaccessiblememonly_func() #8 [ "unknown"() ] <-> call void @a_readonly_func(i8* %p) #7 [ "unknown"() ]
; CHECK: Both ModRef: call void @an_inaccessiblememonly_func() #8 [ "unknown"() ] <-> call void @an_inaccessibleorargmemonly_func(i8* %q) #9 [ "unknown"() ]
; CHECK: NoModRef: call void @an_inaccessiblememonly_func() #8 [ "unknown"() ] <-> call void @an_argmemonly_func(i8* %q) #10 [ "unknown"() ]
; CHECK: Both ModRef: call void @an_inaccessibleorargmemonly_func(i8* %q) #9 [ "unknown"() ] <-> call void @a_readonly_func(i8* %p) #7 [ "unknown"() ]
; CHECK: Both ModRef: call void @an_inaccessibleorargmemonly_func(i8* %q) #9 [ "unknown"() ] <-> call void @an_inaccessiblememonly_func() #8 [ "unknown"() ]
; CHECK: Both ModRef (MustAlias): call void @an_inaccessibleorargmemonly_func(i8* %q) #9 [ "unknown"() ] <-> call void @an_argmemonly_func(i8* %q) #10 [ "unknown"() ]
; CHECK: Both ModRef: call void @an_argmemonly_func(i8* %q) #10 [ "unknown"() ] <-> call void @a_readonly_func(i8* %p) #7 [ "unknown"() ]
; CHECK: NoModRef: call void @an_argmemonly_func(i8* %q) #10 [ "unknown"() ] <-> call void @an_inaccessiblememonly_func() #8 [ "unknown"() ]
; CHECK: Both ModRef (MustAlias): call void @an_argmemonly_func(i8* %q) #10 [ "unknown"() ] <-> call void @an_inaccessibleorargmemonly_func(i8* %q) #9 [ "unknown"() ]
; CHECK: Just Ref: Ptr: i8* %p <-> call void @a_readonly_func(i8* %p) #8 [ "unknown"() ]
; CHECK: Just Ref: Ptr: i8* %q <-> call void @a_readonly_func(i8* %p) #8 [ "unknown"() ]
; CHECK: NoModRef: Ptr: i8* %p <-> call void @an_inaccessiblememonly_func() #9 [ "unknown"() ]
; CHECK: NoModRef: Ptr: i8* %q <-> call void @an_inaccessiblememonly_func() #9 [ "unknown"() ]
; CHECK: NoModRef: Ptr: i8* %p <-> call void @an_inaccessibleorargmemonly_func(i8* %q) #10 [ "unknown"() ]
; CHECK: Both ModRef (MustAlias): Ptr: i8* %q <-> call void @an_inaccessibleorargmemonly_func(i8* %q) #10 [ "unknown"() ]
; CHECK: NoModRef: Ptr: i8* %p <-> call void @an_argmemonly_func(i8* %q) #11 [ "unknown"() ]
; CHECK: Both ModRef (MustAlias): Ptr: i8* %q <-> call void @an_argmemonly_func(i8* %q) #11 [ "unknown"() ]
; CHECK: Just Ref: call void @a_readonly_func(i8* %p) #8 [ "unknown"() ] <-> call void @an_inaccessiblememonly_func() #9 [ "unknown"() ]
; CHECK: Just Ref: call void @a_readonly_func(i8* %p) #8 [ "unknown"() ] <-> call void @an_inaccessibleorargmemonly_func(i8* %q) #10 [ "unknown"() ]
; CHECK: Just Ref: call void @a_readonly_func(i8* %p) #8 [ "unknown"() ] <-> call void @an_argmemonly_func(i8* %q) #11 [ "unknown"() ]
; CHECK: Both ModRef: call void @an_inaccessiblememonly_func() #9 [ "unknown"() ] <-> call void @a_readonly_func(i8* %p) #8 [ "unknown"() ]
; CHECK: Both ModRef: call void @an_inaccessiblememonly_func() #9 [ "unknown"() ] <-> call void @an_inaccessibleorargmemonly_func(i8* %q) #10 [ "unknown"() ]
; CHECK: NoModRef: call void @an_inaccessiblememonly_func() #9 [ "unknown"() ] <-> call void @an_argmemonly_func(i8* %q) #11 [ "unknown"() ]
; CHECK: Both ModRef: call void @an_inaccessibleorargmemonly_func(i8* %q) #10 [ "unknown"() ] <-> call void @a_readonly_func(i8* %p) #8 [ "unknown"() ]
; CHECK: Both ModRef: call void @an_inaccessibleorargmemonly_func(i8* %q) #10 [ "unknown"() ] <-> call void @an_inaccessiblememonly_func() #9 [ "unknown"() ]
; CHECK: Both ModRef (MustAlias): call void @an_inaccessibleorargmemonly_func(i8* %q) #10 [ "unknown"() ] <-> call void @an_argmemonly_func(i8* %q) #11 [ "unknown"() ]
; CHECK: Both ModRef: call void @an_argmemonly_func(i8* %q) #11 [ "unknown"() ] <-> call void @a_readonly_func(i8* %p) #8 [ "unknown"() ]
; CHECK: NoModRef: call void @an_argmemonly_func(i8* %q) #11 [ "unknown"() ] <-> call void @an_inaccessiblememonly_func() #9 [ "unknown"() ]
; CHECK: Both ModRef (MustAlias): call void @an_argmemonly_func(i8* %q) #11 [ "unknown"() ] <-> call void @an_inaccessibleorargmemonly_func(i8* %q) #10 [ "unknown"() ]
}
; CHECK: attributes #0 = { argmemonly nounwind willreturn writeonly }
; CHECK-NEXT: attributes #1 = { argmemonly nounwind willreturn }
; CHECK-NEXT: attributes #2 = { noinline nounwind readonly }
; CHECK-NEXT: attributes #3 = { noinline nounwind writeonly }
; CHECK-NEXT: attributes #4 = { nounwind ssp }
; CHECK-NEXT: attributes #5 = { inaccessiblememonly nounwind }
; CHECK-NEXT: attributes #6 = { inaccessiblemem_or_argmemonly nounwind }
; CHECK-NEXT: attributes #7 = { argmemonly nounwind }
; CHECK-NEXT: attributes #8 = { readonly }
; CHECK-NEXT: attributes #9 = { inaccessiblememonly }
; CHECK-NEXT: attributes #10 = { inaccessiblemem_or_argmemonly }
; CHECK-NEXT: attributes #11 = { argmemonly }
attributes #0 = { argmemonly nounwind }
attributes #1 = { noinline nounwind readonly }
attributes #2 = { noinline nounwind writeonly }

View File

@ -508,7 +508,7 @@ define noalias i8* @test23() nounwind uwtable ssp {
; CHECK-NEXT: store i8 97, i8* [[ARRAYIDX]], align 1
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [2 x i8], [2 x i8]* [[X]], i64 0, i64 1
; CHECK-NEXT: store i8 0, i8* [[ARRAYIDX1]], align 1
; CHECK-NEXT: [[CALL:%.*]] = call i8* @strdup(i8* [[ARRAYIDX]]) #2
; CHECK-NEXT: [[CALL:%.*]] = call i8* @strdup(i8* [[ARRAYIDX]]) #3
; CHECK-NEXT: ret i8* [[CALL]]
;
%x = alloca [2 x i8], align 1
@ -546,7 +546,7 @@ define i8* @test25(i8* %p) nounwind {
; CHECK-NEXT: [[P_4:%.*]] = getelementptr i8, i8* [[P:%.*]], i64 4
; CHECK-NEXT: [[TMP:%.*]] = load i8, i8* [[P_4]], align 1
; CHECK-NEXT: store i8 0, i8* [[P_4]], align 1
; CHECK-NEXT: [[Q:%.*]] = call i8* @strdup(i8* [[P]]) #5
; CHECK-NEXT: [[Q:%.*]] = call i8* @strdup(i8* [[P]]) #6
; CHECK-NEXT: store i8 [[TMP]], i8* [[P_4]], align 1
; CHECK-NEXT: ret i8* [[Q]]
;

View File

@ -292,7 +292,7 @@ define void @test10() {
define void @test11() {
; CHECK-LABEL: @test11(
; CHECK-NEXT: [[CALL:%.*]] = call dereferenceable(8) i8* @_Znwm(i64 8) #5
; CHECK-NEXT: [[CALL:%.*]] = call dereferenceable(8) i8* @_Znwm(i64 8) #6
; CHECK-NEXT: call void @_ZdlPv(i8* nonnull [[CALL]])
; CHECK-NEXT: ret void
;

View File

@ -821,5 +821,5 @@ entry:
; CHECK: attributes [[NUW]] = { nounwind }
; CHECK: attributes #1 = { argmemonly nounwind willreturn }
; CHECK: attributes #1 = { argmemonly nounwind willreturn writeonly }
; CHECK: attributes #2 = { nonlazybind }