1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals 2; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=8 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM 3; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=8 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM 4; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM 5; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM 6 7declare noalias i8* @malloc(i64) allockind("alloc,uninitialized") allocsize(0) 8 9declare void @nocapture_func_frees_pointer(i8* nocapture) 10 11declare void @func_throws(...) 12 13declare void @sync_func(i8* %p) 14 15declare void @sync_will_return(i8* %p) willreturn nounwind 16 17declare void @no_sync_func(i8* nocapture %p) nofree nosync willreturn 18 19declare void @nofree_func(i8* nocapture %p) nofree nosync willreturn 20 21declare void @foo(i32* %p) 22 23declare void @foo_nounw(i32* %p) nounwind nofree 24 25declare void @usei8(i8) 26 27declare i32 @no_return_call() noreturn 28 29declare void @free(i8* nocapture) allockind("free") 30 31declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) nounwind 32 33define void @h2s_value_simplify_interaction(i1 %c, i8* %A) { 34; IS________OPM-LABEL: define {{[^@]+}}@h2s_value_simplify_interaction 35; IS________OPM-SAME: (i1 [[C:%.*]], i8* nocapture nofree readnone [[A:%.*]]) { 36; IS________OPM-NEXT: entry: 37; IS________OPM-NEXT: [[ADD:%.*]] = add i64 2, 2 38; IS________OPM-NEXT: [[M:%.*]] = tail call noalias align 16 i8* @malloc(i64 noundef [[ADD]]) 39; IS________OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 40; IS________OPM: t: 41; IS________OPM-NEXT: br i1 false, label [[DEAD:%.*]], label [[F2:%.*]] 42; IS________OPM: f: 43; IS________OPM-NEXT: br label [[J:%.*]] 44; IS________OPM: f2: 45; IS________OPM-NEXT: [[C1:%.*]] = bitcast i8* [[M]] to i32* 46; IS________OPM-NEXT: [[C2:%.*]] = bitcast i32* [[C1]] to i8* 47; IS________OPM-NEXT: [[L:%.*]] = load i8, i8* [[C2]], align 16 48; IS________OPM-NEXT: call void @usei8(i8 [[L]]) 49; IS________OPM-NEXT: call void @no_sync_func(i8* nocapture nofree noundef align 16 [[C2]]) #[[ATTR9:[0-9]+]] 50; IS________OPM-NEXT: br label [[J]] 51; IS________OPM: dead: 52; IS________OPM-NEXT: unreachable 53; IS________OPM: j: 54; IS________OPM-NEXT: [[PHI:%.*]] = phi i8* [ [[M]], [[F]] ], [ null, [[F2]] ] 55; IS________OPM-NEXT: tail call void @no_sync_func(i8* nocapture nofree noundef align 16 [[PHI]]) #[[ATTR9]] 56; IS________OPM-NEXT: ret void 57; 58; IS________NPM-LABEL: define {{[^@]+}}@h2s_value_simplify_interaction 59; IS________NPM-SAME: (i1 [[C:%.*]], i8* nocapture nofree readnone [[A:%.*]]) { 60; IS________NPM-NEXT: entry: 61; IS________NPM-NEXT: [[ADD:%.*]] = add i64 2, 2 62; IS________NPM-NEXT: [[M:%.*]] = tail call noalias align 16 i8* @malloc(i64 noundef [[ADD]]) 63; IS________NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 64; IS________NPM: t: 65; IS________NPM-NEXT: br i1 false, label [[DEAD:%.*]], label [[F2:%.*]] 66; IS________NPM: f: 67; IS________NPM-NEXT: br label [[J:%.*]] 68; IS________NPM: f2: 69; IS________NPM-NEXT: [[L:%.*]] = load i8, i8* [[M]], align 16 70; IS________NPM-NEXT: call void @usei8(i8 [[L]]) 71; IS________NPM-NEXT: call void @no_sync_func(i8* nocapture nofree noundef align 16 [[M]]) #[[ATTR10:[0-9]+]] 72; IS________NPM-NEXT: br label [[J]] 73; IS________NPM: dead: 74; IS________NPM-NEXT: unreachable 75; IS________NPM: j: 76; IS________NPM-NEXT: [[PHI:%.*]] = phi i8* [ [[M]], [[F]] ], [ null, [[F2]] ] 77; IS________NPM-NEXT: tail call void @no_sync_func(i8* nocapture nofree noundef align 16 [[PHI]]) #[[ATTR10]] 78; IS________NPM-NEXT: ret void 79; 80entry: 81 %add = add i64 2, 2 82 %m = tail call align 16 noalias i8* @malloc(i64 %add) 83 br i1 %c, label %t, label %f 84t: 85 br i1 false, label %dead, label %f2 86f: 87 br label %j 88f2: 89 %c1 = bitcast i8* %m to i32* 90 %c2 = bitcast i32* %c1 to i8* 91 %l = load i8, i8* %c2 92 call void @usei8(i8 %l) 93 call void @no_sync_func(i8* noundef %c2) nounwind 94 br label %j 95dead: 96 br label %j 97j: 98 %phi = phi i8* [ %m, %f ], [ null, %f2 ], [ %A, %dead ] 99 tail call void @no_sync_func(i8* noundef %phi) nounwind 100 ;tail call void @free(i8* %m) 101 ret void 102} 103 104define void @nofree_arg_only(i8* %p1, i8* %p2) { 105; CHECK-LABEL: define {{[^@]+}}@nofree_arg_only 106; CHECK-SAME: (i8* nocapture nofree [[P1:%.*]], i8* nocapture [[P2:%.*]]) { 107; CHECK-NEXT: tail call void @free(i8* nocapture [[P2]]) 108; CHECK-NEXT: tail call void @nofree_func(i8* nocapture nofree [[P1]]) 109; CHECK-NEXT: ret void 110; 111 tail call void @free(i8* %p2) 112 tail call void @nofree_func(i8* %p1) 113 ret void 114} 115 116; TEST 1 - negative, pointer freed in another function. 117 118define void @test1() { 119; CHECK-LABEL: define {{[^@]+}}@test1() { 120; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) 121; CHECK-NEXT: tail call void @nocapture_func_frees_pointer(i8* noalias nocapture [[TMP1]]) 122; CHECK-NEXT: tail call void (...) @func_throws() 123; CHECK-NEXT: tail call void @free(i8* noalias nocapture [[TMP1]]) 124; CHECK-NEXT: ret void 125; 126 %1 = tail call noalias i8* @malloc(i64 4) 127 tail call void @nocapture_func_frees_pointer(i8* %1) 128 tail call void (...) @func_throws() 129 tail call void @free(i8* %1) 130 ret void 131} 132 133; TEST 2 - negative, call to a sync function. 134 135define void @test2() { 136; CHECK-LABEL: define {{[^@]+}}@test2() { 137; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) 138; CHECK-NEXT: tail call void @sync_func(i8* [[TMP1]]) 139; CHECK-NEXT: tail call void @free(i8* nocapture [[TMP1]]) 140; CHECK-NEXT: ret void 141; 142 %1 = tail call noalias i8* @malloc(i64 4) 143 tail call void @sync_func(i8* %1) 144 tail call void @free(i8* %1) 145 ret void 146} 147 148; TEST 3 - 1 malloc, 1 free 149 150define void @test3() { 151; IS________OPM-LABEL: define {{[^@]+}}@test3() { 152; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) 153; IS________OPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]]) 154; IS________OPM-NEXT: tail call void @free(i8* noalias nocapture [[TMP1]]) 155; IS________OPM-NEXT: ret void 156; 157; IS________NPM-LABEL: define {{[^@]+}}@test3() { 158; IS________NPM-NEXT: [[DOTH2S:%.*]] = alloca i8, i64 4, align 1 159; IS________NPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[DOTH2S]]) 160; IS________NPM-NEXT: ret void 161; 162 %1 = tail call noalias i8* @malloc(i64 4) 163 tail call void @no_sync_func(i8* %1) 164 tail call void @free(i8* %1) 165 ret void 166} 167 168define void @test3a(i8* %p) { 169; IS________OPM-LABEL: define {{[^@]+}}@test3a 170; IS________OPM-SAME: (i8* nocapture [[P:%.*]]) { 171; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) 172; IS________OPM-NEXT: tail call void @nofree_arg_only(i8* nocapture nofree [[TMP1]], i8* nocapture [[P]]) 173; IS________OPM-NEXT: tail call void @free(i8* noalias nocapture [[TMP1]]) 174; IS________OPM-NEXT: ret void 175; 176; IS________NPM-LABEL: define {{[^@]+}}@test3a 177; IS________NPM-SAME: (i8* nocapture [[P:%.*]]) { 178; IS________NPM-NEXT: [[DOTH2S:%.*]] = alloca i8, i64 4, align 1 179; IS________NPM-NEXT: tail call void @nofree_arg_only(i8* noalias nocapture nofree [[DOTH2S]], i8* nocapture [[P]]) 180; IS________NPM-NEXT: ret void 181; 182 %1 = tail call noalias i8* @malloc(i64 4) 183 tail call void @nofree_arg_only(i8* %1, i8* %p) 184 tail call void @free(i8* %1) 185 ret void 186} 187 188declare noalias i8* @aligned_alloc(i64 allocalign, i64) allockind("alloc,uninitialized,aligned") allocsize(1) 189 190define void @test3b(i8* %p) { 191; IS________OPM-LABEL: define {{[^@]+}}@test3b 192; IS________OPM-SAME: (i8* nocapture [[P:%.*]]) { 193; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @aligned_alloc(i64 noundef 32, i64 noundef 128) 194; IS________OPM-NEXT: tail call void @nofree_arg_only(i8* nocapture nofree [[TMP1]], i8* nocapture [[P]]) 195; IS________OPM-NEXT: tail call void @free(i8* noalias nocapture [[TMP1]]) 196; IS________OPM-NEXT: ret void 197; 198; IS________NPM-LABEL: define {{[^@]+}}@test3b 199; IS________NPM-SAME: (i8* nocapture [[P:%.*]]) { 200; IS________NPM-NEXT: [[DOTH2S:%.*]] = alloca i8, i64 128, align 32 201; IS________NPM-NEXT: tail call void @nofree_arg_only(i8* noalias nocapture nofree [[DOTH2S]], i8* nocapture [[P]]) 202; IS________NPM-NEXT: ret void 203; 204 %1 = tail call noalias i8* @aligned_alloc(i64 32, i64 128) 205 tail call void @nofree_arg_only(i8* %1, i8* %p) 206 tail call void @free(i8* %1) 207 ret void 208} 209 210; leave alone non-constant alignments. 211define void @test3c(i64 %alignment) { 212; CHECK-LABEL: define {{[^@]+}}@test3c 213; CHECK-SAME: (i64 [[ALIGNMENT:%.*]]) { 214; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @aligned_alloc(i64 [[ALIGNMENT]], i64 noundef 128) 215; CHECK-NEXT: tail call void @free(i8* noalias nocapture [[TMP1]]) 216; CHECK-NEXT: ret void 217; 218 %1 = tail call noalias i8* @aligned_alloc(i64 %alignment, i64 128) 219 tail call void @free(i8* %1) 220 ret void 221} 222 223; leave alone a constant-but-invalid alignment 224define void @test3d(i8* %p) { 225; IS________OPM-LABEL: define {{[^@]+}}@test3d 226; IS________OPM-SAME: (i8* nocapture [[P:%.*]]) { 227; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @aligned_alloc(i64 noundef 33, i64 noundef 128) 228; IS________OPM-NEXT: tail call void @nofree_arg_only(i8* nocapture nofree [[TMP1]], i8* nocapture [[P]]) 229; IS________OPM-NEXT: tail call void @free(i8* noalias nocapture [[TMP1]]) 230; IS________OPM-NEXT: ret void 231; 232; IS________NPM-LABEL: define {{[^@]+}}@test3d 233; IS________NPM-SAME: (i8* nocapture [[P:%.*]]) { 234; IS________NPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @aligned_alloc(i64 noundef 33, i64 noundef 128) 235; IS________NPM-NEXT: tail call void @nofree_arg_only(i8* noalias nocapture nofree [[TMP1]], i8* nocapture [[P]]) 236; IS________NPM-NEXT: tail call void @free(i8* noalias nocapture [[TMP1]]) 237; IS________NPM-NEXT: ret void 238; 239; CHECK-SAME; (i8* nocapture [[P:%.*]]) { 240 %1 = tail call noalias i8* @aligned_alloc(i64 33, i64 128) 241 tail call void @nofree_arg_only(i8* %1, i8* %p) 242 tail call void @free(i8* %1) 243 ret void 244} 245 246declare noalias i8* @calloc(i64, i64) allockind("alloc,zeroed") allocsize(0,1) 247 248define void @test0() { 249; IS________OPM-LABEL: define {{[^@]+}}@test0() { 250; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @calloc(i64 noundef 2, i64 noundef 4) 251; IS________OPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]]) 252; IS________OPM-NEXT: tail call void @free(i8* noalias nocapture [[TMP1]]) 253; IS________OPM-NEXT: ret void 254; 255; IS________NPM-LABEL: define {{[^@]+}}@test0() { 256; IS________NPM-NEXT: [[DOTH2S:%.*]] = alloca i8, i64 8, align 1 257; IS________NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* [[DOTH2S]], i8 0, i64 8, i1 false) 258; IS________NPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[DOTH2S]]) 259; IS________NPM-NEXT: ret void 260; 261 %1 = tail call noalias i8* @calloc(i64 2, i64 4) 262 tail call void @no_sync_func(i8* %1) 263 tail call void @free(i8* %1) 264 ret void 265} 266 267; TEST 4 268define void @test4() { 269; CHECK-LABEL: define {{[^@]+}}@test4() { 270; CHECK-NEXT: [[DOTH2S:%.*]] = alloca i8, i64 4, align 1 271; CHECK-NEXT: tail call void @nofree_func(i8* noalias nocapture nofree [[DOTH2S]]) 272; CHECK-NEXT: ret void 273; 274 %1 = tail call noalias i8* @malloc(i64 4) 275 tail call void @nofree_func(i8* %1) 276 ret void 277} 278 279; TEST 5 - not all exit paths have a call to free, but all uses of malloc 280; are in nofree functions and are not captured 281 282define void @test5(i32, i8* %p) { 283; IS________OPM-LABEL: define {{[^@]+}}@test5 284; IS________OPM-SAME: (i32 [[TMP0:%.*]], i8* nocapture [[P:%.*]]) { 285; IS________OPM-NEXT: [[TMP2:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) 286; IS________OPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0 287; IS________OPM-NEXT: br i1 [[TMP3]], label [[TMP5:%.*]], label [[TMP4:%.*]] 288; IS________OPM: 4: 289; IS________OPM-NEXT: tail call void @nofree_func(i8* noalias nocapture nofree [[TMP2]]) 290; IS________OPM-NEXT: br label [[TMP6:%.*]] 291; IS________OPM: 5: 292; IS________OPM-NEXT: tail call void @nofree_arg_only(i8* nocapture nofree [[TMP2]], i8* nocapture [[P]]) 293; IS________OPM-NEXT: tail call void @free(i8* noalias nocapture [[TMP2]]) 294; IS________OPM-NEXT: br label [[TMP6]] 295; IS________OPM: 6: 296; IS________OPM-NEXT: ret void 297; 298; IS________NPM-LABEL: define {{[^@]+}}@test5 299; IS________NPM-SAME: (i32 [[TMP0:%.*]], i8* nocapture [[P:%.*]]) { 300; IS________NPM-NEXT: [[DOTH2S:%.*]] = alloca i8, i64 4, align 1 301; IS________NPM-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP0]], 0 302; IS________NPM-NEXT: br i1 [[TMP2]], label [[TMP4:%.*]], label [[TMP3:%.*]] 303; IS________NPM: 3: 304; IS________NPM-NEXT: tail call void @nofree_func(i8* noalias nocapture nofree [[DOTH2S]]) 305; IS________NPM-NEXT: br label [[TMP5:%.*]] 306; IS________NPM: 4: 307; IS________NPM-NEXT: tail call void @nofree_arg_only(i8* noalias nocapture nofree [[DOTH2S]], i8* nocapture [[P]]) 308; IS________NPM-NEXT: br label [[TMP5]] 309; IS________NPM: 5: 310; IS________NPM-NEXT: ret void 311; 312 %2 = tail call noalias i8* @malloc(i64 4) 313 %3 = icmp eq i32 %0, 0 314 br i1 %3, label %5, label %4 315 3164: ; preds = %1 317 tail call void @nofree_func(i8* %2) 318 br label %6 319 3205: ; preds = %1 321 tail call void @nofree_arg_only(i8* %2, i8* %p) 322 tail call void @free(i8* %2) 323 br label %6 324 3256: ; preds = %5, %4 326 ret void 327} 328 329; TEST 6 - all exit paths have a call to free 330 331define void @test6(i32) { 332; IS________OPM-LABEL: define {{[^@]+}}@test6 333; IS________OPM-SAME: (i32 [[TMP0:%.*]]) { 334; IS________OPM-NEXT: [[TMP2:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) 335; IS________OPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0 336; IS________OPM-NEXT: br i1 [[TMP3]], label [[TMP5:%.*]], label [[TMP4:%.*]] 337; IS________OPM: 4: 338; IS________OPM-NEXT: tail call void @nofree_func(i8* noalias nocapture nofree [[TMP2]]) 339; IS________OPM-NEXT: tail call void @free(i8* noalias nocapture [[TMP2]]) 340; IS________OPM-NEXT: br label [[TMP6:%.*]] 341; IS________OPM: 5: 342; IS________OPM-NEXT: tail call void @free(i8* noalias nocapture [[TMP2]]) 343; IS________OPM-NEXT: br label [[TMP6]] 344; IS________OPM: 6: 345; IS________OPM-NEXT: ret void 346; 347; IS________NPM-LABEL: define {{[^@]+}}@test6 348; IS________NPM-SAME: (i32 [[TMP0:%.*]]) { 349; IS________NPM-NEXT: [[DOTH2S:%.*]] = alloca i8, i64 4, align 1 350; IS________NPM-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP0]], 0 351; IS________NPM-NEXT: br i1 [[TMP2]], label [[TMP4:%.*]], label [[TMP3:%.*]] 352; IS________NPM: 3: 353; IS________NPM-NEXT: tail call void @nofree_func(i8* noalias nocapture nofree [[DOTH2S]]) 354; IS________NPM-NEXT: br label [[TMP5:%.*]] 355; IS________NPM: 4: 356; IS________NPM-NEXT: br label [[TMP5]] 357; IS________NPM: 5: 358; IS________NPM-NEXT: ret void 359; 360 %2 = tail call noalias i8* @malloc(i64 4) 361 %3 = icmp eq i32 %0, 0 362 br i1 %3, label %5, label %4 363 3644: ; preds = %1 365 tail call void @nofree_func(i8* %2) 366 tail call void @free(i8* %2) 367 br label %6 368 3695: ; preds = %1 370 tail call void @free(i8* %2) 371 br label %6 372 3736: ; preds = %5, %4 374 ret void 375} 376 377; TEST 7 - free is dead. 378 379define void @test7() { 380; IS________OPM-LABEL: define {{[^@]+}}@test7() { 381; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) 382; IS________OPM-NEXT: [[TMP2:%.*]] = tail call i32 @no_return_call() #[[ATTR4:[0-9]+]] 383; IS________OPM-NEXT: unreachable 384; 385; IS________NPM-LABEL: define {{[^@]+}}@test7() { 386; IS________NPM-NEXT: [[DOTH2S:%.*]] = alloca i8, i64 4, align 1 387; IS________NPM-NEXT: [[TMP1:%.*]] = tail call i32 @no_return_call() #[[ATTR4:[0-9]+]] 388; IS________NPM-NEXT: unreachable 389; 390 %1 = tail call noalias i8* @malloc(i64 4) 391 tail call i32 @no_return_call() 392 tail call void @free(i8* %1) 393 ret void 394} 395 396; TEST 8 - Negative: bitcast pointer used in capture function 397 398define void @test8() { 399; CHECK-LABEL: define {{[^@]+}}@test8() { 400; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) 401; CHECK-NEXT: tail call void @no_sync_func(i8* nocapture nofree [[TMP1]]) 402; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* 403; CHECK-NEXT: store i32 10, i32* [[TMP2]], align 4 404; CHECK-NEXT: tail call void @foo(i32* noundef align 4 [[TMP2]]) 405; CHECK-NEXT: tail call void @free(i8* nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]]) 406; CHECK-NEXT: ret void 407; 408 %1 = tail call noalias i8* @malloc(i64 4) 409 tail call void @no_sync_func(i8* %1) 410 %2 = bitcast i8* %1 to i32* 411 store i32 10, i32* %2 412 %3 = load i32, i32* %2 413 tail call void @foo(i32* %2) 414 tail call void @free(i8* %1) 415 ret void 416} 417 418; TEST 9 - FIXME: malloc should be converted. 419define void @test9() { 420; IS________OPM-LABEL: define {{[^@]+}}@test9() { 421; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) 422; IS________OPM-NEXT: tail call void @no_sync_func(i8* nocapture nofree [[TMP1]]) 423; IS________OPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* 424; IS________OPM-NEXT: store i32 10, i32* [[TMP2]], align 4 425; IS________OPM-NEXT: tail call void @foo_nounw(i32* nofree noundef align 4 [[TMP2]]) #[[ATTR9]] 426; IS________OPM-NEXT: tail call void @free(i8* nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]]) 427; IS________OPM-NEXT: ret void 428; 429; IS________NPM-LABEL: define {{[^@]+}}@test9() { 430; IS________NPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) 431; IS________NPM-NEXT: tail call void @no_sync_func(i8* nocapture nofree [[TMP1]]) 432; IS________NPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* 433; IS________NPM-NEXT: store i32 10, i32* [[TMP2]], align 4 434; IS________NPM-NEXT: tail call void @foo_nounw(i32* nofree noundef align 4 [[TMP2]]) #[[ATTR10]] 435; IS________NPM-NEXT: tail call void @free(i8* nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]]) 436; IS________NPM-NEXT: ret void 437; 438 %1 = tail call noalias i8* @malloc(i64 4) 439 tail call void @no_sync_func(i8* %1) 440 %2 = bitcast i8* %1 to i32* 441 store i32 10, i32* %2 442 %3 = load i32, i32* %2 443 tail call void @foo_nounw(i32* %2) 444 tail call void @free(i8* %1) 445 ret void 446} 447 448; TEST 10 - 1 malloc, 1 free 449 450define i32 @test10() { 451; IS________OPM-LABEL: define {{[^@]+}}@test10() { 452; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) 453; IS________OPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]]) 454; IS________OPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* 455; IS________OPM-NEXT: store i32 10, i32* [[TMP2]], align 4 456; IS________OPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 457; IS________OPM-NEXT: tail call void @free(i8* noalias nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]]) 458; IS________OPM-NEXT: ret i32 [[TMP3]] 459; 460; IS________NPM-LABEL: define {{[^@]+}}@test10() { 461; IS________NPM-NEXT: [[DOTH2S:%.*]] = alloca i8, i64 4, align 1 462; IS________NPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[DOTH2S]]) 463; IS________NPM-NEXT: [[TMP1:%.*]] = bitcast i8* [[DOTH2S]] to i32* 464; IS________NPM-NEXT: store i32 10, i32* [[TMP1]], align 4 465; IS________NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[TMP1]], align 4 466; IS________NPM-NEXT: ret i32 [[TMP2]] 467; 468 %1 = tail call noalias i8* @malloc(i64 4) 469 tail call void @no_sync_func(i8* %1) 470 %2 = bitcast i8* %1 to i32* 471 store i32 10, i32* %2 472 %3 = load i32, i32* %2 473 tail call void @free(i8* %1) 474 ret i32 %3 475} 476 477define i32 @test_lifetime() { 478; IS________OPM-LABEL: define {{[^@]+}}@test_lifetime() { 479; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) 480; IS________OPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]]) 481; IS________OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP1]]) 482; IS________OPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* 483; IS________OPM-NEXT: store i32 10, i32* [[TMP2]], align 4 484; IS________OPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 485; IS________OPM-NEXT: tail call void @free(i8* noalias nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]]) 486; IS________OPM-NEXT: ret i32 [[TMP3]] 487; 488; IS________NPM-LABEL: define {{[^@]+}}@test_lifetime() { 489; IS________NPM-NEXT: [[DOTH2S:%.*]] = alloca i8, i64 4, align 1 490; IS________NPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[DOTH2S]]) 491; IS________NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[DOTH2S]]) 492; IS________NPM-NEXT: [[TMP1:%.*]] = bitcast i8* [[DOTH2S]] to i32* 493; IS________NPM-NEXT: store i32 10, i32* [[TMP1]], align 4 494; IS________NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[TMP1]], align 4 495; IS________NPM-NEXT: ret i32 [[TMP2]] 496; 497 %1 = tail call noalias i8* @malloc(i64 4) 498 tail call void @no_sync_func(i8* %1) 499 call void @llvm.lifetime.start.p0i8(i64 4, i8* %1) 500 %2 = bitcast i8* %1 to i32* 501 store i32 10, i32* %2 502 %3 = load i32, i32* %2 503 tail call void @free(i8* %1) 504 ret i32 %3 505} 506 507; TEST 11 508 509define void @test11() { 510; IS________OPM-LABEL: define {{[^@]+}}@test11() { 511; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) 512; IS________OPM-NEXT: tail call void @sync_will_return(i8* [[TMP1]]) #[[ATTR9]] 513; IS________OPM-NEXT: tail call void @free(i8* nocapture [[TMP1]]) 514; IS________OPM-NEXT: ret void 515; 516; IS________NPM-LABEL: define {{[^@]+}}@test11() { 517; IS________NPM-NEXT: [[DOTH2S:%.*]] = alloca i8, i64 4, align 1 518; IS________NPM-NEXT: tail call void @sync_will_return(i8* [[DOTH2S]]) #[[ATTR10]] 519; IS________NPM-NEXT: ret void 520; 521 %1 = tail call noalias i8* @malloc(i64 4) 522 tail call void @sync_will_return(i8* %1) 523 tail call void @free(i8* %1) 524 ret void 525} 526 527; TEST 12 528define i32 @irreducible_cfg(i32 %0) { 529; IS________OPM-LABEL: define {{[^@]+}}@irreducible_cfg 530; IS________OPM-SAME: (i32 [[TMP0:%.*]]) { 531; IS________OPM-NEXT: [[TMP2:%.*]] = call noalias i8* @malloc(i64 noundef 4) 532; IS________OPM-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to i32* 533; IS________OPM-NEXT: store i32 10, i32* [[TMP3]], align 4 534; IS________OPM-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP0]], 1 535; IS________OPM-NEXT: br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP7:%.*]] 536; IS________OPM: 5: 537; IS________OPM-NEXT: [[TMP6:%.*]] = add nsw i32 [[TMP0]], 5 538; IS________OPM-NEXT: br label [[TMP13:%.*]] 539; IS________OPM: 7: 540; IS________OPM-NEXT: br label [[TMP8:%.*]] 541; IS________OPM: 8: 542; IS________OPM-NEXT: [[DOT0:%.*]] = phi i32 [ [[TMP14:%.*]], [[TMP13]] ], [ 1, [[TMP7]] ] 543; IS________OPM-NEXT: [[TMP9:%.*]] = load i32, i32* [[TMP3]], align 4 544; IS________OPM-NEXT: [[TMP10:%.*]] = add nsw i32 [[TMP9]], -1 545; IS________OPM-NEXT: store i32 [[TMP10]], i32* [[TMP3]], align 4 546; IS________OPM-NEXT: [[TMP11:%.*]] = icmp ne i32 [[TMP9]], 0 547; IS________OPM-NEXT: br i1 [[TMP11]], label [[TMP12:%.*]], label [[TMP15:%.*]] 548; IS________OPM: 12: 549; IS________OPM-NEXT: br label [[TMP13]] 550; IS________OPM: 13: 551; IS________OPM-NEXT: [[DOT1:%.*]] = phi i32 [ [[TMP6]], [[TMP5]] ], [ [[DOT0]], [[TMP12]] ] 552; IS________OPM-NEXT: [[TMP14]] = add nsw i32 [[DOT1]], 1 553; IS________OPM-NEXT: br label [[TMP8]] 554; IS________OPM: 15: 555; IS________OPM-NEXT: [[TMP16:%.*]] = bitcast i32* [[TMP3]] to i8* 556; IS________OPM-NEXT: call void @free(i8* nocapture noundef [[TMP16]]) 557; IS________OPM-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP3]], align 4 558; IS________OPM-NEXT: ret i32 [[TMP17]] 559; 560; IS________NPM-LABEL: define {{[^@]+}}@irreducible_cfg 561; IS________NPM-SAME: (i32 [[TMP0:%.*]]) { 562; IS________NPM-NEXT: [[DOTH2S:%.*]] = alloca i8, i64 4, align 1 563; IS________NPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[DOTH2S]] to i32* 564; IS________NPM-NEXT: store i32 10, i32* [[TMP2]], align 4 565; IS________NPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 1 566; IS________NPM-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP6:%.*]] 567; IS________NPM: 4: 568; IS________NPM-NEXT: [[TMP5:%.*]] = add nsw i32 [[TMP0]], 5 569; IS________NPM-NEXT: br label [[TMP12:%.*]] 570; IS________NPM: 6: 571; IS________NPM-NEXT: br label [[TMP7:%.*]] 572; IS________NPM: 7: 573; IS________NPM-NEXT: [[DOT0:%.*]] = phi i32 [ [[TMP13:%.*]], [[TMP12]] ], [ 1, [[TMP6]] ] 574; IS________NPM-NEXT: [[TMP8:%.*]] = load i32, i32* [[TMP2]], align 4 575; IS________NPM-NEXT: [[TMP9:%.*]] = add nsw i32 [[TMP8]], -1 576; IS________NPM-NEXT: store i32 [[TMP9]], i32* [[TMP2]], align 4 577; IS________NPM-NEXT: [[TMP10:%.*]] = icmp ne i32 [[TMP8]], 0 578; IS________NPM-NEXT: br i1 [[TMP10]], label [[TMP11:%.*]], label [[TMP14:%.*]] 579; IS________NPM: 11: 580; IS________NPM-NEXT: br label [[TMP12]] 581; IS________NPM: 12: 582; IS________NPM-NEXT: [[DOT1:%.*]] = phi i32 [ [[TMP5]], [[TMP4]] ], [ [[DOT0]], [[TMP11]] ] 583; IS________NPM-NEXT: [[TMP13]] = add nsw i32 [[DOT1]], 1 584; IS________NPM-NEXT: br label [[TMP7]] 585; IS________NPM: 14: 586; IS________NPM-NEXT: [[TMP15:%.*]] = load i32, i32* [[TMP2]], align 4 587; IS________NPM-NEXT: ret i32 [[TMP15]] 588; 589 %2 = call noalias i8* @malloc(i64 4) 590 %3 = bitcast i8* %2 to i32* 591 store i32 10, i32* %3, align 4 592 %4 = icmp eq i32 %0, 1 593 br i1 %4, label %5, label %7 594 5955: ; preds = %1 596 %6 = add nsw i32 %0, 5 597 br label %13 598 5997: ; preds = %1 600 br label %8 601 6028: ; preds = %13, %7 603 %.0 = phi i32 [ %14, %13 ], [ 1, %7 ] 604 %9 = load i32, i32* %3, align 4 605 %10 = add nsw i32 %9, -1 606 store i32 %10, i32* %3, align 4 607 %11 = icmp ne i32 %9, 0 608 br i1 %11, label %12, label %15 609 61012: ; preds = %8 611 br label %13 612 61313: ; preds = %12, %5 614 %.1 = phi i32 [ %6, %5 ], [ %.0, %12 ] 615 %14 = add nsw i32 %.1, 1 616 br label %8 617 61815: ; preds = %8 619 %16 = load i32, i32* %3, align 4 620 %17 = bitcast i32* %3 to i8* 621 call void @free(i8* %17) 622 %18 = load i32, i32* %3, align 4 623 ret i32 %18 624} 625 626 627define i32 @malloc_in_loop(i32 %0) { 628; CHECK-LABEL: define {{[^@]+}}@malloc_in_loop 629; CHECK-SAME: (i32 [[TMP0:%.*]]) { 630; CHECK-NEXT: [[TMP2:%.*]] = alloca i32, align 4 631; CHECK-NEXT: [[TMP3:%.*]] = alloca i32*, align 8 632; CHECK-NEXT: store i32 [[TMP0]], i32* [[TMP2]], align 4 633; CHECK-NEXT: br label [[TMP4:%.*]] 634; CHECK: 4: 635; CHECK-NEXT: [[TMP5:%.*]] = load i32, i32* [[TMP2]], align 4 636; CHECK-NEXT: [[TMP6:%.*]] = add nsw i32 [[TMP5]], -1 637; CHECK-NEXT: store i32 [[TMP6]], i32* [[TMP2]], align 4 638; CHECK-NEXT: [[TMP7:%.*]] = icmp sgt i32 [[TMP6]], 0 639; CHECK-NEXT: br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP10:%.*]] 640; CHECK: 8: 641; CHECK-NEXT: [[DOTH2S:%.*]] = alloca i8, i64 4, align 1 642; CHECK-NEXT: [[TMP9:%.*]] = bitcast i8* [[DOTH2S]] to i32* 643; CHECK-NEXT: br label [[TMP4]] 644; CHECK: 10: 645; CHECK-NEXT: ret i32 5 646; 647 %2 = alloca i32, align 4 648 %3 = alloca i32*, align 8 649 store i32 %0, i32* %2, align 4 650 br label %4 651 6524: ; preds = %8, %1 653 %5 = load i32, i32* %2, align 4 654 %6 = add nsw i32 %5, -1 655 store i32 %6, i32* %2, align 4 656 %7 = icmp sgt i32 %6, 0 657 br i1 %7, label %8, label %11 658 6598: ; preds = %4 660 %9 = call noalias i8* @malloc(i64 4) 661 %10 = bitcast i8* %9 to i32* 662 store i32 1, i32* %10, align 8 663 br label %4 664 66511: ; preds = %4 666 ret i32 5 667} 668 669; Malloc/Calloc too large 670define i32 @test13() { 671; CHECK-LABEL: define {{[^@]+}}@test13() { 672; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 256) 673; CHECK-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]]) 674; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* 675; CHECK-NEXT: store i32 10, i32* [[TMP2]], align 4 676; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 677; CHECK-NEXT: tail call void @free(i8* noalias nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]]) 678; CHECK-NEXT: ret i32 [[TMP3]] 679; 680 %1 = tail call noalias i8* @malloc(i64 256) 681 tail call void @no_sync_func(i8* %1) 682 %2 = bitcast i8* %1 to i32* 683 store i32 10, i32* %2 684 %3 = load i32, i32* %2 685 tail call void @free(i8* %1) 686 ret i32 %3 687} 688 689define i32 @test_sle() { 690; CHECK-LABEL: define {{[^@]+}}@test_sle() { 691; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef -1) 692; CHECK-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]]) 693; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* 694; CHECK-NEXT: store i32 10, i32* [[TMP2]], align 4 695; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 696; CHECK-NEXT: tail call void @free(i8* noalias nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]]) 697; CHECK-NEXT: ret i32 [[TMP3]] 698; 699 %1 = tail call noalias i8* @malloc(i64 -1) 700 tail call void @no_sync_func(i8* %1) 701 %2 = bitcast i8* %1 to i32* 702 store i32 10, i32* %2 703 %3 = load i32, i32* %2 704 tail call void @free(i8* %1) 705 ret i32 %3 706} 707 708define i32 @test_overflow() { 709; CHECK-LABEL: define {{[^@]+}}@test_overflow() { 710; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @calloc(i64 noundef 65537, i64 noundef 65537) 711; CHECK-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]]) 712; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* 713; CHECK-NEXT: store i32 10, i32* [[TMP2]], align 4 714; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 715; CHECK-NEXT: tail call void @free(i8* noalias nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]]) 716; CHECK-NEXT: ret i32 [[TMP3]] 717; 718 %1 = tail call noalias i8* @calloc(i64 65537, i64 65537) 719 tail call void @no_sync_func(i8* %1) 720 %2 = bitcast i8* %1 to i32* 721 store i32 10, i32* %2 722 %3 = load i32, i32* %2 723 tail call void @free(i8* %1) 724 ret i32 %3 725} 726 727define void @test14() { 728; CHECK-LABEL: define {{[^@]+}}@test14() { 729; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @calloc(i64 noundef 64, i64 noundef 4) 730; CHECK-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]]) 731; CHECK-NEXT: tail call void @free(i8* noalias nocapture [[TMP1]]) 732; CHECK-NEXT: ret void 733; 734 %1 = tail call noalias i8* @calloc(i64 64, i64 4) 735 tail call void @no_sync_func(i8* %1) 736 tail call void @free(i8* %1) 737 ret void 738} 739 740define void @test15(i64 %S) { 741; CHECK-LABEL: define {{[^@]+}}@test15 742; CHECK-SAME: (i64 [[S:%.*]]) { 743; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 [[S]]) 744; CHECK-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]]) 745; CHECK-NEXT: tail call void @free(i8* noalias nocapture [[TMP1]]) 746; CHECK-NEXT: ret void 747; 748 %1 = tail call noalias i8* @malloc(i64 %S) 749 tail call void @no_sync_func(i8* %1) 750 tail call void @free(i8* %1) 751 ret void 752} 753 754define void @test16a(i8 %v, i8** %P) { 755; IS________OPM-LABEL: define {{[^@]+}}@test16a 756; IS________OPM-SAME: (i8 [[V:%.*]], i8** nocapture nofree readnone [[P:%.*]]) { 757; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) 758; IS________OPM-NEXT: store i8 [[V]], i8* [[TMP1]], align 1 759; IS________OPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree noundef nonnull dereferenceable(1) [[TMP1]]) 760; IS________OPM-NEXT: tail call void @free(i8* noalias nocapture noundef nonnull dereferenceable(1) [[TMP1]]) 761; IS________OPM-NEXT: ret void 762; 763; IS________NPM-LABEL: define {{[^@]+}}@test16a 764; IS________NPM-SAME: (i8 [[V:%.*]], i8** nocapture nofree readnone [[P:%.*]]) { 765; IS________NPM-NEXT: [[DOTH2S:%.*]] = alloca i8, i64 4, align 1 766; IS________NPM-NEXT: store i8 [[V]], i8* [[DOTH2S]], align 1 767; IS________NPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree noundef nonnull dereferenceable(1) [[DOTH2S]]) 768; IS________NPM-NEXT: ret void 769; 770 %1 = tail call noalias i8* @malloc(i64 4) 771 store i8 %v, i8* %1 772 tail call void @no_sync_func(i8* %1) 773 tail call void @free(i8* nonnull dereferenceable(1) %1) 774 ret void 775} 776 777define void @test16b(i8 %v, i8** %P) { 778; CHECK-LABEL: define {{[^@]+}}@test16b 779; CHECK-SAME: (i8 [[V:%.*]], i8** nocapture nofree writeonly [[P:%.*]]) { 780; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) 781; CHECK-NEXT: store i8* [[TMP1]], i8** [[P]], align 8 782; CHECK-NEXT: tail call void @no_sync_func(i8* nocapture nofree [[TMP1]]) 783; CHECK-NEXT: tail call void @free(i8* nocapture [[TMP1]]) 784; CHECK-NEXT: ret void 785; 786 %1 = tail call noalias i8* @malloc(i64 4) 787 store i8* %1, i8** %P 788 tail call void @no_sync_func(i8* %1) 789 tail call void @free(i8* %1) 790 ret void 791} 792 793define void @test16c(i8 %v, i8** %P) { 794; IS________OPM-LABEL: define {{[^@]+}}@test16c 795; IS________OPM-SAME: (i8 [[V:%.*]], i8** nocapture nofree writeonly [[P:%.*]]) { 796; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) 797; IS________OPM-NEXT: store i8* [[TMP1]], i8** [[P]], align 8 798; IS________OPM-NEXT: tail call void @no_sync_func(i8* nocapture nofree [[TMP1]]) #[[ATTR9]] 799; IS________OPM-NEXT: tail call void @free(i8* nocapture [[TMP1]]) 800; IS________OPM-NEXT: ret void 801; 802; IS________NPM-LABEL: define {{[^@]+}}@test16c 803; IS________NPM-SAME: (i8 [[V:%.*]], i8** nocapture nofree writeonly [[P:%.*]]) { 804; IS________NPM-NEXT: [[DOTH2S:%.*]] = alloca i8, i64 4, align 1 805; IS________NPM-NEXT: store i8* [[DOTH2S]], i8** [[P]], align 8 806; IS________NPM-NEXT: tail call void @no_sync_func(i8* nocapture nofree [[DOTH2S]]) #[[ATTR10]] 807; IS________NPM-NEXT: ret void 808; 809 %1 = tail call noalias i8* @malloc(i64 4) 810 store i8* %1, i8** %P 811 tail call void @no_sync_func(i8* %1) nounwind 812 tail call void @free(i8* %1) 813 ret void 814} 815 816define void @test16d(i8 %v, i8** %P) { 817; CHECK-LABEL: define {{[^@]+}}@test16d 818; CHECK-SAME: (i8 [[V:%.*]], i8** nocapture nofree writeonly [[P:%.*]]) { 819; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) 820; CHECK-NEXT: store i8* [[TMP1]], i8** [[P]], align 8 821; CHECK-NEXT: ret void 822; 823 %1 = tail call noalias i8* @malloc(i64 4) 824 store i8* %1, i8** %P 825 ret void 826} 827;. 828; IS________OPM: attributes #[[ATTR0:[0-9]+]] = { allockind("alloc,uninitialized") allocsize(0) } 829; IS________OPM: attributes #[[ATTR1:[0-9]+]] = { nounwind willreturn } 830; IS________OPM: attributes #[[ATTR2:[0-9]+]] = { nofree nosync willreturn } 831; IS________OPM: attributes #[[ATTR3:[0-9]+]] = { nofree nounwind } 832; IS________OPM: attributes #[[ATTR4]] = { noreturn } 833; IS________OPM: attributes #[[ATTR5:[0-9]+]] = { allockind("free") } 834; IS________OPM: attributes #[[ATTR6:[0-9]+]] = { argmemonly nocallback nofree nosync nounwind willreturn } 835; IS________OPM: attributes #[[ATTR7:[0-9]+]] = { allockind("alloc,uninitialized,aligned") allocsize(1) } 836; IS________OPM: attributes #[[ATTR8:[0-9]+]] = { allockind("alloc,zeroed") allocsize(0,1) } 837; IS________OPM: attributes #[[ATTR9]] = { nounwind } 838;. 839; IS________NPM: attributes #[[ATTR0:[0-9]+]] = { allockind("alloc,uninitialized") allocsize(0) } 840; IS________NPM: attributes #[[ATTR1:[0-9]+]] = { nounwind willreturn } 841; IS________NPM: attributes #[[ATTR2:[0-9]+]] = { nofree nosync willreturn } 842; IS________NPM: attributes #[[ATTR3:[0-9]+]] = { nofree nounwind } 843; IS________NPM: attributes #[[ATTR4]] = { noreturn } 844; IS________NPM: attributes #[[ATTR5:[0-9]+]] = { allockind("free") } 845; IS________NPM: attributes #[[ATTR6:[0-9]+]] = { argmemonly nocallback nofree nosync nounwind willreturn } 846; IS________NPM: attributes #[[ATTR7:[0-9]+]] = { allockind("alloc,uninitialized,aligned") allocsize(1) } 847; IS________NPM: attributes #[[ATTR8:[0-9]+]] = { allockind("alloc,zeroed") allocsize(0,1) } 848; IS________NPM: attributes #[[ATTR9:[0-9]+]] = { argmemonly nocallback nofree nounwind willreturn writeonly } 849; IS________NPM: attributes #[[ATTR10]] = { nounwind } 850;. 851