1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -basic-aa -dse -S | FileCheck %s 3 4target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64" 5 6declare void @use(i32 *) 7 8; Tests where the pointer/object is accessible after the function returns. 9 10define void @accessible_after_return_1(i32* noalias %P, i1 %c1) { 11; CHECK-LABEL: @accessible_after_return_1( 12; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] 13; CHECK: bb1: 14; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4 15; CHECK-NEXT: br label [[BB5:%.*]] 16; CHECK: bb2: 17; CHECK-NEXT: store i32 3, i32* [[P]], align 4 18; CHECK-NEXT: br label [[BB5]] 19; CHECK: bb5: 20; CHECK-NEXT: call void @use(i32* [[P]]) 21; CHECK-NEXT: ret void 22; 23 store i32 1, i32* %P 24 br i1 %c1, label %bb1, label %bb2 25 26bb1: 27 store i32 0, i32* %P 28 br label %bb5 29bb2: 30 store i32 3, i32* %P 31 br label %bb5 32 33bb5: 34 call void @use(i32* %P) 35 ret void 36} 37 38define void @accessible_after_return_2(i32* noalias %P, i1 %c.1, i1 %c.2) { 39; CHECK-LABEL: @accessible_after_return_2( 40; CHECK-NEXT: br i1 [[C_1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] 41; CHECK: bb1: 42; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4 43; CHECK-NEXT: br label [[BB5:%.*]] 44; CHECK: bb2: 45; CHECK-NEXT: br i1 [[C_2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]] 46; CHECK: bb3: 47; CHECK-NEXT: store i32 3, i32* [[P]], align 4 48; CHECK-NEXT: br label [[BB5]] 49; CHECK: bb4: 50; CHECK-NEXT: store i32 5, i32* [[P]], align 4 51; CHECK-NEXT: br label [[BB5]] 52; CHECK: bb5: 53; CHECK-NEXT: call void @use(i32* [[P]]) 54; CHECK-NEXT: ret void 55; 56 store i32 1, i32* %P 57 br i1 %c.1, label %bb1, label %bb2 58bb1: 59 store i32 0, i32* %P 60 br label %bb5 61 62bb2: 63 br i1 %c.2, label %bb3, label %bb4 64 65bb3: 66 store i32 3, i32* %P 67 br label %bb5 68 69bb4: 70 store i32 5, i32* %P 71 br label %bb5 72 73bb5: 74 call void @use(i32* %P) 75 ret void 76} 77 78; Cannot remove store in entry block because it is not overwritten on path 79; entry->bb2->bb5. 80define void @accessible_after_return_3(i32* noalias %P, i1 %c1) { 81; CHECK-LABEL: @accessible_after_return_3( 82; CHECK-NEXT: store i32 1, i32* [[P:%.*]], align 4 83; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] 84; CHECK: bb1: 85; CHECK-NEXT: store i32 0, i32* [[P]], align 4 86; CHECK-NEXT: br label [[BB5:%.*]] 87; CHECK: bb2: 88; CHECK-NEXT: br label [[BB5]] 89; CHECK: bb5: 90; CHECK-NEXT: call void @use(i32* [[P]]) 91; CHECK-NEXT: ret void 92; 93 store i32 1, i32* %P 94 br i1 %c1, label %bb1, label %bb2 95 96bb1: 97 store i32 0, i32* %P 98 br label %bb5 99 100bb2: 101 br label %bb5 102 103bb5: 104 call void @use(i32* %P) 105 ret void 106} 107 108; Cannot remove store in entry block because it is not overwritten on path 109; entry->bb2->bb5. 110define void @accessible_after_return_4(i32* noalias %P, i1 %c1) { 111; CHECK-LABEL: @accessible_after_return_4( 112; CHECK-NEXT: store i32 1, i32* [[P:%.*]], align 4 113; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] 114; CHECK: bb1: 115; CHECK-NEXT: store i32 0, i32* [[P]], align 4 116; CHECK-NEXT: call void @use(i32* [[P]]) 117; CHECK-NEXT: br label [[BB5:%.*]] 118; CHECK: bb2: 119; CHECK-NEXT: br label [[BB5]] 120; CHECK: bb5: 121; CHECK-NEXT: ret void 122; 123 store i32 1, i32* %P 124 br i1 %c1, label %bb1, label %bb2 125 126bb1: 127 store i32 0, i32* %P 128 call void @use(i32* %P) 129 br label %bb5 130 131bb2: 132 br label %bb5 133 134bb5: 135 ret void 136} 137 138; Cannot remove the store in entry, as it is not overwritten on all paths to an 139; exit (patch including bb4). 140define void @accessible_after_return5(i32* %P, i1 %c.1, i1 %c.2) { 141; CHECK-LABEL: @accessible_after_return5( 142; CHECK-NEXT: entry: 143; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4 144; CHECK-NEXT: br i1 [[C_1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] 145; CHECK: bb1: 146; CHECK-NEXT: br i1 [[C_2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]] 147; CHECK: bb2: 148; CHECK-NEXT: store i32 1, i32* [[P]], align 4 149; CHECK-NEXT: br label [[BB5:%.*]] 150; CHECK: bb3: 151; CHECK-NEXT: store i32 2, i32* [[P]], align 4 152; CHECK-NEXT: br label [[BB5]] 153; CHECK: bb4: 154; CHECK-NEXT: br label [[BB5]] 155; CHECK: bb5: 156; CHECK-NEXT: ret void 157; 158entry: 159 store i32 0, i32* %P 160 br i1 %c.1, label %bb1, label %bb2 161 162bb1: 163 br i1 %c.2, label %bb3, label %bb4 164 165bb2: 166 store i32 1, i32* %P 167 br label %bb5 168 169bb3: 170 store i32 2, i32* %P 171 br label %bb5 172 173bb4: 174 br label %bb5 175 176bb5: 177 ret void 178} 179 180; Can remove store in entry block, because it is overwritten before each return. 181define void @accessible_after_return6(i32* %P, i1 %c.1, i1 %c.2) { 182; CHECK-LABEL: @accessible_after_return6( 183; CHECK-NEXT: entry: 184; CHECK-NEXT: br i1 [[C_1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] 185; CHECK: bb1: 186; CHECK-NEXT: br i1 [[C_2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]] 187; CHECK: bb2: 188; CHECK-NEXT: store i32 1, i32* [[P:%.*]], align 4 189; CHECK-NEXT: ret void 190; CHECK: bb3: 191; CHECK-NEXT: store i32 2, i32* [[P]], align 4 192; CHECK-NEXT: ret void 193; CHECK: bb4: 194; CHECK-NEXT: store i32 3, i32* [[P]], align 4 195; CHECK-NEXT: ret void 196; 197entry: 198 store i32 0, i32* %P 199 br i1 %c.1, label %bb1, label %bb2 200 201bb1: 202 br i1 %c.2, label %bb3, label %bb4 203 204bb2: 205 store i32 1, i32* %P 206 ret void 207 208bb3: 209 store i32 2, i32* %P 210 ret void 211 212bb4: 213 store i32 3, i32* %P 214 ret void 215} 216 217; Can remove store in bb1, because it is overwritten along each path 218; from bb1 to the exit. 219define void @accessible_after_return7(i32* %P, i1 %c.1, i1 %c.2) { 220; CHECK-LABEL: @accessible_after_return7( 221; CHECK-NEXT: entry: 222; CHECK-NEXT: br i1 [[C_1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] 223; CHECK: bb1: 224; CHECK-NEXT: br i1 [[C_2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]] 225; CHECK: bb3: 226; CHECK-NEXT: store i32 2, i32* [[P:%.*]], align 4 227; CHECK-NEXT: br label [[BB5:%.*]] 228; CHECK: bb4: 229; CHECK-NEXT: store i32 1, i32* [[P]], align 4 230; CHECK-NEXT: br label [[BB5]] 231; CHECK: bb2: 232; CHECK-NEXT: br label [[BB5]] 233; CHECK: bb5: 234; CHECK-NEXT: ret void 235; 236entry: 237 br i1 %c.1, label %bb1, label %bb2 238 239bb1: 240 store i32 0, i32* %P 241 br i1 %c.2, label %bb3, label %bb4 242 243bb3: 244 store i32 2, i32* %P 245 br label %bb5 246 247bb4: 248 store i32 1, i32* %P 249 br label %bb5 250 251bb2: 252 br label %bb5 253 254bb5: 255 ret void 256} 257 258 259; Cannot remove store in entry block, because it is overwritten along each path to 260; the exit (entry->bb1->bb4->bb5). 261define void @accessible_after_return8(i32* %P, i1 %c.1, i1 %c.2) { 262; CHECK-LABEL: @accessible_after_return8( 263; CHECK-NEXT: entry: 264; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4 265; CHECK-NEXT: br i1 [[C_1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] 266; CHECK: bb1: 267; CHECK-NEXT: br i1 [[C_2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]] 268; CHECK: bb2: 269; CHECK-NEXT: store i32 1, i32* [[P]], align 4 270; CHECK-NEXT: br label [[BB5:%.*]] 271; CHECK: bb3: 272; CHECK-NEXT: store i32 2, i32* [[P]], align 4 273; CHECK-NEXT: br label [[BB5]] 274; CHECK: bb4: 275; CHECK-NEXT: br label [[BB5]] 276; CHECK: bb5: 277; CHECK-NEXT: ret void 278; 279entry: 280 store i32 0, i32* %P 281 br i1 %c.1, label %bb1, label %bb2 282 283bb1: 284 br i1 %c.2, label %bb3, label %bb4 285 286bb2: 287 store i32 1, i32* %P 288 br label %bb5 289 290bb3: 291 store i32 2, i32* %P 292 br label %bb5 293 294bb4: 295 br label %bb5 296 297bb5: 298 ret void 299} 300 301; Make sure no stores are removed here. In particular, the store in if.then 302; should not be removed. 303define void @accessible_after_return9(i8* noalias %ptr) { 304; CHECK-LABEL: @accessible_after_return9( 305; CHECK-NEXT: entry: 306; CHECK-NEXT: [[C_0:%.*]] = call i1 @cond() 307; CHECK-NEXT: br i1 [[C_0]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]] 308; CHECK: for.body: 309; CHECK-NEXT: store i8 99, i8* [[PTR:%.*]], align 8 310; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond() 311; CHECK-NEXT: br i1 [[C_1]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] 312; CHECK: if.then: 313; CHECK-NEXT: store i8 20, i8* [[PTR]], align 8 314; CHECK-NEXT: br label [[IF_END]] 315; CHECK: if.end: 316; CHECK-NEXT: [[C_2:%.*]] = call i1 @cond() 317; CHECK-NEXT: br i1 [[C_2]], label [[IF_THEN10:%.*]], label [[FOR_INC:%.*]] 318; CHECK: if.then10: 319; CHECK-NEXT: store i8 0, i8* [[PTR]], align 8 320; CHECK-NEXT: br label [[FOR_INC]] 321; CHECK: for.inc: 322; CHECK-NEXT: [[C_3:%.*]] = call i1 @cond() 323; CHECK-NEXT: br i1 [[C_3]], label [[FOR_BODY]], label [[FOR_END]] 324; CHECK: for.end: 325; CHECK-NEXT: ret void 326; 327entry: 328 %c.0 = call i1 @cond() 329 br i1 %c.0, label %for.body, label %for.end 330 331for.body: 332 store i8 99, i8* %ptr, align 8 333 %c.1 = call i1 @cond() 334 br i1 %c.1, label %if.end, label %if.then 335 336if.then: 337 store i8 20, i8* %ptr, align 8 338 br label %if.end 339 340if.end: 341 %c.2 = call i1 @cond() 342 br i1 %c.2, label %if.then10, label %for.inc 343 344if.then10: 345 store i8 0, i8* %ptr, align 8 346 br label %for.inc 347 348for.inc: 349 %c.3 = call i1 @cond() 350 br i1 %c.3, label %for.body, label %for.end 351 352for.end: 353 ret void 354} 355 356; Cannot remove store in entry block because it is not overwritten on path 357; entry->bb2->bb4. Also make sure we deal with dead exit blocks without 358; crashing. 359define void @accessible_after_return10_dead_block(i32* %P, i1 %c.1, i1 %c.2) { 360; CHECK-LABEL: @accessible_after_return10_dead_block( 361; CHECK-NEXT: entry: 362; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4 363; CHECK-NEXT: br i1 [[C_1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] 364; CHECK: bb1: 365; CHECK-NEXT: br i1 [[C_2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]] 366; CHECK: bb2: 367; CHECK-NEXT: store i32 1, i32* [[P]], align 4 368; CHECK-NEXT: ret void 369; CHECK: bb3: 370; CHECK-NEXT: store i32 2, i32* [[P]], align 4 371; CHECK-NEXT: ret void 372; CHECK: bb4: 373; CHECK-NEXT: ret void 374; CHECK: bb5: 375; CHECK-NEXT: ret void 376; 377entry: 378 store i32 0, i32* %P 379 br i1 %c.1, label %bb1, label %bb2 380 381bb1: 382 br i1 %c.2, label %bb3, label %bb4 383 384bb2: 385 store i32 1, i32* %P 386 ret void 387 388bb3: 389 store i32 2, i32* %P 390 ret void 391 392bb4: 393 ret void 394 395bb5: 396 ret void 397} 398 399@linenum = external local_unnamed_addr global i32, align 4 400 401define void @accessible_after_return11_loop() { 402; CHECK-LABEL: @accessible_after_return11_loop( 403; CHECK-NEXT: entry: 404; CHECK-NEXT: br label [[FOR_BODY_I:%.*]] 405; CHECK: for.body.i: 406; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond() 407; CHECK-NEXT: br i1 [[C_1]], label [[FOR_BODY_I]], label [[INIT_PARSE_EXIT:%.*]] 408; CHECK: init_parse.exit: 409; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 16, i8* nonnull undef) 410; CHECK-NEXT: store i32 0, i32* @linenum, align 4 411; CHECK-NEXT: br label [[FOR_BODY_I20:%.*]] 412; CHECK: for.body.i20: 413; CHECK-NEXT: [[C_2:%.*]] = call i1 @cond() 414; CHECK-NEXT: br i1 [[C_2]], label [[FOR_BODY_I20]], label [[EXIT:%.*]] 415; CHECK: exit: 416; CHECK-NEXT: ret void 417; 418entry: 419 br label %for.body.i 420 421for.body.i: ; preds = %for.body.i, %entry 422 %c.1 = call i1 @cond() 423 br i1 %c.1, label %for.body.i, label %init_parse.exit 424 425init_parse.exit: ; preds = %for.body.i 426 store i32 0, i32* @linenum, align 4 427 call void @llvm.lifetime.end.p0i8(i64 16, i8* nonnull undef) #2 428 store i32 0, i32* @linenum, align 4 429 br label %for.body.i20 430 431for.body.i20: ; preds = %for.body.i20, %init_parse.exit 432 %c.2 = call i1 @cond() 433 br i1 %c.2, label %for.body.i20, label %exit 434 435exit: 436 ret void 437} 438declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) 439declare i1 @cond() readnone nounwind 440 441; Tests where the pointer/object is *NOT* accessible after the function returns. 442 443; The store in the entry block can be eliminated, because it is overwritten 444; on all paths to the exit. 445define void @alloca_1(i1 %c1) { 446; CHECK-LABEL: @alloca_1( 447; CHECK-NEXT: [[P:%.*]] = alloca i32, align 4 448; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] 449; CHECK: bb1: 450; CHECK-NEXT: store i32 0, i32* [[P]], align 4 451; CHECK-NEXT: br label [[BB5:%.*]] 452; CHECK: bb2: 453; CHECK-NEXT: store i32 3, i32* [[P]], align 4 454; CHECK-NEXT: br label [[BB5]] 455; CHECK: bb5: 456; CHECK-NEXT: call void @use(i32* [[P]]) 457; CHECK-NEXT: ret void 458; 459 %P = alloca i32 460 store i32 1, i32* %P 461 br i1 %c1, label %bb1, label %bb2 462 463bb1: 464 store i32 0, i32* %P 465 br label %bb5 466bb2: 467 store i32 3, i32* %P 468 br label %bb5 469 470bb5: 471 call void @use(i32* %P) 472 ret void 473} 474 475; The store in the entry block can be eliminated, because it is overwritten 476; on all paths to the exit. 477define void @alloca_2(i1 %c.1, i1 %c.2) { 478; CHECK-LABEL: @alloca_2( 479; CHECK-NEXT: [[P:%.*]] = alloca i32, align 4 480; CHECK-NEXT: br i1 [[C_1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] 481; CHECK: bb1: 482; CHECK-NEXT: store i32 0, i32* [[P]], align 4 483; CHECK-NEXT: br label [[BB5:%.*]] 484; CHECK: bb2: 485; CHECK-NEXT: br i1 [[C_2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]] 486; CHECK: bb3: 487; CHECK-NEXT: store i32 3, i32* [[P]], align 4 488; CHECK-NEXT: br label [[BB5]] 489; CHECK: bb4: 490; CHECK-NEXT: store i32 5, i32* [[P]], align 4 491; CHECK-NEXT: br label [[BB5]] 492; CHECK: bb5: 493; CHECK-NEXT: call void @use(i32* [[P]]) 494; CHECK-NEXT: ret void 495; 496 %P = alloca i32 497 store i32 1, i32* %P 498 br i1 %c.1, label %bb1, label %bb2 499 500bb1: 501 store i32 0, i32* %P 502 br label %bb5 503 504bb2: 505 br i1 %c.2, label %bb3, label %bb4 506 507bb3: 508 store i32 3, i32* %P 509 br label %bb5 510 511bb4: 512 store i32 5, i32* %P 513 br label %bb5 514 515bb5: 516 call void @use(i32* %P) 517 ret void 518} 519 520; The store in the entry block cannot be eliminated. There's a path from the 521; first store to the read in bb5, where the location is not overwritten. 522define void @alloca_3(i1 %c1) { 523; CHECK-LABEL: @alloca_3( 524; CHECK-NEXT: [[P:%.*]] = alloca i32, align 4 525; CHECK-NEXT: store i32 1, i32* [[P]], align 4 526; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] 527; CHECK: bb1: 528; CHECK-NEXT: store i32 0, i32* [[P]], align 4 529; CHECK-NEXT: br label [[BB5:%.*]] 530; CHECK: bb2: 531; CHECK-NEXT: br label [[BB5]] 532; CHECK: bb5: 533; CHECK-NEXT: call void @use(i32* [[P]]) 534; CHECK-NEXT: ret void 535; 536 %P = alloca i32 537 store i32 1, i32* %P 538 br i1 %c1, label %bb1, label %bb2 539 540bb1: 541 store i32 0, i32* %P 542 br label %bb5 543bb2: 544 br label %bb5 545 546bb5: 547 call void @use(i32* %P) 548 ret void 549} 550 551; The store in the entry block can be eliminated, because it is overwritten 552; before the use in bb1 and not read on other paths to the function exit. The 553; object cannot be accessed by the caller. 554define void @alloca_4(i1 %c1) { 555; CHECK-LABEL: @alloca_4( 556; CHECK-NEXT: [[P:%.*]] = alloca i32, align 4 557; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] 558; CHECK: bb1: 559; CHECK-NEXT: store i32 0, i32* [[P]], align 4 560; CHECK-NEXT: call void @use(i32* [[P]]) 561; CHECK-NEXT: br label [[BB5:%.*]] 562; CHECK: bb2: 563; CHECK-NEXT: br label [[BB5]] 564; CHECK: bb5: 565; CHECK-NEXT: ret void 566; 567 %P = alloca i32 568 store i32 1, i32* %P 569 br i1 %c1, label %bb1, label %bb2 570 571bb1: 572 store i32 0, i32* %P 573 call void @use(i32* %P) 574 br label %bb5 575 576bb2: 577 br label %bb5 578 579bb5: 580 ret void 581} 582 583%struct.blam.4 = type { %struct.bar.5, [4 x i8] } 584%struct.bar.5 = type <{ i64, i64*, i32, i64 }> 585 586; Make sure we do not eliminate the store in %bb. 587define void @alloca_5(i1 %c) { 588; CHECK-LABEL: @alloca_5( 589; CHECK-NEXT: bb: 590; CHECK-NEXT: [[TMP:%.*]] = alloca [[STRUCT_BLAM_4:%.*]], align 8 591; CHECK-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_BLAM_4]], %struct.blam.4* [[TMP]], i64 0, i32 0, i32 3 592; CHECK-NEXT: [[TMP39:%.*]] = bitcast i64* [[TMP38]] to i64* 593; CHECK-NEXT: store i64 0, i64* [[TMP39]], align 4 594; CHECK-NEXT: br i1 [[C:%.*]], label [[BB46:%.*]], label [[BB47:%.*]] 595; CHECK: bb46: 596; CHECK-NEXT: ret void 597; CHECK: bb47: 598; CHECK-NEXT: [[TMP48:%.*]] = getelementptr inbounds [[STRUCT_BLAM_4]], %struct.blam.4* [[TMP]], i64 0, i32 0, i32 2 599; CHECK-NEXT: store i32 20, i32* [[TMP48]], align 8 600; CHECK-NEXT: br label [[BB52:%.*]] 601; CHECK: bb52: 602; CHECK-NEXT: br i1 [[C]], label [[BB68:%.*]], label [[BB59:%.*]] 603; CHECK: bb59: 604; CHECK-NEXT: call void @use.2(%struct.blam.4* [[TMP]]) 605; CHECK-NEXT: ret void 606; CHECK: bb68: 607; CHECK-NEXT: ret void 608; 609bb: 610 %tmp = alloca %struct.blam.4, align 8 611 %tmp36 = getelementptr inbounds %struct.blam.4, %struct.blam.4* %tmp, i64 0, i32 0, i32 1 612 %tmp37 = bitcast i64** %tmp36 to i8* 613 %tmp38 = getelementptr inbounds %struct.blam.4, %struct.blam.4* %tmp, i64 0, i32 0, i32 3 614 %tmp39 = bitcast i64* %tmp38 to i64* 615 store i64 0, i64* %tmp39, align 4 616 br i1 %c, label %bb46, label %bb47 617 618bb46: ; preds = %bb12 619 call void @llvm.memset.p0i8.i64(i8* nonnull align 8 dereferenceable(20) %tmp37, i8 0, i64 26, i1 false) 620 ret void 621 622bb47: ; preds = %bb12 623 %tmp48 = getelementptr inbounds %struct.blam.4, %struct.blam.4* %tmp, i64 0, i32 0, i32 2 624 store i32 20, i32* %tmp48, align 8 625 br label %bb52 626 627bb52: ; preds = %bb47 628 br i1 %c, label %bb68, label %bb59 629 630bb59: ; preds = %bb52 631 call void @use.2(%struct.blam.4* %tmp) 632 ret void 633 634bb68: ; preds = %bb52 635 ret void 636} 637 638declare void @use.2(%struct.blam.4*) 639 640declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1 immarg) 641