1; RUN: opt -passes=attributor --attributor-disable=false -attributor-annotate-decl-cs -S < %s | FileCheck %s 2 3declare noalias i8* @malloc(i64) 4 5declare void @nocapture_func_frees_pointer(i8* nocapture) 6 7declare void @func_throws(...) 8 9declare void @sync_func(i8* %p) 10 11declare void @sync_will_return(i8* %p) willreturn nounwind 12 13declare void @no_sync_func(i8* nocapture %p) nofree nosync willreturn 14 15declare void @nofree_func(i8* nocapture %p) nofree nosync willreturn 16 17declare void @foo(i32* %p) 18 19declare void @foo_nounw(i32* %p) nounwind nofree 20 21declare i32 @no_return_call() noreturn 22 23declare void @free(i8* nocapture) 24 25declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) nounwind 26 27; CHECK: @nofree_arg_only(i8* nocapture nofree %p1, i8* nocapture %p2) 28define void @nofree_arg_only(i8* %p1, i8* %p2) { 29 tail call void @free(i8* %p2) 30 tail call void @nofree_func(i8* %p1) 31 ret void 32} 33 34; TEST 1 - negative, pointer freed in another function. 35 36define void @test1() { 37 %1 = tail call noalias i8* @malloc(i64 4) 38 ; CHECK: @malloc(i64 4) 39 ; CHECK-NEXT: @nocapture_func_frees_pointer(i8* noalias nocapture %1) 40 tail call void @nocapture_func_frees_pointer(i8* %1) 41 tail call void (...) @func_throws() 42 tail call void @free(i8* %1) 43 ret void 44} 45 46; TEST 2 - negative, call to a sync function. 47 48define void @test2() { 49 %1 = tail call noalias i8* @malloc(i64 4) 50 ; CHECK: @malloc(i64 4) 51 ; CHECK-NEXT: @sync_func(i8* %1) 52 tail call void @sync_func(i8* %1) 53 tail call void @free(i8* %1) 54 ret void 55} 56 57; TEST 3 - 1 malloc, 1 free 58 59define void @test3() { 60 %1 = tail call noalias i8* @malloc(i64 4) 61 ; CHECK: %1 = alloca i8, i64 4 62 ; CHECK-NEXT: @no_sync_func(i8* noalias nocapture nofree %1) 63 tail call void @no_sync_func(i8* %1) 64 ; CHECK-NOT: @free(i8* %1) 65 tail call void @free(i8* %1) 66 ret void 67} 68 69define void @test3a(i8* %p) { 70 %1 = tail call noalias i8* @malloc(i64 4) 71 ; CHECK: %1 = alloca i8, i64 4 72 ; CHECK-NEXT: tail call void @nofree_arg_only 73 tail call void @nofree_arg_only(i8* %1, i8* %p) 74 ; CHECK-NOT: @free(i8* %1) 75 tail call void @free(i8* %1) 76 ret void 77} 78 79declare noalias i8* @calloc(i64, i64) 80 81define void @test0() { 82 %1 = tail call noalias i8* @calloc(i64 2, i64 4) 83 ; CHECK: %1 = alloca i8, i64 8 84 ; CHECK-NEXT: %calloc_bc = bitcast i8* %1 to i8* 85 ; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* %calloc_bc, i8 0, i64 8, i1 false) 86 ; CHECK-NEXT: @no_sync_func(i8* noalias nocapture nofree %1) 87 tail call void @no_sync_func(i8* %1) 88 ; CHECK-NOT: @free(i8* %1) 89 tail call void @free(i8* %1) 90 ret void 91} 92 93; TEST 4 94define void @test4() { 95 %1 = tail call noalias i8* @malloc(i64 4) 96 ; CHECK: %1 = alloca i8, i64 4 97 ; CHECK-NEXT: @nofree_func(i8* noalias nocapture nofree %1) 98 tail call void @nofree_func(i8* %1) 99 ret void 100} 101 102; TEST 5 - not all exit paths have a call to free, but all uses of malloc 103; are in nofree functions and are not captured 104 105define void @test5(i32, i8* %p) { 106 %2 = tail call noalias i8* @malloc(i64 4) 107 ; CHECK: %2 = alloca i8, i64 4 108 ; CHECK-NEXT: icmp eq i32 %0, 0 109 %3 = icmp eq i32 %0, 0 110 br i1 %3, label %5, label %4 111 1124: ; preds = %1 113 tail call void @nofree_func(i8* %2) 114 br label %6 115 1165: ; preds = %1 117 tail call void @nofree_arg_only(i8* %2, i8* %p) 118 tail call void @free(i8* %2) 119 ; CHECK-NOT: @free(i8* %2) 120 br label %6 121 1226: ; preds = %5, %4 123 ret void 124} 125 126; TEST 6 - all exit paths have a call to free 127 128define void @test6(i32) { 129 %2 = tail call noalias i8* @malloc(i64 4) 130 ; CHECK: %2 = alloca i8, i64 4 131 ; CHECK-NEXT: icmp eq i32 %0, 0 132 %3 = icmp eq i32 %0, 0 133 br i1 %3, label %5, label %4 134 1354: ; preds = %1 136 tail call void @nofree_func(i8* %2) 137 tail call void @free(i8* %2) 138 ; CHECK-NOT: @free(i8* %2) 139 br label %6 140 1415: ; preds = %1 142 tail call void @free(i8* %2) 143 ; CHECK-NOT: @free(i8* %2) 144 br label %6 145 1466: ; preds = %5, %4 147 ret void 148} 149 150; TEST 7 - free is dead. 151 152define void @test7() { 153 %1 = tail call noalias i8* @malloc(i64 4) 154 ; CHECK: alloca i8, i64 4 155 ; CHECK-NEXT: tail call i32 @no_return_call() 156 tail call i32 @no_return_call() 157 ; CHECK-NOT: @free(i8* %1) 158 tail call void @free(i8* %1) 159 ret void 160} 161 162; TEST 8 - Negative: bitcast pointer used in capture function 163 164define void @test8() { 165 %1 = tail call noalias i8* @malloc(i64 4) 166 ; CHECK: %1 = tail call noalias i8* @malloc(i64 4) 167 ; CHECK-NEXT: @no_sync_func(i8* nocapture nofree %1) 168 tail call void @no_sync_func(i8* %1) 169 %2 = bitcast i8* %1 to i32* 170 store i32 10, i32* %2 171 %3 = load i32, i32* %2 172 tail call void @foo(i32* %2) 173 ; CHECK: @free(i8* %1) 174 tail call void @free(i8* %1) 175 ret void 176} 177 178; TEST 9 - FIXME: malloc should be converted. 179define void @test9() { 180 %1 = tail call noalias i8* @malloc(i64 4) 181 ; CHECK: %1 = tail call noalias i8* @malloc(i64 4) 182 ; CHECK-NEXT: @no_sync_func(i8* nocapture nofree %1) 183 tail call void @no_sync_func(i8* %1) 184 %2 = bitcast i8* %1 to i32* 185 store i32 10, i32* %2 186 %3 = load i32, i32* %2 187 tail call void @foo_nounw(i32* %2) 188 ; CHECK: @free(i8* %1) 189 tail call void @free(i8* %1) 190 ret void 191} 192 193; TEST 10 - 1 malloc, 1 free 194 195define i32 @test10() { 196 %1 = tail call noalias i8* @malloc(i64 4) 197 ; CHECK: %1 = alloca i8, i64 4 198 ; CHECK-NEXT: @no_sync_func(i8* noalias nocapture nofree %1) 199 tail call void @no_sync_func(i8* %1) 200 %2 = bitcast i8* %1 to i32* 201 store i32 10, i32* %2 202 %3 = load i32, i32* %2 203 ; CHECK-NOT: @free(i8* %1) 204 tail call void @free(i8* %1) 205 ret i32 %3 206} 207 208define i32 @test_lifetime() { 209 %1 = tail call noalias i8* @malloc(i64 4) 210 ; CHECK: %1 = alloca i8, i64 4 211 ; CHECK-NEXT: @no_sync_func(i8* noalias nocapture nofree %1) 212 tail call void @no_sync_func(i8* %1) 213 call void @llvm.lifetime.start.p0i8(i64 4, i8* %1) 214 %2 = bitcast i8* %1 to i32* 215 store i32 10, i32* %2 216 %3 = load i32, i32* %2 217 ; CHECK-NOT: @free(i8* %1) 218 tail call void @free(i8* %1) 219 ret i32 %3 220} 221 222; TEST 11 223 224define void @test11() { 225 %1 = tail call noalias i8* @malloc(i64 4) 226 ; CHECK: test11 227 ; CHECK-NEXT: alloc 228 ; CHECK-NEXT: @sync_will_return(i8* %1) 229 tail call void @sync_will_return(i8* %1) 230 tail call void @free(i8* %1) 231 ret void 232} 233 234; TEST 12 235define i32 @irreducible_cfg(i32 %0) { 236 ; CHECK: alloca i8, i64 4 237 ; CHECK-NEXT: %3 = bitcast 238 %2 = call noalias i8* @malloc(i64 4) 239 %3 = bitcast i8* %2 to i32* 240 store i32 10, i32* %3, align 4 241 %4 = icmp eq i32 %0, 1 242 br i1 %4, label %5, label %7 243 2445: ; preds = %1 245 %6 = add nsw i32 %0, 5 246 br label %13 247 2487: ; preds = %1 249 br label %8 250 2518: ; preds = %13, %7 252 %.0 = phi i32 [ %14, %13 ], [ 1, %7 ] 253 %9 = load i32, i32* %3, align 4 254 %10 = add nsw i32 %9, -1 255 store i32 %10, i32* %3, align 4 256 %11 = icmp ne i32 %9, 0 257 br i1 %11, label %12, label %15 258 25912: ; preds = %8 260 br label %13 261 26213: ; preds = %12, %5 263 %.1 = phi i32 [ %6, %5 ], [ %.0, %12 ] 264 %14 = add nsw i32 %.1, 1 265 br label %8 266 26715: ; preds = %8 268 %16 = load i32, i32* %3, align 4 269 %17 = bitcast i32* %3 to i8* 270 call void @free(i8* %17) 271 %18 = load i32, i32* %3, align 4 272 ret i32 %18 273} 274 275 276define i32 @malloc_in_loop(i32 %0) { 277 %2 = alloca i32, align 4 278 %3 = alloca i32*, align 8 279 store i32 %0, i32* %2, align 4 280 br label %4 281 2824: ; preds = %8, %1 283 %5 = load i32, i32* %2, align 4 284 %6 = add nsw i32 %5, -1 285 store i32 %6, i32* %2, align 4 286 %7 = icmp sgt i32 %6, 0 287 br i1 %7, label %8, label %11 288 2898: ; preds = %4 290 %9 = call noalias i8* @malloc(i64 4) 291 ; CHECK: alloca i8, i64 4 292 %10 = bitcast i8* %9 to i32* 293 store i32 1, i32* %10, align 8 294 br label %4 295 29611: ; preds = %4 297 ret i32 5 298} 299 300; Malloc/Calloc too large 301define i32 @test13() { 302 %1 = tail call noalias i8* @malloc(i64 256) 303 ; CHECK: %1 = tail call noalias i8* @malloc(i64 256) 304 ; CHECK-NEXT: @no_sync_func(i8* noalias nofree %1) 305 tail call void @no_sync_func(i8* %1) 306 %2 = bitcast i8* %1 to i32* 307 store i32 10, i32* %2 308 %3 = load i32, i32* %2 309 tail call void @free(i8* %1) 310 ; CHECK: tail call void @free(i8* noalias %1) 311 ret i32 %3 312} 313 314define i32 @test_sle() { 315 %1 = tail call noalias i8* @malloc(i64 -1) 316 ; CHECK: %1 = tail call noalias i8* @malloc(i64 -1) 317 ; CHECK-NEXT: @no_sync_func(i8* noalias nofree %1) 318 tail call void @no_sync_func(i8* %1) 319 %2 = bitcast i8* %1 to i32* 320 store i32 10, i32* %2 321 %3 = load i32, i32* %2 322 tail call void @free(i8* %1) 323 ; CHECK: tail call void @free(i8* noalias %1) 324 ret i32 %3 325} 326 327define i32 @test_overflow() { 328 %1 = tail call noalias i8* @calloc(i64 65537, i64 65537) 329 ; CHECK: %1 = tail call noalias i8* @calloc(i64 65537, i64 65537) 330 ; CHECK-NEXT: @no_sync_func(i8* noalias nofree %1) 331 tail call void @no_sync_func(i8* %1) 332 %2 = bitcast i8* %1 to i32* 333 store i32 10, i32* %2 334 %3 = load i32, i32* %2 335 tail call void @free(i8* %1) 336 ; CHECK: tail call void @free(i8* noalias %1) 337 ret i32 %3 338} 339 340define void @test14() { 341 %1 = tail call noalias i8* @calloc(i64 64, i64 4) 342 ; CHECK: %1 = tail call noalias i8* @calloc(i64 64, i64 4) 343 ; CHECK-NEXT: @no_sync_func(i8* noalias nofree %1) 344 tail call void @no_sync_func(i8* %1) 345 tail call void @free(i8* %1) 346 ; CHECK: tail call void @free(i8* noalias %1) 347 ret void 348} 349 350define void @test15(i64 %S) { 351 ; CHECK: %1 = tail call noalias i8* @malloc(i64 %S) 352 %1 = tail call noalias i8* @malloc(i64 %S) 353 ; CHECK-NEXT: @no_sync_func(i8* noalias nofree %1) 354 tail call void @no_sync_func(i8* %1) 355 ; CHECK-NEXT: @free(i8* noalias %1) 356 tail call void @free(i8* %1) 357 ret void 358} 359 360define void @test16a(i8 %v, i8** %P) { 361 ; CHECK: %1 = alloca 362 %1 = tail call noalias i8* @malloc(i64 4) 363 ; CHECK-NEXT: store i8 %v, i8* %1 364 store i8 %v, i8* %1 365 ; CHECK-NEXT: @no_sync_func(i8* noalias nocapture nofree %1) 366 tail call void @no_sync_func(i8* %1) 367 ; CHECK-NOT: @free(i8* %1) 368 tail call void @free(i8* %1) 369 ret void 370} 371 372define void @test16b(i8 %v, i8** %P) { 373 ; CHECK: %1 = tail call noalias i8* @malloc(i64 4) 374 %1 = tail call noalias i8* @malloc(i64 4) 375 ; CHECK-NEXT: store i8* %1, i8** %P 376 store i8* %1, i8** %P 377 ; CHECK-NEXT: @no_sync_func(i8* nocapture nofree %1) 378 tail call void @no_sync_func(i8* %1) 379 ; CHECK-NEXT: @free(i8* %1) 380 tail call void @free(i8* %1) 381 ret void 382} 383 384define void @test16c(i8 %v, i8** %P) { 385 ; CHECK: %1 = alloca 386 %1 = tail call noalias i8* @malloc(i64 4) 387 ; CHECK-NEXT: store i8* %1, i8** %P 388 store i8* %1, i8** %P 389 ; CHECK-NEXT: @no_sync_func(i8* nocapture nofree %1) 390 tail call void @no_sync_func(i8* %1) nounwind 391 ; CHECK-NOT: @free 392 tail call void @free(i8* %1) 393 ret void 394} 395 396define void @test16d(i8 %v, i8** %P) { 397 ; CHECK: %1 = tail call noalias i8* @malloc(i64 4) 398 %1 = tail call noalias i8* @malloc(i64 4) 399 ; CHECK-NEXT: store i8* %1, i8** %P 400 store i8* %1, i8** %P 401 ret void 402} 403