1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -sink-common-insts -S < %s | FileCheck %s 3; RUN: opt -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -sink-common-insts -S < %s --try-experimental-debuginfo-iterators | FileCheck %s 4 5; Test that we tail merge noreturn call blocks and phi constants properly. 6 7declare void @abort() 8declare void @assert_fail_1(i32) 9declare void @assert_fail_1_alt(i32) 10 11define void @merge_simple() { 12; CHECK-LABEL: @merge_simple( 13; CHECK-NEXT: [[C1:%.*]] = call i1 @foo() 14; CHECK-NEXT: br i1 [[C1]], label [[CONT1:%.*]], label [[A1:%.*]] 15; CHECK: a1: 16; CHECK-NEXT: call void @assert_fail_1(i32 0) 17; CHECK-NEXT: unreachable 18; CHECK: cont1: 19; CHECK-NEXT: [[C2:%.*]] = call i1 @foo() 20; CHECK-NEXT: br i1 [[C2]], label [[CONT2:%.*]], label [[A2:%.*]] 21; CHECK: a2: 22; CHECK-NEXT: call void @assert_fail_1(i32 0) 23; CHECK-NEXT: unreachable 24; CHECK: cont2: 25; CHECK-NEXT: [[C3:%.*]] = call i1 @foo() 26; CHECK-NEXT: br i1 [[C3]], label [[CONT3:%.*]], label [[A3:%.*]] 27; CHECK: a3: 28; CHECK-NEXT: call void @assert_fail_1(i32 0) 29; CHECK-NEXT: unreachable 30; CHECK: cont3: 31; CHECK-NEXT: ret void 32; 33 %c1 = call i1 @foo() 34 br i1 %c1, label %cont1, label %a1 35a1: 36 call void @assert_fail_1(i32 0) 37 unreachable 38cont1: 39 %c2 = call i1 @foo() 40 br i1 %c2, label %cont2, label %a2 41a2: 42 call void @assert_fail_1(i32 0) 43 unreachable 44cont2: 45 %c3 = call i1 @foo() 46 br i1 %c3, label %cont3, label %a3 47a3: 48 call void @assert_fail_1(i32 0) 49 unreachable 50cont3: 51 ret void 52} 53 54define void @phi_three_constants() { 55; CHECK-LABEL: @phi_three_constants( 56; CHECK-NEXT: entry: 57; CHECK-NEXT: [[C1:%.*]] = call i1 @foo() 58; CHECK-NEXT: br i1 [[C1]], label [[CONT1:%.*]], label [[A1:%.*]] 59; CHECK: a1: 60; CHECK-NEXT: call void @assert_fail_1(i32 0) 61; CHECK-NEXT: unreachable 62; CHECK: cont1: 63; CHECK-NEXT: [[C2:%.*]] = call i1 @foo() 64; CHECK-NEXT: br i1 [[C2]], label [[CONT2:%.*]], label [[A2:%.*]] 65; CHECK: a2: 66; CHECK-NEXT: call void @assert_fail_1(i32 1) 67; CHECK-NEXT: unreachable 68; CHECK: cont2: 69; CHECK-NEXT: [[C3:%.*]] = call i1 @foo() 70; CHECK-NEXT: br i1 [[C3]], label [[CONT3:%.*]], label [[A3:%.*]] 71; CHECK: a3: 72; CHECK-NEXT: call void @assert_fail_1(i32 2) 73; CHECK-NEXT: unreachable 74; CHECK: cont3: 75; CHECK-NEXT: ret void 76; 77entry: 78 %c1 = call i1 @foo() 79 br i1 %c1, label %cont1, label %a1 80a1: 81 call void @assert_fail_1(i32 0) 82 unreachable 83cont1: 84 %c2 = call i1 @foo() 85 br i1 %c2, label %cont2, label %a2 86a2: 87 call void @assert_fail_1(i32 1) 88 unreachable 89cont2: 90 %c3 = call i1 @foo() 91 br i1 %c3, label %cont3, label %a3 92a3: 93 call void @assert_fail_1(i32 2) 94 unreachable 95cont3: 96 ret void 97} 98 99define void @dont_phi_values(i32 %x, i32 %y) { 100; CHECK-LABEL: @dont_phi_values( 101; CHECK-NEXT: [[C1:%.*]] = call i1 @foo() 102; CHECK-NEXT: br i1 [[C1]], label [[CONT1:%.*]], label [[A1:%.*]] 103; CHECK: a1: 104; CHECK-NEXT: call void @assert_fail_1(i32 [[X:%.*]]) 105; CHECK-NEXT: unreachable 106; CHECK: cont1: 107; CHECK-NEXT: [[C2:%.*]] = call i1 @foo() 108; CHECK-NEXT: br i1 [[C2]], label [[CONT2:%.*]], label [[A2:%.*]] 109; CHECK: a2: 110; CHECK-NEXT: call void @assert_fail_1(i32 [[Y:%.*]]) 111; CHECK-NEXT: unreachable 112; CHECK: cont2: 113; CHECK-NEXT: ret void 114; 115 %c1 = call i1 @foo() 116 br i1 %c1, label %cont1, label %a1 117a1: 118 call void @assert_fail_1(i32 %x) 119 unreachable 120cont1: 121 %c2 = call i1 @foo() 122 br i1 %c2, label %cont2, label %a2 123a2: 124 call void @assert_fail_1(i32 %y) 125 unreachable 126cont2: 127 ret void 128} 129 130define void @dont_phi_callees() { 131; CHECK-LABEL: @dont_phi_callees( 132; CHECK-NEXT: [[C1:%.*]] = call i1 @foo() 133; CHECK-NEXT: br i1 [[C1]], label [[CONT1:%.*]], label [[A1:%.*]] 134; CHECK: cont1: 135; CHECK-NEXT: [[C2:%.*]] = call i1 @foo() 136; CHECK-NEXT: br i1 [[C2]], label [[CONT2:%.*]], label [[A2:%.*]] 137; CHECK: cont2: 138; CHECK-NEXT: ret void 139; CHECK: a1: 140; CHECK-NEXT: call void @assert_fail_1(i32 0) 141; CHECK-NEXT: unreachable 142; CHECK: a2: 143; CHECK-NEXT: call void @assert_fail_1_alt(i32 0) 144; CHECK-NEXT: unreachable 145; 146 %c1 = call i1 @foo() 147 br i1 %c1, label %cont1, label %a1 148cont1: 149 %c2 = call i1 @foo() 150 br i1 %c2, label %cont2, label %a2 151cont2: 152 ret void 153a1: 154 call void @assert_fail_1(i32 0) 155 unreachable 156a2: 157 call void @assert_fail_1_alt(i32 0) 158 unreachable 159} 160 161declare i1 @foo() 162declare i1 @bar() 163 164define void @unmergeable_phis(i32 %v, i1 %c) { 165; CHECK-LABEL: @unmergeable_phis( 166; CHECK-NEXT: entry: 167; CHECK-NEXT: br i1 [[C:%.*]], label [[S1:%.*]], label [[S2:%.*]] 168; CHECK: s1: 169; CHECK-NEXT: [[C1:%.*]] = call i1 @foo() 170; CHECK-NEXT: br i1 [[C1]], label [[A1:%.*]], label [[A2:%.*]] 171; CHECK: s2: 172; CHECK-NEXT: [[C2:%.*]] = call i1 @bar() 173; CHECK-NEXT: br i1 [[C2]], label [[A1]], label [[A2]] 174; CHECK: a1: 175; CHECK-NEXT: [[L1:%.*]] = phi i32 [ 0, [[S1]] ], [ 1, [[S2]] ] 176; CHECK-NEXT: call void @assert_fail_1(i32 [[L1]]) 177; CHECK-NEXT: unreachable 178; CHECK: a2: 179; CHECK-NEXT: [[L2:%.*]] = phi i32 [ 2, [[S1]] ], [ 3, [[S2]] ] 180; CHECK-NEXT: call void @assert_fail_1(i32 [[L2]]) 181; CHECK-NEXT: unreachable 182; 183entry: 184 br i1 %c, label %s1, label %s2 185s1: 186 %c1 = call i1 @foo() 187 br i1 %c1, label %a1, label %a2 188s2: 189 %c2 = call i1 @bar() 190 br i1 %c2, label %a1, label %a2 191a1: 192 %l1 = phi i32 [ 0, %s1 ], [ 1, %s2 ] 193 call void @assert_fail_1(i32 %l1) 194 unreachable 195a2: 196 %l2 = phi i32 [ 2, %s1 ], [ 3, %s2 ] 197 call void @assert_fail_1(i32 %l2) 198 unreachable 199} 200 201define void @tail_merge_switch(i32 %v) { 202; CHECK-LABEL: @tail_merge_switch( 203; CHECK-NEXT: entry: 204; CHECK-NEXT: switch i32 [[V:%.*]], label [[RET:%.*]] [ 205; CHECK-NEXT: i32 0, label [[A1:%.*]] 206; CHECK-NEXT: i32 13, label [[A2:%.*]] 207; CHECK-NEXT: i32 42, label [[A3:%.*]] 208; CHECK-NEXT: ] 209; CHECK: a1: 210; CHECK-NEXT: call void @assert_fail_1(i32 0) 211; CHECK-NEXT: unreachable 212; CHECK: a2: 213; CHECK-NEXT: call void @assert_fail_1(i32 1) 214; CHECK-NEXT: unreachable 215; CHECK: a3: 216; CHECK-NEXT: call void @assert_fail_1(i32 2) 217; CHECK-NEXT: unreachable 218; CHECK: ret: 219; CHECK-NEXT: ret void 220; 221entry: 222 switch i32 %v, label %ret [ 223 i32 0, label %a1 224 i32 13, label %a2 225 i32 42, label %a3 226 ] 227a1: 228 call void @assert_fail_1(i32 0) 229 unreachable 230a2: 231 call void @assert_fail_1(i32 1) 232 unreachable 233a3: 234 call void @assert_fail_1(i32 2) 235 unreachable 236ret: 237 ret void 238} 239 240define void @need_to_add_bb2_preds(i1 %c1) { 241; CHECK-LABEL: @need_to_add_bb2_preds( 242; CHECK-NEXT: bb1: 243; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB2:%.*]], label [[A1:%.*]] 244; CHECK: bb2: 245; CHECK-NEXT: [[C2:%.*]] = call i1 @bar() 246; CHECK-NEXT: br i1 [[C2]], label [[A2:%.*]], label [[A3:%.*]] 247; CHECK: a1: 248; CHECK-NEXT: call void @assert_fail_1(i32 0) 249; CHECK-NEXT: unreachable 250; CHECK: a2: 251; CHECK-NEXT: call void @assert_fail_1(i32 1) 252; CHECK-NEXT: unreachable 253; CHECK: a3: 254; CHECK-NEXT: call void @assert_fail_1(i32 2) 255; CHECK-NEXT: unreachable 256; 257bb1: 258 br i1 %c1, label %bb2, label %a1 259bb2: 260 %c2 = call i1 @bar() 261 br i1 %c2, label %a2, label %a3 262 263a1: 264 call void @assert_fail_1(i32 0) 265 unreachable 266a2: 267 call void @assert_fail_1(i32 1) 268 unreachable 269a3: 270 call void @assert_fail_1(i32 2) 271 unreachable 272} 273 274define void @phi_in_bb2() { 275; CHECK-LABEL: @phi_in_bb2( 276; CHECK-NEXT: entry: 277; CHECK-NEXT: [[C1:%.*]] = call i1 @foo() 278; CHECK-NEXT: br i1 [[C1]], label [[CONT1:%.*]], label [[A1:%.*]] 279; CHECK: a1: 280; CHECK-NEXT: call void @assert_fail_1(i32 0) 281; CHECK-NEXT: unreachable 282; CHECK: cont1: 283; CHECK-NEXT: [[C2:%.*]] = call i1 @foo() 284; CHECK-NEXT: br i1 [[C2]], label [[CONT2:%.*]], label [[A2:%.*]] 285; CHECK: a2: 286; CHECK-NEXT: [[P2:%.*]] = phi i32 [ 1, [[CONT1]] ], [ 2, [[CONT2]] ] 287; CHECK-NEXT: call void @assert_fail_1(i32 [[P2]]) 288; CHECK-NEXT: unreachable 289; CHECK: cont2: 290; CHECK-NEXT: [[C3:%.*]] = call i1 @foo() 291; CHECK-NEXT: br i1 [[C3]], label [[CONT3:%.*]], label [[A2]] 292; CHECK: cont3: 293; CHECK-NEXT: ret void 294; 295entry: 296 %c1 = call i1 @foo() 297 br i1 %c1, label %cont1, label %a1 298a1: 299 call void @assert_fail_1(i32 0) 300 unreachable 301cont1: 302 %c2 = call i1 @foo() 303 br i1 %c2, label %cont2, label %a2 304a2: 305 %p2 = phi i32 [ 1, %cont1 ], [ 2, %cont2 ] 306 call void @assert_fail_1(i32 %p2) 307 unreachable 308cont2: 309 %c3 = call i1 @foo() 310 br i1 %c3, label %cont3, label %a2 311cont3: 312 ret void 313} 314 315; Don't tail merge these noreturn blocks using lifetime end. It prevents us 316; from sharing stack slots for x and y. 317 318declare void @escape_i32_ptr(ptr) 319declare void @llvm.lifetime.start(i64, ptr nocapture) 320declare void @llvm.lifetime.end(i64, ptr nocapture) 321 322define void @dont_merge_lifetimes(i32 %c1, i32 %c2) { 323; CHECK-LABEL: @dont_merge_lifetimes( 324; CHECK-NEXT: entry: 325; CHECK-NEXT: [[X:%.*]] = alloca i32, align 4 326; CHECK-NEXT: [[Y:%.*]] = alloca i32, align 4 327; CHECK-NEXT: switch i32 [[C1:%.*]], label [[IF_END9:%.*]] [ 328; CHECK-NEXT: i32 13, label [[IF_THEN:%.*]] 329; CHECK-NEXT: i32 42, label [[IF_THEN3:%.*]] 330; CHECK-NEXT: ] 331; CHECK: if.then: 332; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[X]]) 333; CHECK-NEXT: store i32 0, ptr [[X]], align 4 334; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[C2:%.*]], 0 335; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN1:%.*]] 336; CHECK: if.then1: 337; CHECK-NEXT: call void @escape_i32_ptr(ptr nonnull [[X]]) 338; CHECK-NEXT: br label [[IF_END]] 339; CHECK: if.end: 340; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr nonnull [[X]]) 341; CHECK-NEXT: call void @abort() 342; CHECK-NEXT: unreachable 343; CHECK: if.then3: 344; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[Y]]) 345; CHECK-NEXT: store i32 0, ptr [[Y]], align 4 346; CHECK-NEXT: [[TOBOOL5:%.*]] = icmp eq i32 [[C2]], 0 347; CHECK-NEXT: br i1 [[TOBOOL5]], label [[IF_END7:%.*]], label [[IF_THEN6:%.*]] 348; CHECK: if.then6: 349; CHECK-NEXT: call void @escape_i32_ptr(ptr nonnull [[Y]]) 350; CHECK-NEXT: br label [[IF_END7]] 351; CHECK: if.end7: 352; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr nonnull [[Y]]) 353; CHECK-NEXT: call void @abort() 354; CHECK-NEXT: unreachable 355; CHECK: if.end9: 356; CHECK-NEXT: ret void 357; 358entry: 359 %x = alloca i32, align 4 360 %y = alloca i32, align 4 361 switch i32 %c1, label %if.end9 [ 362 i32 13, label %if.then 363 i32 42, label %if.then3 364 ] 365 366if.then: ; preds = %entry 367 call void @llvm.lifetime.start(i64 4, ptr nonnull %x) 368 store i32 0, ptr %x, align 4 369 %tobool = icmp eq i32 %c2, 0 370 br i1 %tobool, label %if.end, label %if.then1 371 372if.then1: ; preds = %if.then 373 call void @escape_i32_ptr(ptr nonnull %x) 374 br label %if.end 375 376if.end: ; preds = %if.then1, %if.then 377 call void @llvm.lifetime.end(i64 4, ptr nonnull %x) 378 call void @abort() 379 unreachable 380 381if.then3: ; preds = %entry 382 call void @llvm.lifetime.start(i64 4, ptr nonnull %y) 383 store i32 0, ptr %y, align 4 384 %tobool5 = icmp eq i32 %c2, 0 385 br i1 %tobool5, label %if.end7, label %if.then6 386 387if.then6: ; preds = %if.then3 388 call void @escape_i32_ptr(ptr nonnull %y) 389 br label %if.end7 390 391if.end7: ; preds = %if.then6, %if.then3 392 call void @llvm.lifetime.end(i64 4, ptr nonnull %y) 393 call void @abort() 394 unreachable 395 396if.end9: ; preds = %entry 397 ret void 398} 399 400; Dead phis in the block need to be handled. 401 402declare void @llvm.dbg.value(metadata, i64, metadata, metadata) 403 404define void @dead_phi() { 405; CHECK-LABEL: @dead_phi( 406; CHECK-NEXT: entry: 407; CHECK-NEXT: [[C1:%.*]] = call i1 @foo() 408; CHECK-NEXT: br i1 [[C1]], label [[CONT1:%.*]], label [[A1:%.*]] 409; CHECK: a1: 410; CHECK-NEXT: [[DEAD:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[CONT1]] ] 411; CHECK-NEXT: call void @assert_fail_1(i32 0) 412; CHECK-NEXT: unreachable 413; CHECK: cont1: 414; CHECK-NEXT: [[C2:%.*]] = call i1 @foo() 415; CHECK-NEXT: br i1 [[C2]], label [[CONT2:%.*]], label [[A1]] 416; CHECK: cont2: 417; CHECK-NEXT: [[C3:%.*]] = call i1 @foo() 418; CHECK-NEXT: br i1 [[C3]], label [[CONT3:%.*]], label [[A3:%.*]] 419; CHECK: a3: 420; CHECK-NEXT: call void @assert_fail_1(i32 0) 421; CHECK-NEXT: unreachable 422; CHECK: cont3: 423; CHECK-NEXT: ret void 424; 425entry: 426 %c1 = call i1 @foo() 427 br i1 %c1, label %cont1, label %a1 428a1: 429 %dead = phi i32 [ 0, %entry ], [ 1, %cont1 ] 430 call void @assert_fail_1(i32 0) 431 unreachable 432cont1: 433 %c2 = call i1 @foo() 434 br i1 %c2, label %cont2, label %a1 435cont2: 436 %c3 = call i1 @foo() 437 br i1 %c3, label %cont3, label %a3 438a3: 439 call void @assert_fail_1(i32 0) 440 unreachable 441cont3: 442 ret void 443} 444 445define void @strip_dbg_value(i32 %c) { 446; CHECK-LABEL: @strip_dbg_value( 447; CHECK-NEXT: entry: 448; CHECK-NEXT: #dbg_value(i32 [[C:%.*]], [[META5:![0-9]+]], !DIExpression(), [[META7:![0-9]+]]) 449; CHECK-NEXT: switch i32 [[C]], label [[SW_EPILOG:%.*]] [ 450; CHECK-NEXT: i32 13, label [[SW_BB:%.*]] 451; CHECK-NEXT: i32 42, label [[SW_BB1:%.*]] 452; CHECK-NEXT: ] 453; CHECK: sw.bb: 454; CHECK-NEXT: #dbg_value(i32 55, [[META5]], !DIExpression(), [[META7]]) 455; CHECK-NEXT: tail call void @abort() 456; CHECK-NEXT: unreachable 457; CHECK: sw.bb1: 458; CHECK-NEXT: #dbg_value(i32 67, [[META5]], !DIExpression(), [[META7]]) 459; CHECK-NEXT: tail call void @abort() 460; CHECK-NEXT: unreachable 461; CHECK: sw.epilog: 462; CHECK-NEXT: ret void 463; 464entry: 465 call void @llvm.dbg.value(metadata i32 %c, i64 0, metadata !12, metadata !13), !dbg !14 466 switch i32 %c, label %sw.epilog [ 467 i32 13, label %sw.bb 468 i32 42, label %sw.bb1 469 ] 470 471sw.bb: ; preds = %entry 472 call void @llvm.dbg.value(metadata i32 55, i64 0, metadata !12, metadata !13), !dbg !14 473 tail call void @abort() 474 unreachable 475 476sw.bb1: ; preds = %entry 477 call void @llvm.dbg.value(metadata i32 67, i64 0, metadata !12, metadata !13), !dbg !14 478 tail call void @abort() 479 unreachable 480 481sw.epilog: ; preds = %entry 482 ret void 483} 484 485define void @dead_phi_and_dbg(i32 %c) { 486; CHECK-LABEL: @dead_phi_and_dbg( 487; CHECK-NEXT: entry: 488; CHECK-NEXT: #dbg_value(i32 [[C:%.*]], [[META5]], !DIExpression(), [[META7]]) 489; CHECK-NEXT: switch i32 [[C]], label [[SW_EPILOG:%.*]] [ 490; CHECK-NEXT: i32 13, label [[SW_BB:%.*]] 491; CHECK-NEXT: i32 42, label [[SW_BB1:%.*]] 492; CHECK-NEXT: i32 53, label [[SW_BB2:%.*]] 493; CHECK-NEXT: ] 494; CHECK: sw.bb: 495; CHECK-NEXT: [[C_1:%.*]] = phi i32 [ 55, [[ENTRY:%.*]] ], [ 67, [[SW_BB1]] ] 496; CHECK-NEXT: #dbg_value(i32 [[C_1]], [[META5]], !DIExpression(), [[META7]]) 497; CHECK-NEXT: tail call void @abort() 498; CHECK-NEXT: unreachable 499; CHECK: sw.bb1: 500; CHECK-NEXT: br label [[SW_BB]] 501; CHECK: sw.bb2: 502; CHECK-NEXT: #dbg_value(i32 84, [[META5]], !DIExpression(), [[META7]]) 503; CHECK-NEXT: tail call void @abort() 504; CHECK-NEXT: unreachable 505; CHECK: sw.epilog: 506; CHECK-NEXT: ret void 507; 508entry: 509 call void @llvm.dbg.value(metadata i32 %c, i64 0, metadata !12, metadata !13), !dbg !14 510 switch i32 %c, label %sw.epilog [ 511 i32 13, label %sw.bb 512 i32 42, label %sw.bb1 513 i32 53, label %sw.bb2 514 ] 515 516sw.bb: ; preds = %entry 517 %c.1 = phi i32 [ 55, %entry], [ 67, %sw.bb1 ] 518 call void @llvm.dbg.value(metadata i32 %c.1, i64 0, metadata !12, metadata !13), !dbg !14 519 tail call void @abort() 520 unreachable 521 522sw.bb1: 523 br label %sw.bb 524 525sw.bb2: ; preds = %entry 526 call void @llvm.dbg.value(metadata i32 84, i64 0, metadata !12, metadata !13), !dbg !14 527 tail call void @abort() 528 unreachable 529 530sw.epilog: ; preds = %entry 531 ret void 532} 533 534!llvm.dbg.cu = !{!0} 535!llvm.module.flags = !{!3, !4, !5} 536 537!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, runtimeVersion: 0, emissionKind: FullDebug) 538!1 = !DIFile(filename: "t.c", directory: "asdf") 539!3 = !{i32 2, !"Dwarf Version", i32 4} 540!4 = !{i32 2, !"Debug Info Version", i32 3} 541!5 = !{i32 1, !"PIC Level", i32 2} 542!7 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 2, isLocal: false, isDefinition: true, scopeLine: 2, flags: DIFlagPrototyped, isOptimized: true, unit: !0) 543!12 = !DILocalVariable(name: "c", scope: !7) 544!13 = !DIExpression() 545!14 = !DILocation(line: 2, column: 12, scope: !7) 546