1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes 2; RUN: opt < %s -passes=function-attrs -S | FileCheck %s 3 4target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 5target triple = "x86_64-unknown-linux-gnu" 6 7define void @_Z4foo1Pi(ptr nocapture readnone %a) local_unnamed_addr #0 { 8; CHECK: Function Attrs: uwtable 9; CHECK-LABEL: @_Z4foo1Pi( 10; CHECK-NEXT: entry: 11; CHECK-NEXT: tail call void @_Z3extv() 12; CHECK-NEXT: ret void 13; 14entry: 15 tail call void @_Z3extv() 16 ret void 17} 18 19declare void @_Z3extv() local_unnamed_addr 20 21define void @_Z4foo2Pi(ptr nocapture %a) local_unnamed_addr #1 { 22; CHECK: Function Attrs: nounwind uwtable 23; CHECK-LABEL: @_Z4foo2Pi( 24; CHECK-NEXT: entry: 25; CHECK-NEXT: tail call void @free(ptr [[A:%.*]]) #[[ATTR2:[0-9]+]] 26; CHECK-NEXT: ret void 27; 28entry: 29 tail call void @free(ptr %a) #2 30 ret void 31} 32 33declare void @free(ptr nocapture) local_unnamed_addr #2 34 35define i32 @_Z4foo3Pi(ptr nocapture readonly %a) local_unnamed_addr #3 { 36; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) uwtable 37; CHECK-LABEL: @_Z4foo3Pi( 38; CHECK-NEXT: entry: 39; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A:%.*]], align 4 40; CHECK-NEXT: ret i32 [[TMP0]] 41; 42entry: 43 %0 = load i32, ptr %a, align 4 44 ret i32 %0 45} 46 47define double @_Z4foo4Pd(ptr nocapture readonly %a) local_unnamed_addr #1 { 48; CHECK: Function Attrs: nounwind uwtable 49; CHECK-LABEL: @_Z4foo4Pd( 50; CHECK-NEXT: entry: 51; CHECK-NEXT: [[TMP0:%.*]] = load double, ptr [[A:%.*]], align 8 52; CHECK-NEXT: [[CALL:%.*]] = tail call double @cos(double [[TMP0]]) #[[ATTR2]] 53; CHECK-NEXT: ret double [[CALL]] 54; 55entry: 56 %0 = load double, ptr %a, align 8 57 %call = tail call double @cos(double %0) #2 58 ret double %call 59} 60 61declare double @cos(double) local_unnamed_addr #2 62 63define noalias ptr @_Z4foo5Pm(ptr nocapture readonly %a) local_unnamed_addr #1 { 64; CHECK: Function Attrs: nounwind uwtable 65; CHECK-LABEL: @_Z4foo5Pm( 66; CHECK-NEXT: entry: 67; CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr [[A:%.*]], align 8 68; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @malloc(i64 [[TMP0]]) #[[ATTR2]] 69; CHECK-NEXT: ret ptr [[CALL]] 70; 71entry: 72 %0 = load i64, ptr %a, align 8 73 %call = tail call noalias ptr @malloc(i64 %0) #2 74 ret ptr %call 75} 76 77declare noalias ptr @malloc(i64) local_unnamed_addr #2 78 79define noalias ptr @_Z4foo6Pm(ptr nocapture %a) local_unnamed_addr #1 { 80; CHECK: Function Attrs: nounwind uwtable 81; CHECK-LABEL: @_Z4foo6Pm( 82; CHECK-NEXT: entry: 83; CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr [[A:%.*]], align 8 84; CHECK-NEXT: [[CALL:%.*]] = tail call ptr @realloc(ptr [[A]], i64 [[TMP0]]) #[[ATTR2]] 85; CHECK-NEXT: ret ptr [[CALL]] 86; 87entry: 88 %0 = load i64, ptr %a, align 8 89 %call = tail call ptr @realloc(ptr %a, i64 %0) #2 90 ret ptr %call 91} 92 93declare noalias ptr @realloc(ptr nocapture, i64) local_unnamed_addr #2 94 95define void @_Z4foo7Pi(ptr %a) local_unnamed_addr #1 { 96; CHECK: Function Attrs: nounwind uwtable 97; CHECK-LABEL: @_Z4foo7Pi( 98; CHECK-NEXT: entry: 99; CHECK-NEXT: [[ISNULL:%.*]] = icmp eq ptr [[A:%.*]], null 100; CHECK-NEXT: br i1 [[ISNULL]], label [[DELETE_END:%.*]], label [[DELETE_NOTNULL:%.*]] 101; CHECK: delete.notnull: 102; CHECK-NEXT: tail call void @_ZdlPv(ptr [[A]]) #[[ATTR6:[0-9]+]] 103; CHECK-NEXT: br label [[DELETE_END]] 104; CHECK: delete.end: 105; CHECK-NEXT: ret void 106; 107entry: 108 %isnull = icmp eq ptr %a, null 109 br i1 %isnull, label %delete.end, label %delete.notnull 110 111delete.notnull: ; preds = %entry 112 tail call void @_ZdlPv(ptr %a) #5 113 br label %delete.end 114 115delete.end: ; preds = %delete.notnull, %entry 116 ret void 117} 118 119declare void @_ZdlPv(ptr) local_unnamed_addr #4 120 121define void @_Z4foo8Pi(ptr %a) local_unnamed_addr #1 { 122; CHECK: Function Attrs: nounwind uwtable 123; CHECK-LABEL: @_Z4foo8Pi( 124; CHECK-NEXT: entry: 125; CHECK-NEXT: [[ISNULL:%.*]] = icmp eq ptr [[A:%.*]], null 126; CHECK-NEXT: br i1 [[ISNULL]], label [[DELETE_END:%.*]], label [[DELETE_NOTNULL:%.*]] 127; CHECK: delete.notnull: 128; CHECK-NEXT: tail call void @_ZdaPv(ptr [[A]]) #[[ATTR6]] 129; CHECK-NEXT: br label [[DELETE_END]] 130; CHECK: delete.end: 131; CHECK-NEXT: ret void 132; 133entry: 134 %isnull = icmp eq ptr %a, null 135 br i1 %isnull, label %delete.end, label %delete.notnull 136 137delete.notnull: ; preds = %entry 138 tail call void @_ZdaPv(ptr %a) #5 139 br label %delete.end 140 141delete.end: ; preds = %delete.notnull, %entry 142 ret void 143} 144 145declare void @may_free() 146 147define void @nofree_callsite_attr(ptr %a) { 148; CHECK: Function Attrs: nofree 149; CHECK-LABEL: @nofree_callsite_attr( 150; CHECK-NEXT: entry: 151; CHECK-NEXT: call void @may_free() #[[ATTR5:[0-9]+]] 152; CHECK-NEXT: ret void 153; 154entry: 155 call void @may_free() nofree 156 ret void 157} 158 159declare void @_ZdaPv(ptr) local_unnamed_addr #4 160 161attributes #0 = { uwtable } 162attributes #1 = { nounwind uwtable } 163attributes #2 = { nounwind } 164attributes #3 = { norecurse nounwind readonly uwtable } 165attributes #4 = { nobuiltin nounwind } 166attributes #5 = { builtin nounwind } 167