244 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals2; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT3; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC4 5; TEST 16define i32 @foo1() {7; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)8; CHECK-LABEL: define {{[^@]+}}@foo19; CHECK-SAME: () #[[ATTR0:[0-9]+]] {10; CHECK-NEXT: ret i32 111;12 ret i32 113}14 15declare void @unknown()16define void @foo2() nounwind {17; CHECK: Function Attrs: nounwind18; CHECK-LABEL: define {{[^@]+}}@foo219; CHECK-SAME: () #[[ATTR1:[0-9]+]] {20; CHECK-NEXT: call void @unknown()21; CHECK-NEXT: ret void22;23 call void @unknown()24 ret void25}26 27; TEST 228define i32 @scc1_foo() {29; TUNIT: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)30; TUNIT-LABEL: define {{[^@]+}}@scc1_foo31; TUNIT-SAME: () #[[ATTR2:[0-9]+]] {32; TUNIT-NEXT: ret i32 133;34; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)35; CGSCC-LABEL: define {{[^@]+}}@scc1_foo36; CGSCC-SAME: () #[[ATTR0]] {37; CGSCC-NEXT: ret i32 138;39 %1 = call i32 @scc1_bar()40 ret i32 141}42 43 44; TEST 345define i32 @scc1_bar() {46; TUNIT: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)47; TUNIT-LABEL: define {{[^@]+}}@scc1_bar48; TUNIT-SAME: () #[[ATTR2]] {49; TUNIT-NEXT: ret i32 150;51; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)52; CGSCC-LABEL: define {{[^@]+}}@scc1_bar53; CGSCC-SAME: () #[[ATTR0]] {54; CGSCC-NEXT: ret i32 155;56 %1 = call i32 @scc1_foo()57 ret i32 158}59 60declare i32 @non_nounwind()61 62; TEST 463define void @call_non_nounwind(){64; CHECK-LABEL: define {{[^@]+}}@call_non_nounwind() {65; CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @non_nounwind()66; CHECK-NEXT: ret void67;68 tail call i32 @non_nounwind()69 ret void70}71 72; TEST 5 - throw73; int maybe_throw(bool canThrow) {74; if (canThrow)75; throw;76; else77; return -1;78; }79 80define i32 @maybe_throw(i1 zeroext %0) {81; CHECK-LABEL: define {{[^@]+}}@maybe_throw82; CHECK-SAME: (i1 noundef zeroext [[TMP0:%.*]]) {83; CHECK-NEXT: br i1 [[TMP0]], label [[TMP2:%.*]], label [[TMP3:%.*]]84; CHECK: 2:85; CHECK-NEXT: tail call void @__cxa_rethrow()86; CHECK-NEXT: unreachable87; CHECK: 3:88; CHECK-NEXT: ret i32 -189;90 br i1 %0, label %2, label %391 922: ; preds = %193 tail call void @__cxa_rethrow() #194 unreachable95 963: ; preds = %197 ret i32 -198}99 100declare void @__cxa_rethrow()101 102; TEST 6 - catch103; int catch_thing() {104; try {105; int a = doThing(true);106; }107; catch(...) { return -1; }108; return 1;109; }110 111define i32 @catch_thing() personality ptr @__gxx_personality_v0 {112; CHECK-LABEL: define {{[^@]+}}@catch_thing() personality ptr @__gxx_personality_v0 {113; CHECK-NEXT: invoke void @__cxa_rethrow()114; CHECK-NEXT: to label [[TMP1:%.*]] unwind label [[TMP2:%.*]]115; CHECK: 1:116; CHECK-NEXT: unreachable117; CHECK: 2:118; CHECK-NEXT: [[TMP3:%.*]] = landingpad { ptr, i32 }119; CHECK-NEXT: catch ptr null120; CHECK-NEXT: [[TMP4:%.*]] = extractvalue { ptr, i32 } [[TMP3]], 0121; CHECK-NEXT: [[TMP5:%.*]] = tail call ptr @__cxa_begin_catch(ptr [[TMP4]])122; CHECK-NEXT: tail call void @__cxa_end_catch()123; CHECK-NEXT: ret i32 -1124;125 invoke void @__cxa_rethrow() #1126 to label %1 unwind label %2127 1281: ; preds = %0129 unreachable130 1312: ; preds = %0132 %3 = landingpad { ptr, i32 }133 catch ptr null134 %4 = extractvalue { ptr, i32 } %3, 0135 %5 = tail call ptr @__cxa_begin_catch(ptr %4) #2136 tail call void @__cxa_end_catch()137 ret i32 -1138}139 140define i32 @catch_thing_user() {141; TUNIT-LABEL: define {{[^@]+}}@catch_thing_user() {142; TUNIT-NEXT: [[CATCH_THING_CALL:%.*]] = call i32 @catch_thing()143; TUNIT-NEXT: ret i32 -1144;145; CGSCC-LABEL: define {{[^@]+}}@catch_thing_user() {146; CGSCC-NEXT: [[CATCH_THING_CALL:%.*]] = call noundef i32 @catch_thing()147; CGSCC-NEXT: ret i32 [[CATCH_THING_CALL]]148;149 %catch_thing_call = call i32 @catch_thing()150 ret i32 %catch_thing_call151}152 153define void @two_potential_callees_pos1(i1 %c) {154; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)155; TUNIT-LABEL: define {{[^@]+}}@two_potential_callees_pos1156; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {157; TUNIT-NEXT: ret void158;159; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn160; CGSCC-LABEL: define {{[^@]+}}@two_potential_callees_pos1161; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR2:[0-9]+]] {162; CGSCC-NEXT: [[FP:%.*]] = select i1 [[C]], ptr @foo1, ptr @scc1_foo163; CGSCC-NEXT: [[TMP1:%.*]] = icmp eq ptr [[FP]], @scc1_foo164; CGSCC-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]165; CGSCC: 2:166; CGSCC-NEXT: call void @scc1_foo()167; CGSCC-NEXT: br label [[TMP6:%.*]]168; CGSCC: 3:169; CGSCC-NEXT: br i1 true, label [[TMP4:%.*]], label [[TMP5:%.*]]170; CGSCC: 4:171; CGSCC-NEXT: call void @foo1()172; CGSCC-NEXT: br label [[TMP6]]173; CGSCC: 5:174; CGSCC-NEXT: unreachable175; CGSCC: 6:176; CGSCC-NEXT: ret void177;178 %fp = select i1 %c, ptr @foo1, ptr @scc1_foo179 call void %fp()180 ret void181}182define void @two_potential_callees_pos2(i1 %c) {183; CHECK: Function Attrs: nounwind184; CHECK-LABEL: define {{[^@]+}}@two_potential_callees_pos2185; CHECK-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {186; CHECK-NEXT: [[FP:%.*]] = select i1 [[C]], ptr @foo2, ptr @scc1_foo187; CHECK-NEXT: [[TMP1:%.*]] = icmp eq ptr [[FP]], @scc1_foo188; CHECK-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]189; CHECK: 2:190; CHECK-NEXT: call void @scc1_foo()191; CHECK-NEXT: br label [[TMP6:%.*]]192; CHECK: 3:193; CHECK-NEXT: br i1 true, label [[TMP4:%.*]], label [[TMP5:%.*]]194; CHECK: 4:195; CHECK-NEXT: call void @foo2()196; CHECK-NEXT: br label [[TMP6]]197; CHECK: 5:198; CHECK-NEXT: unreachable199; CHECK: 6:200; CHECK-NEXT: ret void201;202 %fp = select i1 %c, ptr @foo2, ptr @scc1_foo203 call void %fp()204 ret void205}206define void @two_potential_callees_neg(i1 %c) {207; CHECK-LABEL: define {{[^@]+}}@two_potential_callees_neg208; CHECK-SAME: (i1 [[C:%.*]]) {209; CHECK-NEXT: [[FP:%.*]] = select i1 [[C]], ptr @foo1, ptr @non_nounwind210; CHECK-NEXT: [[TMP1:%.*]] = icmp eq ptr [[FP]], @non_nounwind211; CHECK-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]212; CHECK: 2:213; CHECK-NEXT: call void @non_nounwind()214; CHECK-NEXT: br label [[TMP6:%.*]]215; CHECK: 3:216; CHECK-NEXT: br i1 true, label [[TMP4:%.*]], label [[TMP5:%.*]]217; CHECK: 4:218; CHECK-NEXT: call void @foo1()219; CHECK-NEXT: br label [[TMP6]]220; CHECK: 5:221; CHECK-NEXT: unreachable222; CHECK: 6:223; CHECK-NEXT: ret void224;225 %fp = select i1 %c, ptr @foo1, ptr @non_nounwind226 call void %fp()227 ret void228}229 230declare i32 @__gxx_personality_v0(...)231 232declare ptr @__cxa_begin_catch(ptr)233 234declare void @__cxa_end_catch()235;.236; TUNIT: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }237; TUNIT: attributes #[[ATTR1]] = { nounwind }238; TUNIT: attributes #[[ATTR2]] = { mustprogress nofree nosync nounwind willreturn memory(none) }239;.240; CGSCC: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }241; CGSCC: attributes #[[ATTR1]] = { nounwind }242; CGSCC: attributes #[[ATTR2]] = { mustprogress nofree nosync nounwind willreturn }243;.244