Add, and infer, a nofree function attribute

This patch adds a function attribute, nofree, to indicate that a function does
not, directly or indirectly, call a memory-deallocation function (e.g., free,
C++'s operator delete).

Reviewers: jdoerfert

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

llvm-svn: 365336
diff --git a/llvm/test/Transforms/FunctionAttrs/atomic.ll b/llvm/test/Transforms/FunctionAttrs/atomic.ll
index af87a28..35de0ce 100644
--- a/llvm/test/Transforms/FunctionAttrs/atomic.ll
+++ b/llvm/test/Transforms/FunctionAttrs/atomic.ll
@@ -21,4 +21,4 @@
 }
 
 ; CHECK: attributes #0 = { norecurse nounwind readnone ssp uwtable }
-; CHECK: attributes #1 = { norecurse nounwind ssp uwtable }
+; CHECK: attributes #1 = { nofree norecurse nounwind ssp uwtable }
diff --git a/llvm/test/Transforms/FunctionAttrs/nofree.ll b/llvm/test/Transforms/FunctionAttrs/nofree.ll
new file mode 100644
index 0000000..e72ff2f
--- /dev/null
+++ b/llvm/test/Transforms/FunctionAttrs/nofree.ll
@@ -0,0 +1,113 @@
+; RUN: opt < %s -functionattrs -S | FileCheck %s
+; RUN: opt < %s -passes=function-attrs -S | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; CHECK: define void @_Z4foo1Pi(i32* nocapture readnone %a) local_unnamed_addr #0 {
+define void @_Z4foo1Pi(i32* nocapture readnone %a) local_unnamed_addr #0 {
+entry:
+  tail call void @_Z3extv()
+  ret void
+}
+
+declare void @_Z3extv() local_unnamed_addr
+
+; CHECK: define void @_Z4foo2Pi(i32* nocapture %a) local_unnamed_addr #1 {
+define void @_Z4foo2Pi(i32* nocapture %a) local_unnamed_addr #1 {
+entry:
+  %0 = bitcast i32* %a to i8*
+  tail call void @free(i8* %0) #2
+  ret void
+}
+
+declare void @free(i8* nocapture) local_unnamed_addr #2
+
+; CHECK: define i32 @_Z4foo3Pi(i32* nocapture readonly %a) local_unnamed_addr #3 {
+define i32 @_Z4foo3Pi(i32* nocapture readonly %a) local_unnamed_addr #3 {
+entry:
+  %0 = load i32, i32* %a, align 4
+  ret i32 %0
+}
+
+; CHECK: define double @_Z4foo4Pd(double* nocapture readonly %a) local_unnamed_addr #1 {
+define double @_Z4foo4Pd(double* nocapture readonly %a) local_unnamed_addr #1 {
+entry:
+  %0 = load double, double* %a, align 8
+  %call = tail call double @cos(double %0) #2
+  ret double %call
+}
+
+declare double @cos(double) local_unnamed_addr #2
+
+; CHECK: define noalias i32* @_Z4foo5Pm(i64* nocapture readonly %a) local_unnamed_addr #1 {
+define noalias i32* @_Z4foo5Pm(i64* nocapture readonly %a) local_unnamed_addr #1 {
+entry:
+  %0 = load i64, i64* %a, align 8
+  %call = tail call noalias i8* @malloc(i64 %0) #2
+  %1 = bitcast i8* %call to i32*
+  ret i32* %1
+}
+
+declare noalias i8* @malloc(i64) local_unnamed_addr #2
+
+; CHECK: define noalias i64* @_Z4foo6Pm(i64* nocapture %a) local_unnamed_addr #1 {
+define noalias i64* @_Z4foo6Pm(i64* nocapture %a) local_unnamed_addr #1 {
+entry:
+  %0 = bitcast i64* %a to i8*
+  %1 = load i64, i64* %a, align 8
+  %call = tail call i8* @realloc(i8* %0, i64 %1) #2
+  %2 = bitcast i8* %call to i64*
+  ret i64* %2
+}
+
+declare noalias i8* @realloc(i8* nocapture, i64) local_unnamed_addr #2
+
+; CHECK: define void @_Z4foo7Pi(i32* %a) local_unnamed_addr #1 {
+define void @_Z4foo7Pi(i32* %a) local_unnamed_addr #1 {
+entry:
+  %isnull = icmp eq i32* %a, null
+  br i1 %isnull, label %delete.end, label %delete.notnull
+
+delete.notnull:                                   ; preds = %entry
+  %0 = bitcast i32* %a to i8*
+  tail call void @_ZdlPv(i8* %0) #5
+  br label %delete.end
+
+delete.end:                                       ; preds = %delete.notnull, %entry
+  ret void
+}
+
+declare void @_ZdlPv(i8*) local_unnamed_addr #4
+
+; CHECK: define void @_Z4foo8Pi(i32* %a) local_unnamed_addr #1 {
+define void @_Z4foo8Pi(i32* %a) local_unnamed_addr #1 {
+entry:
+  %isnull = icmp eq i32* %a, null
+  br i1 %isnull, label %delete.end, label %delete.notnull
+
+delete.notnull:                                   ; preds = %entry
+  %0 = bitcast i32* %a to i8*
+  tail call void @_ZdaPv(i8* %0) #5
+  br label %delete.end
+
+delete.end:                                       ; preds = %delete.notnull, %entry
+  ret void
+}
+
+declare void @_ZdaPv(i8*) local_unnamed_addr #4
+
+attributes #0 = { uwtable }
+attributes #1 = { nounwind uwtable }
+attributes #2 = { nounwind }
+attributes #3 = { norecurse nounwind readonly uwtable }
+attributes #4 = { nobuiltin nounwind }
+attributes #5 = { builtin nounwind }
+
+; CHECK: attributes #0 = { uwtable }
+; CHECK: attributes #1 = { nounwind uwtable }
+; CHECK: attributes #2 = { nounwind }
+; CHECK: attributes #3 = { norecurse nounwind readonly uwtable }
+; CHECK: attributes #4 = { nobuiltin nounwind }
+; CHECK: attributes #5 = { builtin nounwind }
+
diff --git a/llvm/test/Transforms/FunctionAttrs/operand-bundles-scc.ll b/llvm/test/Transforms/FunctionAttrs/operand-bundles-scc.ll
index 69808a8..4ad195e 100644
--- a/llvm/test/Transforms/FunctionAttrs/operand-bundles-scc.ll
+++ b/llvm/test/Transforms/FunctionAttrs/operand-bundles-scc.ll
@@ -14,4 +14,4 @@
 }
 
 
-; CHECK: attributes #0 = { nounwind }
+; CHECK: attributes #0 = { nofree nounwind }
diff --git a/llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll b/llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll
index 0828db3..be190b7 100644
--- a/llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll
+++ b/llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll
@@ -30,7 +30,7 @@
 ;
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 
-; CHECK: Function Attrs: nounwind
+; CHECK: Function Attrs: nofree nounwind
 ; CHECK-NEXT: define i32* @external_ret2_nrw(i32* %n0, i32* %r0, i32* %w0)
 define i32* @external_ret2_nrw(i32* %n0, i32* %r0, i32* %w0) {
 entry:
@@ -41,7 +41,7 @@
   ret i32* %call3
 }
 
-; CHECK: Function Attrs: nounwind
+; CHECK: Function Attrs: nofree nounwind
 ; CHECK-NEXT: define internal i32* @internal_ret0_nw(i32* %n0, i32* %w0)
 define internal i32* @internal_ret0_nw(i32* %n0, i32* %w0) {
 entry:
@@ -70,7 +70,7 @@
   ret i32* %retval.0
 }
 
-; CHECK: Function Attrs: nounwind
+; CHECK: Function Attrs: nofree nounwind
 ; CHECK-NEXT: define internal i32* @internal_ret1_rrw(i32* %r0, i32* %r1, i32* %w0)
 define internal i32* @internal_ret1_rrw(i32* %r0, i32* %r1, i32* %w0) {
 entry:
@@ -102,7 +102,7 @@
   ret i32* %retval.0
 }
 
-; CHECK: Function Attrs: norecurse nounwind
+; CHECK: Function Attrs: nofree norecurse nounwind
 ; CHECK-NEXT: define i32* @external_sink_ret2_nrw(i32* readnone %n0, i32* nocapture readonly %r0, i32* returned %w0)
 define i32* @external_sink_ret2_nrw(i32* %n0, i32* %r0, i32* %w0) {
 entry:
@@ -121,7 +121,7 @@
   ret i32* %w0
 }
 
-; CHECK: Function Attrs: nounwind
+; CHECK: Function Attrs: nofree nounwind
 ; CHECK-NEXT: define internal i32* @internal_ret1_rw(i32* %r0, i32* %w0)
 define internal i32* @internal_ret1_rw(i32* %r0, i32* %w0) {
 entry:
@@ -147,7 +147,7 @@
   ret i32* %retval.0
 }
 
-; CHECK: Function Attrs: nounwind
+; CHECK: Function Attrs: nofree nounwind
 ; CHECK-NEXT: define i32* @external_source_ret2_nrw(i32* %n0, i32* %r0, i32* %w0)
 define i32* @external_source_ret2_nrw(i32* %n0, i32* %r0, i32* %w0) {
 entry:
@@ -160,6 +160,6 @@
 ; for a subset relation.
 ;
 ; CHECK-NOT: attributes #
-; CHECK: attributes #{{.*}} = { nounwind }
-; CHECK: attributes #{{.*}} = { norecurse nounwind }
+; CHECK: attributes #{{.*}} = { nofree nounwind }
+; CHECK: attributes #{{.*}} = { nofree norecurse nounwind }
 ; CHECK-NOT: attributes #