From 0b21d552620dd593ddc93a93b5e779d5950f4a24 Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Thu, 16 Jan 2020 10:25:29 +0000 Subject: [PATCH] [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 --- llvm/include/llvm/IR/Intrinsics.td | 7 ++- llvm/test/Analysis/BasicAA/cs-cs.ll | 56 ++++++++++++------- .../Transforms/DeadStoreElimination/simple.ll | 4 +- .../InstCombine/malloc-free-delete.ll | 2 +- llvm/test/Transforms/ObjCARC/nested.ll | 2 +- 5 files changed, 43 insertions(+), 28 deletions(-) diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td index 865e4ccc9bc4..aa9f5adc4aba 100644 --- a/llvm/include/llvm/IR/Intrinsics.td +++ b/llvm/include/llvm/IR/Intrinsics.td @@ -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 ------------------------===// // diff --git a/llvm/test/Analysis/BasicAA/cs-cs.ll b/llvm/test/Analysis/BasicAA/cs-cs.ll index beb9eaa83002..28fc8febd608 100644 --- a/llvm/test/Analysis/BasicAA/cs-cs.ll +++ b/llvm/test/Analysis/BasicAA/cs-cs.ll @@ -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 } diff --git a/llvm/test/Transforms/DeadStoreElimination/simple.ll b/llvm/test/Transforms/DeadStoreElimination/simple.ll index 755f173570cb..5ccf875e49cd 100644 --- a/llvm/test/Transforms/DeadStoreElimination/simple.ll +++ b/llvm/test/Transforms/DeadStoreElimination/simple.ll @@ -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]] ; diff --git a/llvm/test/Transforms/InstCombine/malloc-free-delete.ll b/llvm/test/Transforms/InstCombine/malloc-free-delete.ll index a0828e1b6b17..7f6d7b4b2832 100644 --- a/llvm/test/Transforms/InstCombine/malloc-free-delete.ll +++ b/llvm/test/Transforms/InstCombine/malloc-free-delete.ll @@ -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 ; diff --git a/llvm/test/Transforms/ObjCARC/nested.ll b/llvm/test/Transforms/ObjCARC/nested.ll index 841104854fad..993e7d0475bc 100644 --- a/llvm/test/Transforms/ObjCARC/nested.ll +++ b/llvm/test/Transforms/ObjCARC/nested.ll @@ -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 }