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: [[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]]) #[[ATTR5:[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]]) #[[ATTR5]] 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]]) #[[ATTR6:[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]]) #[[ATTR6]] 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, i64) 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) 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; IS________OPM-LABEL: define {{[^@]+}}@test4() { 270; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) 271; IS________OPM-NEXT: tail call void @nofree_func(i8* noalias nocapture nofree [[TMP1]]) 272; IS________OPM-NEXT: ret void 273; 274; IS________NPM-LABEL: define {{[^@]+}}@test4() { 275; IS________NPM-NEXT: [[DOTH2S:%.*]] = alloca i8, i64 4, align 1 276; IS________NPM-NEXT: tail call void @nofree_func(i8* noalias nocapture nofree [[DOTH2S]]) 277; IS________NPM-NEXT: ret void 278; 279 %1 = tail call noalias i8* @malloc(i64 4) 280 tail call void @nofree_func(i8* %1) 281 ret void 282} 283 284; TEST 5 - not all exit paths have a call to free, but all uses of malloc 285; are in nofree functions and are not captured 286 287define void @test5(i32, i8* %p) { 288; IS________OPM-LABEL: define {{[^@]+}}@test5 289; IS________OPM-SAME: (i32 [[TMP0:%.*]], i8* nocapture [[P:%.*]]) { 290; IS________OPM-NEXT: [[TMP2:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) 291; IS________OPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0 292; IS________OPM-NEXT: br i1 [[TMP3]], label [[TMP5:%.*]], label [[TMP4:%.*]] 293; IS________OPM: 4: 294; IS________OPM-NEXT: tail call void @nofree_func(i8* noalias nocapture nofree [[TMP2]]) 295; IS________OPM-NEXT: br label [[TMP6:%.*]] 296; IS________OPM: 5: 297; IS________OPM-NEXT: tail call void @nofree_arg_only(i8* nocapture nofree [[TMP2]], i8* nocapture [[P]]) 298; IS________OPM-NEXT: tail call void @free(i8* noalias nocapture [[TMP2]]) 299; IS________OPM-NEXT: br label [[TMP6]] 300; IS________OPM: 6: 301; IS________OPM-NEXT: ret void 302; 303; IS________NPM-LABEL: define {{[^@]+}}@test5 304; IS________NPM-SAME: (i32 [[TMP0:%.*]], i8* nocapture [[P:%.*]]) { 305; IS________NPM-NEXT: [[DOTH2S:%.*]] = alloca i8, i64 4, align 1 306; IS________NPM-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP0]], 0 307; IS________NPM-NEXT: br i1 [[TMP2]], label [[TMP4:%.*]], label [[TMP3:%.*]] 308; IS________NPM: 3: 309; IS________NPM-NEXT: tail call void @nofree_func(i8* noalias nocapture nofree [[DOTH2S]]) 310; IS________NPM-NEXT: br label [[TMP5:%.*]] 311; IS________NPM: 4: 312; IS________NPM-NEXT: tail call void @nofree_arg_only(i8* noalias nocapture nofree [[DOTH2S]], i8* nocapture [[P]]) 313; IS________NPM-NEXT: br label [[TMP5]] 314; IS________NPM: 5: 315; IS________NPM-NEXT: ret void 316; 317 %2 = tail call noalias i8* @malloc(i64 4) 318 %3 = icmp eq i32 %0, 0 319 br i1 %3, label %5, label %4 320 3214: ; preds = %1 322 tail call void @nofree_func(i8* %2) 323 br label %6 324 3255: ; preds = %1 326 tail call void @nofree_arg_only(i8* %2, i8* %p) 327 tail call void @free(i8* %2) 328 br label %6 329 3306: ; preds = %5, %4 331 ret void 332} 333 334; TEST 6 - all exit paths have a call to free 335 336define void @test6(i32) { 337; IS________OPM-LABEL: define {{[^@]+}}@test6 338; IS________OPM-SAME: (i32 [[TMP0:%.*]]) { 339; IS________OPM-NEXT: [[TMP2:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) 340; IS________OPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0 341; IS________OPM-NEXT: br i1 [[TMP3]], label [[TMP5:%.*]], label [[TMP4:%.*]] 342; IS________OPM: 4: 343; IS________OPM-NEXT: tail call void @nofree_func(i8* noalias nocapture nofree [[TMP2]]) 344; IS________OPM-NEXT: tail call void @free(i8* noalias nocapture [[TMP2]]) 345; IS________OPM-NEXT: br label [[TMP6:%.*]] 346; IS________OPM: 5: 347; IS________OPM-NEXT: tail call void @free(i8* noalias nocapture [[TMP2]]) 348; IS________OPM-NEXT: br label [[TMP6]] 349; IS________OPM: 6: 350; IS________OPM-NEXT: ret void 351; 352; IS________NPM-LABEL: define {{[^@]+}}@test6 353; IS________NPM-SAME: (i32 [[TMP0:%.*]]) { 354; IS________NPM-NEXT: [[DOTH2S:%.*]] = alloca i8, i64 4, align 1 355; IS________NPM-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP0]], 0 356; IS________NPM-NEXT: br i1 [[TMP2]], label [[TMP4:%.*]], label [[TMP3:%.*]] 357; IS________NPM: 3: 358; IS________NPM-NEXT: tail call void @nofree_func(i8* noalias nocapture nofree [[DOTH2S]]) 359; IS________NPM-NEXT: br label [[TMP5:%.*]] 360; IS________NPM: 4: 361; IS________NPM-NEXT: br label [[TMP5]] 362; IS________NPM: 5: 363; IS________NPM-NEXT: ret void 364; 365 %2 = tail call noalias i8* @malloc(i64 4) 366 %3 = icmp eq i32 %0, 0 367 br i1 %3, label %5, label %4 368 3694: ; preds = %1 370 tail call void @nofree_func(i8* %2) 371 tail call void @free(i8* %2) 372 br label %6 373 3745: ; preds = %1 375 tail call void @free(i8* %2) 376 br label %6 377 3786: ; preds = %5, %4 379 ret void 380} 381 382; TEST 7 - free is dead. 383 384define void @test7() { 385; IS________OPM-LABEL: define {{[^@]+}}@test7() { 386; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) 387; IS________OPM-NEXT: [[TMP2:%.*]] = tail call i32 @no_return_call() #[[ATTR3:[0-9]+]] 388; IS________OPM-NEXT: unreachable 389; 390; IS________NPM-LABEL: define {{[^@]+}}@test7() { 391; IS________NPM-NEXT: [[DOTH2S:%.*]] = alloca i8, i64 4, align 1 392; IS________NPM-NEXT: [[TMP1:%.*]] = tail call i32 @no_return_call() #[[ATTR3:[0-9]+]] 393; IS________NPM-NEXT: unreachable 394; 395 %1 = tail call noalias i8* @malloc(i64 4) 396 tail call i32 @no_return_call() 397 tail call void @free(i8* %1) 398 ret void 399} 400 401; TEST 8 - Negative: bitcast pointer used in capture function 402 403define void @test8() { 404; CHECK-LABEL: define {{[^@]+}}@test8() { 405; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) 406; CHECK-NEXT: tail call void @no_sync_func(i8* nocapture nofree [[TMP1]]) 407; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* 408; CHECK-NEXT: store i32 10, i32* [[TMP2]], align 4 409; CHECK-NEXT: tail call void @foo(i32* noundef align 4 [[TMP2]]) 410; CHECK-NEXT: tail call void @free(i8* nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]]) 411; CHECK-NEXT: ret void 412; 413 %1 = tail call noalias i8* @malloc(i64 4) 414 tail call void @no_sync_func(i8* %1) 415 %2 = bitcast i8* %1 to i32* 416 store i32 10, i32* %2 417 %3 = load i32, i32* %2 418 tail call void @foo(i32* %2) 419 tail call void @free(i8* %1) 420 ret void 421} 422 423; TEST 9 - FIXME: malloc should be converted. 424define void @test9() { 425; IS________OPM-LABEL: define {{[^@]+}}@test9() { 426; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) 427; IS________OPM-NEXT: tail call void @no_sync_func(i8* nocapture nofree [[TMP1]]) 428; IS________OPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* 429; IS________OPM-NEXT: store i32 10, i32* [[TMP2]], align 4 430; IS________OPM-NEXT: tail call void @foo_nounw(i32* nofree noundef align 4 [[TMP2]]) #[[ATTR5]] 431; IS________OPM-NEXT: tail call void @free(i8* nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]]) 432; IS________OPM-NEXT: ret void 433; 434; IS________NPM-LABEL: define {{[^@]+}}@test9() { 435; IS________NPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) 436; IS________NPM-NEXT: tail call void @no_sync_func(i8* nocapture nofree [[TMP1]]) 437; IS________NPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* 438; IS________NPM-NEXT: store i32 10, i32* [[TMP2]], align 4 439; IS________NPM-NEXT: tail call void @foo_nounw(i32* nofree noundef align 4 [[TMP2]]) #[[ATTR6]] 440; IS________NPM-NEXT: tail call void @free(i8* nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]]) 441; IS________NPM-NEXT: ret void 442; 443 %1 = tail call noalias i8* @malloc(i64 4) 444 tail call void @no_sync_func(i8* %1) 445 %2 = bitcast i8* %1 to i32* 446 store i32 10, i32* %2 447 %3 = load i32, i32* %2 448 tail call void @foo_nounw(i32* %2) 449 tail call void @free(i8* %1) 450 ret void 451} 452 453; TEST 10 - 1 malloc, 1 free 454 455define i32 @test10() { 456; IS________OPM-LABEL: define {{[^@]+}}@test10() { 457; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) 458; IS________OPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]]) 459; IS________OPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* 460; IS________OPM-NEXT: store i32 10, i32* [[TMP2]], align 4 461; IS________OPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 462; IS________OPM-NEXT: tail call void @free(i8* noalias nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]]) 463; IS________OPM-NEXT: ret i32 [[TMP3]] 464; 465; IS________NPM-LABEL: define {{[^@]+}}@test10() { 466; IS________NPM-NEXT: [[DOTH2S:%.*]] = alloca i8, i64 4, align 1 467; IS________NPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[DOTH2S]]) 468; IS________NPM-NEXT: [[TMP1:%.*]] = bitcast i8* [[DOTH2S]] to i32* 469; IS________NPM-NEXT: store i32 10, i32* [[TMP1]], align 4 470; IS________NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[TMP1]], align 4 471; IS________NPM-NEXT: ret i32 [[TMP2]] 472; 473 %1 = tail call noalias i8* @malloc(i64 4) 474 tail call void @no_sync_func(i8* %1) 475 %2 = bitcast i8* %1 to i32* 476 store i32 10, i32* %2 477 %3 = load i32, i32* %2 478 tail call void @free(i8* %1) 479 ret i32 %3 480} 481 482define i32 @test_lifetime() { 483; IS________OPM-LABEL: define {{[^@]+}}@test_lifetime() { 484; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) 485; IS________OPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]]) 486; IS________OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP1]]) 487; IS________OPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* 488; IS________OPM-NEXT: store i32 10, i32* [[TMP2]], align 4 489; IS________OPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 490; IS________OPM-NEXT: tail call void @free(i8* noalias nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]]) 491; IS________OPM-NEXT: ret i32 [[TMP3]] 492; 493; IS________NPM-LABEL: define {{[^@]+}}@test_lifetime() { 494; IS________NPM-NEXT: [[DOTH2S:%.*]] = alloca i8, i64 4, align 1 495; IS________NPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[DOTH2S]]) 496; IS________NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[DOTH2S]]) 497; IS________NPM-NEXT: [[TMP1:%.*]] = bitcast i8* [[DOTH2S]] to i32* 498; IS________NPM-NEXT: store i32 10, i32* [[TMP1]], align 4 499; IS________NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[TMP1]], align 4 500; IS________NPM-NEXT: ret i32 [[TMP2]] 501; 502 %1 = tail call noalias i8* @malloc(i64 4) 503 tail call void @no_sync_func(i8* %1) 504 call void @llvm.lifetime.start.p0i8(i64 4, i8* %1) 505 %2 = bitcast i8* %1 to i32* 506 store i32 10, i32* %2 507 %3 = load i32, i32* %2 508 tail call void @free(i8* %1) 509 ret i32 %3 510} 511 512; TEST 11 513 514define void @test11() { 515; IS________OPM-LABEL: define {{[^@]+}}@test11() { 516; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) 517; IS________OPM-NEXT: tail call void @sync_will_return(i8* [[TMP1]]) #[[ATTR5]] 518; IS________OPM-NEXT: tail call void @free(i8* nocapture [[TMP1]]) 519; IS________OPM-NEXT: ret void 520; 521; IS________NPM-LABEL: define {{[^@]+}}@test11() { 522; IS________NPM-NEXT: [[DOTH2S:%.*]] = alloca i8, i64 4, align 1 523; IS________NPM-NEXT: tail call void @sync_will_return(i8* [[DOTH2S]]) #[[ATTR6]] 524; IS________NPM-NEXT: ret void 525; 526 %1 = tail call noalias i8* @malloc(i64 4) 527 tail call void @sync_will_return(i8* %1) 528 tail call void @free(i8* %1) 529 ret void 530} 531 532; TEST 12 533define i32 @irreducible_cfg(i32 %0) { 534; IS________OPM-LABEL: define {{[^@]+}}@irreducible_cfg 535; IS________OPM-SAME: (i32 [[TMP0:%.*]]) { 536; IS________OPM-NEXT: [[TMP2:%.*]] = call noalias i8* @malloc(i64 noundef 4) 537; IS________OPM-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to i32* 538; IS________OPM-NEXT: store i32 10, i32* [[TMP3]], align 4 539; IS________OPM-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP0]], 1 540; IS________OPM-NEXT: br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP7:%.*]] 541; IS________OPM: 5: 542; IS________OPM-NEXT: [[TMP6:%.*]] = add nsw i32 [[TMP0]], 5 543; IS________OPM-NEXT: br label [[TMP13:%.*]] 544; IS________OPM: 7: 545; IS________OPM-NEXT: br label [[TMP8:%.*]] 546; IS________OPM: 8: 547; IS________OPM-NEXT: [[DOT0:%.*]] = phi i32 [ [[TMP14:%.*]], [[TMP13]] ], [ 1, [[TMP7]] ] 548; IS________OPM-NEXT: [[TMP9:%.*]] = load i32, i32* [[TMP3]], align 4 549; IS________OPM-NEXT: [[TMP10:%.*]] = add nsw i32 [[TMP9]], -1 550; IS________OPM-NEXT: store i32 [[TMP10]], i32* [[TMP3]], align 4 551; IS________OPM-NEXT: [[TMP11:%.*]] = icmp ne i32 [[TMP9]], 0 552; IS________OPM-NEXT: br i1 [[TMP11]], label [[TMP12:%.*]], label [[TMP15:%.*]] 553; IS________OPM: 12: 554; IS________OPM-NEXT: br label [[TMP13]] 555; IS________OPM: 13: 556; IS________OPM-NEXT: [[DOT1:%.*]] = phi i32 [ [[TMP6]], [[TMP5]] ], [ [[DOT0]], [[TMP12]] ] 557; IS________OPM-NEXT: [[TMP14]] = add nsw i32 [[DOT1]], 1 558; IS________OPM-NEXT: br label [[TMP8]] 559; IS________OPM: 15: 560; IS________OPM-NEXT: [[TMP16:%.*]] = load i32, i32* [[TMP3]], align 4 561; IS________OPM-NEXT: [[TMP17:%.*]] = bitcast i32* [[TMP3]] to i8* 562; IS________OPM-NEXT: call void @free(i8* nocapture noundef [[TMP17]]) 563; IS________OPM-NEXT: [[TMP18:%.*]] = load i32, i32* [[TMP3]], align 4 564; IS________OPM-NEXT: ret i32 [[TMP18]] 565; 566; IS________NPM-LABEL: define {{[^@]+}}@irreducible_cfg 567; IS________NPM-SAME: (i32 [[TMP0:%.*]]) { 568; IS________NPM-NEXT: [[DOTH2S:%.*]] = alloca i8, i64 4, align 1 569; IS________NPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[DOTH2S]] to i32* 570; IS________NPM-NEXT: store i32 10, i32* [[TMP2]], align 4 571; IS________NPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 1 572; IS________NPM-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP6:%.*]] 573; IS________NPM: 4: 574; IS________NPM-NEXT: [[TMP5:%.*]] = add nsw i32 [[TMP0]], 5 575; IS________NPM-NEXT: br label [[TMP12:%.*]] 576; IS________NPM: 6: 577; IS________NPM-NEXT: br label [[TMP7:%.*]] 578; IS________NPM: 7: 579; IS________NPM-NEXT: [[DOT0:%.*]] = phi i32 [ [[TMP13:%.*]], [[TMP12]] ], [ 1, [[TMP6]] ] 580; IS________NPM-NEXT: [[TMP8:%.*]] = load i32, i32* [[TMP2]], align 4 581; IS________NPM-NEXT: [[TMP9:%.*]] = add nsw i32 [[TMP8]], -1 582; IS________NPM-NEXT: store i32 [[TMP9]], i32* [[TMP2]], align 4 583; IS________NPM-NEXT: [[TMP10:%.*]] = icmp ne i32 [[TMP8]], 0 584; IS________NPM-NEXT: br i1 [[TMP10]], label [[TMP11:%.*]], label [[TMP14:%.*]] 585; IS________NPM: 11: 586; IS________NPM-NEXT: br label [[TMP12]] 587; IS________NPM: 12: 588; IS________NPM-NEXT: [[DOT1:%.*]] = phi i32 [ [[TMP5]], [[TMP4]] ], [ [[DOT0]], [[TMP11]] ] 589; IS________NPM-NEXT: [[TMP13]] = add nsw i32 [[DOT1]], 1 590; IS________NPM-NEXT: br label [[TMP7]] 591; IS________NPM: 14: 592; IS________NPM-NEXT: [[TMP15:%.*]] = load i32, i32* [[TMP2]], align 4 593; IS________NPM-NEXT: ret i32 [[TMP15]] 594; 595 %2 = call noalias i8* @malloc(i64 4) 596 %3 = bitcast i8* %2 to i32* 597 store i32 10, i32* %3, align 4 598 %4 = icmp eq i32 %0, 1 599 br i1 %4, label %5, label %7 600 6015: ; preds = %1 602 %6 = add nsw i32 %0, 5 603 br label %13 604 6057: ; preds = %1 606 br label %8 607 6088: ; preds = %13, %7 609 %.0 = phi i32 [ %14, %13 ], [ 1, %7 ] 610 %9 = load i32, i32* %3, align 4 611 %10 = add nsw i32 %9, -1 612 store i32 %10, i32* %3, align 4 613 %11 = icmp ne i32 %9, 0 614 br i1 %11, label %12, label %15 615 61612: ; preds = %8 617 br label %13 618 61913: ; preds = %12, %5 620 %.1 = phi i32 [ %6, %5 ], [ %.0, %12 ] 621 %14 = add nsw i32 %.1, 1 622 br label %8 623 62415: ; preds = %8 625 %16 = load i32, i32* %3, align 4 626 %17 = bitcast i32* %3 to i8* 627 call void @free(i8* %17) 628 %18 = load i32, i32* %3, align 4 629 ret i32 %18 630} 631 632 633define i32 @malloc_in_loop(i32 %0) { 634; IS________OPM-LABEL: define {{[^@]+}}@malloc_in_loop 635; IS________OPM-SAME: (i32 [[TMP0:%.*]]) { 636; IS________OPM-NEXT: [[TMP2:%.*]] = alloca i32, align 4 637; IS________OPM-NEXT: [[TMP3:%.*]] = alloca i32*, align 8 638; IS________OPM-NEXT: store i32 [[TMP0]], i32* [[TMP2]], align 4 639; IS________OPM-NEXT: br label [[TMP4:%.*]] 640; IS________OPM: 4: 641; IS________OPM-NEXT: [[TMP5:%.*]] = load i32, i32* [[TMP2]], align 4 642; IS________OPM-NEXT: [[TMP6:%.*]] = add nsw i32 [[TMP5]], -1 643; IS________OPM-NEXT: store i32 [[TMP6]], i32* [[TMP2]], align 4 644; IS________OPM-NEXT: [[TMP7:%.*]] = icmp sgt i32 [[TMP6]], 0 645; IS________OPM-NEXT: br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP11:%.*]] 646; IS________OPM: 8: 647; IS________OPM-NEXT: [[TMP9:%.*]] = call noalias i8* @malloc(i64 noundef 4) 648; IS________OPM-NEXT: [[TMP10:%.*]] = bitcast i8* [[TMP9]] to i32* 649; IS________OPM-NEXT: br label [[TMP4]] 650; IS________OPM: 11: 651; IS________OPM-NEXT: ret i32 5 652; 653; IS________NPM-LABEL: define {{[^@]+}}@malloc_in_loop 654; IS________NPM-SAME: (i32 [[TMP0:%.*]]) { 655; IS________NPM-NEXT: [[TMP2:%.*]] = alloca i32, align 4 656; IS________NPM-NEXT: [[TMP3:%.*]] = alloca i32*, align 8 657; IS________NPM-NEXT: store i32 [[TMP0]], i32* [[TMP2]], align 4 658; IS________NPM-NEXT: br label [[TMP4:%.*]] 659; IS________NPM: 4: 660; IS________NPM-NEXT: [[TMP5:%.*]] = load i32, i32* [[TMP2]], align 4 661; IS________NPM-NEXT: [[TMP6:%.*]] = add nsw i32 [[TMP5]], -1 662; IS________NPM-NEXT: store i32 [[TMP6]], i32* [[TMP2]], align 4 663; IS________NPM-NEXT: [[TMP7:%.*]] = icmp sgt i32 [[TMP6]], 0 664; IS________NPM-NEXT: br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP10:%.*]] 665; IS________NPM: 8: 666; IS________NPM-NEXT: [[DOTH2S:%.*]] = alloca i8, i64 4, align 1 667; IS________NPM-NEXT: [[TMP9:%.*]] = bitcast i8* [[DOTH2S]] to i32* 668; IS________NPM-NEXT: br label [[TMP4]] 669; IS________NPM: 10: 670; IS________NPM-NEXT: ret i32 5 671; 672 %2 = alloca i32, align 4 673 %3 = alloca i32*, align 8 674 store i32 %0, i32* %2, align 4 675 br label %4 676 6774: ; preds = %8, %1 678 %5 = load i32, i32* %2, align 4 679 %6 = add nsw i32 %5, -1 680 store i32 %6, i32* %2, align 4 681 %7 = icmp sgt i32 %6, 0 682 br i1 %7, label %8, label %11 683 6848: ; preds = %4 685 %9 = call noalias i8* @malloc(i64 4) 686 %10 = bitcast i8* %9 to i32* 687 store i32 1, i32* %10, align 8 688 br label %4 689 69011: ; preds = %4 691 ret i32 5 692} 693 694; Malloc/Calloc too large 695define i32 @test13() { 696; CHECK-LABEL: define {{[^@]+}}@test13() { 697; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 256) 698; CHECK-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]]) 699; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* 700; CHECK-NEXT: store i32 10, i32* [[TMP2]], align 4 701; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 702; CHECK-NEXT: tail call void @free(i8* noalias nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]]) 703; CHECK-NEXT: ret i32 [[TMP3]] 704; 705 %1 = tail call noalias i8* @malloc(i64 256) 706 tail call void @no_sync_func(i8* %1) 707 %2 = bitcast i8* %1 to i32* 708 store i32 10, i32* %2 709 %3 = load i32, i32* %2 710 tail call void @free(i8* %1) 711 ret i32 %3 712} 713 714define i32 @test_sle() { 715; CHECK-LABEL: define {{[^@]+}}@test_sle() { 716; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef -1) 717; CHECK-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]]) 718; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* 719; CHECK-NEXT: store i32 10, i32* [[TMP2]], align 4 720; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 721; CHECK-NEXT: tail call void @free(i8* noalias nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]]) 722; CHECK-NEXT: ret i32 [[TMP3]] 723; 724 %1 = tail call noalias i8* @malloc(i64 -1) 725 tail call void @no_sync_func(i8* %1) 726 %2 = bitcast i8* %1 to i32* 727 store i32 10, i32* %2 728 %3 = load i32, i32* %2 729 tail call void @free(i8* %1) 730 ret i32 %3 731} 732 733define i32 @test_overflow() { 734; CHECK-LABEL: define {{[^@]+}}@test_overflow() { 735; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @calloc(i64 noundef 65537, i64 noundef 65537) 736; CHECK-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]]) 737; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32* 738; CHECK-NEXT: store i32 10, i32* [[TMP2]], align 4 739; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 740; CHECK-NEXT: tail call void @free(i8* noalias nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]]) 741; CHECK-NEXT: ret i32 [[TMP3]] 742; 743 %1 = tail call noalias i8* @calloc(i64 65537, i64 65537) 744 tail call void @no_sync_func(i8* %1) 745 %2 = bitcast i8* %1 to i32* 746 store i32 10, i32* %2 747 %3 = load i32, i32* %2 748 tail call void @free(i8* %1) 749 ret i32 %3 750} 751 752define void @test14() { 753; CHECK-LABEL: define {{[^@]+}}@test14() { 754; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @calloc(i64 noundef 64, i64 noundef 4) 755; CHECK-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]]) 756; CHECK-NEXT: tail call void @free(i8* noalias nocapture [[TMP1]]) 757; CHECK-NEXT: ret void 758; 759 %1 = tail call noalias i8* @calloc(i64 64, i64 4) 760 tail call void @no_sync_func(i8* %1) 761 tail call void @free(i8* %1) 762 ret void 763} 764 765define void @test15(i64 %S) { 766; CHECK-LABEL: define {{[^@]+}}@test15 767; CHECK-SAME: (i64 [[S:%.*]]) { 768; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 [[S]]) 769; CHECK-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]]) 770; CHECK-NEXT: tail call void @free(i8* noalias nocapture [[TMP1]]) 771; CHECK-NEXT: ret void 772; 773 %1 = tail call noalias i8* @malloc(i64 %S) 774 tail call void @no_sync_func(i8* %1) 775 tail call void @free(i8* %1) 776 ret void 777} 778 779define void @test16a(i8 %v, i8** %P) { 780; IS________OPM-LABEL: define {{[^@]+}}@test16a 781; IS________OPM-SAME: (i8 [[V:%.*]], i8** nocapture nofree readnone [[P:%.*]]) { 782; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) 783; IS________OPM-NEXT: store i8 [[V]], i8* [[TMP1]], align 1 784; IS________OPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree noundef nonnull dereferenceable(1) [[TMP1]]) 785; IS________OPM-NEXT: tail call void @free(i8* noalias nocapture noundef nonnull dereferenceable(1) [[TMP1]]) 786; IS________OPM-NEXT: ret void 787; 788; IS________NPM-LABEL: define {{[^@]+}}@test16a 789; IS________NPM-SAME: (i8 [[V:%.*]], i8** nocapture nofree readnone [[P:%.*]]) { 790; IS________NPM-NEXT: [[DOTH2S:%.*]] = alloca i8, i64 4, align 1 791; IS________NPM-NEXT: store i8 [[V]], i8* [[DOTH2S]], align 1 792; IS________NPM-NEXT: tail call void @no_sync_func(i8* noalias nocapture nofree noundef nonnull dereferenceable(1) [[DOTH2S]]) 793; IS________NPM-NEXT: ret void 794; 795 %1 = tail call noalias i8* @malloc(i64 4) 796 store i8 %v, i8* %1 797 tail call void @no_sync_func(i8* %1) 798 tail call void @free(i8* nonnull dereferenceable(1) %1) 799 ret void 800} 801 802define void @test16b(i8 %v, i8** %P) { 803; CHECK-LABEL: define {{[^@]+}}@test16b 804; CHECK-SAME: (i8 [[V:%.*]], i8** nocapture nofree writeonly [[P:%.*]]) { 805; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) 806; CHECK-NEXT: store i8* [[TMP1]], i8** [[P]], align 8 807; CHECK-NEXT: tail call void @no_sync_func(i8* nocapture nofree [[TMP1]]) 808; CHECK-NEXT: tail call void @free(i8* nocapture [[TMP1]]) 809; CHECK-NEXT: ret void 810; 811 %1 = tail call noalias i8* @malloc(i64 4) 812 store i8* %1, i8** %P 813 tail call void @no_sync_func(i8* %1) 814 tail call void @free(i8* %1) 815 ret void 816} 817 818define void @test16c(i8 %v, i8** %P) { 819; IS________OPM-LABEL: define {{[^@]+}}@test16c 820; IS________OPM-SAME: (i8 [[V:%.*]], i8** nocapture nofree writeonly [[P:%.*]]) { 821; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) 822; IS________OPM-NEXT: store i8* [[TMP1]], i8** [[P]], align 8 823; IS________OPM-NEXT: tail call void @no_sync_func(i8* nocapture nofree [[TMP1]]) #[[ATTR5]] 824; IS________OPM-NEXT: tail call void @free(i8* nocapture [[TMP1]]) 825; IS________OPM-NEXT: ret void 826; 827; IS________NPM-LABEL: define {{[^@]+}}@test16c 828; IS________NPM-SAME: (i8 [[V:%.*]], i8** nocapture nofree writeonly [[P:%.*]]) { 829; IS________NPM-NEXT: [[DOTH2S:%.*]] = alloca i8, i64 4, align 1 830; IS________NPM-NEXT: store i8* [[DOTH2S]], i8** [[P]], align 8 831; IS________NPM-NEXT: tail call void @no_sync_func(i8* nocapture nofree [[DOTH2S]]) #[[ATTR6]] 832; IS________NPM-NEXT: ret void 833; 834 %1 = tail call noalias i8* @malloc(i64 4) 835 store i8* %1, i8** %P 836 tail call void @no_sync_func(i8* %1) nounwind 837 tail call void @free(i8* %1) 838 ret void 839} 840 841define void @test16d(i8 %v, i8** %P) { 842; CHECK-LABEL: define {{[^@]+}}@test16d 843; CHECK-SAME: (i8 [[V:%.*]], i8** nocapture nofree writeonly [[P:%.*]]) { 844; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4) 845; CHECK-NEXT: store i8* [[TMP1]], i8** [[P]], align 8 846; CHECK-NEXT: ret void 847; 848 %1 = tail call noalias i8* @malloc(i64 4) 849 store i8* %1, i8** %P 850 ret void 851} 852;. 853; IS________OPM: attributes #[[ATTR0:[0-9]+]] = { nounwind willreturn } 854; IS________OPM: attributes #[[ATTR1:[0-9]+]] = { nofree nosync willreturn } 855; IS________OPM: attributes #[[ATTR2:[0-9]+]] = { nofree nounwind } 856; IS________OPM: attributes #[[ATTR3]] = { noreturn } 857; IS________OPM: attributes #[[ATTR4:[0-9]+]] = { argmemonly nocallback nofree nosync nounwind willreturn } 858; IS________OPM: attributes #[[ATTR5]] = { nounwind } 859;. 860; IS________NPM: attributes #[[ATTR0:[0-9]+]] = { nounwind willreturn } 861; IS________NPM: attributes #[[ATTR1:[0-9]+]] = { nofree nosync willreturn } 862; IS________NPM: attributes #[[ATTR2:[0-9]+]] = { nofree nounwind } 863; IS________NPM: attributes #[[ATTR3]] = { noreturn } 864; IS________NPM: attributes #[[ATTR4:[0-9]+]] = { argmemonly nocallback nofree nosync nounwind willreturn } 865; IS________NPM: attributes #[[ATTR5:[0-9]+]] = { argmemonly nofree nounwind willreturn writeonly } 866; IS________NPM: attributes #[[ATTR6]] = { nounwind } 867;. 868