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* @aligned_alloc(i64, i64) 80 81define void @test3b(i8* %p) { 82 %1 = tail call noalias i8* @aligned_alloc(i64 32, i64 128) 83 ; CHECK: %1 = alloca i8, i64 128, align 32 84 ; CHECK-NEXT: tail call void @nofree_arg_only 85 tail call void @nofree_arg_only(i8* %1, i8* %p) 86 ; CHECK-NOT: @free(i8* %1) 87 tail call void @free(i8* %1) 88 ret void 89} 90 91; leave alone non-constant alignments. 92define void @test3c(i64 %alignment) { 93 %1 = tail call noalias i8* @aligned_alloc(i64 %alignment, i64 128) 94 ; CHECK: tail call noalias i8* @aligned_alloc 95 tail call void @free(i8* %1) 96 ret void 97} 98 99declare noalias i8* @calloc(i64, i64) 100 101define void @test0() { 102 %1 = tail call noalias i8* @calloc(i64 2, i64 4) 103 ; CHECK: %1 = alloca i8, i64 8 104 ; CHECK-NEXT: %calloc_bc = bitcast i8* %1 to i8* 105 ; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* %calloc_bc, i8 0, i64 8, i1 false) 106 ; CHECK-NEXT: @no_sync_func(i8* noalias nocapture nofree %1) 107 tail call void @no_sync_func(i8* %1) 108 ; CHECK-NOT: @free(i8* %1) 109 tail call void @free(i8* %1) 110 ret void 111} 112 113; TEST 4 114define void @test4() { 115 %1 = tail call noalias i8* @malloc(i64 4) 116 ; CHECK: %1 = alloca i8, i64 4 117 ; CHECK-NEXT: @nofree_func(i8* noalias nocapture nofree %1) 118 tail call void @nofree_func(i8* %1) 119 ret void 120} 121 122; TEST 5 - not all exit paths have a call to free, but all uses of malloc 123; are in nofree functions and are not captured 124 125define void @test5(i32, i8* %p) { 126 %2 = tail call noalias i8* @malloc(i64 4) 127 ; CHECK: %2 = alloca i8, i64 4 128 ; CHECK-NEXT: icmp eq i32 %0, 0 129 %3 = icmp eq i32 %0, 0 130 br i1 %3, label %5, label %4 131 1324: ; preds = %1 133 tail call void @nofree_func(i8* %2) 134 br label %6 135 1365: ; preds = %1 137 tail call void @nofree_arg_only(i8* %2, i8* %p) 138 tail call void @free(i8* %2) 139 ; CHECK-NOT: @free(i8* %2) 140 br label %6 141 1426: ; preds = %5, %4 143 ret void 144} 145 146; TEST 6 - all exit paths have a call to free 147 148define void @test6(i32) { 149 %2 = tail call noalias i8* @malloc(i64 4) 150 ; CHECK: %2 = alloca i8, i64 4 151 ; CHECK-NEXT: icmp eq i32 %0, 0 152 %3 = icmp eq i32 %0, 0 153 br i1 %3, label %5, label %4 154 1554: ; preds = %1 156 tail call void @nofree_func(i8* %2) 157 tail call void @free(i8* %2) 158 ; CHECK-NOT: @free(i8* %2) 159 br label %6 160 1615: ; preds = %1 162 tail call void @free(i8* %2) 163 ; CHECK-NOT: @free(i8* %2) 164 br label %6 165 1666: ; preds = %5, %4 167 ret void 168} 169 170; TEST 7 - free is dead. 171 172define void @test7() { 173 %1 = tail call noalias i8* @malloc(i64 4) 174 ; CHECK: alloca i8, i64 4 175 ; CHECK-NEXT: tail call i32 @no_return_call() 176 tail call i32 @no_return_call() 177 ; CHECK-NOT: @free(i8* %1) 178 tail call void @free(i8* %1) 179 ret void 180} 181 182; TEST 8 - Negative: bitcast pointer used in capture function 183 184define void @test8() { 185 %1 = tail call noalias i8* @malloc(i64 4) 186 ; CHECK: %1 = tail call noalias i8* @malloc(i64 4) 187 ; CHECK-NEXT: @no_sync_func(i8* noalias nocapture nofree %1) 188 tail call void @no_sync_func(i8* %1) 189 %2 = bitcast i8* %1 to i32* 190 store i32 10, i32* %2 191 %3 = load i32, i32* %2 192 tail call void @foo(i32* %2) 193 ; CHECK: @free(i8* nonnull align 4 dereferenceable(4) %1) 194 tail call void @free(i8* %1) 195 ret void 196} 197 198; TEST 9 - FIXME: malloc should be converted. 199define void @test9() { 200 %1 = tail call noalias i8* @malloc(i64 4) 201 ; CHECK: %1 = tail call noalias i8* @malloc(i64 4) 202 ; CHECK-NEXT: @no_sync_func(i8* noalias nocapture nofree %1) 203 tail call void @no_sync_func(i8* %1) 204 %2 = bitcast i8* %1 to i32* 205 store i32 10, i32* %2 206 %3 = load i32, i32* %2 207 tail call void @foo_nounw(i32* %2) 208 ; CHECK: @free(i8* nonnull align 4 dereferenceable(4) %1) 209 tail call void @free(i8* %1) 210 ret void 211} 212 213; TEST 10 - 1 malloc, 1 free 214 215define i32 @test10() { 216 %1 = tail call noalias i8* @malloc(i64 4) 217 ; CHECK: %1 = alloca i8, i64 4 218 ; CHECK-NEXT: @no_sync_func(i8* noalias nocapture nofree %1) 219 tail call void @no_sync_func(i8* %1) 220 %2 = bitcast i8* %1 to i32* 221 store i32 10, i32* %2 222 %3 = load i32, i32* %2 223 ; CHECK-NOT: @free(i8* %1) 224 tail call void @free(i8* %1) 225 ret i32 %3 226} 227 228define i32 @test_lifetime() { 229 %1 = tail call noalias i8* @malloc(i64 4) 230 ; CHECK: %1 = alloca i8, i64 4 231 ; CHECK-NEXT: @no_sync_func(i8* noalias nocapture nofree %1) 232 tail call void @no_sync_func(i8* %1) 233 call void @llvm.lifetime.start.p0i8(i64 4, i8* %1) 234 %2 = bitcast i8* %1 to i32* 235 store i32 10, i32* %2 236 %3 = load i32, i32* %2 237 ; CHECK-NOT: @free(i8* %1) 238 tail call void @free(i8* %1) 239 ret i32 %3 240} 241 242; TEST 11 243 244define void @test11() { 245 %1 = tail call noalias i8* @malloc(i64 4) 246 ; CHECK: test11 247 ; CHECK-NEXT: alloc 248 ; CHECK-NEXT: @sync_will_return(i8* %1) 249 tail call void @sync_will_return(i8* %1) 250 tail call void @free(i8* %1) 251 ret void 252} 253 254; TEST 12 255define i32 @irreducible_cfg(i32 %0) { 256 ; CHECK: alloca i8, i64 4 257 ; CHECK-NEXT: %3 = bitcast 258 %2 = call noalias i8* @malloc(i64 4) 259 %3 = bitcast i8* %2 to i32* 260 store i32 10, i32* %3, align 4 261 %4 = icmp eq i32 %0, 1 262 br i1 %4, label %5, label %7 263 2645: ; preds = %1 265 %6 = add nsw i32 %0, 5 266 br label %13 267 2687: ; preds = %1 269 br label %8 270 2718: ; preds = %13, %7 272 %.0 = phi i32 [ %14, %13 ], [ 1, %7 ] 273 %9 = load i32, i32* %3, align 4 274 %10 = add nsw i32 %9, -1 275 store i32 %10, i32* %3, align 4 276 %11 = icmp ne i32 %9, 0 277 br i1 %11, label %12, label %15 278 27912: ; preds = %8 280 br label %13 281 28213: ; preds = %12, %5 283 %.1 = phi i32 [ %6, %5 ], [ %.0, %12 ] 284 %14 = add nsw i32 %.1, 1 285 br label %8 286 28715: ; preds = %8 288 %16 = load i32, i32* %3, align 4 289 %17 = bitcast i32* %3 to i8* 290 call void @free(i8* %17) 291 %18 = load i32, i32* %3, align 4 292 ret i32 %18 293} 294 295 296define i32 @malloc_in_loop(i32 %0) { 297 %2 = alloca i32, align 4 298 %3 = alloca i32*, align 8 299 store i32 %0, i32* %2, align 4 300 br label %4 301 3024: ; preds = %8, %1 303 %5 = load i32, i32* %2, align 4 304 %6 = add nsw i32 %5, -1 305 store i32 %6, i32* %2, align 4 306 %7 = icmp sgt i32 %6, 0 307 br i1 %7, label %8, label %11 308 3098: ; preds = %4 310 %9 = call noalias i8* @malloc(i64 4) 311 ; CHECK: alloca i8, i64 4 312 %10 = bitcast i8* %9 to i32* 313 store i32 1, i32* %10, align 8 314 br label %4 315 31611: ; preds = %4 317 ret i32 5 318} 319 320; Malloc/Calloc too large 321define i32 @test13() { 322 %1 = tail call noalias i8* @malloc(i64 256) 323 ; CHECK: %1 = tail call noalias i8* @malloc(i64 256) 324 ; CHECK-NEXT: @no_sync_func(i8* noalias nofree %1) 325 tail call void @no_sync_func(i8* %1) 326 %2 = bitcast i8* %1 to i32* 327 store i32 10, i32* %2 328 %3 = load i32, i32* %2 329 tail call void @free(i8* %1) 330 ; CHECK: tail call void @free(i8* noalias nonnull align 4 dereferenceable(4) %1) 331 ret i32 %3 332} 333 334define i32 @test_sle() { 335 %1 = tail call noalias i8* @malloc(i64 -1) 336 ; CHECK: %1 = tail call noalias i8* @malloc(i64 -1) 337 ; CHECK-NEXT: @no_sync_func(i8* noalias nofree %1) 338 tail call void @no_sync_func(i8* %1) 339 %2 = bitcast i8* %1 to i32* 340 store i32 10, i32* %2 341 %3 = load i32, i32* %2 342 tail call void @free(i8* %1) 343 ; CHECK: tail call void @free(i8* noalias nonnull align 4 dereferenceable(4) %1) 344 ret i32 %3 345} 346 347define i32 @test_overflow() { 348 %1 = tail call noalias i8* @calloc(i64 65537, i64 65537) 349 ; CHECK: %1 = tail call noalias i8* @calloc(i64 65537, i64 65537) 350 ; CHECK-NEXT: @no_sync_func(i8* noalias nofree %1) 351 tail call void @no_sync_func(i8* %1) 352 %2 = bitcast i8* %1 to i32* 353 store i32 10, i32* %2 354 %3 = load i32, i32* %2 355 tail call void @free(i8* %1) 356 ; CHECK: tail call void @free(i8* noalias nonnull align 4 dereferenceable(4) %1) 357 ret i32 %3 358} 359 360define void @test14() { 361 %1 = tail call noalias i8* @calloc(i64 64, i64 4) 362 ; CHECK: %1 = tail call noalias i8* @calloc(i64 64, i64 4) 363 ; CHECK-NEXT: @no_sync_func(i8* noalias nofree %1) 364 tail call void @no_sync_func(i8* %1) 365 tail call void @free(i8* %1) 366 ; CHECK: tail call void @free(i8* noalias %1) 367 ret void 368} 369 370define void @test15(i64 %S) { 371 ; CHECK: %1 = tail call noalias i8* @malloc(i64 %S) 372 %1 = tail call noalias i8* @malloc(i64 %S) 373 ; CHECK-NEXT: @no_sync_func(i8* noalias nofree %1) 374 tail call void @no_sync_func(i8* %1) 375 ; CHECK-NEXT: @free(i8* noalias %1) 376 tail call void @free(i8* %1) 377 ret void 378} 379 380define void @test16a(i8 %v, i8** %P) { 381 ; CHECK: %1 = alloca 382 %1 = tail call noalias i8* @malloc(i64 4) 383 ; CHECK-NEXT: store i8 %v, i8* %1 384 store i8 %v, i8* %1 385 ; CHECK-NEXT: @no_sync_func(i8* noalias nocapture nofree nonnull dereferenceable(1) %1) 386 tail call void @no_sync_func(i8* %1) 387 ; CHECK-NOT: @free(i8* %1) 388 tail call void @free(i8* nonnull dereferenceable(1) %1) 389 ret void 390} 391 392define void @test16b(i8 %v, i8** %P) { 393 ; CHECK: %1 = tail call noalias i8* @malloc(i64 4) 394 %1 = tail call noalias i8* @malloc(i64 4) 395 ; CHECK-NEXT: store i8* %1, i8** %P 396 store i8* %1, i8** %P 397 ; CHECK-NEXT: @no_sync_func(i8* nocapture nofree %1) 398 tail call void @no_sync_func(i8* %1) 399 ; CHECK-NEXT: @free(i8* %1) 400 tail call void @free(i8* %1) 401 ret void 402} 403 404define void @test16c(i8 %v, i8** %P) { 405 ; CHECK: %1 = alloca 406 %1 = tail call noalias i8* @malloc(i64 4) 407 ; CHECK-NEXT: store i8* %1, i8** %P 408 store i8* %1, i8** %P 409 ; CHECK-NEXT: @no_sync_func(i8* nocapture nofree %1) 410 tail call void @no_sync_func(i8* %1) nounwind 411 ; CHECK-NOT: @free 412 tail call void @free(i8* %1) 413 ret void 414} 415 416define void @test16d(i8 %v, i8** %P) { 417 ; CHECK: %1 = tail call noalias i8* @malloc(i64 4) 418 %1 = tail call noalias i8* @malloc(i64 4) 419 ; CHECK-NEXT: store i8* %1, i8** %P 420 store i8* %1, i8** %P 421 ret void 422} 423