716 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals2; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT3; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC4 5declare noalias ptr @malloc(i64) allockind("alloc,uninitialized") allocsize(0)6 7declare void @nocapture_func_frees_pointer(ptr nocapture)8 9declare void @func_throws(...)10 11declare void @sync_func(ptr %p)12 13declare void @sync_will_return(ptr %p) willreturn nounwind14 15declare void @no_sync_func(ptr nocapture %p) nofree nosync willreturn16 17declare void @nofree_func(ptr nocapture %p) nofree nosync willreturn18 19declare void @foo(ptr %p)20 21declare void @foo_nounw(ptr %p) nounwind nofree22 23declare void @usei8(i8)24declare void @usei8p(ptr nocapture)25 26declare i32 @no_return_call() noreturn27 28declare void @free(ptr nocapture) allockind("free")29 30declare void @llvm.lifetime.start.p0(ptr nocapture) nounwind31 32;.33; CHECK: @G = internal global ptr undef, align 434;.35define void @h2s_value_simplify_interaction(i1 %c, ptr %A) {36; CHECK-LABEL: define {{[^@]+}}@h2s_value_simplify_interaction37; CHECK-SAME: (i1 [[C:%.*]], ptr nofree readnone captures(none) [[A:%.*]]) {38; CHECK-NEXT: entry:39; CHECK-NEXT: [[ADD:%.*]] = add i64 2, 240; CHECK-NEXT: [[M:%.*]] = tail call noalias align 16 ptr @malloc(i64 noundef [[ADD]])41; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]42; CHECK: t:43; CHECK-NEXT: br i1 false, label [[DEAD:%.*]], label [[F2:%.*]]44; CHECK: f:45; CHECK-NEXT: br label [[J:%.*]]46; CHECK: f2:47; CHECK-NEXT: [[L:%.*]] = load i8, ptr [[M]], align 1648; CHECK-NEXT: call void @usei8(i8 [[L]])49; CHECK-NEXT: call void @no_sync_func(ptr noalias nofree noundef nonnull align 16 captures(none) dereferenceable(1) [[M]]) #[[ATTR11:[0-9]+]]50; CHECK-NEXT: br label [[J]]51; CHECK: dead:52; CHECK-NEXT: unreachable53; CHECK: j:54; CHECK-NEXT: [[PHI:%.*]] = phi ptr [ [[M]], [[F]] ], [ null, [[F2]] ]55; CHECK-NEXT: tail call void @no_sync_func(ptr nofree noundef align 16 captures(none) [[PHI]]) #[[ATTR11]]56; CHECK-NEXT: ret void57;58entry:59 %add = add i64 2, 260 %m = tail call noalias align 16 ptr @malloc(i64 %add)61 br i1 %c, label %t, label %f62 63t:64 br i1 false, label %dead, label %f265 66f:67 br label %j68 69f2:70 %l = load i8, ptr %m, align 171 call void @usei8(i8 %l)72 call void @no_sync_func(ptr noundef %m) nounwind73 br label %j74 75dead:76 br label %j77 78j:79 %phi = phi ptr [ %m, %f ], [ null, %f2 ], [ %A, %dead ]80 tail call void @no_sync_func(ptr noundef %phi) nounwind81 ret void82}83 84define void @nofree_arg_only(ptr %p1, ptr %p2) {85; CHECK-LABEL: define {{[^@]+}}@nofree_arg_only86; CHECK-SAME: (ptr nofree captures(none) [[P1:%.*]], ptr captures(none) [[P2:%.*]]) {87; CHECK-NEXT: bb:88; CHECK-NEXT: tail call void @free(ptr captures(none) [[P2]])89; CHECK-NEXT: tail call void @nofree_func(ptr nofree captures(none) [[P1]])90; CHECK-NEXT: ret void91;92bb:93 tail call void @free(ptr %p2)94 tail call void @nofree_func(ptr %p1)95 ret void96}97 98; TEST 1 - negative, pointer freed in another function.99 100define void @test1() {101; CHECK-LABEL: define {{[^@]+}}@test1() {102; CHECK-NEXT: bb:103; CHECK-NEXT: [[I:%.*]] = tail call noalias ptr @malloc(i64 noundef 4)104; CHECK-NEXT: tail call void @nocapture_func_frees_pointer(ptr noalias captures(none) [[I]])105; CHECK-NEXT: tail call void (...) @func_throws()106; CHECK-NEXT: tail call void @free(ptr noalias captures(none) [[I]])107; CHECK-NEXT: ret void108;109bb:110 %i = tail call noalias ptr @malloc(i64 4)111 tail call void @nocapture_func_frees_pointer(ptr %i)112 tail call void (...) @func_throws()113 tail call void @free(ptr %i)114 ret void115}116 117; TEST 2 - negative, call to a sync function.118 119define void @test2() {120; CHECK-LABEL: define {{[^@]+}}@test2() {121; CHECK-NEXT: bb:122; CHECK-NEXT: [[I:%.*]] = tail call noalias ptr @malloc(i64 noundef 4)123; CHECK-NEXT: tail call void @sync_func(ptr [[I]])124; CHECK-NEXT: tail call void @free(ptr captures(none) [[I]])125; CHECK-NEXT: ret void126;127bb:128 %i = tail call noalias ptr @malloc(i64 4)129 tail call void @sync_func(ptr %i)130 tail call void @free(ptr %i)131 ret void132}133 134; TEST 3 - 1 malloc, 1 free135 136define void @test3() {137; CHECK-LABEL: define {{[^@]+}}@test3() {138; CHECK-NEXT: bb:139; CHECK-NEXT: [[I_H2S:%.*]] = alloca i8, i64 4, align 1140; CHECK-NEXT: tail call void @no_sync_func(ptr noalias nofree captures(none) [[I_H2S]])141; CHECK-NEXT: ret void142;143bb:144 %i = tail call noalias ptr @malloc(i64 4)145 tail call void @no_sync_func(ptr %i)146 tail call void @free(ptr %i)147 ret void148}149 150define void @test3a(ptr %p) {151; CHECK-LABEL: define {{[^@]+}}@test3a152; CHECK-SAME: (ptr captures(none) [[P:%.*]]) {153; CHECK-NEXT: bb:154; CHECK-NEXT: [[I_H2S:%.*]] = alloca i8, i64 4, align 1155; CHECK-NEXT: tail call void @nofree_arg_only(ptr noalias nofree captures(none) [[I_H2S]], ptr captures(none) [[P]])156; CHECK-NEXT: ret void157;158bb:159 %i = tail call noalias ptr @malloc(i64 4)160 tail call void @nofree_arg_only(ptr %i, ptr %p)161 tail call void @free(ptr %i)162 ret void163}164 165declare noalias ptr @aligned_alloc(i64 allocalign, i64) allockind("alloc,uninitialized,aligned") allocsize(1)166 167define void @test3b(ptr %p) {168; CHECK-LABEL: define {{[^@]+}}@test3b169; CHECK-SAME: (ptr captures(none) [[P:%.*]]) {170; CHECK-NEXT: bb:171; CHECK-NEXT: [[I_H2S:%.*]] = alloca i8, i64 128, align 32172; CHECK-NEXT: tail call void @nofree_arg_only(ptr noalias nofree captures(none) [[I_H2S]], ptr captures(none) [[P]])173; CHECK-NEXT: ret void174;175bb:176 %i = tail call noalias ptr @aligned_alloc(i64 32, i64 128)177 tail call void @nofree_arg_only(ptr %i, ptr %p)178 tail call void @free(ptr %i)179 ret void180}181 182; leave alone non-constant alignments.183define void @test3c(i64 %alignment) {184; CHECK-LABEL: define {{[^@]+}}@test3c185; CHECK-SAME: (i64 [[ALIGNMENT:%.*]]) {186; CHECK-NEXT: bb:187; CHECK-NEXT: [[I:%.*]] = tail call noalias ptr @aligned_alloc(i64 [[ALIGNMENT]], i64 noundef 128)188; CHECK-NEXT: tail call void @free(ptr noalias captures(none) [[I]])189; CHECK-NEXT: ret void190;191bb:192 %i = tail call noalias ptr @aligned_alloc(i64 %alignment, i64 128)193 tail call void @free(ptr %i)194 ret void195}196 197; leave alone a constant-but-invalid alignment198define void @test3d(ptr %p) {199; CHECK-LABEL: define {{[^@]+}}@test3d200; CHECK-SAME: (ptr captures(none) [[P:%.*]]) {201; CHECK-NEXT: bb:202; CHECK-NEXT: [[I:%.*]] = tail call noalias ptr @aligned_alloc(i64 noundef 33, i64 noundef 128)203; CHECK-NEXT: tail call void @nofree_arg_only(ptr noalias nofree captures(none) [[I]], ptr captures(none) [[P]])204; CHECK-NEXT: tail call void @free(ptr noalias captures(none) [[I]])205; CHECK-NEXT: ret void206;207bb:208 %i = tail call noalias ptr @aligned_alloc(i64 33, i64 128)209 tail call void @nofree_arg_only(ptr %i, ptr %p)210 tail call void @free(ptr %i)211 ret void212}213 214declare noalias ptr @calloc(i64, i64) allockind("alloc,zeroed") allocsize(0,1)215 216define void @test0() {217; CHECK-LABEL: define {{[^@]+}}@test0() {218; CHECK-NEXT: bb:219; CHECK-NEXT: [[I_H2S:%.*]] = alloca i8, i64 8, align 1220; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr [[I_H2S]], i8 0, i64 8, i1 false)221; CHECK-NEXT: tail call void @no_sync_func(ptr noalias nofree captures(none) [[I_H2S]])222; CHECK-NEXT: ret void223;224bb:225 %i = tail call noalias ptr @calloc(i64 2, i64 4)226 tail call void @no_sync_func(ptr %i)227 tail call void @free(ptr %i)228 ret void229}230 231; TEST 4232define void @test4() {233; CHECK-LABEL: define {{[^@]+}}@test4() {234; CHECK-NEXT: bb:235; CHECK-NEXT: [[I_H2S:%.*]] = alloca i8, i64 4, align 1236; CHECK-NEXT: tail call void @nofree_func(ptr noalias nofree captures(none) [[I_H2S]])237; CHECK-NEXT: ret void238;239bb:240 %i = tail call noalias ptr @malloc(i64 4)241 tail call void @nofree_func(ptr %i)242 ret void243}244 245; TEST 5 - not all exit paths have a call to free, but all uses of malloc246; are in nofree functions and are not captured247 248define void @test5(i32 %arg, ptr %p) {249; CHECK-LABEL: define {{[^@]+}}@test5250; CHECK-SAME: (i32 [[ARG:%.*]], ptr captures(none) [[P:%.*]]) {251; CHECK-NEXT: bb:252; CHECK-NEXT: [[I_H2S:%.*]] = alloca i8, i64 4, align 1253; CHECK-NEXT: [[I1:%.*]] = icmp eq i32 [[ARG]], 0254; CHECK-NEXT: br i1 [[I1]], label [[BB3:%.*]], label [[BB2:%.*]]255; CHECK: bb2:256; CHECK-NEXT: tail call void @nofree_func(ptr noalias nofree captures(none) [[I_H2S]])257; CHECK-NEXT: br label [[BB4:%.*]]258; CHECK: bb3:259; CHECK-NEXT: tail call void @nofree_arg_only(ptr noalias nofree captures(none) [[I_H2S]], ptr captures(none) [[P]])260; CHECK-NEXT: br label [[BB4]]261; CHECK: bb4:262; CHECK-NEXT: ret void263;264bb:265 %i = tail call noalias ptr @malloc(i64 4)266 %i1 = icmp eq i32 %arg, 0267 br i1 %i1, label %bb3, label %bb2268 269bb2:270 tail call void @nofree_func(ptr %i)271 br label %bb4272 273bb3:274 tail call void @nofree_arg_only(ptr %i, ptr %p)275 tail call void @free(ptr %i)276 br label %bb4277 278bb4:279 ret void280}281 282; TEST 6 - all exit paths have a call to free283 284define void @test6(i32 %arg) {285; CHECK-LABEL: define {{[^@]+}}@test6286; CHECK-SAME: (i32 [[ARG:%.*]]) {287; CHECK-NEXT: bb:288; CHECK-NEXT: [[I_H2S:%.*]] = alloca i8, i64 4, align 1289; CHECK-NEXT: [[I1:%.*]] = icmp eq i32 [[ARG]], 0290; CHECK-NEXT: br i1 [[I1]], label [[BB3:%.*]], label [[BB2:%.*]]291; CHECK: bb2:292; CHECK-NEXT: tail call void @nofree_func(ptr noalias nofree captures(none) [[I_H2S]])293; CHECK-NEXT: br label [[BB4:%.*]]294; CHECK: bb3:295; CHECK-NEXT: br label [[BB4]]296; CHECK: bb4:297; CHECK-NEXT: ret void298;299bb:300 %i = tail call noalias ptr @malloc(i64 4)301 %i1 = icmp eq i32 %arg, 0302 br i1 %i1, label %bb3, label %bb2303 304bb2:305 tail call void @nofree_func(ptr %i)306 tail call void @free(ptr %i)307 br label %bb4308 309bb3:310 tail call void @free(ptr %i)311 br label %bb4312 313bb4:314 ret void315}316 317; TEST 7 - free is dead.318 319define void @test7() {320; CHECK-LABEL: define {{[^@]+}}@test7() {321; CHECK-NEXT: bb:322; CHECK-NEXT: [[I_H2S:%.*]] = alloca i8, i64 4, align 1323; CHECK-NEXT: [[I1:%.*]] = tail call i32 @no_return_call() #[[ATTR4:[0-9]+]]324; CHECK-NEXT: unreachable325;326bb:327 %i = tail call noalias ptr @malloc(i64 4)328 %i1 = tail call i32 @no_return_call()329 tail call void @free(ptr %i)330 ret void331}332 333; TEST 8 - Negative: bitcast pointer used in capture function334 335define void @test8() {336; CHECK-LABEL: define {{[^@]+}}@test8() {337; CHECK-NEXT: bb:338; CHECK-NEXT: [[I:%.*]] = tail call noalias ptr @malloc(i64 noundef 4)339; CHECK-NEXT: tail call void @no_sync_func(ptr nofree captures(none) [[I]])340; CHECK-NEXT: store i32 10, ptr [[I]], align 4341; CHECK-NEXT: tail call void @foo(ptr nonnull align 4 dereferenceable(4) [[I]])342; CHECK-NEXT: tail call void @free(ptr nonnull align 4 captures(none) dereferenceable(4) [[I]])343; CHECK-NEXT: ret void344;345bb:346 %i = tail call noalias ptr @malloc(i64 4)347 tail call void @no_sync_func(ptr %i)348 store i32 10, ptr %i, align 4349 %i2 = load i32, ptr %i, align 4350 tail call void @foo(ptr %i)351 tail call void @free(ptr %i)352 ret void353}354 355; TEST 9 - FIXME: malloc should be converted.356define void @test9() {357; CHECK-LABEL: define {{[^@]+}}@test9() {358; CHECK-NEXT: bb:359; CHECK-NEXT: [[I:%.*]] = tail call noalias ptr @malloc(i64 noundef 4)360; CHECK-NEXT: tail call void @no_sync_func(ptr nofree captures(none) [[I]])361; CHECK-NEXT: store i32 10, ptr [[I]], align 4362; CHECK-NEXT: tail call void @foo_nounw(ptr nofree nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR11]]363; CHECK-NEXT: tail call void @free(ptr nonnull align 4 captures(none) dereferenceable(4) [[I]])364; CHECK-NEXT: ret void365;366bb:367 %i = tail call noalias ptr @malloc(i64 4)368 tail call void @no_sync_func(ptr %i)369 store i32 10, ptr %i, align 4370 %i2 = load i32, ptr %i, align 4371 tail call void @foo_nounw(ptr %i)372 tail call void @free(ptr %i)373 ret void374}375 376; TEST 10 - 1 malloc, 1 free377 378define i32 @test10() {379; CHECK-LABEL: define {{[^@]+}}@test10() {380; CHECK-NEXT: bb:381; CHECK-NEXT: [[I_H2S:%.*]] = alloca i8, i64 4, align 1382; CHECK-NEXT: tail call void @no_sync_func(ptr noalias nofree captures(none) [[I_H2S]])383; CHECK-NEXT: store i32 10, ptr [[I_H2S]], align 4384; CHECK-NEXT: [[I2:%.*]] = load i32, ptr [[I_H2S]], align 4385; CHECK-NEXT: ret i32 [[I2]]386;387bb:388 %i = tail call noalias ptr @malloc(i64 4)389 tail call void @no_sync_func(ptr %i)390 store i32 10, ptr %i, align 4391 %i2 = load i32, ptr %i, align 4392 tail call void @free(ptr %i)393 ret i32 %i2394}395 396; TEST 11397 398define void @test11() {399; CHECK-LABEL: define {{[^@]+}}@test11() {400; CHECK-NEXT: bb:401; CHECK-NEXT: [[I_H2S:%.*]] = alloca i8, i64 4, align 1402; CHECK-NEXT: tail call void @sync_will_return(ptr [[I_H2S]]) #[[ATTR11]]403; CHECK-NEXT: ret void404;405bb:406 %i = tail call noalias ptr @malloc(i64 4)407 tail call void @sync_will_return(ptr %i)408 tail call void @free(ptr %i)409 ret void410}411 412; TEST 12413define i32 @irreducible_cfg(i32 %arg) {414; CHECK-LABEL: define {{[^@]+}}@irreducible_cfg415; CHECK-SAME: (i32 [[ARG:%.*]]) {416; CHECK-NEXT: bb:417; CHECK-NEXT: [[I_H2S:%.*]] = alloca i8, i64 4, align 1418; CHECK-NEXT: store i32 10, ptr [[I_H2S]], align 4419; CHECK-NEXT: [[I2:%.*]] = icmp eq i32 [[ARG]], 1420; CHECK-NEXT: br i1 [[I2]], label [[BB3:%.*]], label [[BB5:%.*]]421; CHECK: bb3:422; CHECK-NEXT: [[I4:%.*]] = add nsw i32 [[ARG]], 5423; CHECK-NEXT: br label [[BB11:%.*]]424; CHECK: bb5:425; CHECK-NEXT: br label [[BB6:%.*]]426; CHECK: bb6:427; CHECK-NEXT: [[DOT0:%.*]] = phi i32 [ [[I12:%.*]], [[BB11]] ], [ 1, [[BB5]] ]428; CHECK-NEXT: [[I7:%.*]] = load i32, ptr [[I_H2S]], align 4429; CHECK-NEXT: [[I8:%.*]] = add nsw i32 [[I7]], -1430; CHECK-NEXT: store i32 [[I8]], ptr [[I_H2S]], align 4431; CHECK-NEXT: [[I9:%.*]] = icmp ne i32 [[I7]], 0432; CHECK-NEXT: br i1 [[I9]], label [[BB10:%.*]], label [[BB13:%.*]]433; CHECK: bb10:434; CHECK-NEXT: br label [[BB11]]435; CHECK: bb11:436; CHECK-NEXT: [[DOT1:%.*]] = phi i32 [ [[I4]], [[BB3]] ], [ [[DOT0]], [[BB10]] ]437; CHECK-NEXT: [[I12]] = add nsw i32 [[DOT1]], 1438; CHECK-NEXT: br label [[BB6]]439; CHECK: bb13:440; CHECK-NEXT: [[I16:%.*]] = load i32, ptr [[I_H2S]], align 4441; CHECK-NEXT: ret i32 [[I16]]442;443bb:444 %i = call noalias ptr @malloc(i64 4)445 store i32 10, ptr %i, align 4446 %i2 = icmp eq i32 %arg, 1447 br i1 %i2, label %bb3, label %bb5448 449bb3:450 %i4 = add nsw i32 %arg, 5451 br label %bb11452 453bb5:454 br label %bb6455 456bb6:457 %.0 = phi i32 [ %i12, %bb11 ], [ 1, %bb5 ]458 %i7 = load i32, ptr %i, align 4459 %i8 = add nsw i32 %i7, -1460 store i32 %i8, ptr %i, align 4461 %i9 = icmp ne i32 %i7, 0462 br i1 %i9, label %bb10, label %bb13463 464bb10:465 br label %bb11466 467bb11:468 %.1 = phi i32 [ %i4, %bb3 ], [ %.0, %bb10 ]469 %i12 = add nsw i32 %.1, 1470 br label %bb6471 472bb13:473 %i14 = load i32, ptr %i, align 4474 call void @free(ptr %i)475 %i16 = load i32, ptr %i, align 4476 ret i32 %i16477}478 479 480define i32 @malloc_in_loop(i32 %arg) {481; CHECK-LABEL: define {{[^@]+}}@malloc_in_loop482; CHECK-SAME: (i32 [[ARG:%.*]]) {483; CHECK-NEXT: bb:484; CHECK-NEXT: [[I:%.*]] = alloca i32, align 4485; CHECK-NEXT: [[I1:%.*]] = alloca ptr, align 8486; CHECK-NEXT: [[I11:%.*]] = alloca i8, i32 0, align 8487; CHECK-NEXT: store i32 [[ARG]], ptr [[I]], align 4488; CHECK-NEXT: br label [[BB2:%.*]]489; CHECK: bb2:490; CHECK-NEXT: [[I3:%.*]] = load i32, ptr [[I]], align 4491; CHECK-NEXT: [[I4:%.*]] = add nsw i32 [[I3]], -1492; CHECK-NEXT: store i32 [[I4]], ptr [[I]], align 4493; CHECK-NEXT: [[I5:%.*]] = icmp sgt i32 [[I4]], 0494; CHECK-NEXT: br i1 [[I5]], label [[BB6:%.*]], label [[BB9:%.*]]495; CHECK: bb6:496; CHECK-NEXT: [[I7_H2S:%.*]] = alloca i8, i64 4, align 1497; CHECK-NEXT: br label [[BB2]]498; CHECK: bb9:499; CHECK-NEXT: ret i32 5500;501bb:502 %i = alloca i32, align 4503 %i1 = alloca ptr, align 8504 store i32 %arg, ptr %i, align 4505 br label %bb2506 507bb2:508 %i3 = load i32, ptr %i, align 4509 %i4 = add nsw i32 %i3, -1510 store i32 %i4, ptr %i, align 4511 %i5 = icmp sgt i32 %i4, 0512 br i1 %i5, label %bb6, label %bb9513 514bb6:515 %i7 = call noalias ptr @malloc(i64 4)516 store i32 1, ptr %i7, align 8517 br label %bb2518 519bb9:520 ret i32 5521}522 523; Malloc/Calloc too large524define i32 @test13() {525; CHECK-LABEL: define {{[^@]+}}@test13() {526; CHECK-NEXT: bb:527; CHECK-NEXT: [[I:%.*]] = tail call noalias ptr @malloc(i64 noundef 256)528; CHECK-NEXT: tail call void @no_sync_func(ptr noalias nofree captures(none) [[I]])529; CHECK-NEXT: store i32 10, ptr [[I]], align 4530; CHECK-NEXT: [[I2:%.*]] = load i32, ptr [[I]], align 4531; CHECK-NEXT: tail call void @free(ptr noalias nonnull align 4 captures(none) dereferenceable(4) [[I]])532; CHECK-NEXT: ret i32 [[I2]]533;534bb:535 %i = tail call noalias ptr @malloc(i64 256)536 tail call void @no_sync_func(ptr %i)537 store i32 10, ptr %i, align 4538 %i2 = load i32, ptr %i, align 4539 tail call void @free(ptr %i)540 ret i32 %i2541}542 543define i32 @test_sle() {544; CHECK-LABEL: define {{[^@]+}}@test_sle() {545; CHECK-NEXT: bb:546; CHECK-NEXT: [[I:%.*]] = tail call noalias ptr @malloc(i64 noundef -1)547; CHECK-NEXT: tail call void @no_sync_func(ptr noalias nofree captures(none) [[I]])548; CHECK-NEXT: store i32 10, ptr [[I]], align 4549; CHECK-NEXT: [[I2:%.*]] = load i32, ptr [[I]], align 4550; CHECK-NEXT: tail call void @free(ptr noalias nonnull align 4 captures(none) dereferenceable(4) [[I]])551; CHECK-NEXT: ret i32 [[I2]]552;553bb:554 %i = tail call noalias ptr @malloc(i64 -1)555 tail call void @no_sync_func(ptr %i)556 store i32 10, ptr %i, align 4557 %i2 = load i32, ptr %i, align 4558 tail call void @free(ptr %i)559 ret i32 %i2560}561 562define i32 @test_overflow() {563; CHECK-LABEL: define {{[^@]+}}@test_overflow() {564; CHECK-NEXT: bb:565; CHECK-NEXT: [[I:%.*]] = tail call noalias ptr @calloc(i64 noundef 65537, i64 noundef 65537)566; CHECK-NEXT: tail call void @no_sync_func(ptr noalias nofree captures(none) [[I]])567; CHECK-NEXT: store i32 10, ptr [[I]], align 4568; CHECK-NEXT: [[I2:%.*]] = load i32, ptr [[I]], align 4569; CHECK-NEXT: tail call void @free(ptr noalias nonnull align 4 captures(none) dereferenceable(4) [[I]])570; CHECK-NEXT: ret i32 [[I2]]571;572bb:573 %i = tail call noalias ptr @calloc(i64 65537, i64 65537)574 tail call void @no_sync_func(ptr %i)575 store i32 10, ptr %i, align 4576 %i2 = load i32, ptr %i, align 4577 tail call void @free(ptr %i)578 ret i32 %i2579}580 581define void @test14() {582; CHECK-LABEL: define {{[^@]+}}@test14() {583; CHECK-NEXT: bb:584; CHECK-NEXT: [[I:%.*]] = tail call noalias ptr @calloc(i64 noundef 64, i64 noundef 4)585; CHECK-NEXT: tail call void @no_sync_func(ptr noalias nofree captures(none) [[I]])586; CHECK-NEXT: tail call void @free(ptr noalias captures(none) [[I]])587; CHECK-NEXT: ret void588;589bb:590 %i = tail call noalias ptr @calloc(i64 64, i64 4)591 tail call void @no_sync_func(ptr %i)592 tail call void @free(ptr %i)593 ret void594}595 596define void @test15(i64 %S) {597; CHECK-LABEL: define {{[^@]+}}@test15598; CHECK-SAME: (i64 [[S:%.*]]) {599; CHECK-NEXT: bb:600; CHECK-NEXT: [[I:%.*]] = tail call noalias ptr @malloc(i64 [[S]])601; CHECK-NEXT: tail call void @no_sync_func(ptr noalias nofree captures(none) [[I]])602; CHECK-NEXT: tail call void @free(ptr noalias captures(none) [[I]])603; CHECK-NEXT: ret void604;605bb:606 %i = tail call noalias ptr @malloc(i64 %S)607 tail call void @no_sync_func(ptr %i)608 tail call void @free(ptr %i)609 ret void610}611 612define void @test16a(i8 %v, ptr %P) {613; CHECK-LABEL: define {{[^@]+}}@test16a614; CHECK-SAME: (i8 [[V:%.*]], ptr nofree readnone captures(none) [[P:%.*]]) {615; CHECK-NEXT: bb:616; CHECK-NEXT: [[I_H2S:%.*]] = alloca i8, i64 4, align 1617; CHECK-NEXT: store i8 [[V]], ptr [[I_H2S]], align 1618; CHECK-NEXT: tail call void @no_sync_func(ptr noalias nofree noundef nonnull captures(none) dereferenceable(1) [[I_H2S]])619; CHECK-NEXT: ret void620;621bb:622 %i = tail call noalias ptr @malloc(i64 4)623 store i8 %v, ptr %i, align 1624 tail call void @no_sync_func(ptr %i)625 tail call void @free(ptr nonnull dereferenceable(1) %i)626 ret void627}628 629define void @test16b(i8 %v, ptr %P) {630; CHECK-LABEL: define {{[^@]+}}@test16b631; CHECK-SAME: (i8 [[V:%.*]], ptr nofree writeonly captures(none) [[P:%.*]]) {632; CHECK-NEXT: bb:633; CHECK-NEXT: [[I:%.*]] = tail call noalias ptr @malloc(i64 noundef 4)634; CHECK-NEXT: store ptr [[I]], ptr [[P]], align 8635; CHECK-NEXT: tail call void @no_sync_func(ptr nofree captures(none) [[I]])636; CHECK-NEXT: tail call void @free(ptr captures(none) [[I]])637; CHECK-NEXT: ret void638;639bb:640 %i = tail call noalias ptr @malloc(i64 4)641 store ptr %i, ptr %P, align 8642 tail call void @no_sync_func(ptr %i)643 tail call void @free(ptr %i)644 ret void645}646 647define void @test16c(i8 %v, ptr %P) {648; CHECK-LABEL: define {{[^@]+}}@test16c649; CHECK-SAME: (i8 [[V:%.*]], ptr nofree writeonly captures(none) [[P:%.*]]) {650; CHECK-NEXT: bb:651; CHECK-NEXT: [[I_H2S:%.*]] = alloca i8, i64 4, align 1652; CHECK-NEXT: store ptr [[I_H2S]], ptr [[P]], align 8653; CHECK-NEXT: tail call void @no_sync_func(ptr nofree captures(none) [[I_H2S]]) #[[ATTR11]]654; CHECK-NEXT: ret void655;656bb:657 %i = tail call noalias ptr @malloc(i64 4)658 store ptr %i, ptr %P, align 8659 tail call void @no_sync_func(ptr %i) nounwind660 tail call void @free(ptr %i)661 ret void662}663 664define void @test16d(i8 %v, ptr %P) {665; CHECK-LABEL: define {{[^@]+}}@test16d666; CHECK-SAME: (i8 [[V:%.*]], ptr nofree writeonly captures(none) [[P:%.*]]) {667; CHECK-NEXT: bb:668; CHECK-NEXT: [[I:%.*]] = tail call noalias ptr @malloc(i64 noundef 4)669; CHECK-NEXT: store ptr [[I]], ptr [[P]], align 8670; CHECK-NEXT: ret void671;672bb:673 %i = tail call noalias ptr @malloc(i64 4)674 store ptr %i, ptr %P, align 8675 ret void676}677 678@G = internal global ptr undef, align 4679define void @test16e(i8 %v) norecurse {680; CHECK: Function Attrs: norecurse681; CHECK-LABEL: define {{[^@]+}}@test16e682; CHECK-SAME: (i8 [[V:%.*]]) #[[ATTR9:[0-9]+]] {683; CHECK-NEXT: bb:684; CHECK-NEXT: [[I_H2S:%.*]] = alloca i8, i64 4, align 1685; CHECK-NEXT: store ptr [[I_H2S]], ptr @G, align 8686; CHECK-NEXT: call void @usei8p(ptr nofree captures(none) [[I_H2S]]) #[[ATTR12:[0-9]+]]687; CHECK-NEXT: ret void688;689bb:690 %i = tail call noalias ptr @malloc(i64 4)691 store ptr %i, ptr @G, align 8692 %i1 = load ptr, ptr @G, align 8693 call void @usei8p(ptr nocapture nofree %i1) nocallback nosync nounwind willreturn694 call void @free(ptr %i)695 ret void696}697 698;.699; CHECK: attributes #[[ATTR0:[0-9]+]] = { allockind("alloc,uninitialized") allocsize(0) }700; CHECK: attributes #[[ATTR1:[0-9]+]] = { nounwind willreturn }701; CHECK: attributes #[[ATTR2:[0-9]+]] = { nofree nosync willreturn }702; CHECK: attributes #[[ATTR3:[0-9]+]] = { nofree nounwind }703; CHECK: attributes #[[ATTR4]] = { noreturn }704; CHECK: attributes #[[ATTR5:[0-9]+]] = { allockind("free") }705; CHECK: attributes #[[ATTR6:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }706; CHECK: attributes #[[ATTR7:[0-9]+]] = { allockind("alloc,uninitialized,aligned") allocsize(1) }707; CHECK: attributes #[[ATTR8:[0-9]+]] = { allockind("alloc,zeroed") allocsize(0,1) }708; CHECK: attributes #[[ATTR9]] = { norecurse }709; CHECK: attributes #[[ATTR10:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) }710; CHECK: attributes #[[ATTR11]] = { nounwind }711; CHECK: attributes #[[ATTR12]] = { nocallback nosync nounwind willreturn }712;.713;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:714; CGSCC: {{.*}}715; TUNIT: {{.*}}716