1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s 3target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" 4 5declare i32 @__gxx_personality_v0(...) 6declare void @fn() 7 8 9define void @test1() personality ptr @__gxx_personality_v0 { 10; CHECK-LABEL: @test1( 11; CHECK-NEXT: entry: 12; CHECK-NEXT: invoke void @fn() 13; CHECK-NEXT: to label [[INVOKE2:%.*]] unwind label [[LPAD2:%.*]] 14; CHECK: invoke2: 15; CHECK-NEXT: invoke void @fn() 16; CHECK-NEXT: to label [[COMMON_RET:%.*]] unwind label [[LPAD2]] 17; CHECK: common.ret: 18; CHECK-NEXT: ret void 19; CHECK: lpad2: 20; CHECK-NEXT: [[EXN2:%.*]] = landingpad { ptr, i32 } 21; CHECK-NEXT: cleanup 22; CHECK-NEXT: call void @fn() 23; CHECK-NEXT: br label [[COMMON_RET]] 24; 25entry: 26 invoke void @fn() 27 to label %invoke2 unwind label %lpad1 28 29invoke2: 30 invoke void @fn() 31 to label %invoke.cont unwind label %lpad2 32 33invoke.cont: 34 ret void 35 36lpad1: 37 %exn = landingpad {ptr, i32} 38 cleanup 39 br label %shared_resume 40 41lpad2: 42 %exn2 = landingpad {ptr, i32} 43 cleanup 44 br label %shared_resume 45 46shared_resume: 47 call void @fn() 48 ret void 49} 50 51; Don't trigger if blocks aren't the same/empty 52define void @neg1() personality ptr @__gxx_personality_v0 { 53; CHECK-LABEL: @neg1( 54; CHECK-NEXT: entry: 55; CHECK-NEXT: invoke void @fn() 56; CHECK-NEXT: to label [[INVOKE2:%.*]] unwind label [[LPAD1:%.*]] 57; CHECK: invoke2: 58; CHECK-NEXT: invoke void @fn() 59; CHECK-NEXT: to label [[COMMON_RET:%.*]] unwind label [[LPAD2:%.*]] 60; CHECK: common.ret: 61; CHECK-NEXT: ret void 62; CHECK: lpad1: 63; CHECK-NEXT: [[EXN:%.*]] = landingpad { ptr, i32 } 64; CHECK-NEXT: filter [0 x ptr] zeroinitializer 65; CHECK-NEXT: call void @fn() 66; CHECK-NEXT: br label [[SHARED_RESUME:%.*]] 67; CHECK: lpad2: 68; CHECK-NEXT: [[EXN2:%.*]] = landingpad { ptr, i32 } 69; CHECK-NEXT: cleanup 70; CHECK-NEXT: br label [[SHARED_RESUME]] 71; CHECK: shared_resume: 72; CHECK-NEXT: call void @fn() 73; CHECK-NEXT: br label [[COMMON_RET]] 74; 75entry: 76 invoke void @fn() 77 to label %invoke2 unwind label %lpad1 78 79invoke2: 80 invoke void @fn() 81 to label %invoke.cont unwind label %lpad2 82 83invoke.cont: 84 ret void 85 86lpad1: 87 %exn = landingpad {ptr, i32} 88 filter [0 x ptr] zeroinitializer 89 call void @fn() 90 br label %shared_resume 91 92lpad2: 93 %exn2 = landingpad {ptr, i32} 94 cleanup 95 br label %shared_resume 96 97shared_resume: 98 call void @fn() 99 ret void 100} 101 102; Should not trigger when the landing pads are not the exact same 103define void @neg2() personality ptr @__gxx_personality_v0 { 104; CHECK-LABEL: @neg2( 105; CHECK-NEXT: entry: 106; CHECK-NEXT: invoke void @fn() 107; CHECK-NEXT: to label [[INVOKE2:%.*]] unwind label [[LPAD1:%.*]] 108; CHECK: invoke2: 109; CHECK-NEXT: invoke void @fn() 110; CHECK-NEXT: to label [[COMMON_RET:%.*]] unwind label [[LPAD2:%.*]] 111; CHECK: common.ret: 112; CHECK-NEXT: ret void 113; CHECK: lpad1: 114; CHECK-NEXT: [[EXN:%.*]] = landingpad { ptr, i32 } 115; CHECK-NEXT: filter [0 x ptr] zeroinitializer 116; CHECK-NEXT: br label [[SHARED_RESUME:%.*]] 117; CHECK: lpad2: 118; CHECK-NEXT: [[EXN2:%.*]] = landingpad { ptr, i32 } 119; CHECK-NEXT: cleanup 120; CHECK-NEXT: br label [[SHARED_RESUME]] 121; CHECK: shared_resume: 122; CHECK-NEXT: call void @fn() 123; CHECK-NEXT: br label [[COMMON_RET]] 124; 125entry: 126 invoke void @fn() 127 to label %invoke2 unwind label %lpad1 128 129invoke2: 130 invoke void @fn() 131 to label %invoke.cont unwind label %lpad2 132 133invoke.cont: 134 ret void 135 136lpad1: 137 %exn = landingpad {ptr, i32} 138 filter [0 x ptr] zeroinitializer 139 br label %shared_resume 140 141lpad2: 142 %exn2 = landingpad {ptr, i32} 143 cleanup 144 br label %shared_resume 145 146shared_resume: 147 call void @fn() 148 ret void 149} 150