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