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 4; Test that we tail merge resume blocks and phi operands properly. 5 6declare void @maybe_throws() 7declare void @foo() 8declare void @bar() 9declare void @baz() 10declare void @qux() 11declare void @quux() 12declare void @quuz() 13declare void @common() 14 15define void @merge_simple(i1 %cond) personality ptr @__gxx_personality_v0 { 16; CHECK-LABEL: @merge_simple( 17; CHECK-NEXT: invoke void @maybe_throws() 18; CHECK-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 19; CHECK: invoke.cont: 20; CHECK-NEXT: invoke void @maybe_throws() 21; CHECK-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD2:%.*]] 22; CHECK: invoke.cont2: 23; CHECK-NEXT: invoke void @maybe_throws() 24; CHECK-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD3:%.*]] 25; CHECK: invoke.cont3: 26; CHECK-NEXT: ret void 27; CHECK: lpad: 28; CHECK-NEXT: [[LP:%.*]] = landingpad { ptr, i32 } 29; CHECK-NEXT: cleanup 30; CHECK-NEXT: call void @foo() 31; CHECK-NEXT: br i1 [[COND:%.*]], label [[RESUME0:%.*]], label [[RESUME1:%.*]] 32; CHECK: lpad2: 33; CHECK-NEXT: [[LP2:%.*]] = landingpad { ptr, i32 } 34; CHECK-NEXT: cleanup 35; CHECK-NEXT: call void @bar() 36; CHECK-NEXT: br label [[RESUME2:%.*]] 37; CHECK: lpad3: 38; CHECK-NEXT: [[LP3:%.*]] = landingpad { ptr, i32 } 39; CHECK-NEXT: cleanup 40; CHECK-NEXT: call void @baz() 41; CHECK-NEXT: br label [[RESUME2]] 42; CHECK: common.resume: 43; CHECK-NEXT: [[COMMON_RESUME_OP:%.*]] = phi { ptr, i32 } [ [[LP]], [[RESUME0]] ], [ [[LP]], [[RESUME1]] ], [ [[SEMICOMMON_LP:%.*]], [[RESUME2]] ] 44; CHECK-NEXT: call void @common() 45; CHECK-NEXT: resume { ptr, i32 } [[COMMON_RESUME_OP]] 46; CHECK: resume0: 47; CHECK-NEXT: call void @qux() 48; CHECK-NEXT: br label [[COMMON_RESUME:%.*]] 49; CHECK: resume1: 50; CHECK-NEXT: call void @quux() 51; CHECK-NEXT: br label [[COMMON_RESUME]] 52; CHECK: resume2: 53; CHECK-NEXT: [[SEMICOMMON_LP]] = phi { ptr, i32 } [ [[LP2]], [[LPAD2]] ], [ [[LP3]], [[LPAD3]] ] 54; CHECK-NEXT: call void @quuz() 55; CHECK-NEXT: br label [[COMMON_RESUME]] 56; 57 invoke void @maybe_throws() to label %invoke.cont unwind label %lpad 58 59invoke.cont: 60 invoke void @maybe_throws() to label %invoke.cont2 unwind label %lpad2 61 62invoke.cont2: 63 invoke void @maybe_throws() to label %invoke.cont3 unwind label %lpad3 64 65invoke.cont3: 66 ret void 67 68lpad: 69 %lp = landingpad { ptr, i32 } cleanup 70 call void @foo() 71 br i1 %cond, label %resume0, label %resume1 72 73lpad2: 74 %lp2 = landingpad { ptr, i32 } cleanup 75 call void @bar() 76 br label %resume2 77 78lpad3: 79 %lp3 = landingpad { ptr, i32 } cleanup 80 call void @baz() 81 br label %resume2 82 83resume0: 84 call void @qux() 85 call void @common() 86 resume { ptr, i32 } %lp 87 88resume1: 89 call void @quux() 90 call void @common() 91 resume { ptr, i32 } %lp 92 93resume2: 94 %semicommon.lp = phi { ptr, i32 } [ %lp2, %lpad2 ], [ %lp3, %lpad3 ] 95 call void @quuz() 96 call void @common() 97 resume { ptr, i32 } %semicommon.lp 98} 99 100declare dso_local i32 @__gxx_personality_v0(...) 101