brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.2 KiB · 5441e2a Raw
350 lines · plain
1; RUN: opt < %s -passes=inline -S | FileCheck %s2; RUN: opt < %s -passes='cgscc(inline)' -S | FileCheck %s3 4; Test that the inliner correctly handles inlining into invoke sites5; by appending selectors and forwarding _Unwind_Resume directly to the6; enclosing landing pad.7 8;; Test 0 - basic functionality.9 10%struct.A = type { i8 }11 12@_ZTIi = external constant ptr13 14declare void @_ZN1AC1Ev(ptr)15 16declare void @_ZN1AD1Ev(ptr)17 18declare void @use(i32) nounwind19 20declare void @opaque()21 22declare i32 @llvm.eh.typeid.for.p0(ptr) nounwind23 24declare i32 @__gxx_personality_v0(...)25 26declare ptr @__cxa_begin_catch(ptr)27 28declare void @__cxa_end_catch()29 30declare void @_ZSt9terminatev()31 32define internal void @test0_in() alwaysinline uwtable ssp personality ptr @__gxx_personality_v0 {33entry:34  %a = alloca %struct.A, align 135  %b = alloca %struct.A, align 136  call void @_ZN1AC1Ev(ptr %a)37  invoke void @_ZN1AC1Ev(ptr %b)38          to label %invoke.cont unwind label %lpad39 40invoke.cont:41  invoke void @_ZN1AD1Ev(ptr %b)42          to label %invoke.cont1 unwind label %lpad43 44invoke.cont1:45  call void @_ZN1AD1Ev(ptr %a)46  ret void47 48lpad:49  %exn = landingpad {ptr, i32}50            cleanup51  invoke void @_ZN1AD1Ev(ptr %a)52          to label %invoke.cont2 unwind label %terminate.lpad53 54invoke.cont2:55  resume { ptr, i32 } %exn56 57terminate.lpad:58  %exn1 = landingpad {ptr, i32}59            catch ptr null60  call void @_ZSt9terminatev() noreturn nounwind61  unreachable62}63 64define void @test0_out() uwtable ssp personality ptr @__gxx_personality_v0 {65entry:66  invoke void @test0_in()67          to label %ret unwind label %lpad68 69ret:70  ret void71 72lpad:                                             ; preds = %entry73  %exn = landingpad {ptr, i32}74            catch ptr @_ZTIi75  %eh.exc = extractvalue { ptr, i32 } %exn, 076  %eh.selector = extractvalue { ptr, i32 } %exn, 177  %0 = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIi) nounwind78  %1 = icmp eq i32 %eh.selector, %079  br i1 %1, label %catch, label %eh.resume80 81catch:82  %ignored = call ptr @__cxa_begin_catch(ptr %eh.exc) nounwind83  call void @__cxa_end_catch() nounwind84  br label %ret85 86eh.resume:87  resume { ptr, i32 } %exn88}89 90; CHECK:    define void @test0_out()91; CHECK:      [[A:%.*]] = alloca %struct.A,92; CHECK:      [[B:%.*]] = alloca %struct.A,93; CHECK:      invoke void @_ZN1AC1Ev(ptr [[A]])94; CHECK:      invoke void @_ZN1AC1Ev(ptr [[B]])95; CHECK:      invoke void @_ZN1AD1Ev(ptr [[B]])96; CHECK:      invoke void @_ZN1AD1Ev(ptr [[A]])97; CHECK:      landingpad { ptr, i32 }98; CHECK-NEXT:    cleanup99; CHECK-NEXT:    catch ptr @_ZTIi100; CHECK-NEXT: invoke void @_ZN1AD1Ev(ptr [[A]])101; CHECK-NEXT:   to label %[[LBL:[^\s]+]] unwind102; CHECK: [[LBL]]:103; CHECK-NEXT: br label %[[LPAD:[^\s]+]]104; CHECK:      ret void105; CHECK:      landingpad { ptr, i32 }106; CHECK-NEXT:    catch ptr @_ZTIi107; CHECK-NEXT: br label %[[LPAD]]108; CHECK: [[LPAD]]:109; CHECK-NEXT: phi { ptr, i32 } [110; CHECK-NEXT: extractvalue { ptr, i32 }111; CHECK-NEXT: extractvalue { ptr, i32 }112; CHECK-NEXT: call i32 @llvm.eh.typeid.for.p0(113 114 115;; Test 1 - Correctly handle phis in outer landing pads.116 117define void @test1_out() uwtable ssp personality ptr @__gxx_personality_v0 {118entry:119  invoke void @test0_in()120          to label %cont unwind label %lpad121 122cont:123  invoke void @test0_in()124          to label %ret unwind label %lpad125 126ret:127  ret void128 129lpad:130  %x = phi i32 [ 0, %entry ], [ 1, %cont ]131  %y = phi i32 [ 1, %entry ], [ 4, %cont ]132  %exn = landingpad {ptr, i32}133            catch ptr @_ZTIi134  %eh.exc = extractvalue { ptr, i32 } %exn, 0135  %eh.selector = extractvalue { ptr, i32 } %exn, 1136  %0 = call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIi) nounwind137  %1 = icmp eq i32 %eh.selector, %0138  br i1 %1, label %catch, label %eh.resume139 140catch:141  %ignored = call ptr @__cxa_begin_catch(ptr %eh.exc) nounwind142  call void @use(i32 %x)143  call void @use(i32 %y)144  call void @__cxa_end_catch() nounwind145  br label %ret146 147eh.resume:148  resume { ptr, i32 } %exn149}150 151; CHECK:    define void @test1_out()152; CHECK:      [[A2:%.*]] = alloca %struct.A,153; CHECK:      [[B2:%.*]] = alloca %struct.A,154; CHECK:      [[A1:%.*]] = alloca %struct.A,155; CHECK:      [[B1:%.*]] = alloca %struct.A,156; CHECK:      invoke void @_ZN1AC1Ev(ptr [[A1]])157; CHECK-NEXT:   unwind label %[[LPAD:[^\s]+]]158; CHECK:      invoke void @_ZN1AC1Ev(ptr [[B1]])159; CHECK-NEXT:   unwind label %[[LPAD1:[^\s]+]]160; CHECK:      invoke void @_ZN1AD1Ev(ptr [[B1]])161; CHECK-NEXT:   unwind label %[[LPAD1]]162; CHECK:      invoke void @_ZN1AD1Ev(ptr [[A1]])163; CHECK-NEXT:   unwind label %[[LPAD]]164 165; Inner landing pad from first inlining.166; CHECK:    [[LPAD1]]:167; CHECK-NEXT: [[LPADVAL1:%.*]] = landingpad { ptr, i32 }168; CHECK-NEXT:    cleanup169; CHECK-NEXT:    catch ptr @_ZTIi170; CHECK-NEXT: invoke void @_ZN1AD1Ev(ptr [[A1]])171; CHECK-NEXT:   to label %[[RESUME1:[^\s]+]] unwind172; CHECK: [[RESUME1]]:173; CHECK-NEXT: br label %[[LPAD_JOIN1:[^\s]+]]174 175; CHECK:      invoke void @_ZN1AC1Ev(ptr [[A2]])176; CHECK-NEXT:   unwind label %[[LPAD]]177; CHECK:      invoke void @_ZN1AC1Ev(ptr [[B2]])178; CHECK-NEXT:   unwind label %[[LPAD2:[^\s]+]]179; CHECK:      invoke void @_ZN1AD1Ev(ptr [[B2]])180; CHECK-NEXT:   unwind label %[[LPAD2]]181; CHECK:      invoke void @_ZN1AD1Ev(ptr [[A2]])182; CHECK-NEXT:   unwind label %[[LPAD]]183 184; Inner landing pad from second inlining.185; CHECK:    [[LPAD2]]:186; CHECK-NEXT: [[LPADVAL2:%.*]] = landingpad { ptr, i32 }187; CHECK-NEXT:   cleanup188; CHECK-NEXT:   catch ptr @_ZTIi189; CHECK-NEXT: invoke void @_ZN1AD1Ev(ptr [[A2]])190; CHECK-NEXT:   to label %[[RESUME2:[^\s]+]] unwind191; CHECK: [[RESUME2]]:192; CHECK-NEXT: br label %[[LPAD_JOIN2:[^\s]+]]193 194; CHECK:      ret void195 196; CHECK:    [[LPAD]]:197; CHECK-NEXT: [[X:%.*]] = phi i32 [ 0, %entry ], [ 0, {{%.*}} ], [ 1, %cont ], [ 1, {{%.*}} ]198; CHECK-NEXT: [[Y:%.*]] = phi i32 [ 1, %entry ], [ 1, {{%.*}} ], [ 4, %cont ], [ 4, {{%.*}} ]199; CHECK-NEXT: [[LPADVAL:%.*]] = landingpad { ptr, i32 }200; CHECK-NEXT:   catch ptr @_ZTIi201; CHECK-NEXT: br label %[[LPAD_JOIN2]]202 203; CHECK: [[LPAD_JOIN2]]:204; CHECK-NEXT: [[XJ2:%.*]] = phi i32 [ [[X]], %[[LPAD]] ], [ 1, %[[RESUME2]] ]205; CHECK-NEXT: [[YJ2:%.*]] = phi i32 [ [[Y]], %[[LPAD]] ], [ 4, %[[RESUME2]] ]206; CHECK-NEXT: [[EXNJ2:%.*]] = phi { ptr, i32 } [ [[LPADVAL]], %[[LPAD]] ], [ [[LPADVAL2]], %[[RESUME2]] ]207; CHECK-NEXT: br label %[[LPAD_JOIN1]]208 209; CHECK: [[LPAD_JOIN1]]:210; CHECK-NEXT: [[XJ1:%.*]] = phi i32 [ [[XJ2]], %[[LPAD_JOIN2]] ], [ 0, %[[RESUME1]] ]211; CHECK-NEXT: [[YJ1:%.*]] = phi i32 [ [[YJ2]], %[[LPAD_JOIN2]] ], [ 1, %[[RESUME1]] ]212; CHECK-NEXT: [[EXNJ1:%.*]] = phi { ptr, i32 } [ [[EXNJ2]], %[[LPAD_JOIN2]] ], [ [[LPADVAL1]], %[[RESUME1]] ]213; CHECK-NEXT: extractvalue { ptr, i32 } [[EXNJ1]], 0214; CHECK-NEXT: [[SELJ1:%.*]] = extractvalue { ptr, i32 } [[EXNJ1]], 1215; CHECK-NEXT: [[T:%.*]] = call i32 @llvm.eh.typeid.for.p0(216; CHECK-NEXT: icmp eq i32 [[SELJ1]], [[T]]217 218; CHECK:      call void @use(i32 [[XJ1]])219; CHECK:      call void @use(i32 [[YJ1]])220 221; CHECK:      resume { ptr, i32 }222 223 224;; Test 2 - Don't make invalid IR for inlines into landing pads without eh.exception calls225define void @test2_out() uwtable ssp personality ptr @__gxx_personality_v0 {226entry:227  invoke void @test0_in()228          to label %ret unwind label %lpad229 230ret:231  ret void232 233lpad:234  %exn = landingpad {ptr, i32}235            cleanup236  call void @_ZSt9terminatev()237  unreachable238}239 240; CHECK: define void @test2_out()241; CHECK:      [[A:%.*]] = alloca %struct.A,242; CHECK:      [[B:%.*]] = alloca %struct.A,243; CHECK:      invoke void @_ZN1AC1Ev(ptr [[A]])244; CHECK-NEXT:   unwind label %[[LPAD:[^\s]+]]245; CHECK:      invoke void @_ZN1AC1Ev(ptr [[B]])246; CHECK-NEXT:   unwind label %[[LPAD2:[^\s]+]]247; CHECK:      invoke void @_ZN1AD1Ev(ptr [[B]])248; CHECK-NEXT:   unwind label %[[LPAD2]]249; CHECK:      invoke void @_ZN1AD1Ev(ptr [[A]])250; CHECK-NEXT:   unwind label %[[LPAD]]251 252 253;; Test 3 - Deal correctly with split unwind edges.254define void @test3_out() uwtable ssp personality ptr @__gxx_personality_v0 {255entry:256  invoke void @test0_in()257          to label %ret unwind label %lpad258 259ret:260  ret void261 262lpad:263  %exn = landingpad {ptr, i32}264            catch ptr @_ZTIi265  br label %lpad.cont266 267lpad.cont:268  call void @_ZSt9terminatev()269  unreachable270}271 272; CHECK: define void @test3_out()273; CHECK:      landingpad { ptr, i32 }274; CHECK-NEXT:    cleanup275; CHECK-NEXT:    catch ptr @_ZTIi276; CHECK-NEXT: invoke void @_ZN1AD1Ev(277; CHECK-NEXT:   to label %[[L:[^\s]+]] unwind278; CHECK:    [[L]]:279; CHECK-NEXT: br label %[[JOIN:[^\s]+]]280; CHECK:    [[JOIN]]:281; CHECK-NEXT: phi { ptr, i32 }282; CHECK-NEXT: br label %lpad.cont283; CHECK:    lpad.cont:284; CHECK-NEXT: call void @_ZSt9terminatev()285 286 287;; Test 4 - Split unwind edges with a dominance problem288define void @test4_out() uwtable ssp personality ptr @__gxx_personality_v0 {289entry:290  invoke void @test0_in()291          to label %cont unwind label %lpad.crit292 293cont:294  invoke void @opaque()295          to label %ret unwind label %lpad296 297ret:298  ret void299 300lpad.crit:301  %exn = landingpad {ptr, i32}302            catch ptr @_ZTIi303  call void @opaque() nounwind304  br label %terminate305 306lpad:307  %exn2 = landingpad {ptr, i32}308            catch ptr @_ZTIi309  br label %terminate310 311terminate:312  %phi = phi i32 [ 0, %lpad.crit ], [ 1, %lpad ]313  call void @use(i32 %phi)314  call void @_ZSt9terminatev()315  unreachable316}317 318; CHECK: define void @test4_out()319; CHECK:      landingpad { ptr, i32 }320; CHECK-NEXT:    cleanup321; CHECK-NEXT:    catch ptr @_ZTIi322; CHECK-NEXT: invoke void @_ZN1AD1Ev(323; CHECK-NEXT:   to label %[[L:[^\s]+]] unwind324; CHECK:    [[L]]:325; CHECK-NEXT: br label %[[JOIN:[^\s]+]]326; CHECK:      invoke void @opaque()327; CHECK-NEXT:                  unwind label %lpad328; CHECK:    lpad.crit:329; CHECK-NEXT: landingpad { ptr, i32 }330; CHECK-NEXT:   catch ptr @_ZTIi331; CHECK-NEXT: br label %[[JOIN]]332; CHECK:    [[JOIN]]:333; CHECK-NEXT: phi { ptr, i32 }334; CHECK-NEXT: call void @opaque() [[NUW:#[0-9]+]]335; CHECK-NEXT: br label %[[FIX:[^\s]+]]336; CHECK:    lpad:337; CHECK-NEXT: landingpad { ptr, i32 }338; CHECK-NEXT:   catch ptr @_ZTIi339; CHECK-NEXT: br label %[[FIX]]340; CHECK:    [[FIX]]:341; CHECK-NEXT: [[T1:%.*]] = phi i32 [ 0, %[[JOIN]] ], [ 1, %lpad ]342; CHECK-NEXT: call void @use(i32 [[T1]])343; CHECK-NEXT: call void @_ZSt9terminatev()344 345; CHECK: attributes [[NUW]] = { nounwind }346; CHECK: attributes #1 = { nounwind memory(none) }347; CHECK: attributes #2 = { ssp uwtable }348; CHECK: attributes #3 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }349; CHECK: attributes #4 = { noreturn nounwind }350