442 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes2; RUN: opt -passes=function-attrs -S < %s | FileCheck --check-prefixes=COMMON,FNATTRS %s3; RUN: opt -passes=attributor-light -S < %s | FileCheck --check-prefixes=COMMON,ATTRIBUTOR %s4 5; TEST 16define i32 @foo1() {7; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)8; FNATTRS-LABEL: define {{[^@]+}}@foo19; FNATTRS-SAME: () #[[ATTR0:[0-9]+]] {10; FNATTRS-NEXT: ret i32 111;12; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)13; ATTRIBUTOR-LABEL: define {{[^@]+}}@foo114; ATTRIBUTOR-SAME: () #[[ATTR0:[0-9]+]] {15; ATTRIBUTOR-NEXT: ret i32 116;17 ret i32 118}19 20; TEST 221define i32 @scc1_foo() {22; FNATTRS: Function Attrs: nofree nosync nounwind memory(none)23; FNATTRS-LABEL: define {{[^@]+}}@scc1_foo24; FNATTRS-SAME: () #[[ATTR1:[0-9]+]] {25; FNATTRS-NEXT: [[TMP1:%.*]] = call i32 @scc1_bar()26; FNATTRS-NEXT: ret i32 127;28; ATTRIBUTOR: Function Attrs: nofree nosync nounwind memory(none)29; ATTRIBUTOR-LABEL: define {{[^@]+}}@scc1_foo30; ATTRIBUTOR-SAME: () #[[ATTR1:[0-9]+]] {31; ATTRIBUTOR-NEXT: [[TMP1:%.*]] = call i32 @scc1_bar() #[[ATTR1]]32; ATTRIBUTOR-NEXT: ret i32 133;34 %1 = call i32 @scc1_bar()35 ret i32 136}37 38 39; TEST 340define i32 @scc1_bar() {41; FNATTRS: Function Attrs: nofree nosync nounwind memory(none)42; FNATTRS-LABEL: define {{[^@]+}}@scc1_bar43; FNATTRS-SAME: () #[[ATTR1]] {44; FNATTRS-NEXT: [[TMP1:%.*]] = call i32 @scc1_foo()45; FNATTRS-NEXT: ret i32 146;47; ATTRIBUTOR: Function Attrs: nofree nosync nounwind memory(none)48; ATTRIBUTOR-LABEL: define {{[^@]+}}@scc1_bar49; ATTRIBUTOR-SAME: () #[[ATTR1]] {50; ATTRIBUTOR-NEXT: [[TMP1:%.*]] = call i32 @scc1_foo() #[[ATTR1]]51; ATTRIBUTOR-NEXT: ret i32 152;53 %1 = call i32 @scc1_foo()54 ret i32 155}56 57declare i32 @non_nounwind()58 59; TEST 460define void @call_non_nounwind(){61; COMMON-LABEL: define {{[^@]+}}@call_non_nounwind() {62; COMMON-NEXT: [[TMP1:%.*]] = tail call i32 @non_nounwind()63; COMMON-NEXT: ret void64;65 tail call i32 @non_nounwind()66 ret void67}68 69; TEST 5 - throw70; int maybe_throw(bool canThrow) {71; if (canThrow)72; throw;73; else74; return -1;75; }76 77define i32 @maybe_throw(i1 zeroext %0) {78; FNATTRS-LABEL: define {{[^@]+}}@maybe_throw79; FNATTRS-SAME: (i1 zeroext [[TMP0:%.*]]) {80; FNATTRS-NEXT: br i1 [[TMP0]], label [[TMP2:%.*]], label [[TMP3:%.*]]81; FNATTRS: 2:82; FNATTRS-NEXT: tail call void @__cxa_rethrow()83; FNATTRS-NEXT: unreachable84; FNATTRS: 3:85; FNATTRS-NEXT: ret i32 -186;87; ATTRIBUTOR-LABEL: define {{[^@]+}}@maybe_throw88; ATTRIBUTOR-SAME: (i1 zeroext [[TMP0:%.*]]) {89; ATTRIBUTOR-NEXT: br i1 [[TMP0]], label [[TMP2:%.*]], label [[TMP3:%.*]]90; ATTRIBUTOR: 2:91; ATTRIBUTOR-NEXT: tail call void @__cxa_rethrow()92; ATTRIBUTOR-NEXT: unreachable93; ATTRIBUTOR: 3:94; ATTRIBUTOR-NEXT: ret i32 -195;96 br i1 %0, label %2, label %397 982: ; preds = %199 tail call void @__cxa_rethrow() #1100 unreachable101 1023: ; preds = %1103 ret i32 -1104}105 106declare void @__cxa_rethrow()107 108; TEST 6 - catch109; int catch_thing() {110; try {111; int a = doThing(true);112; }113; catch(...) { return -1; }114; return 1;115; }116 117define i32 @catch_thing() personality ptr @__gxx_personality_v0 {118; FNATTRS-LABEL: define {{[^@]+}}@catch_thing() personality ptr @__gxx_personality_v0 {119; FNATTRS-NEXT: invoke void @__cxa_rethrow()120; FNATTRS-NEXT: to label [[TMP1:%.*]] unwind label [[TMP2:%.*]]121; FNATTRS: 1:122; FNATTRS-NEXT: unreachable123; FNATTRS: 2:124; FNATTRS-NEXT: [[TMP3:%.*]] = landingpad { ptr, i32 }125; FNATTRS-NEXT: catch ptr null126; FNATTRS-NEXT: [[TMP4:%.*]] = extractvalue { ptr, i32 } [[TMP3]], 0127; FNATTRS-NEXT: [[TMP5:%.*]] = tail call ptr @__cxa_begin_catch(ptr [[TMP4]])128; FNATTRS-NEXT: tail call void @__cxa_end_catch()129; FNATTRS-NEXT: ret i32 -1130;131; ATTRIBUTOR-LABEL: define {{[^@]+}}@catch_thing() personality ptr @__gxx_personality_v0 {132; ATTRIBUTOR-NEXT: invoke void @__cxa_rethrow()133; ATTRIBUTOR-NEXT: to label [[TMP1:%.*]] unwind label [[TMP2:%.*]]134; ATTRIBUTOR: 1:135; ATTRIBUTOR-NEXT: unreachable136; ATTRIBUTOR: 2:137; ATTRIBUTOR-NEXT: [[TMP3:%.*]] = landingpad { ptr, i32 }138; ATTRIBUTOR-NEXT: catch ptr null139; ATTRIBUTOR-NEXT: [[TMP4:%.*]] = extractvalue { ptr, i32 } [[TMP3]], 0140; ATTRIBUTOR-NEXT: [[TMP5:%.*]] = tail call ptr @__cxa_begin_catch(ptr [[TMP4]])141; ATTRIBUTOR-NEXT: tail call void @__cxa_end_catch()142; ATTRIBUTOR-NEXT: ret i32 -1143;144 invoke void @__cxa_rethrow() #1145 to label %1 unwind label %2146 1471: ; preds = %0148 unreachable149 1502: ; preds = %0151 %3 = landingpad { ptr, i32 }152 catch ptr null153 %4 = extractvalue { ptr, i32 } %3, 0154 %5 = tail call ptr @__cxa_begin_catch(ptr %4) #2155 tail call void @__cxa_end_catch()156 ret i32 -1157}158 159define i32 @catch_thing_user() {160; FNATTRS-LABEL: define {{[^@]+}}@catch_thing_user() {161; FNATTRS-NEXT: [[CATCH_THING_CALL:%.*]] = call i32 @catch_thing()162; FNATTRS-NEXT: ret i32 [[CATCH_THING_CALL]]163;164; ATTRIBUTOR-LABEL: define {{[^@]+}}@catch_thing_user() {165; ATTRIBUTOR-NEXT: [[CATCH_THING_CALL:%.*]] = call i32 @catch_thing()166; ATTRIBUTOR-NEXT: ret i32 [[CATCH_THING_CALL]]167;168 %catch_thing_call = call i32 @catch_thing()169 ret i32 %catch_thing_call170}171 172declare void @do_throw()173declare void @abort() nounwind174@catch_ty = external global ptr175 176define void @catch_specific_landingpad() personality ptr @__gxx_personality_v0 {177; COMMON: Function Attrs: noreturn178; COMMON-LABEL: define {{[^@]+}}@catch_specific_landingpad179; COMMON-SAME: () #[[ATTR3:[0-9]+]] personality ptr @__gxx_personality_v0 {180; COMMON-NEXT: invoke void @do_throw()181; COMMON-NEXT: to label [[UNREACHABLE:%.*]] unwind label [[LPAD:%.*]]182; COMMON: lpad:183; COMMON-NEXT: [[LP:%.*]] = landingpad { ptr, i32 }184; COMMON-NEXT: catch ptr @catch_ty185; COMMON-NEXT: call void @abort()186; COMMON-NEXT: unreachable187; COMMON: unreachable:188; COMMON-NEXT: unreachable189;190 invoke void @do_throw()191 to label %unreachable unwind label %lpad192 193lpad:194 %lp = landingpad { ptr, i32 }195 catch ptr @catch_ty196 call void @abort()197 unreachable198 199unreachable:200 unreachable201}202 203define void @catch_all_landingpad() personality ptr @__gxx_personality_v0 {204; COMMON: Function Attrs: noreturn nounwind205; COMMON-LABEL: define {{[^@]+}}@catch_all_landingpad206; COMMON-SAME: () #[[ATTR4:[0-9]+]] personality ptr @__gxx_personality_v0 {207; COMMON-NEXT: invoke void @do_throw()208; COMMON-NEXT: to label [[UNREACHABLE:%.*]] unwind label [[LPAD:%.*]]209; COMMON: lpad:210; COMMON-NEXT: [[LP:%.*]] = landingpad { ptr, i32 }211; COMMON-NEXT: catch ptr null212; COMMON-NEXT: call void @abort()213; COMMON-NEXT: unreachable214; COMMON: unreachable:215; COMMON-NEXT: unreachable216;217 invoke void @do_throw()218 to label %unreachable unwind label %lpad219 220lpad:221 %lp = landingpad { ptr, i32 }222 catch ptr null223 call void @abort()224 unreachable225 226unreachable:227 unreachable228}229 230define void @filter_specific_landingpad() personality ptr @__gxx_personality_v0 {231; COMMON: Function Attrs: noreturn232; COMMON-LABEL: define {{[^@]+}}@filter_specific_landingpad233; COMMON-SAME: () #[[ATTR3]] personality ptr @__gxx_personality_v0 {234; COMMON-NEXT: invoke void @do_throw()235; COMMON-NEXT: to label [[UNREACHABLE:%.*]] unwind label [[LPAD:%.*]]236; COMMON: lpad:237; COMMON-NEXT: [[LP:%.*]] = landingpad { ptr, i32 }238; COMMON-NEXT: filter [1 x ptr] [ptr @catch_ty]239; COMMON-NEXT: call void @abort()240; COMMON-NEXT: unreachable241; COMMON: unreachable:242; COMMON-NEXT: unreachable243;244 invoke void @do_throw()245 to label %unreachable unwind label %lpad246 247lpad:248 %lp = landingpad { ptr, i32 }249 filter [1 x ptr] [ptr @catch_ty]250 call void @abort()251 unreachable252 253unreachable:254 unreachable255}256 257define void @filter_none_landingpad() personality ptr @__gxx_personality_v0 {258; COMMON: Function Attrs: noreturn nounwind259; COMMON-LABEL: define {{[^@]+}}@filter_none_landingpad260; COMMON-SAME: () #[[ATTR4]] personality ptr @__gxx_personality_v0 {261; COMMON-NEXT: invoke void @do_throw()262; COMMON-NEXT: to label [[UNREACHABLE:%.*]] unwind label [[LPAD:%.*]]263; COMMON: lpad:264; COMMON-NEXT: [[LP:%.*]] = landingpad { ptr, i32 }265; COMMON-NEXT: filter [0 x ptr] zeroinitializer266; COMMON-NEXT: call void @abort()267; COMMON-NEXT: unreachable268; COMMON: unreachable:269; COMMON-NEXT: unreachable270;271 invoke void @do_throw()272 to label %unreachable unwind label %lpad273 274lpad:275 %lp = landingpad { ptr, i32 }276 filter [0 x ptr] zeroinitializer277 call void @abort()278 unreachable279 280unreachable:281 unreachable282}283 284define void @cleanup_landingpad() personality ptr @__gxx_personality_v0 {285; COMMON: Function Attrs: noreturn286; COMMON-LABEL: define {{[^@]+}}@cleanup_landingpad287; COMMON-SAME: () #[[ATTR3]] personality ptr @__gxx_personality_v0 {288; COMMON-NEXT: invoke void @do_throw()289; COMMON-NEXT: to label [[UNREACHABLE:%.*]] unwind label [[LPAD:%.*]]290; COMMON: lpad:291; COMMON-NEXT: [[LP:%.*]] = landingpad { ptr, i32 }292; COMMON-NEXT: cleanup293; COMMON-NEXT: call void @abort()294; COMMON-NEXT: unreachable295; COMMON: unreachable:296; COMMON-NEXT: unreachable297;298 invoke void @do_throw()299 to label %unreachable unwind label %lpad300 301lpad:302 %lp = landingpad { ptr, i32 }303 cleanup304 call void @abort()305 unreachable306 307unreachable:308 unreachable309}310 311define void @cleanuppad() personality ptr @__gxx_personality_v0 {312; FNATTRS: Function Attrs: noreturn313; FNATTRS-LABEL: define {{[^@]+}}@cleanuppad314; FNATTRS-SAME: () #[[ATTR3]] personality ptr @__gxx_personality_v0 {315; FNATTRS-NEXT: invoke void @do_throw()316; FNATTRS-NEXT: to label [[UNREACHABLE:%.*]] unwind label [[CPAD:%.*]]317; FNATTRS: cpad:318; FNATTRS-NEXT: [[CP:%.*]] = cleanuppad within none []319; FNATTRS-NEXT: call void @abort()320; FNATTRS-NEXT: unreachable321; FNATTRS: unreachable:322; FNATTRS-NEXT: unreachable323;324; ATTRIBUTOR: Function Attrs: noreturn nounwind325; ATTRIBUTOR-LABEL: define {{[^@]+}}@cleanuppad326; ATTRIBUTOR-SAME: () #[[ATTR4]] personality ptr @__gxx_personality_v0 {327; ATTRIBUTOR-NEXT: invoke void @do_throw()328; ATTRIBUTOR-NEXT: to label [[UNREACHABLE:%.*]] unwind label [[CPAD:%.*]]329; ATTRIBUTOR: cpad:330; ATTRIBUTOR-NEXT: [[CP:%.*]] = cleanuppad within none []331; ATTRIBUTOR-NEXT: call void @abort()332; ATTRIBUTOR-NEXT: unreachable333; ATTRIBUTOR: unreachable:334; ATTRIBUTOR-NEXT: unreachable335;336 invoke void @do_throw()337 to label %unreachable unwind label %cpad338 339cpad:340 %cp = cleanuppad within none []341 call void @abort()342 unreachable343 344unreachable:345 unreachable346}347 348define void @catchswitch_cleanuppad() personality ptr @__gxx_personality_v0 {349; FNATTRS: Function Attrs: noreturn350; FNATTRS-LABEL: define {{[^@]+}}@catchswitch_cleanuppad351; FNATTRS-SAME: () #[[ATTR3]] personality ptr @__gxx_personality_v0 {352; FNATTRS-NEXT: invoke void @do_throw()353; FNATTRS-NEXT: to label [[UNREACHABLE:%.*]] unwind label [[CS:%.*]]354; FNATTRS: cs:355; FNATTRS-NEXT: [[TOK:%.*]] = catchswitch within none [label %catch] unwind label [[CPAD:%.*]]356; FNATTRS: catch:357; FNATTRS-NEXT: [[C:%.*]] = catchpad within [[TOK]] [ptr @catch_ty, i32 0, ptr null]358; FNATTRS-NEXT: call void @abort()359; FNATTRS-NEXT: unreachable360; FNATTRS: cpad:361; FNATTRS-NEXT: [[CP:%.*]] = cleanuppad within none []362; FNATTRS-NEXT: call void @abort()363; FNATTRS-NEXT: unreachable364; FNATTRS: unreachable:365; FNATTRS-NEXT: unreachable366;367; ATTRIBUTOR: Function Attrs: noreturn nounwind368; ATTRIBUTOR-LABEL: define {{[^@]+}}@catchswitch_cleanuppad369; ATTRIBUTOR-SAME: () #[[ATTR4]] personality ptr @__gxx_personality_v0 {370; ATTRIBUTOR-NEXT: invoke void @do_throw()371; ATTRIBUTOR-NEXT: to label [[UNREACHABLE:%.*]] unwind label [[CS:%.*]]372; ATTRIBUTOR: cs:373; ATTRIBUTOR-NEXT: [[TOK:%.*]] = catchswitch within none [label %catch] unwind label [[CPAD:%.*]]374; ATTRIBUTOR: catch:375; ATTRIBUTOR-NEXT: [[C:%.*]] = catchpad within [[TOK]] [ptr @catch_ty, i32 0, ptr null]376; ATTRIBUTOR-NEXT: call void @abort()377; ATTRIBUTOR-NEXT: unreachable378; ATTRIBUTOR: cpad:379; ATTRIBUTOR-NEXT: [[CP:%.*]] = cleanuppad within none []380; ATTRIBUTOR-NEXT: call void @abort()381; ATTRIBUTOR-NEXT: unreachable382; ATTRIBUTOR: unreachable:383; ATTRIBUTOR-NEXT: unreachable384;385 invoke void @do_throw()386 to label %unreachable unwind label %cs387 388cs:389 %tok = catchswitch within none [label %catch] unwind label %cpad390 391catch:392 %c = catchpad within %tok [ptr @catch_ty, i32 0, ptr null]393 call void @abort()394 unreachable395 396cpad:397 %cp = cleanuppad within none []398 call void @abort()399 unreachable400 401unreachable:402 unreachable403}404 405define void @unknown_call(ptr %fn) {406; FNATTRS-LABEL: define {{[^@]+}}@unknown_call407; FNATTRS-SAME: (ptr readonly captures(none) [[FN:%.*]]) {408; FNATTRS-NEXT: call void [[FN]]()409; FNATTRS-NEXT: ret void410;411; ATTRIBUTOR-LABEL: define {{[^@]+}}@unknown_call412; ATTRIBUTOR-SAME: (ptr nofree nonnull captures(none) [[FN:%.*]]) {413; ATTRIBUTOR-NEXT: call void [[FN]]()414; ATTRIBUTOR-NEXT: ret void415;416 call void %fn()417 ret void418}419 420define void @unknown_nounwind_call(ptr %fn) {421; FNATTRS: Function Attrs: nounwind422; FNATTRS-LABEL: define {{[^@]+}}@unknown_nounwind_call423; FNATTRS-SAME: (ptr readonly captures(none) [[FN:%.*]]) #[[ATTR2:[0-9]+]] {424; FNATTRS-NEXT: call void [[FN]]() #[[ATTR2]]425; FNATTRS-NEXT: ret void426;427; ATTRIBUTOR: Function Attrs: nounwind428; ATTRIBUTOR-LABEL: define {{[^@]+}}@unknown_nounwind_call429; ATTRIBUTOR-SAME: (ptr nofree nonnull captures(none) [[FN:%.*]]) #[[ATTR2:[0-9]+]] {430; ATTRIBUTOR-NEXT: call void [[FN]]() #[[ATTR2]]431; ATTRIBUTOR-NEXT: ret void432;433 call void %fn() nounwind434 ret void435}436 437declare i32 @__gxx_personality_v0(...)438 439declare ptr @__cxa_begin_catch(ptr)440 441declare void @__cxa_end_catch()442