1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals 2; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=14 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM 3; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=14 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM 4; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM 5; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM 6 7target datalayout = "e-m:e-i54:64-f80:128-n8:16:32:64-S128" 8 9; Test cases specifically designed for the "willreturn" function attribute. 10; We use FIXME's to indicate problems and missing attributes. 11 12 13; TEST 1 (positive case) 14define void @only_return() #0 { 15; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable 16; CHECK-LABEL: define {{[^@]+}}@only_return 17; CHECK-SAME: () #[[ATTR0:[0-9]+]] { 18; CHECK-NEXT: ret void 19; 20 ret void 21} 22 23 24; TEST 2 (positive & negative case) 25; 2.1 (positive case) 26; recursive function which will halt 27; int fib(int n){ 28; return n<=1? n : fib(n-1) + fib(n-2); 29; } 30 31; FIXME: missing willreturn 32define i32 @fib(i32 %0) local_unnamed_addr #0 { 33; IS__TUNIT_OPM: Function Attrs: nofree noinline nosync nounwind readnone uwtable 34; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@fib 35; IS__TUNIT_OPM-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { 36; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP0]], 2 37; IS__TUNIT_OPM-NEXT: br i1 [[TMP2]], label [[TMP9:%.*]], label [[TMP3:%.*]] 38; IS__TUNIT_OPM: 3: 39; IS__TUNIT_OPM-NEXT: [[TMP4:%.*]] = add nsw i32 [[TMP0]], -1 40; IS__TUNIT_OPM-NEXT: [[TMP5:%.*]] = tail call i32 @fib(i32 [[TMP4]]) #[[ATTR24:[0-9]+]] 41; IS__TUNIT_OPM-NEXT: [[TMP6:%.*]] = add nsw i32 [[TMP0]], -2 42; IS__TUNIT_OPM-NEXT: [[TMP7:%.*]] = tail call i32 @fib(i32 [[TMP6]]) #[[ATTR24]] 43; IS__TUNIT_OPM-NEXT: [[TMP8:%.*]] = add nsw i32 [[TMP7]], [[TMP5]] 44; IS__TUNIT_OPM-NEXT: ret i32 [[TMP8]] 45; IS__TUNIT_OPM: 9: 46; IS__TUNIT_OPM-NEXT: ret i32 [[TMP0]] 47; 48; IS__TUNIT_NPM: Function Attrs: nofree noinline nosync nounwind readnone uwtable 49; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@fib 50; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { 51; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP0]], 2 52; IS__TUNIT_NPM-NEXT: br i1 [[TMP2]], label [[TMP9:%.*]], label [[TMP3:%.*]] 53; IS__TUNIT_NPM: 3: 54; IS__TUNIT_NPM-NEXT: [[TMP4:%.*]] = add nsw i32 [[TMP0]], -1 55; IS__TUNIT_NPM-NEXT: [[TMP5:%.*]] = tail call i32 @fib(i32 [[TMP4]]) #[[ATTR26:[0-9]+]] 56; IS__TUNIT_NPM-NEXT: [[TMP6:%.*]] = add nsw i32 [[TMP0]], -2 57; IS__TUNIT_NPM-NEXT: [[TMP7:%.*]] = tail call i32 @fib(i32 [[TMP6]]) #[[ATTR26]] 58; IS__TUNIT_NPM-NEXT: [[TMP8:%.*]] = add nsw i32 [[TMP7]], [[TMP5]] 59; IS__TUNIT_NPM-NEXT: ret i32 [[TMP8]] 60; IS__TUNIT_NPM: 9: 61; IS__TUNIT_NPM-NEXT: ret i32 [[TMP0]] 62; 63; IS__CGSCC_OPM: Function Attrs: nofree noinline nosync nounwind readnone uwtable 64; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@fib 65; IS__CGSCC_OPM-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { 66; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP0]], 2 67; IS__CGSCC_OPM-NEXT: br i1 [[TMP2]], label [[TMP9:%.*]], label [[TMP3:%.*]] 68; IS__CGSCC_OPM: 3: 69; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = add nsw i32 [[TMP0]], -1 70; IS__CGSCC_OPM-NEXT: [[TMP5:%.*]] = tail call i32 @fib(i32 [[TMP4]]) #[[ATTR17:[0-9]+]] 71; IS__CGSCC_OPM-NEXT: [[TMP6:%.*]] = add nsw i32 [[TMP0]], -2 72; IS__CGSCC_OPM-NEXT: [[TMP7:%.*]] = tail call i32 @fib(i32 [[TMP6]]) #[[ATTR17]] 73; IS__CGSCC_OPM-NEXT: [[TMP8:%.*]] = add nsw i32 [[TMP7]], [[TMP5]] 74; IS__CGSCC_OPM-NEXT: ret i32 [[TMP8]] 75; IS__CGSCC_OPM: 9: 76; IS__CGSCC_OPM-NEXT: ret i32 [[TMP0]] 77; 78; IS__CGSCC_NPM: Function Attrs: nofree noinline nosync nounwind readnone uwtable 79; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@fib 80; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { 81; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP0]], 2 82; IS__CGSCC_NPM-NEXT: br i1 [[TMP2]], label [[TMP9:%.*]], label [[TMP3:%.*]] 83; IS__CGSCC_NPM: 3: 84; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = add nsw i32 [[TMP0]], -1 85; IS__CGSCC_NPM-NEXT: [[TMP5:%.*]] = tail call i32 @fib(i32 [[TMP4]]) #[[ATTR19:[0-9]+]] 86; IS__CGSCC_NPM-NEXT: [[TMP6:%.*]] = add nsw i32 [[TMP0]], -2 87; IS__CGSCC_NPM-NEXT: [[TMP7:%.*]] = tail call i32 @fib(i32 [[TMP6]]) #[[ATTR19]] 88; IS__CGSCC_NPM-NEXT: [[TMP8:%.*]] = add nsw i32 [[TMP7]], [[TMP5]] 89; IS__CGSCC_NPM-NEXT: ret i32 [[TMP8]] 90; IS__CGSCC_NPM: 9: 91; IS__CGSCC_NPM-NEXT: ret i32 [[TMP0]] 92; 93 %2 = icmp slt i32 %0, 2 94 br i1 %2, label %9, label %3 95 96; <label>:3: ; preds = %1 97 %4 = add nsw i32 %0, -1 98 %5 = tail call i32 @fib(i32 %4) 99 %6 = add nsw i32 %0, -2 100 %7 = tail call i32 @fib(i32 %6) 101 %8 = add nsw i32 %7, %5 102 ret i32 %8 103 104; <label>:9: ; preds = %1 105 ret i32 %0 106} 107 108; 2.2 (negative case) 109; recursive function which doesn't stop for some input. 110; int fact_maybe_not_halt(int n) { 111; if (n==0) { 112; return 1; 113; } 114; return fact_maybe_not_halt( n > 0 ? n-1 : n) * n; 115; } 116; fact_maybe_not(-1) doesn't stop. 117 118define i32 @fact_maybe_not_halt(i32 %0) local_unnamed_addr #0 { 119; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable 120; CHECK-LABEL: define {{[^@]+}}@fact_maybe_not_halt 121; CHECK-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] { 122; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP0]], 0 123; CHECK-NEXT: br i1 [[TMP2]], label [[TMP11:%.*]], label [[TMP3:%.*]] 124; CHECK: 3: 125; CHECK-NEXT: [[TMP4:%.*]] = phi i32 [ [[TMP8:%.*]], [[TMP3]] ], [ [[TMP0]], [[TMP1:%.*]] ] 126; CHECK-NEXT: [[TMP5:%.*]] = phi i32 [ [[TMP9:%.*]], [[TMP3]] ], [ 1, [[TMP1]] ] 127; CHECK-NEXT: [[TMP6:%.*]] = icmp sgt i32 [[TMP4]], 0 128; CHECK-NEXT: [[TMP7:%.*]] = sext i1 [[TMP6]] to i32 129; CHECK-NEXT: [[TMP8]] = add nsw i32 [[TMP4]], [[TMP7]] 130; CHECK-NEXT: [[TMP9]] = mul nsw i32 [[TMP4]], [[TMP5]] 131; CHECK-NEXT: [[TMP10:%.*]] = icmp eq i32 [[TMP8]], 0 132; CHECK-NEXT: br i1 [[TMP10]], label [[TMP11]], label [[TMP3]] 133; CHECK: 11: 134; CHECK-NEXT: [[TMP12:%.*]] = phi i32 [ 1, [[TMP1]] ], [ [[TMP9]], [[TMP3]] ] 135; CHECK-NEXT: ret i32 [[TMP12]] 136; 137 %2 = icmp eq i32 %0, 0 138 br i1 %2, label %11, label %3 139 140; <label>:3: ; preds = %1, %3 141 %4 = phi i32 [ %8, %3 ], [ %0, %1 ] 142 %5 = phi i32 [ %9, %3 ], [ 1, %1 ] 143 %6 = icmp sgt i32 %4, 0 144 %7 = sext i1 %6 to i32 145 %8 = add nsw i32 %4, %7 146 %9 = mul nsw i32 %4, %5 147 %10 = icmp eq i32 %8, 0 148 br i1 %10, label %11, label %3 149 150; <label>:11: ; preds = %3, %1 151 %12 = phi i32 [ 1, %1 ], [ %9, %3 ] 152 ret i32 %12 153} 154 155 156; TEST 3 (positive case) 157; loop 158; int fact_loop(int n ){ 159; int ans = 1; 160; for(int i = 1;i<=n;i++){ 161; ans *= i; 162; } 163; return ans; 164; } 165 166define i32 @fact_loop(i32 %0) local_unnamed_addr #0 { 167; IS________OPM: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable 168; IS________OPM-LABEL: define {{[^@]+}}@fact_loop 169; IS________OPM-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2]] { 170; IS________OPM-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP0]], 1 171; IS________OPM-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]] 172; IS________OPM: 3: 173; IS________OPM-NEXT: [[TMP4:%.*]] = phi i32 [ 1, [[TMP1:%.*]] ], [ [[TMP8:%.*]], [[TMP5]] ] 174; IS________OPM-NEXT: ret i32 [[TMP4]] 175; IS________OPM: 5: 176; IS________OPM-NEXT: [[TMP6:%.*]] = phi i32 [ [[TMP9:%.*]], [[TMP5]] ], [ 1, [[TMP1]] ] 177; IS________OPM-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8]], [[TMP5]] ], [ 1, [[TMP1]] ] 178; IS________OPM-NEXT: [[TMP8]] = mul nsw i32 [[TMP6]], [[TMP7]] 179; IS________OPM-NEXT: [[TMP9]] = add nuw nsw i32 [[TMP6]], 1 180; IS________OPM-NEXT: [[TMP10:%.*]] = icmp eq i32 [[TMP6]], [[TMP0]] 181; IS________OPM-NEXT: br i1 [[TMP10]], label [[TMP3]], label [[TMP5]] 182; 183; IS________NPM: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable 184; IS________NPM-LABEL: define {{[^@]+}}@fact_loop 185; IS________NPM-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] { 186; IS________NPM-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP0]], 1 187; IS________NPM-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]] 188; IS________NPM: 3: 189; IS________NPM-NEXT: [[TMP4:%.*]] = phi i32 [ 1, [[TMP1:%.*]] ], [ [[TMP8:%.*]], [[TMP5]] ] 190; IS________NPM-NEXT: ret i32 [[TMP4]] 191; IS________NPM: 5: 192; IS________NPM-NEXT: [[TMP6:%.*]] = phi i32 [ [[TMP9:%.*]], [[TMP5]] ], [ 1, [[TMP1]] ] 193; IS________NPM-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8]], [[TMP5]] ], [ 1, [[TMP1]] ] 194; IS________NPM-NEXT: [[TMP8]] = mul nsw i32 [[TMP6]], [[TMP7]] 195; IS________NPM-NEXT: [[TMP9]] = add nuw nsw i32 [[TMP6]], 1 196; IS________NPM-NEXT: [[TMP10:%.*]] = icmp eq i32 [[TMP6]], [[TMP0]] 197; IS________NPM-NEXT: br i1 [[TMP10]], label [[TMP3]], label [[TMP5]] 198; 199 %2 = icmp slt i32 %0, 1 200 br i1 %2, label %3, label %5 201 202; <label>:3: ; preds = %5, %1 203 %4 = phi i32 [ 1, %1 ], [ %8, %5 ] 204 ret i32 %4 205 206; <label>:5: ; preds = %1, %5 207 %6 = phi i32 [ %9, %5 ], [ 1, %1 ] 208 %7 = phi i32 [ %8, %5 ], [ 1, %1 ] 209 %8 = mul nsw i32 %6, %7 210 %9 = add nuw nsw i32 %6, 1 211 %10 = icmp eq i32 %6, %0 212 br i1 %10, label %3, label %5 213} 214 215; TEST 4 (negative case) 216; mutual recursion 217; void mutual_recursion1(){ 218; mutual_recursion2(); 219; } 220; void mutual_recursion2(){ 221; mutual_recursion1(); 222; } 223 224declare void @sink() nounwind willreturn nosync nofree 225 226define void @mutual_recursion1(i1 %c) #0 { 227; IS________OPM: Function Attrs: nofree noinline nosync nounwind uwtable 228; IS________OPM-LABEL: define {{[^@]+}}@mutual_recursion1 229; IS________OPM-SAME: (i1 [[C:%.*]]) #[[ATTR4:[0-9]+]] { 230; IS________OPM-NEXT: br i1 [[C]], label [[REC:%.*]], label [[END:%.*]] 231; IS________OPM: rec: 232; IS________OPM-NEXT: call void @sink() #[[ATTR12:[0-9]+]] 233; IS________OPM-NEXT: call void @mutual_recursion2(i1 [[C]]) #[[ATTR25:[0-9]+]] 234; IS________OPM-NEXT: br label [[END]] 235; IS________OPM: end: 236; IS________OPM-NEXT: ret void 237; 238; IS________NPM: Function Attrs: nofree noinline nosync nounwind uwtable 239; IS________NPM-LABEL: define {{[^@]+}}@mutual_recursion1 240; IS________NPM-SAME: (i1 [[C:%.*]]) #[[ATTR4:[0-9]+]] { 241; IS________NPM-NEXT: br i1 [[C]], label [[REC:%.*]], label [[END:%.*]] 242; IS________NPM: rec: 243; IS________NPM-NEXT: call void @sink() #[[ATTR12:[0-9]+]] 244; IS________NPM-NEXT: call void @mutual_recursion2(i1 noundef [[C]]) #[[ATTR27:[0-9]+]] 245; IS________NPM-NEXT: br label [[END]] 246; IS________NPM: end: 247; IS________NPM-NEXT: ret void 248; 249 br i1 %c, label %rec, label %end 250rec: 251 call void @sink() 252 call void @mutual_recursion2(i1 %c) 253 br label %end 254end: 255 ret void 256} 257 258 259define void @mutual_recursion2(i1 %c) #0 { 260; IS________OPM: Function Attrs: nofree noinline nosync nounwind uwtable 261; IS________OPM-LABEL: define {{[^@]+}}@mutual_recursion2 262; IS________OPM-SAME: (i1 [[C:%.*]]) #[[ATTR4]] { 263; IS________OPM-NEXT: call void @mutual_recursion1(i1 [[C]]) #[[ATTR25]] 264; IS________OPM-NEXT: ret void 265; 266; IS________NPM: Function Attrs: nofree noinline nosync nounwind uwtable 267; IS________NPM-LABEL: define {{[^@]+}}@mutual_recursion2 268; IS________NPM-SAME: (i1 [[C:%.*]]) #[[ATTR4]] { 269; IS________NPM-NEXT: call void @mutual_recursion1(i1 [[C]]) #[[ATTR27]] 270; IS________NPM-NEXT: ret void 271; 272 call void @mutual_recursion1(i1 %c) 273 ret void 274} 275 276 277; TEST 5 (negative case) 278; call exit/abort (has noreturn attribute) 279; CHECK: Function Attrs: noreturn 280; CHECK-NEXT: declare void @exit(i32) local_unnamed_add 281declare void @exit(i32 %0) local_unnamed_addr noreturn 282 283define void @only_exit() local_unnamed_addr #0 { 284; CHECK: Function Attrs: noinline noreturn nounwind uwtable 285; CHECK-LABEL: define {{[^@]+}}@only_exit 286; CHECK-SAME: () local_unnamed_addr #[[ATTR6:[0-9]+]] { 287; CHECK-NEXT: tail call void @exit(i32 noundef 0) #[[ATTR5:[0-9]+]] 288; CHECK-NEXT: unreachable 289; 290 tail call void @exit(i32 0) 291 unreachable 292} 293 294; conditional exit 295; void conditional_exit(int cond, int *p){ 296; if(cond){ 297; exit(0); 298; } 299; if(*p){ 300; exit(1); 301; } 302; return; 303; } 304define void @conditional_exit(i32 %0, i32* nocapture readonly %1) local_unnamed_addr #0 { 305; CHECK: Function Attrs: noinline nounwind uwtable 306; CHECK-LABEL: define {{[^@]+}}@conditional_exit 307; CHECK-SAME: (i32 [[TMP0:%.*]], i32* nocapture nofree readonly [[TMP1:%.*]]) local_unnamed_addr #[[ATTR7:[0-9]+]] { 308; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0 309; CHECK-NEXT: br i1 [[TMP3]], label [[TMP5:%.*]], label [[TMP4:%.*]] 310; CHECK: 4: 311; CHECK-NEXT: tail call void @exit(i32 noundef 0) #[[ATTR5]] 312; CHECK-NEXT: unreachable 313; CHECK: 5: 314; CHECK-NEXT: [[TMP6:%.*]] = load i32, i32* [[TMP1]], align 4 315; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i32 [[TMP6]], 0 316; CHECK-NEXT: br i1 [[TMP7]], label [[TMP9:%.*]], label [[TMP8:%.*]] 317; CHECK: 8: 318; CHECK-NEXT: tail call void @exit(i32 noundef 1) #[[ATTR5]] 319; CHECK-NEXT: unreachable 320; CHECK: 9: 321; CHECK-NEXT: ret void 322; 323 %3 = icmp eq i32 %0, 0 324 br i1 %3, label %5, label %4 325 326; <label>:4: ; preds = %2 327 tail call void @exit(i32 0) 328 unreachable 329 330; <label>:5: ; preds = %2 331 %6 = load i32, i32* %1, align 4 332 %7 = icmp eq i32 %6, 0 333 br i1 %7, label %9, label %8 334 335; <label>:8: ; preds = %5 336 tail call void @exit(i32 1) 337 unreachable 338 339; <label>:9: ; preds = %5 340 ret void 341} 342 343; TEST 6 (positive case) 344; Call intrinsic function 345; CHECK: Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn 346; CHECK-NEXT: declare float @llvm.floor.f32(float) 347declare float @llvm.floor.f32(float) 348 349define void @call_floor(float %a) #0 { 350; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable 351; CHECK-LABEL: define {{[^@]+}}@call_floor 352; CHECK-SAME: (float [[A:%.*]]) #[[ATTR0]] { 353; CHECK-NEXT: ret void 354; 355 tail call float @llvm.floor.f32(float %a) 356 ret void 357} 358 359define float @call_floor2(float %a) #0 { 360; IS________OPM: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable 361; IS________OPM-LABEL: define {{[^@]+}}@call_floor2 362; IS________OPM-SAME: (float [[A:%.*]]) #[[ATTR0]] { 363; IS________OPM-NEXT: [[C:%.*]] = tail call float @llvm.floor.f32(float [[A]]) #[[ATTR26:[0-9]+]] 364; IS________OPM-NEXT: ret float [[C]] 365; 366; IS________NPM: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable 367; IS________NPM-LABEL: define {{[^@]+}}@call_floor2 368; IS________NPM-SAME: (float [[A:%.*]]) #[[ATTR0]] { 369; IS________NPM-NEXT: [[C:%.*]] = tail call float @llvm.floor.f32(float [[A]]) #[[ATTR28:[0-9]+]] 370; IS________NPM-NEXT: ret float [[C]] 371; 372 %c = tail call float @llvm.floor.f32(float %a) 373 ret float %c 374} 375 376 377; TEST 7 (negative case) 378; Call function declaration without willreturn 379 380; CHECK: Function Attrs: noinline nounwind uwtable 381; CHECK-NOT: willreturn 382; CHECK-NEXT: declare void @maybe_noreturn() 383declare void @maybe_noreturn() #0 384 385define void @call_maybe_noreturn() #0 { 386; IS________OPM: Function Attrs: noinline nounwind uwtable 387; IS________OPM-LABEL: define {{[^@]+}}@call_maybe_noreturn 388; IS________OPM-SAME: () #[[ATTR7]] { 389; IS________OPM-NEXT: tail call void @maybe_noreturn() #[[ATTR27:[0-9]+]] 390; IS________OPM-NEXT: ret void 391; 392; IS________NPM: Function Attrs: noinline nounwind uwtable 393; IS________NPM-LABEL: define {{[^@]+}}@call_maybe_noreturn 394; IS________NPM-SAME: () #[[ATTR7]] { 395; IS________NPM-NEXT: tail call void @maybe_noreturn() #[[ATTR29:[0-9]+]] 396; IS________NPM-NEXT: ret void 397; 398 tail call void @maybe_noreturn() 399 ret void 400} 401 402 403; TEST 8 (positive case) 404; Check propagation. 405 406; CHECK: Function Attrs: norecurse willreturn 407; CHECK-NEXT: declare void @will_return() 408declare void @will_return() willreturn norecurse 409 410define void @f1() #0 { 411; IS________OPM: Function Attrs: noinline nounwind willreturn uwtable 412; IS________OPM-LABEL: define {{[^@]+}}@f1 413; IS________OPM-SAME: () #[[ATTR10:[0-9]+]] { 414; IS________OPM-NEXT: tail call void @will_return() #[[ATTR28:[0-9]+]] 415; IS________OPM-NEXT: ret void 416; 417; IS________NPM: Function Attrs: noinline nounwind willreturn uwtable 418; IS________NPM-LABEL: define {{[^@]+}}@f1 419; IS________NPM-SAME: () #[[ATTR10:[0-9]+]] { 420; IS________NPM-NEXT: tail call void @will_return() #[[ATTR30:[0-9]+]] 421; IS________NPM-NEXT: ret void 422; 423 tail call void @will_return() 424 ret void 425} 426 427define void @f2() #0 { 428; CHECK: Function Attrs: noinline nounwind willreturn uwtable 429; CHECK-LABEL: define {{[^@]+}}@f2 430; CHECK-SAME: () #[[ATTR10:[0-9]+]] { 431; CHECK-NEXT: tail call void @f1() #[[ATTR12:[0-9]+]] 432; CHECK-NEXT: ret void 433; 434 tail call void @f1() 435 ret void 436} 437 438 439; TEST 9 (negative case) 440; call willreturn function in endless loop. 441 442define void @call_will_return_but_has_loop() #0 { 443; CHECK: Function Attrs: noinline noreturn nounwind uwtable 444; CHECK-LABEL: define {{[^@]+}}@call_will_return_but_has_loop 445; CHECK-SAME: () #[[ATTR6]] { 446; CHECK-NEXT: br label [[LABEL1:%.*]] 447; CHECK: label1: 448; CHECK-NEXT: tail call void @will_return() 449; CHECK-NEXT: br label [[LABEL2:%.*]] 450; CHECK: label2: 451; CHECK-NEXT: br label [[LABEL1]] 452; 453 br label %label1 454label1: 455 tail call void @will_return() 456 br label %label2 457label2: 458 br label %label1 459} 460 461 462; TEST 10 (positive case) 463; invoke a function with willreturn 464 465; CHECK: Function Attrs: noinline willreturn uwtable 466; CHECK-NEXT: declare i1 @maybe_raise_exception() 467declare i1 @maybe_raise_exception() #1 willreturn 468 469define void @invoke_test() personality i32 (...)* @__gxx_personality_v0 { 470; IS________OPM: Function Attrs: nounwind willreturn 471; IS________OPM-LABEL: define {{[^@]+}}@invoke_test 472; IS________OPM-SAME: () #[[ATTR12]] personality i32 (...)* @__gxx_personality_v0 { 473; IS________OPM-NEXT: [[TMP1:%.*]] = invoke i1 @maybe_raise_exception() #[[ATTR28]] 474; IS________OPM-NEXT: to label [[N:%.*]] unwind label [[F:%.*]] 475; IS________OPM: N: 476; IS________OPM-NEXT: ret void 477; IS________OPM: F: 478; IS________OPM-NEXT: [[VAL:%.*]] = landingpad { i8*, i32 } 479; IS________OPM-NEXT: catch i8* null 480; IS________OPM-NEXT: ret void 481; 482; IS________NPM: Function Attrs: nounwind willreturn 483; IS________NPM-LABEL: define {{[^@]+}}@invoke_test 484; IS________NPM-SAME: () #[[ATTR12]] personality i32 (...)* @__gxx_personality_v0 { 485; IS________NPM-NEXT: [[TMP1:%.*]] = invoke i1 @maybe_raise_exception() #[[ATTR30]] 486; IS________NPM-NEXT: to label [[N:%.*]] unwind label [[F:%.*]] 487; IS________NPM: N: 488; IS________NPM-NEXT: ret void 489; IS________NPM: F: 490; IS________NPM-NEXT: [[VAL:%.*]] = landingpad { i8*, i32 } 491; IS________NPM-NEXT: catch i8* null 492; IS________NPM-NEXT: ret void 493; 494 invoke i1 @maybe_raise_exception() 495 to label %N unwind label %F 496 N: 497 ret void 498 F: 499 %val = landingpad { i8*, i32 } 500 catch i8* null 501 ret void 502} 503 504declare i32 @__gxx_personality_v0(...) 505 506 507; TEST 11 (positive case) 508; constant trip count 509; int loop_constant_trip_count(int*p){ 510; int ans = 0; 511; for(int i = 0;i<10;i++){ 512; ans += p[i]; 513; } 514; return ans; 515; } 516 517define i32 @loop_constant_trip_count(i32* nocapture readonly %0) #0 { 518; IS________OPM: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly uwtable 519; IS________OPM-LABEL: define {{[^@]+}}@loop_constant_trip_count 520; IS________OPM-SAME: (i32* nocapture nofree readonly [[TMP0:%.*]]) #[[ATTR13:[0-9]+]] { 521; IS________OPM-NEXT: br label [[TMP3:%.*]] 522; IS________OPM: 2: 523; IS________OPM-NEXT: ret i32 [[TMP8:%.*]] 524; IS________OPM: 3: 525; IS________OPM-NEXT: [[TMP4:%.*]] = phi i64 [ 0, [[TMP1:%.*]] ], [ [[TMP9:%.*]], [[TMP3]] ] 526; IS________OPM-NEXT: [[TMP5:%.*]] = phi i32 [ 0, [[TMP1]] ], [ [[TMP8]], [[TMP3]] ] 527; IS________OPM-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 [[TMP4]] 528; IS________OPM-NEXT: [[TMP7:%.*]] = load i32, i32* [[TMP6]], align 4 529; IS________OPM-NEXT: [[TMP8]] = add nsw i32 [[TMP7]], [[TMP5]] 530; IS________OPM-NEXT: [[TMP9]] = add nuw nsw i64 [[TMP4]], 1 531; IS________OPM-NEXT: [[TMP10:%.*]] = icmp eq i64 [[TMP9]], 10 532; IS________OPM-NEXT: br i1 [[TMP10]], label [[TMP2:%.*]], label [[TMP3]] 533; 534; IS________NPM: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly willreturn uwtable 535; IS________NPM-LABEL: define {{[^@]+}}@loop_constant_trip_count 536; IS________NPM-SAME: (i32* nocapture nofree nonnull readonly dereferenceable(4) [[TMP0:%.*]]) #[[ATTR13:[0-9]+]] { 537; IS________NPM-NEXT: br label [[TMP3:%.*]] 538; IS________NPM: 2: 539; IS________NPM-NEXT: ret i32 [[TMP8:%.*]] 540; IS________NPM: 3: 541; IS________NPM-NEXT: [[TMP4:%.*]] = phi i64 [ 0, [[TMP1:%.*]] ], [ [[TMP9:%.*]], [[TMP3]] ] 542; IS________NPM-NEXT: [[TMP5:%.*]] = phi i32 [ 0, [[TMP1]] ], [ [[TMP8]], [[TMP3]] ] 543; IS________NPM-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 [[TMP4]] 544; IS________NPM-NEXT: [[TMP7:%.*]] = load i32, i32* [[TMP6]], align 4 545; IS________NPM-NEXT: [[TMP8]] = add nsw i32 [[TMP7]], [[TMP5]] 546; IS________NPM-NEXT: [[TMP9]] = add nuw nsw i64 [[TMP4]], 1 547; IS________NPM-NEXT: [[TMP10:%.*]] = icmp eq i64 [[TMP9]], 10 548; IS________NPM-NEXT: br i1 [[TMP10]], label [[TMP2:%.*]], label [[TMP3]] 549; 550 br label %3 551 552; <label>:2: ; preds = %3 553 ret i32 %8 554 555; <label>:3: ; preds = %3, %1 556 %4 = phi i64 [ 0, %1 ], [ %9, %3 ] 557 %5 = phi i32 [ 0, %1 ], [ %8, %3 ] 558 %6 = getelementptr inbounds i32, i32* %0, i64 %4 559 %7 = load i32, i32* %6, align 4 560 %8 = add nsw i32 %7, %5 561 %9 = add nuw nsw i64 %4, 1 562 %10 = icmp eq i64 %9, 10 563 br i1 %10, label %2, label %3 564} 565 566 567; TEST 12 (negative case) 568; unbounded trip count 569 570; int loop_trip_count_unbound(unsigned s,unsigned e, int *p, int offset){ 571; int ans = 0; 572; for(unsigned i = s;i != e;i+=offset){ 573; ans += p[i]; 574; } 575; return ans; 576; } 577define i32 @loop_trip_count_unbound(i32 %0, i32 %1, i32* nocapture readonly %2, i32 %3) local_unnamed_addr #0 { 578; IS________OPM: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly uwtable 579; IS________OPM-LABEL: define {{[^@]+}}@loop_trip_count_unbound 580; IS________OPM-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]], i32* nocapture nofree readonly [[TMP2:%.*]], i32 [[TMP3:%.*]]) local_unnamed_addr #[[ATTR13]] { 581; IS________OPM-NEXT: [[TMP5:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]] 582; IS________OPM-NEXT: br i1 [[TMP5]], label [[TMP6:%.*]], label [[TMP8:%.*]] 583; IS________OPM: 6: 584; IS________OPM-NEXT: [[TMP7:%.*]] = phi i32 [ 0, [[TMP4:%.*]] ], [ [[TMP14:%.*]], [[TMP8]] ] 585; IS________OPM-NEXT: ret i32 [[TMP7]] 586; IS________OPM: 8: 587; IS________OPM-NEXT: [[TMP9:%.*]] = phi i32 [ [[TMP15:%.*]], [[TMP8]] ], [ [[TMP0]], [[TMP4]] ] 588; IS________OPM-NEXT: [[TMP10:%.*]] = phi i32 [ [[TMP14]], [[TMP8]] ], [ 0, [[TMP4]] ] 589; IS________OPM-NEXT: [[TMP11:%.*]] = zext i32 [[TMP9]] to i64 590; IS________OPM-NEXT: [[TMP12:%.*]] = getelementptr inbounds i32, i32* [[TMP2]], i64 [[TMP11]] 591; IS________OPM-NEXT: [[TMP13:%.*]] = load i32, i32* [[TMP12]], align 4 592; IS________OPM-NEXT: [[TMP14]] = add nsw i32 [[TMP13]], [[TMP10]] 593; IS________OPM-NEXT: [[TMP15]] = add i32 [[TMP9]], [[TMP3]] 594; IS________OPM-NEXT: [[TMP16:%.*]] = icmp eq i32 [[TMP15]], [[TMP1]] 595; IS________OPM-NEXT: br i1 [[TMP16]], label [[TMP6]], label [[TMP8]] 596; 597; IS________NPM: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly uwtable 598; IS________NPM-LABEL: define {{[^@]+}}@loop_trip_count_unbound 599; IS________NPM-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]], i32* nocapture nofree readonly [[TMP2:%.*]], i32 [[TMP3:%.*]]) local_unnamed_addr #[[ATTR14:[0-9]+]] { 600; IS________NPM-NEXT: [[TMP5:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]] 601; IS________NPM-NEXT: br i1 [[TMP5]], label [[TMP6:%.*]], label [[TMP8:%.*]] 602; IS________NPM: 6: 603; IS________NPM-NEXT: [[TMP7:%.*]] = phi i32 [ 0, [[TMP4:%.*]] ], [ [[TMP14:%.*]], [[TMP8]] ] 604; IS________NPM-NEXT: ret i32 [[TMP7]] 605; IS________NPM: 8: 606; IS________NPM-NEXT: [[TMP9:%.*]] = phi i32 [ [[TMP15:%.*]], [[TMP8]] ], [ [[TMP0]], [[TMP4]] ] 607; IS________NPM-NEXT: [[TMP10:%.*]] = phi i32 [ [[TMP14]], [[TMP8]] ], [ 0, [[TMP4]] ] 608; IS________NPM-NEXT: [[TMP11:%.*]] = zext i32 [[TMP9]] to i64 609; IS________NPM-NEXT: [[TMP12:%.*]] = getelementptr inbounds i32, i32* [[TMP2]], i64 [[TMP11]] 610; IS________NPM-NEXT: [[TMP13:%.*]] = load i32, i32* [[TMP12]], align 4 611; IS________NPM-NEXT: [[TMP14]] = add nsw i32 [[TMP13]], [[TMP10]] 612; IS________NPM-NEXT: [[TMP15]] = add i32 [[TMP9]], [[TMP3]] 613; IS________NPM-NEXT: [[TMP16:%.*]] = icmp eq i32 [[TMP15]], [[TMP1]] 614; IS________NPM-NEXT: br i1 [[TMP16]], label [[TMP6]], label [[TMP8]] 615; 616 %5 = icmp eq i32 %0, %1 617 br i1 %5, label %6, label %8 618 619; <label>:6: ; preds = %8, %4 620 %7 = phi i32 [ 0, %4 ], [ %14, %8 ] 621 ret i32 %7 622 623; <label>:8: ; preds = %4, %8 624 %9 = phi i32 [ %15, %8 ], [ %0, %4 ] 625 %10 = phi i32 [ %14, %8 ], [ 0, %4 ] 626 %11 = zext i32 %9 to i64 627 %12 = getelementptr inbounds i32, i32* %2, i64 %11 628 %13 = load i32, i32* %12, align 4 629 %14 = add nsw i32 %13, %10 630 %15 = add i32 %9, %3 631 %16 = icmp eq i32 %15, %1 632 br i1 %16, label %6, label %8 633} 634 635 636; TEST 13 (positive case) 637; Function Attrs: norecurse nounwind readonly uwtable 638; int loop_trip_dec(int n, int *p){ 639; int ans = 0; 640; for(;n >= 0;n--){ 641; ans += p[n]; 642; } 643; return ans; 644; } 645 646 647define i32 @loop_trip_dec(i32 %0, i32* nocapture readonly %1) local_unnamed_addr #0 { 648; IS________OPM: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly uwtable 649; IS________OPM-LABEL: define {{[^@]+}}@loop_trip_dec 650; IS________OPM-SAME: (i32 [[TMP0:%.*]], i32* nocapture nofree readonly [[TMP1:%.*]]) local_unnamed_addr #[[ATTR13]] { 651; IS________OPM-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP0]], -1 652; IS________OPM-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP14:%.*]] 653; IS________OPM: 4: 654; IS________OPM-NEXT: [[TMP5:%.*]] = sext i32 [[TMP0]] to i64 655; IS________OPM-NEXT: br label [[TMP6:%.*]] 656; IS________OPM: 6: 657; IS________OPM-NEXT: [[TMP7:%.*]] = phi i64 [ [[TMP5]], [[TMP4]] ], [ [[TMP12:%.*]], [[TMP6]] ] 658; IS________OPM-NEXT: [[TMP8:%.*]] = phi i32 [ 0, [[TMP4]] ], [ [[TMP11:%.*]], [[TMP6]] ] 659; IS________OPM-NEXT: [[TMP9:%.*]] = getelementptr inbounds i32, i32* [[TMP1]], i64 [[TMP7]] 660; IS________OPM-NEXT: [[TMP10:%.*]] = load i32, i32* [[TMP9]], align 4 661; IS________OPM-NEXT: [[TMP11]] = add nsw i32 [[TMP10]], [[TMP8]] 662; IS________OPM-NEXT: [[TMP12]] = add nsw i64 [[TMP7]], -1 663; IS________OPM-NEXT: [[TMP13:%.*]] = icmp sgt i64 [[TMP7]], 0 664; IS________OPM-NEXT: br i1 [[TMP13]], label [[TMP6]], label [[TMP14]] 665; IS________OPM: 14: 666; IS________OPM-NEXT: [[TMP15:%.*]] = phi i32 [ 0, [[TMP2:%.*]] ], [ [[TMP11]], [[TMP6]] ] 667; IS________OPM-NEXT: ret i32 [[TMP15]] 668; 669; IS________NPM: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly willreturn uwtable 670; IS________NPM-LABEL: define {{[^@]+}}@loop_trip_dec 671; IS________NPM-SAME: (i32 [[TMP0:%.*]], i32* nocapture nofree readonly [[TMP1:%.*]]) local_unnamed_addr #[[ATTR13]] { 672; IS________NPM-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP0]], -1 673; IS________NPM-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP14:%.*]] 674; IS________NPM: 4: 675; IS________NPM-NEXT: [[TMP5:%.*]] = sext i32 [[TMP0]] to i64 676; IS________NPM-NEXT: br label [[TMP6:%.*]] 677; IS________NPM: 6: 678; IS________NPM-NEXT: [[TMP7:%.*]] = phi i64 [ [[TMP5]], [[TMP4]] ], [ [[TMP12:%.*]], [[TMP6]] ] 679; IS________NPM-NEXT: [[TMP8:%.*]] = phi i32 [ 0, [[TMP4]] ], [ [[TMP11:%.*]], [[TMP6]] ] 680; IS________NPM-NEXT: [[TMP9:%.*]] = getelementptr inbounds i32, i32* [[TMP1]], i64 [[TMP7]] 681; IS________NPM-NEXT: [[TMP10:%.*]] = load i32, i32* [[TMP9]], align 4 682; IS________NPM-NEXT: [[TMP11]] = add nsw i32 [[TMP10]], [[TMP8]] 683; IS________NPM-NEXT: [[TMP12]] = add nsw i64 [[TMP7]], -1 684; IS________NPM-NEXT: [[TMP13:%.*]] = icmp sgt i64 [[TMP7]], 0 685; IS________NPM-NEXT: br i1 [[TMP13]], label [[TMP6]], label [[TMP14]] 686; IS________NPM: 14: 687; IS________NPM-NEXT: [[TMP15:%.*]] = phi i32 [ 0, [[TMP2:%.*]] ], [ [[TMP11]], [[TMP6]] ] 688; IS________NPM-NEXT: ret i32 [[TMP15]] 689; 690 %3 = icmp sgt i32 %0, -1 691 br i1 %3, label %4, label %14 692 693; <label>:4: ; preds = %2 694 %5 = sext i32 %0 to i64 695 br label %6 696 697; <label>:6: ; preds = %4, %6 698 %7 = phi i64 [ %5, %4 ], [ %12, %6 ] 699 %8 = phi i32 [ 0, %4 ], [ %11, %6 ] 700 %9 = getelementptr inbounds i32, i32* %1, i64 %7 701 %10 = load i32, i32* %9, align 4 702 %11 = add nsw i32 %10, %8 703 %12 = add nsw i64 %7, -1 704 %13 = icmp sgt i64 %7, 0 705 br i1 %13, label %6, label %14 706 707; <label>:14: ; preds = %6, %2 708 %15 = phi i32 [ 0, %2 ], [ %11, %6 ] 709 ret i32 %15 710} 711 712; TEST 14 (positive case) 713; multiple return 714 715define i32 @multiple_return(i32 %a) #0 { 716; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable 717; CHECK-LABEL: define {{[^@]+}}@multiple_return 718; CHECK-SAME: (i32 [[A:%.*]]) #[[ATTR0]] { 719; CHECK-NEXT: [[B:%.*]] = icmp eq i32 [[A]], 0 720; CHECK-NEXT: br i1 [[B]], label [[T:%.*]], label [[F:%.*]] 721; CHECK: t: 722; CHECK-NEXT: ret i32 1 723; CHECK: f: 724; CHECK-NEXT: ret i32 0 725; 726 %b = icmp eq i32 %a, 0 727 br i1 %b, label %t, label %f 728 729t: 730 ret i32 1 731f: 732 ret i32 0 733} 734 735; TEST 15 (positive & negative case) 736; unreachable exit 737 738; 15.1 (positive case) 739define void @unreachable_exit_positive1() #0 { 740; IS________OPM: Function Attrs: noinline nounwind willreturn uwtable 741; IS________OPM-LABEL: define {{[^@]+}}@unreachable_exit_positive1 742; IS________OPM-SAME: () #[[ATTR10]] { 743; IS________OPM-NEXT: tail call void @will_return() #[[ATTR28]] 744; IS________OPM-NEXT: ret void 745; IS________OPM: unreachable_label: 746; IS________OPM-NEXT: unreachable 747; 748; IS________NPM: Function Attrs: noinline nounwind willreturn uwtable 749; IS________NPM-LABEL: define {{[^@]+}}@unreachable_exit_positive1 750; IS________NPM-SAME: () #[[ATTR10]] { 751; IS________NPM-NEXT: tail call void @will_return() #[[ATTR30]] 752; IS________NPM-NEXT: ret void 753; IS________NPM: unreachable_label: 754; IS________NPM-NEXT: unreachable 755; 756 tail call void @will_return() 757 ret void 758 759unreachable_label: 760 tail call void @exit(i32 0) 761 unreachable 762} 763 764define i32 @unreachable_exit_positive2(i32) local_unnamed_addr #0 { 765; IS________OPM: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable 766; IS________OPM-LABEL: define {{[^@]+}}@unreachable_exit_positive2 767; IS________OPM-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2]] { 768; IS________OPM-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP0]], 1 769; IS________OPM-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]] 770; IS________OPM: 3: 771; IS________OPM-NEXT: [[TMP4:%.*]] = phi i32 [ 1, [[TMP1:%.*]] ], [ [[TMP8:%.*]], [[TMP5]] ] 772; IS________OPM-NEXT: ret i32 [[TMP4]] 773; IS________OPM: 5: 774; IS________OPM-NEXT: [[TMP6:%.*]] = phi i32 [ [[TMP9:%.*]], [[TMP5]] ], [ 1, [[TMP1]] ] 775; IS________OPM-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8]], [[TMP5]] ], [ 1, [[TMP1]] ] 776; IS________OPM-NEXT: [[TMP8]] = mul nsw i32 [[TMP6]], [[TMP7]] 777; IS________OPM-NEXT: [[TMP9]] = add nuw nsw i32 [[TMP6]], 1 778; IS________OPM-NEXT: [[TMP10:%.*]] = icmp eq i32 [[TMP6]], [[TMP0]] 779; IS________OPM-NEXT: br i1 [[TMP10]], label [[TMP3]], label [[TMP5]] 780; IS________OPM: unreachable_label: 781; IS________OPM-NEXT: unreachable 782; 783; IS________NPM: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable 784; IS________NPM-LABEL: define {{[^@]+}}@unreachable_exit_positive2 785; IS________NPM-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] { 786; IS________NPM-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP0]], 1 787; IS________NPM-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]] 788; IS________NPM: 3: 789; IS________NPM-NEXT: [[TMP4:%.*]] = phi i32 [ 1, [[TMP1:%.*]] ], [ [[TMP8:%.*]], [[TMP5]] ] 790; IS________NPM-NEXT: ret i32 [[TMP4]] 791; IS________NPM: 5: 792; IS________NPM-NEXT: [[TMP6:%.*]] = phi i32 [ [[TMP9:%.*]], [[TMP5]] ], [ 1, [[TMP1]] ] 793; IS________NPM-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8]], [[TMP5]] ], [ 1, [[TMP1]] ] 794; IS________NPM-NEXT: [[TMP8]] = mul nsw i32 [[TMP6]], [[TMP7]] 795; IS________NPM-NEXT: [[TMP9]] = add nuw nsw i32 [[TMP6]], 1 796; IS________NPM-NEXT: [[TMP10:%.*]] = icmp eq i32 [[TMP6]], [[TMP0]] 797; IS________NPM-NEXT: br i1 [[TMP10]], label [[TMP3]], label [[TMP5]] 798; IS________NPM: unreachable_label: 799; IS________NPM-NEXT: unreachable 800; 801 %2 = icmp slt i32 %0, 1 802 br i1 %2, label %3, label %5 803 804; <label>:3: ; preds = %5, %1 805 %4 = phi i32 [ 1, %1 ], [ %8, %5 ] 806 ret i32 %4 807 808; <label>:5: ; preds = %1, %5 809 %6 = phi i32 [ %9, %5 ], [ 1, %1 ] 810 %7 = phi i32 [ %8, %5 ], [ 1, %1 ] 811 %8 = mul nsw i32 %6, %7 812 %9 = add nuw nsw i32 %6, 1 813 %10 = icmp eq i32 %6, %0 814 br i1 %10, label %3, label %5 815 816unreachable_label: 817 tail call void @exit(i32 0) 818 unreachable 819} 820 821 822;15.2 823 824define void @unreachable_exit_negative1() #0 { 825; CHECK: Function Attrs: noinline nounwind uwtable 826; CHECK-LABEL: define {{[^@]+}}@unreachable_exit_negative1 827; CHECK-SAME: () #[[ATTR7]] { 828; CHECK-NEXT: tail call void @exit(i32 noundef 0) #[[ATTR5]] 829; CHECK-NEXT: unreachable 830; CHECK: unreachable_label: 831; CHECK-NEXT: unreachable 832; 833 tail call void @exit(i32 0) 834 ret void 835 836unreachable_label: 837 tail call void @exit(i32 0) 838 unreachable 839} 840 841define void @unreachable_exit_negative2() #0 { 842; IS________OPM: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable 843; IS________OPM-LABEL: define {{[^@]+}}@unreachable_exit_negative2 844; IS________OPM-SAME: () #[[ATTR14:[0-9]+]] { 845; IS________OPM-NEXT: br label [[L1:%.*]] 846; IS________OPM: L1: 847; IS________OPM-NEXT: br label [[L2:%.*]] 848; IS________OPM: L2: 849; IS________OPM-NEXT: br label [[L1]] 850; IS________OPM: unreachable_label: 851; IS________OPM-NEXT: unreachable 852; 853; IS________NPM: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable 854; IS________NPM-LABEL: define {{[^@]+}}@unreachable_exit_negative2 855; IS________NPM-SAME: () #[[ATTR15:[0-9]+]] { 856; IS________NPM-NEXT: br label [[L1:%.*]] 857; IS________NPM: L1: 858; IS________NPM-NEXT: br label [[L2:%.*]] 859; IS________NPM: L2: 860; IS________NPM-NEXT: br label [[L1]] 861; IS________NPM: unreachable_label: 862; IS________NPM-NEXT: unreachable 863; 864 br label %L1 865L1: 866 br label %L2 867L2: 868 br label %L1 869 870unreachable_label: 871 tail call void @exit(i32 0) 872 unreachable 873} 874 875; CHECK: Function Attrs: noreturn nounwind 876; CHECK-NEXT: declare void @llvm.eh.sjlj.longjmp(i8*) 877declare void @llvm.eh.sjlj.longjmp(i8*) 878 879define void @call_longjmp(i8* nocapture readnone %0) local_unnamed_addr #0 { 880; CHECK: Function Attrs: noinline nounwind uwtable 881; CHECK-LABEL: define {{[^@]+}}@call_longjmp 882; CHECK-SAME: (i8* nocapture readnone [[TMP0:%.*]]) local_unnamed_addr #[[ATTR7]] { 883; CHECK-NEXT: tail call void @llvm.eh.sjlj.longjmp(i8* noalias readnone [[TMP0]]) #[[ATTR5]] 884; CHECK-NEXT: unreachable 885; 886 tail call void @llvm.eh.sjlj.longjmp(i8* %0) 887 ret void 888} 889 890 891; TEST 16 (negative case) 892; int infinite_loop_inside_bounded_loop(int n) { 893; int ans = 0; 894; for (int i = 0; i < n; i++) { 895; while (1) 896; ans++; 897; } 898; return ans; 899; } 900 901define i32 @infinite_loop_inside_bounded_loop(i32 %n) { 902; IS________OPM: Function Attrs: nofree norecurse nosync nounwind readnone 903; IS________OPM-LABEL: define {{[^@]+}}@infinite_loop_inside_bounded_loop 904; IS________OPM-SAME: (i32 [[N:%.*]]) #[[ATTR16:[0-9]+]] { 905; IS________OPM-NEXT: entry: 906; IS________OPM-NEXT: br label [[FOR_COND:%.*]] 907; IS________OPM: for.cond: 908; IS________OPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[N]], 0 909; IS________OPM-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]] 910; IS________OPM: for.cond.cleanup: 911; IS________OPM-NEXT: br label [[FOR_END:%.*]] 912; IS________OPM: for.body: 913; IS________OPM-NEXT: br label [[WHILE_COND:%.*]] 914; IS________OPM: while.cond: 915; IS________OPM-NEXT: br label [[WHILE_BODY:%.*]] 916; IS________OPM: while.body: 917; IS________OPM-NEXT: br label [[WHILE_COND]] 918; IS________OPM: for.inc: 919; IS________OPM-NEXT: unreachable 920; IS________OPM: for.end: 921; IS________OPM-NEXT: ret i32 0 922; 923; IS________NPM: Function Attrs: nofree norecurse nosync nounwind readnone 924; IS________NPM-LABEL: define {{[^@]+}}@infinite_loop_inside_bounded_loop 925; IS________NPM-SAME: (i32 [[N:%.*]]) #[[ATTR17:[0-9]+]] { 926; IS________NPM-NEXT: entry: 927; IS________NPM-NEXT: br label [[FOR_COND:%.*]] 928; IS________NPM: for.cond: 929; IS________NPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[N]], 0 930; IS________NPM-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]] 931; IS________NPM: for.cond.cleanup: 932; IS________NPM-NEXT: br label [[FOR_END:%.*]] 933; IS________NPM: for.body: 934; IS________NPM-NEXT: br label [[WHILE_COND:%.*]] 935; IS________NPM: while.cond: 936; IS________NPM-NEXT: br label [[WHILE_BODY:%.*]] 937; IS________NPM: while.body: 938; IS________NPM-NEXT: br label [[WHILE_COND]] 939; IS________NPM: for.inc: 940; IS________NPM-NEXT: unreachable 941; IS________NPM: for.end: 942; IS________NPM-NEXT: ret i32 0 943; 944entry: 945 br label %for.cond 946 947for.cond: ; preds = %for.inc, %entry 948 %cmp = icmp sgt i32 %n, 0 949 br i1 %cmp, label %for.body, label %for.cond.cleanup 950 951for.cond.cleanup: ; preds = %for.cond 952 br label %for.end 953 954for.body: ; preds = %for.cond 955 br label %while.cond 956 957while.cond: ; preds = %while.body, %for.body 958 br label %while.body 959 960while.body: ; preds = %while.cond 961 br label %while.cond 962 963for.inc: ; No predecessors! 964 br label %for.cond 965 966for.end: ; preds = %for.cond.cleanup 967 ret i32 0 968} 969 970 971; TEST 17 (positive case) 972; Nested loops with constant max trip count 973; int bounded_nested_loops(int n) { 974; int ans = 0; 975; for (int i = 0; i < n; i++) { 976; while (n--) { 977; ans++; 978; } 979; } 980; return ans; 981; } 982 983define i32 @bounded_nested_loops(i32 %n) { 984; IS________OPM: Function Attrs: nofree norecurse nosync nounwind readnone 985; IS________OPM-LABEL: define {{[^@]+}}@bounded_nested_loops 986; IS________OPM-SAME: (i32 [[N:%.*]]) #[[ATTR16]] { 987; IS________OPM-NEXT: entry: 988; IS________OPM-NEXT: br label [[FOR_COND:%.*]] 989; IS________OPM: for.cond: 990; IS________OPM-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC1:%.*]], [[FOR_INC:%.*]] ] 991; IS________OPM-NEXT: [[ANS_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[TMP:%.*]], [[FOR_INC]] ] 992; IS________OPM-NEXT: [[N_ADDR_0:%.*]] = phi i32 [ [[N]], [[ENTRY]] ], [ -1, [[FOR_INC]] ] 993; IS________OPM-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], [[N_ADDR_0]] 994; IS________OPM-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]] 995; IS________OPM: for.cond.cleanup: 996; IS________OPM-NEXT: [[ANS_0_LCSSA:%.*]] = phi i32 [ [[ANS_0]], [[FOR_COND]] ] 997; IS________OPM-NEXT: br label [[FOR_END:%.*]] 998; IS________OPM: for.body: 999; IS________OPM-NEXT: br label [[WHILE_COND:%.*]] 1000; IS________OPM: while.cond: 1001; IS________OPM-NEXT: br i1 true, label [[WHILE_END:%.*]], label [[WHILE_BODY:%.*]] 1002; IS________OPM: while.body: 1003; IS________OPM-NEXT: unreachable 1004; IS________OPM: while.end: 1005; IS________OPM-NEXT: [[TMP]] = add i32 [[N_ADDR_0]], [[ANS_0]] 1006; IS________OPM-NEXT: br label [[FOR_INC]] 1007; IS________OPM: for.inc: 1008; IS________OPM-NEXT: [[INC1]] = add nuw nsw i32 [[I_0]], 1 1009; IS________OPM-NEXT: br label [[FOR_COND]] 1010; IS________OPM: for.end: 1011; IS________OPM-NEXT: ret i32 [[ANS_0_LCSSA]] 1012; 1013; IS________NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 1014; IS________NPM-LABEL: define {{[^@]+}}@bounded_nested_loops 1015; IS________NPM-SAME: (i32 [[N:%.*]]) #[[ATTR18:[0-9]+]] { 1016; IS________NPM-NEXT: entry: 1017; IS________NPM-NEXT: br label [[FOR_COND:%.*]] 1018; IS________NPM: for.cond: 1019; IS________NPM-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC1:%.*]], [[FOR_INC:%.*]] ] 1020; IS________NPM-NEXT: [[ANS_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[TMP:%.*]], [[FOR_INC]] ] 1021; IS________NPM-NEXT: [[N_ADDR_0:%.*]] = phi i32 [ [[N]], [[ENTRY]] ], [ -1, [[FOR_INC]] ] 1022; IS________NPM-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], [[N_ADDR_0]] 1023; IS________NPM-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]] 1024; IS________NPM: for.cond.cleanup: 1025; IS________NPM-NEXT: [[ANS_0_LCSSA:%.*]] = phi i32 [ [[ANS_0]], [[FOR_COND]] ] 1026; IS________NPM-NEXT: br label [[FOR_END:%.*]] 1027; IS________NPM: for.body: 1028; IS________NPM-NEXT: br label [[WHILE_COND:%.*]] 1029; IS________NPM: while.cond: 1030; IS________NPM-NEXT: br i1 true, label [[WHILE_END:%.*]], label [[WHILE_BODY:%.*]] 1031; IS________NPM: while.body: 1032; IS________NPM-NEXT: unreachable 1033; IS________NPM: while.end: 1034; IS________NPM-NEXT: [[TMP]] = add i32 [[N_ADDR_0]], [[ANS_0]] 1035; IS________NPM-NEXT: br label [[FOR_INC]] 1036; IS________NPM: for.inc: 1037; IS________NPM-NEXT: [[INC1]] = add nuw nsw i32 [[I_0]], 1 1038; IS________NPM-NEXT: br label [[FOR_COND]] 1039; IS________NPM: for.end: 1040; IS________NPM-NEXT: ret i32 [[ANS_0_LCSSA]] 1041; 1042entry: 1043 br label %for.cond 1044 1045for.cond: ; preds = %for.inc, %entry 1046 %i.0 = phi i32 [ 0, %entry ], [ %inc1, %for.inc ] 1047 %ans.0 = phi i32 [ 0, %entry ], [ %tmp, %for.inc ] 1048 %n.addr.0 = phi i32 [ %n, %entry ], [ -1, %for.inc ] 1049 %cmp = icmp slt i32 %i.0, %n.addr.0 1050 br i1 %cmp, label %for.body, label %for.cond.cleanup 1051 1052for.cond.cleanup: ; preds = %for.cond 1053 %ans.0.lcssa = phi i32 [ %ans.0, %for.cond ] 1054 br label %for.end 1055 1056for.body: ; preds = %for.cond 1057 br label %while.cond 1058 1059while.cond: ; preds = %while.body, %for.body 1060 br i1 true, label %while.end, label %while.body 1061 1062while.body: ; preds = %while.cond 1063 br label %while.cond 1064 1065while.end: ; preds = %while.cond 1066 %tmp = add i32 %n.addr.0, %ans.0 1067 br label %for.inc 1068 1069for.inc: ; preds = %while.end 1070 %inc1 = add nuw nsw i32 %i.0, 1 1071 br label %for.cond 1072 1073for.end: ; preds = %for.cond.cleanup 1074 ret i32 %ans.0.lcssa 1075} 1076 1077 1078; TEST 18 (negative case) 1079; int bounded_loop_inside_unbounded_loop(int n) { 1080; int ans = 0; 1081; while (n++) { 1082; for (int i = 0; i < n; i++) { 1083; ans++; 1084; } 1085; } 1086; return ans; 1087; } 1088 1089define i32 @bounded_loop_inside_unbounded_loop(i32 %n) { 1090; IS________OPM: Function Attrs: nofree norecurse nosync nounwind readnone 1091; IS________OPM-LABEL: define {{[^@]+}}@bounded_loop_inside_unbounded_loop 1092; IS________OPM-SAME: (i32 [[N:%.*]]) #[[ATTR16]] { 1093; IS________OPM-NEXT: entry: 1094; IS________OPM-NEXT: br label [[WHILE_COND:%.*]] 1095; IS________OPM: while.cond: 1096; IS________OPM-NEXT: [[ANS_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP2:%.*]], [[FOR_END:%.*]] ] 1097; IS________OPM-NEXT: [[N_ADDR_0:%.*]] = phi i32 [ [[N]], [[ENTRY]] ], [ [[INC:%.*]], [[FOR_END]] ] 1098; IS________OPM-NEXT: [[TMP:%.*]] = icmp sgt i32 [[N_ADDR_0]], -1 1099; IS________OPM-NEXT: [[SMAX:%.*]] = select i1 [[TMP]], i32 [[N_ADDR_0]], i32 -1 1100; IS________OPM-NEXT: [[INC]] = add nsw i32 [[N_ADDR_0]], 1 1101; IS________OPM-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[N_ADDR_0]], 0 1102; IS________OPM-NEXT: br i1 [[TOBOOL]], label [[WHILE_END:%.*]], label [[WHILE_BODY:%.*]] 1103; IS________OPM: while.body: 1104; IS________OPM-NEXT: [[TMP1:%.*]] = add i32 [[ANS_0]], 1 1105; IS________OPM-NEXT: br label [[FOR_COND:%.*]] 1106; IS________OPM: for.cond: 1107; IS________OPM-NEXT: br i1 true, label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY:%.*]] 1108; IS________OPM: for.cond.cleanup: 1109; IS________OPM-NEXT: [[TMP2]] = add i32 [[TMP1]], [[SMAX]] 1110; IS________OPM-NEXT: br label [[FOR_END]] 1111; IS________OPM: for.body: 1112; IS________OPM-NEXT: unreachable 1113; IS________OPM: for.inc: 1114; IS________OPM-NEXT: unreachable 1115; IS________OPM: for.end: 1116; IS________OPM-NEXT: br label [[WHILE_COND]] 1117; IS________OPM: while.end: 1118; IS________OPM-NEXT: [[ANS_0_LCSSA:%.*]] = phi i32 [ [[ANS_0]], [[WHILE_COND]] ] 1119; IS________OPM-NEXT: ret i32 [[ANS_0_LCSSA]] 1120; 1121; IS________NPM: Function Attrs: nofree norecurse nosync nounwind readnone 1122; IS________NPM-LABEL: define {{[^@]+}}@bounded_loop_inside_unbounded_loop 1123; IS________NPM-SAME: (i32 [[N:%.*]]) #[[ATTR17]] { 1124; IS________NPM-NEXT: entry: 1125; IS________NPM-NEXT: br label [[WHILE_COND:%.*]] 1126; IS________NPM: while.cond: 1127; IS________NPM-NEXT: [[ANS_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP2:%.*]], [[FOR_END:%.*]] ] 1128; IS________NPM-NEXT: [[N_ADDR_0:%.*]] = phi i32 [ [[N]], [[ENTRY]] ], [ [[INC:%.*]], [[FOR_END]] ] 1129; IS________NPM-NEXT: [[TMP:%.*]] = icmp sgt i32 [[N_ADDR_0]], -1 1130; IS________NPM-NEXT: [[SMAX:%.*]] = select i1 [[TMP]], i32 [[N_ADDR_0]], i32 -1 1131; IS________NPM-NEXT: [[INC]] = add nsw i32 [[N_ADDR_0]], 1 1132; IS________NPM-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[N_ADDR_0]], 0 1133; IS________NPM-NEXT: br i1 [[TOBOOL]], label [[WHILE_END:%.*]], label [[WHILE_BODY:%.*]] 1134; IS________NPM: while.body: 1135; IS________NPM-NEXT: [[TMP1:%.*]] = add i32 [[ANS_0]], 1 1136; IS________NPM-NEXT: br label [[FOR_COND:%.*]] 1137; IS________NPM: for.cond: 1138; IS________NPM-NEXT: br i1 true, label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY:%.*]] 1139; IS________NPM: for.cond.cleanup: 1140; IS________NPM-NEXT: [[TMP2]] = add i32 [[TMP1]], [[SMAX]] 1141; IS________NPM-NEXT: br label [[FOR_END]] 1142; IS________NPM: for.body: 1143; IS________NPM-NEXT: unreachable 1144; IS________NPM: for.inc: 1145; IS________NPM-NEXT: unreachable 1146; IS________NPM: for.end: 1147; IS________NPM-NEXT: br label [[WHILE_COND]] 1148; IS________NPM: while.end: 1149; IS________NPM-NEXT: [[ANS_0_LCSSA:%.*]] = phi i32 [ [[ANS_0]], [[WHILE_COND]] ] 1150; IS________NPM-NEXT: ret i32 [[ANS_0_LCSSA]] 1151; 1152entry: 1153 br label %while.cond 1154 1155while.cond: ; preds = %for.end, %entry 1156 %ans.0 = phi i32 [ 0, %entry ], [ %tmp2, %for.end ] 1157 %n.addr.0 = phi i32 [ %n, %entry ], [ %inc, %for.end ] 1158 %tmp = icmp sgt i32 %n.addr.0, -1 1159 %smax = select i1 %tmp, i32 %n.addr.0, i32 -1 1160 %inc = add nsw i32 %n.addr.0, 1 1161 %tobool = icmp eq i32 %n.addr.0, 0 1162 br i1 %tobool, label %while.end, label %while.body 1163 1164while.body: ; preds = %while.cond 1165 %tmp1 = add i32 %ans.0, 1 1166 br label %for.cond 1167 1168for.cond: ; preds = %for.inc, %while.body 1169 br i1 true, label %for.cond.cleanup, label %for.body 1170 1171for.cond.cleanup: ; preds = %for.cond 1172 %tmp2 = add i32 %tmp1, %smax 1173 br label %for.end 1174 1175for.body: ; preds = %for.cond 1176 br label %for.inc 1177 1178for.inc: ; preds = %for.body 1179 br label %for.cond 1180 1181for.end: ; preds = %for.cond.cleanup 1182 br label %while.cond 1183 1184while.end: ; preds = %while.cond 1185 %ans.0.lcssa = phi i32 [ %ans.0, %while.cond ] 1186 ret i32 %ans.0.lcssa 1187} 1188 1189 1190; TEST 19 (negative case) 1191; int nested_unbounded_loops(int n) { 1192; int ans = 0; 1193; while (n--) { 1194; while (n--) { 1195; ans++; 1196; } 1197; while (n--) { 1198; ans++; 1199; } 1200; } 1201; return ans; 1202; } 1203 1204define i32 @nested_unbounded_loops(i32 %n) { 1205; IS________OPM: Function Attrs: nofree norecurse nosync nounwind readnone 1206; IS________OPM-LABEL: define {{[^@]+}}@nested_unbounded_loops 1207; IS________OPM-SAME: (i32 [[N:%.*]]) #[[ATTR16]] { 1208; IS________OPM-NEXT: entry: 1209; IS________OPM-NEXT: br label [[WHILE_COND:%.*]] 1210; IS________OPM: while.cond: 1211; IS________OPM-NEXT: [[ANS_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP1:%.*]], [[WHILE_END10:%.*]] ] 1212; IS________OPM-NEXT: [[N_ADDR_0:%.*]] = phi i32 [ [[N]], [[ENTRY]] ], [ -1, [[WHILE_END10]] ] 1213; IS________OPM-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[N_ADDR_0]], 0 1214; IS________OPM-NEXT: br i1 [[TOBOOL]], label [[WHILE_END11:%.*]], label [[WHILE_BODY:%.*]] 1215; IS________OPM: while.body: 1216; IS________OPM-NEXT: br label [[WHILE_COND1:%.*]] 1217; IS________OPM: while.cond1: 1218; IS________OPM-NEXT: br i1 true, label [[WHILE_END:%.*]], label [[WHILE_BODY4:%.*]] 1219; IS________OPM: while.body4: 1220; IS________OPM-NEXT: unreachable 1221; IS________OPM: while.end: 1222; IS________OPM-NEXT: [[TMP:%.*]] = add i32 [[N_ADDR_0]], -2 1223; IS________OPM-NEXT: br label [[WHILE_COND5:%.*]] 1224; IS________OPM: while.cond5: 1225; IS________OPM-NEXT: br i1 true, label [[WHILE_END10]], label [[WHILE_BODY8:%.*]] 1226; IS________OPM: while.body8: 1227; IS________OPM-NEXT: unreachable 1228; IS________OPM: while.end10: 1229; IS________OPM-NEXT: [[TMP1]] = add i32 [[TMP]], [[ANS_0]] 1230; IS________OPM-NEXT: br label [[WHILE_COND]] 1231; IS________OPM: while.end11: 1232; IS________OPM-NEXT: [[ANS_0_LCSSA:%.*]] = phi i32 [ [[ANS_0]], [[WHILE_COND]] ] 1233; IS________OPM-NEXT: ret i32 [[ANS_0_LCSSA]] 1234; 1235; IS________NPM: Function Attrs: nofree norecurse nosync nounwind readnone 1236; IS________NPM-LABEL: define {{[^@]+}}@nested_unbounded_loops 1237; IS________NPM-SAME: (i32 [[N:%.*]]) #[[ATTR17]] { 1238; IS________NPM-NEXT: entry: 1239; IS________NPM-NEXT: br label [[WHILE_COND:%.*]] 1240; IS________NPM: while.cond: 1241; IS________NPM-NEXT: [[ANS_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP1:%.*]], [[WHILE_END10:%.*]] ] 1242; IS________NPM-NEXT: [[N_ADDR_0:%.*]] = phi i32 [ [[N]], [[ENTRY]] ], [ -1, [[WHILE_END10]] ] 1243; IS________NPM-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[N_ADDR_0]], 0 1244; IS________NPM-NEXT: br i1 [[TOBOOL]], label [[WHILE_END11:%.*]], label [[WHILE_BODY:%.*]] 1245; IS________NPM: while.body: 1246; IS________NPM-NEXT: br label [[WHILE_COND1:%.*]] 1247; IS________NPM: while.cond1: 1248; IS________NPM-NEXT: br i1 true, label [[WHILE_END:%.*]], label [[WHILE_BODY4:%.*]] 1249; IS________NPM: while.body4: 1250; IS________NPM-NEXT: unreachable 1251; IS________NPM: while.end: 1252; IS________NPM-NEXT: [[TMP:%.*]] = add i32 [[N_ADDR_0]], -2 1253; IS________NPM-NEXT: br label [[WHILE_COND5:%.*]] 1254; IS________NPM: while.cond5: 1255; IS________NPM-NEXT: br i1 true, label [[WHILE_END10]], label [[WHILE_BODY8:%.*]] 1256; IS________NPM: while.body8: 1257; IS________NPM-NEXT: unreachable 1258; IS________NPM: while.end10: 1259; IS________NPM-NEXT: [[TMP1]] = add i32 [[TMP]], [[ANS_0]] 1260; IS________NPM-NEXT: br label [[WHILE_COND]] 1261; IS________NPM: while.end11: 1262; IS________NPM-NEXT: [[ANS_0_LCSSA:%.*]] = phi i32 [ [[ANS_0]], [[WHILE_COND]] ] 1263; IS________NPM-NEXT: ret i32 [[ANS_0_LCSSA]] 1264; 1265entry: 1266 br label %while.cond 1267 1268while.cond: ; preds = %while.end10, %entry 1269 %ans.0 = phi i32 [ 0, %entry ], [ %tmp1, %while.end10 ] 1270 %n.addr.0 = phi i32 [ %n, %entry ], [ -1, %while.end10 ] 1271 %tobool = icmp eq i32 %n.addr.0, 0 1272 br i1 %tobool, label %while.end11, label %while.body 1273 1274while.body: ; preds = %while.cond 1275 br label %while.cond1 1276 1277while.cond1: ; preds = %while.body4, %while.body 1278 br i1 true, label %while.end, label %while.body4 1279 1280while.body4: ; preds = %while.cond1 1281 br label %while.cond1 1282 1283while.end: ; preds = %while.cond1 1284 %tmp = add i32 %n.addr.0, -2 1285 br label %while.cond5 1286 1287while.cond5: ; preds = %while.body8, %while.end 1288 br i1 true, label %while.end10, label %while.body8 1289 1290while.body8: ; preds = %while.cond5 1291 br label %while.cond5 1292 1293while.end10: ; preds = %while.cond5 1294 %tmp1 = add i32 %tmp, %ans.0 1295 br label %while.cond 1296 1297while.end11: ; preds = %while.cond 1298 %ans.0.lcssa = phi i32 [ %ans.0, %while.cond ] 1299 ret i32 %ans.0.lcssa 1300} 1301 1302 1303; TEST 20 (negative case) 1304; void non_loop_cycle(int n) { 1305; if (fact_loop(n)>5) 1306; goto entry1; 1307; else 1308; goto entry2; 1309; 1310; entry1: 1311; if (fact_loop(n)>5) 1312; goto exit; 1313; else 1314; goto entry2; 1315; entry2: 1316; if (fact_loop(n)>5) 1317; goto exit; 1318; else 1319; goto entry1; 1320; exit: 1321; return; 1322; } 1323 1324define void @non_loop_cycle(i32 %n) { 1325; IS__TUNIT_OPM: Function Attrs: nofree norecurse nosync nounwind readnone 1326; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@non_loop_cycle 1327; IS__TUNIT_OPM-SAME: (i32 [[N:%.*]]) #[[ATTR16]] { 1328; IS__TUNIT_OPM-NEXT: entry: 1329; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call i32 @fact_loop(i32 [[N]]) #[[ATTR24]] 1330; IS__TUNIT_OPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[CALL]], 5 1331; IS__TUNIT_OPM-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 1332; IS__TUNIT_OPM: if.then: 1333; IS__TUNIT_OPM-NEXT: br label [[ENTRY1:%.*]] 1334; IS__TUNIT_OPM: if.else: 1335; IS__TUNIT_OPM-NEXT: br label [[ENTRY2:%.*]] 1336; IS__TUNIT_OPM: entry1: 1337; IS__TUNIT_OPM-NEXT: [[CALL1:%.*]] = call i32 @fact_loop(i32 [[N]]) #[[ATTR24]] 1338; IS__TUNIT_OPM-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[CALL1]], 5 1339; IS__TUNIT_OPM-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_ELSE4:%.*]] 1340; IS__TUNIT_OPM: if.then3: 1341; IS__TUNIT_OPM-NEXT: br label [[EXIT:%.*]] 1342; IS__TUNIT_OPM: if.else4: 1343; IS__TUNIT_OPM-NEXT: br label [[ENTRY2]] 1344; IS__TUNIT_OPM: entry2: 1345; IS__TUNIT_OPM-NEXT: [[CALL5:%.*]] = call i32 @fact_loop(i32 [[N]]) #[[ATTR24]] 1346; IS__TUNIT_OPM-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[CALL5]], 5 1347; IS__TUNIT_OPM-NEXT: br i1 [[CMP6]], label [[IF_THEN7:%.*]], label [[IF_ELSE8:%.*]] 1348; IS__TUNIT_OPM: if.then7: 1349; IS__TUNIT_OPM-NEXT: br label [[EXIT]] 1350; IS__TUNIT_OPM: if.else8: 1351; IS__TUNIT_OPM-NEXT: br label [[ENTRY1]] 1352; IS__TUNIT_OPM: exit: 1353; IS__TUNIT_OPM-NEXT: ret void 1354; 1355; IS__TUNIT_NPM: Function Attrs: nofree norecurse nosync nounwind readnone 1356; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@non_loop_cycle 1357; IS__TUNIT_NPM-SAME: (i32 [[N:%.*]]) #[[ATTR17]] { 1358; IS__TUNIT_NPM-NEXT: entry: 1359; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = call i32 @fact_loop(i32 [[N]]) #[[ATTR26]] 1360; IS__TUNIT_NPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[CALL]], 5 1361; IS__TUNIT_NPM-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 1362; IS__TUNIT_NPM: if.then: 1363; IS__TUNIT_NPM-NEXT: br label [[ENTRY1:%.*]] 1364; IS__TUNIT_NPM: if.else: 1365; IS__TUNIT_NPM-NEXT: br label [[ENTRY2:%.*]] 1366; IS__TUNIT_NPM: entry1: 1367; IS__TUNIT_NPM-NEXT: [[CALL1:%.*]] = call i32 @fact_loop(i32 [[N]]) #[[ATTR26]] 1368; IS__TUNIT_NPM-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[CALL1]], 5 1369; IS__TUNIT_NPM-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_ELSE4:%.*]] 1370; IS__TUNIT_NPM: if.then3: 1371; IS__TUNIT_NPM-NEXT: br label [[EXIT:%.*]] 1372; IS__TUNIT_NPM: if.else4: 1373; IS__TUNIT_NPM-NEXT: br label [[ENTRY2]] 1374; IS__TUNIT_NPM: entry2: 1375; IS__TUNIT_NPM-NEXT: [[CALL5:%.*]] = call i32 @fact_loop(i32 [[N]]) #[[ATTR26]] 1376; IS__TUNIT_NPM-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[CALL5]], 5 1377; IS__TUNIT_NPM-NEXT: br i1 [[CMP6]], label [[IF_THEN7:%.*]], label [[IF_ELSE8:%.*]] 1378; IS__TUNIT_NPM: if.then7: 1379; IS__TUNIT_NPM-NEXT: br label [[EXIT]] 1380; IS__TUNIT_NPM: if.else8: 1381; IS__TUNIT_NPM-NEXT: br label [[ENTRY1]] 1382; IS__TUNIT_NPM: exit: 1383; IS__TUNIT_NPM-NEXT: ret void 1384; 1385; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone 1386; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@non_loop_cycle 1387; IS__CGSCC_OPM-SAME: (i32 [[N:%.*]]) #[[ATTR17]] { 1388; IS__CGSCC_OPM-NEXT: entry: 1389; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call i32 @fact_loop(i32 [[N]]) #[[ATTR29:[0-9]+]] 1390; IS__CGSCC_OPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[CALL]], 5 1391; IS__CGSCC_OPM-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 1392; IS__CGSCC_OPM: if.then: 1393; IS__CGSCC_OPM-NEXT: br label [[ENTRY1:%.*]] 1394; IS__CGSCC_OPM: if.else: 1395; IS__CGSCC_OPM-NEXT: br label [[ENTRY2:%.*]] 1396; IS__CGSCC_OPM: entry1: 1397; IS__CGSCC_OPM-NEXT: [[CALL1:%.*]] = call i32 @fact_loop(i32 [[N]]) #[[ATTR29]] 1398; IS__CGSCC_OPM-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[CALL1]], 5 1399; IS__CGSCC_OPM-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_ELSE4:%.*]] 1400; IS__CGSCC_OPM: if.then3: 1401; IS__CGSCC_OPM-NEXT: br label [[EXIT:%.*]] 1402; IS__CGSCC_OPM: if.else4: 1403; IS__CGSCC_OPM-NEXT: br label [[ENTRY2]] 1404; IS__CGSCC_OPM: entry2: 1405; IS__CGSCC_OPM-NEXT: [[CALL5:%.*]] = call i32 @fact_loop(i32 [[N]]) #[[ATTR29]] 1406; IS__CGSCC_OPM-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[CALL5]], 5 1407; IS__CGSCC_OPM-NEXT: br i1 [[CMP6]], label [[IF_THEN7:%.*]], label [[IF_ELSE8:%.*]] 1408; IS__CGSCC_OPM: if.then7: 1409; IS__CGSCC_OPM-NEXT: br label [[EXIT]] 1410; IS__CGSCC_OPM: if.else8: 1411; IS__CGSCC_OPM-NEXT: br label [[ENTRY1]] 1412; IS__CGSCC_OPM: exit: 1413; IS__CGSCC_OPM-NEXT: ret void 1414; 1415; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone 1416; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@non_loop_cycle 1417; IS__CGSCC_NPM-SAME: (i32 [[N:%.*]]) #[[ATTR19]] { 1418; IS__CGSCC_NPM-NEXT: entry: 1419; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call i32 @fact_loop(i32 [[N]]) 1420; IS__CGSCC_NPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[CALL]], 5 1421; IS__CGSCC_NPM-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 1422; IS__CGSCC_NPM: if.then: 1423; IS__CGSCC_NPM-NEXT: br label [[ENTRY1:%.*]] 1424; IS__CGSCC_NPM: if.else: 1425; IS__CGSCC_NPM-NEXT: br label [[ENTRY2:%.*]] 1426; IS__CGSCC_NPM: entry1: 1427; IS__CGSCC_NPM-NEXT: [[CALL1:%.*]] = call i32 @fact_loop(i32 [[N]]) 1428; IS__CGSCC_NPM-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[CALL1]], 5 1429; IS__CGSCC_NPM-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_ELSE4:%.*]] 1430; IS__CGSCC_NPM: if.then3: 1431; IS__CGSCC_NPM-NEXT: br label [[EXIT:%.*]] 1432; IS__CGSCC_NPM: if.else4: 1433; IS__CGSCC_NPM-NEXT: br label [[ENTRY2]] 1434; IS__CGSCC_NPM: entry2: 1435; IS__CGSCC_NPM-NEXT: [[CALL5:%.*]] = call i32 @fact_loop(i32 [[N]]) 1436; IS__CGSCC_NPM-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[CALL5]], 5 1437; IS__CGSCC_NPM-NEXT: br i1 [[CMP6]], label [[IF_THEN7:%.*]], label [[IF_ELSE8:%.*]] 1438; IS__CGSCC_NPM: if.then7: 1439; IS__CGSCC_NPM-NEXT: br label [[EXIT]] 1440; IS__CGSCC_NPM: if.else8: 1441; IS__CGSCC_NPM-NEXT: br label [[ENTRY1]] 1442; IS__CGSCC_NPM: exit: 1443; IS__CGSCC_NPM-NEXT: ret void 1444; 1445entry: 1446 %call = call i32 @fact_loop(i32 %n) 1447 %cmp = icmp sgt i32 %call, 5 1448 br i1 %cmp, label %if.then, label %if.else 1449 1450if.then: ; preds = %entry 1451 br label %entry1 1452 1453if.else: ; preds = %entry 1454 br label %entry2 1455 1456entry1: ; preds = %if.else8, %if.then 1457 %call1 = call i32 @fact_loop(i32 %n) 1458 %cmp2 = icmp sgt i32 %call1, 5 1459 br i1 %cmp2, label %if.then3, label %if.else4 1460 1461if.then3: ; preds = %entry1 1462 br label %exit 1463 1464if.else4: ; preds = %entry1 1465 br label %entry2 1466 1467entry2: ; preds = %if.else4, %if.else 1468 %call5 = call i32 @fact_loop(i32 %n) 1469 %cmp6 = icmp sgt i32 %call5, 5 1470 br i1 %cmp6, label %if.then7, label %if.else8 1471 1472if.then7: ; preds = %entry2 1473 br label %exit 1474 1475if.else8: ; preds = %entry2 1476 br label %entry1 1477 1478exit: ; preds = %if.then7, %if.then3 1479 ret void 1480} 1481 1482declare void @unknown() 1483declare void @readonly() readonly 1484declare void @readnone() readnone 1485declare void @unknown_mustprogress() mustprogress 1486declare void @readonly_mustprogress() readonly mustprogress 1487 1488define void @willreturn_mustprogress_caller_1() mustprogress { 1489; IS__TUNIT_OPM: Function Attrs: mustprogress 1490; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_1 1491; IS__TUNIT_OPM-SAME: () #[[ATTR19:[0-9]+]] { 1492; IS__TUNIT_OPM-NEXT: call void @unknown() 1493; IS__TUNIT_OPM-NEXT: ret void 1494; 1495; IS__TUNIT_NPM: Function Attrs: mustprogress 1496; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_1 1497; IS__TUNIT_NPM-SAME: () #[[ATTR21:[0-9]+]] { 1498; IS__TUNIT_NPM-NEXT: call void @unknown() 1499; IS__TUNIT_NPM-NEXT: ret void 1500; 1501; IS__CGSCC_OPM: Function Attrs: mustprogress 1502; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_1 1503; IS__CGSCC_OPM-SAME: () #[[ATTR20:[0-9]+]] { 1504; IS__CGSCC_OPM-NEXT: call void @unknown() 1505; IS__CGSCC_OPM-NEXT: ret void 1506; 1507; IS__CGSCC_NPM: Function Attrs: mustprogress 1508; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_1 1509; IS__CGSCC_NPM-SAME: () #[[ATTR22:[0-9]+]] { 1510; IS__CGSCC_NPM-NEXT: call void @unknown() 1511; IS__CGSCC_NPM-NEXT: ret void 1512; 1513 call void @unknown() 1514 ret void 1515} 1516define void @willreturn_mustprogress_caller_2() mustprogress { 1517; IS__TUNIT_OPM: Function Attrs: mustprogress readonly willreturn 1518; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_2 1519; IS__TUNIT_OPM-SAME: () #[[ATTR21:[0-9]+]] { 1520; IS__TUNIT_OPM-NEXT: call void @readonly() #[[ATTR17:[0-9]+]] 1521; IS__TUNIT_OPM-NEXT: ret void 1522; 1523; IS__TUNIT_NPM: Function Attrs: mustprogress readonly willreturn 1524; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_2 1525; IS__TUNIT_NPM-SAME: () #[[ATTR23:[0-9]+]] { 1526; IS__TUNIT_NPM-NEXT: call void @readonly() #[[ATTR19:[0-9]+]] 1527; IS__TUNIT_NPM-NEXT: ret void 1528; 1529; IS__CGSCC_OPM: Function Attrs: mustprogress readonly willreturn 1530; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_2 1531; IS__CGSCC_OPM-SAME: () #[[ATTR22:[0-9]+]] { 1532; IS__CGSCC_OPM-NEXT: call void @readonly() #[[ATTR18:[0-9]+]] 1533; IS__CGSCC_OPM-NEXT: ret void 1534; 1535; IS__CGSCC_NPM: Function Attrs: mustprogress readonly willreturn 1536; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_2 1537; IS__CGSCC_NPM-SAME: () #[[ATTR24:[0-9]+]] { 1538; IS__CGSCC_NPM-NEXT: call void @readonly() #[[ATTR20:[0-9]+]] 1539; IS__CGSCC_NPM-NEXT: ret void 1540; 1541 call void @readonly() 1542 ret void 1543} 1544define void @willreturn_mustprogress_caller_3() mustprogress { 1545; IS__TUNIT_OPM: Function Attrs: mustprogress nosync readnone willreturn 1546; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_3 1547; IS__TUNIT_OPM-SAME: () #[[ATTR22:[0-9]+]] { 1548; IS__TUNIT_OPM-NEXT: call void @readnone() 1549; IS__TUNIT_OPM-NEXT: ret void 1550; 1551; IS__TUNIT_NPM: Function Attrs: mustprogress nosync readnone willreturn 1552; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_3 1553; IS__TUNIT_NPM-SAME: () #[[ATTR24:[0-9]+]] { 1554; IS__TUNIT_NPM-NEXT: call void @readnone() 1555; IS__TUNIT_NPM-NEXT: ret void 1556; 1557; IS__CGSCC_OPM: Function Attrs: mustprogress nosync readnone willreturn 1558; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_3 1559; IS__CGSCC_OPM-SAME: () #[[ATTR23:[0-9]+]] { 1560; IS__CGSCC_OPM-NEXT: call void @readnone() 1561; IS__CGSCC_OPM-NEXT: ret void 1562; 1563; IS__CGSCC_NPM: Function Attrs: mustprogress nosync readnone willreturn 1564; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_caller_3 1565; IS__CGSCC_NPM-SAME: () #[[ATTR25:[0-9]+]] { 1566; IS__CGSCC_NPM-NEXT: call void @readnone() 1567; IS__CGSCC_NPM-NEXT: ret void 1568; 1569 call void @readnone() 1570 ret void 1571} 1572define void @willreturn_mustprogress_callee_1() { 1573; CHECK-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_1() { 1574; CHECK-NEXT: call void @unknown_mustprogress() 1575; CHECK-NEXT: ret void 1576; 1577 call void @unknown_mustprogress() 1578 ret void 1579} 1580define void @willreturn_mustprogress_callee_2() { 1581; IS__TUNIT_OPM: Function Attrs: readonly willreturn 1582; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_2 1583; IS__TUNIT_OPM-SAME: () #[[ATTR23:[0-9]+]] { 1584; IS__TUNIT_OPM-NEXT: call void @readonly_mustprogress() #[[ATTR23]] 1585; IS__TUNIT_OPM-NEXT: ret void 1586; 1587; IS__TUNIT_NPM: Function Attrs: readonly willreturn 1588; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_2 1589; IS__TUNIT_NPM-SAME: () #[[ATTR25:[0-9]+]] { 1590; IS__TUNIT_NPM-NEXT: call void @readonly_mustprogress() #[[ATTR25]] 1591; IS__TUNIT_NPM-NEXT: ret void 1592; 1593; IS__CGSCC_OPM: Function Attrs: readonly willreturn 1594; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_2 1595; IS__CGSCC_OPM-SAME: () #[[ATTR24:[0-9]+]] { 1596; IS__CGSCC_OPM-NEXT: call void @readonly_mustprogress() #[[ATTR24]] 1597; IS__CGSCC_OPM-NEXT: ret void 1598; 1599; IS__CGSCC_NPM: Function Attrs: readonly willreturn 1600; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_2 1601; IS__CGSCC_NPM-SAME: () #[[ATTR26:[0-9]+]] { 1602; IS__CGSCC_NPM-NEXT: call void @readonly_mustprogress() #[[ATTR26]] 1603; IS__CGSCC_NPM-NEXT: ret void 1604; 1605 call void @readonly_mustprogress() 1606 ret void 1607} 1608define void @willreturn_mustprogress_callee_3() { 1609; CHECK-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_3() { 1610; CHECK-NEXT: call void @willreturn_mustprogress_callee_1() 1611; CHECK-NEXT: ret void 1612; 1613 call void @willreturn_mustprogress_callee_1() 1614 ret void 1615} 1616define void @willreturn_mustprogress_callee_4() { 1617; IS__TUNIT_OPM: Function Attrs: readonly willreturn 1618; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_4 1619; IS__TUNIT_OPM-SAME: () #[[ATTR23]] { 1620; IS__TUNIT_OPM-NEXT: call void @willreturn_mustprogress_callee_2() #[[ATTR23]] 1621; IS__TUNIT_OPM-NEXT: ret void 1622; 1623; IS__TUNIT_NPM: Function Attrs: readonly willreturn 1624; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_4 1625; IS__TUNIT_NPM-SAME: () #[[ATTR25]] { 1626; IS__TUNIT_NPM-NEXT: call void @willreturn_mustprogress_callee_2() #[[ATTR25]] 1627; IS__TUNIT_NPM-NEXT: ret void 1628; 1629; IS__CGSCC_OPM: Function Attrs: readonly willreturn 1630; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_4 1631; IS__CGSCC_OPM-SAME: () #[[ATTR24]] { 1632; IS__CGSCC_OPM-NEXT: call void @willreturn_mustprogress_callee_2() #[[ATTR24]] 1633; IS__CGSCC_OPM-NEXT: ret void 1634; 1635; IS__CGSCC_NPM: Function Attrs: readonly willreturn 1636; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@willreturn_mustprogress_callee_4 1637; IS__CGSCC_NPM-SAME: () #[[ATTR26]] { 1638; IS__CGSCC_NPM-NEXT: call void @willreturn_mustprogress_callee_2() #[[ATTR26]] 1639; IS__CGSCC_NPM-NEXT: ret void 1640; 1641 call void @willreturn_mustprogress_callee_2() 1642 ret void 1643} 1644 1645attributes #0 = { nounwind uwtable noinline } 1646attributes #1 = { uwtable noinline } 1647;. 1648; IS__TUNIT_OPM: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone willreturn uwtable } 1649; IS__TUNIT_OPM: attributes #[[ATTR1]] = { nofree noinline nosync nounwind readnone uwtable } 1650; IS__TUNIT_OPM: attributes #[[ATTR2]] = { nofree noinline norecurse nosync nounwind readnone uwtable } 1651; IS__TUNIT_OPM: attributes #[[ATTR3:[0-9]+]] = { nofree nosync nounwind willreturn } 1652; IS__TUNIT_OPM: attributes #[[ATTR4]] = { nofree noinline nosync nounwind uwtable } 1653; IS__TUNIT_OPM: attributes #[[ATTR5]] = { noreturn } 1654; IS__TUNIT_OPM: attributes #[[ATTR6]] = { noinline noreturn nounwind uwtable } 1655; IS__TUNIT_OPM: attributes #[[ATTR7]] = { noinline nounwind uwtable } 1656; IS__TUNIT_OPM: attributes #[[ATTR8:[0-9]+]] = { nocallback nofree nosync nounwind readnone speculatable willreturn } 1657; IS__TUNIT_OPM: attributes #[[ATTR9:[0-9]+]] = { norecurse willreturn } 1658; IS__TUNIT_OPM: attributes #[[ATTR10]] = { noinline nounwind willreturn uwtable } 1659; IS__TUNIT_OPM: attributes #[[ATTR11:[0-9]+]] = { noinline willreturn uwtable } 1660; IS__TUNIT_OPM: attributes #[[ATTR12]] = { nounwind willreturn } 1661; IS__TUNIT_OPM: attributes #[[ATTR13]] = { argmemonly nofree noinline norecurse nosync nounwind readonly uwtable } 1662; IS__TUNIT_OPM: attributes #[[ATTR14]] = { nofree noinline norecurse noreturn nosync nounwind readnone uwtable } 1663; IS__TUNIT_OPM: attributes #[[ATTR15:[0-9]+]] = { noreturn nounwind } 1664; IS__TUNIT_OPM: attributes #[[ATTR16]] = { nofree norecurse nosync nounwind readnone } 1665; IS__TUNIT_OPM: attributes #[[ATTR17]] = { readonly } 1666; IS__TUNIT_OPM: attributes #[[ATTR18:[0-9]+]] = { readnone } 1667; IS__TUNIT_OPM: attributes #[[ATTR19]] = { mustprogress } 1668; IS__TUNIT_OPM: attributes #[[ATTR20:[0-9]+]] = { mustprogress readonly } 1669; IS__TUNIT_OPM: attributes #[[ATTR21]] = { mustprogress readonly willreturn } 1670; IS__TUNIT_OPM: attributes #[[ATTR22]] = { mustprogress nosync readnone willreturn } 1671; IS__TUNIT_OPM: attributes #[[ATTR23]] = { readonly willreturn } 1672; IS__TUNIT_OPM: attributes #[[ATTR24]] = { nofree nosync nounwind readnone } 1673; IS__TUNIT_OPM: attributes #[[ATTR25]] = { nofree nosync nounwind } 1674; IS__TUNIT_OPM: attributes #[[ATTR26]] = { readnone willreturn } 1675; IS__TUNIT_OPM: attributes #[[ATTR27]] = { nounwind } 1676; IS__TUNIT_OPM: attributes #[[ATTR28]] = { willreturn } 1677;. 1678; IS__TUNIT_NPM: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone willreturn uwtable } 1679; IS__TUNIT_NPM: attributes #[[ATTR1]] = { nofree noinline nosync nounwind readnone uwtable } 1680; IS__TUNIT_NPM: attributes #[[ATTR2]] = { nofree noinline norecurse nosync nounwind readnone uwtable } 1681; IS__TUNIT_NPM: attributes #[[ATTR3:[0-9]+]] = { nofree nosync nounwind willreturn } 1682; IS__TUNIT_NPM: attributes #[[ATTR4]] = { nofree noinline nosync nounwind uwtable } 1683; IS__TUNIT_NPM: attributes #[[ATTR5]] = { noreturn } 1684; IS__TUNIT_NPM: attributes #[[ATTR6]] = { noinline noreturn nounwind uwtable } 1685; IS__TUNIT_NPM: attributes #[[ATTR7]] = { noinline nounwind uwtable } 1686; IS__TUNIT_NPM: attributes #[[ATTR8:[0-9]+]] = { nocallback nofree nosync nounwind readnone speculatable willreturn } 1687; IS__TUNIT_NPM: attributes #[[ATTR9:[0-9]+]] = { norecurse willreturn } 1688; IS__TUNIT_NPM: attributes #[[ATTR10]] = { noinline nounwind willreturn uwtable } 1689; IS__TUNIT_NPM: attributes #[[ATTR11:[0-9]+]] = { noinline willreturn uwtable } 1690; IS__TUNIT_NPM: attributes #[[ATTR12]] = { nounwind willreturn } 1691; IS__TUNIT_NPM: attributes #[[ATTR13]] = { argmemonly nofree noinline norecurse nosync nounwind readonly willreturn uwtable } 1692; IS__TUNIT_NPM: attributes #[[ATTR14]] = { argmemonly nofree noinline norecurse nosync nounwind readonly uwtable } 1693; IS__TUNIT_NPM: attributes #[[ATTR15]] = { nofree noinline norecurse noreturn nosync nounwind readnone uwtable } 1694; IS__TUNIT_NPM: attributes #[[ATTR16:[0-9]+]] = { noreturn nounwind } 1695; IS__TUNIT_NPM: attributes #[[ATTR17]] = { nofree norecurse nosync nounwind readnone } 1696; IS__TUNIT_NPM: attributes #[[ATTR18]] = { nofree norecurse nosync nounwind readnone willreturn } 1697; IS__TUNIT_NPM: attributes #[[ATTR19]] = { readonly } 1698; IS__TUNIT_NPM: attributes #[[ATTR20:[0-9]+]] = { readnone } 1699; IS__TUNIT_NPM: attributes #[[ATTR21]] = { mustprogress } 1700; IS__TUNIT_NPM: attributes #[[ATTR22:[0-9]+]] = { mustprogress readonly } 1701; IS__TUNIT_NPM: attributes #[[ATTR23]] = { mustprogress readonly willreturn } 1702; IS__TUNIT_NPM: attributes #[[ATTR24]] = { mustprogress nosync readnone willreturn } 1703; IS__TUNIT_NPM: attributes #[[ATTR25]] = { readonly willreturn } 1704; IS__TUNIT_NPM: attributes #[[ATTR26]] = { nofree nosync nounwind readnone } 1705; IS__TUNIT_NPM: attributes #[[ATTR27]] = { nofree nosync nounwind } 1706; IS__TUNIT_NPM: attributes #[[ATTR28]] = { readnone willreturn } 1707; IS__TUNIT_NPM: attributes #[[ATTR29]] = { nounwind } 1708; IS__TUNIT_NPM: attributes #[[ATTR30]] = { willreturn } 1709;. 1710; IS__CGSCC_OPM: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone willreturn uwtable } 1711; IS__CGSCC_OPM: attributes #[[ATTR1]] = { nofree noinline nosync nounwind readnone uwtable } 1712; IS__CGSCC_OPM: attributes #[[ATTR2]] = { nofree noinline norecurse nosync nounwind readnone uwtable } 1713; IS__CGSCC_OPM: attributes #[[ATTR3:[0-9]+]] = { nofree nosync nounwind willreturn } 1714; IS__CGSCC_OPM: attributes #[[ATTR4]] = { nofree noinline nosync nounwind uwtable } 1715; IS__CGSCC_OPM: attributes #[[ATTR5]] = { noreturn } 1716; IS__CGSCC_OPM: attributes #[[ATTR6]] = { noinline noreturn nounwind uwtable } 1717; IS__CGSCC_OPM: attributes #[[ATTR7]] = { noinline nounwind uwtable } 1718; IS__CGSCC_OPM: attributes #[[ATTR8:[0-9]+]] = { nocallback nofree nosync nounwind readnone speculatable willreturn } 1719; IS__CGSCC_OPM: attributes #[[ATTR9:[0-9]+]] = { norecurse willreturn } 1720; IS__CGSCC_OPM: attributes #[[ATTR10]] = { noinline nounwind willreturn uwtable } 1721; IS__CGSCC_OPM: attributes #[[ATTR11:[0-9]+]] = { noinline willreturn uwtable } 1722; IS__CGSCC_OPM: attributes #[[ATTR12]] = { nounwind willreturn } 1723; IS__CGSCC_OPM: attributes #[[ATTR13]] = { argmemonly nofree noinline norecurse nosync nounwind readonly uwtable } 1724; IS__CGSCC_OPM: attributes #[[ATTR14]] = { nofree noinline norecurse noreturn nosync nounwind readnone uwtable } 1725; IS__CGSCC_OPM: attributes #[[ATTR15:[0-9]+]] = { noreturn nounwind } 1726; IS__CGSCC_OPM: attributes #[[ATTR16]] = { nofree norecurse nosync nounwind readnone } 1727; IS__CGSCC_OPM: attributes #[[ATTR17]] = { nofree nosync nounwind readnone } 1728; IS__CGSCC_OPM: attributes #[[ATTR18]] = { readonly } 1729; IS__CGSCC_OPM: attributes #[[ATTR19:[0-9]+]] = { readnone } 1730; IS__CGSCC_OPM: attributes #[[ATTR20]] = { mustprogress } 1731; IS__CGSCC_OPM: attributes #[[ATTR21:[0-9]+]] = { mustprogress readonly } 1732; IS__CGSCC_OPM: attributes #[[ATTR22]] = { mustprogress readonly willreturn } 1733; IS__CGSCC_OPM: attributes #[[ATTR23]] = { mustprogress nosync readnone willreturn } 1734; IS__CGSCC_OPM: attributes #[[ATTR24]] = { readonly willreturn } 1735; IS__CGSCC_OPM: attributes #[[ATTR25]] = { nofree nosync nounwind } 1736; IS__CGSCC_OPM: attributes #[[ATTR26]] = { readnone willreturn } 1737; IS__CGSCC_OPM: attributes #[[ATTR27]] = { nounwind } 1738; IS__CGSCC_OPM: attributes #[[ATTR28]] = { willreturn } 1739; IS__CGSCC_OPM: attributes #[[ATTR29]] = { nounwind readnone } 1740;. 1741; IS__CGSCC_NPM: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone willreturn uwtable } 1742; IS__CGSCC_NPM: attributes #[[ATTR1]] = { nofree noinline nosync nounwind readnone uwtable } 1743; IS__CGSCC_NPM: attributes #[[ATTR2]] = { nofree noinline norecurse nosync nounwind readnone uwtable } 1744; IS__CGSCC_NPM: attributes #[[ATTR3:[0-9]+]] = { nofree nosync nounwind willreturn } 1745; IS__CGSCC_NPM: attributes #[[ATTR4]] = { nofree noinline nosync nounwind uwtable } 1746; IS__CGSCC_NPM: attributes #[[ATTR5]] = { noreturn } 1747; IS__CGSCC_NPM: attributes #[[ATTR6]] = { noinline noreturn nounwind uwtable } 1748; IS__CGSCC_NPM: attributes #[[ATTR7]] = { noinline nounwind uwtable } 1749; IS__CGSCC_NPM: attributes #[[ATTR8:[0-9]+]] = { nocallback nofree nosync nounwind readnone speculatable willreturn } 1750; IS__CGSCC_NPM: attributes #[[ATTR9:[0-9]+]] = { norecurse willreturn } 1751; IS__CGSCC_NPM: attributes #[[ATTR10]] = { noinline nounwind willreturn uwtable } 1752; IS__CGSCC_NPM: attributes #[[ATTR11:[0-9]+]] = { noinline willreturn uwtable } 1753; IS__CGSCC_NPM: attributes #[[ATTR12]] = { nounwind willreturn } 1754; IS__CGSCC_NPM: attributes #[[ATTR13]] = { argmemonly nofree noinline norecurse nosync nounwind readonly willreturn uwtable } 1755; IS__CGSCC_NPM: attributes #[[ATTR14]] = { argmemonly nofree noinline norecurse nosync nounwind readonly uwtable } 1756; IS__CGSCC_NPM: attributes #[[ATTR15]] = { nofree noinline norecurse noreturn nosync nounwind readnone uwtable } 1757; IS__CGSCC_NPM: attributes #[[ATTR16:[0-9]+]] = { noreturn nounwind } 1758; IS__CGSCC_NPM: attributes #[[ATTR17]] = { nofree norecurse nosync nounwind readnone } 1759; IS__CGSCC_NPM: attributes #[[ATTR18]] = { nofree norecurse nosync nounwind readnone willreturn } 1760; IS__CGSCC_NPM: attributes #[[ATTR19]] = { nofree nosync nounwind readnone } 1761; IS__CGSCC_NPM: attributes #[[ATTR20]] = { readonly } 1762; IS__CGSCC_NPM: attributes #[[ATTR21:[0-9]+]] = { readnone } 1763; IS__CGSCC_NPM: attributes #[[ATTR22]] = { mustprogress } 1764; IS__CGSCC_NPM: attributes #[[ATTR23:[0-9]+]] = { mustprogress readonly } 1765; IS__CGSCC_NPM: attributes #[[ATTR24]] = { mustprogress readonly willreturn } 1766; IS__CGSCC_NPM: attributes #[[ATTR25]] = { mustprogress nosync readnone willreturn } 1767; IS__CGSCC_NPM: attributes #[[ATTR26]] = { readonly willreturn } 1768; IS__CGSCC_NPM: attributes #[[ATTR27]] = { nofree nosync nounwind } 1769; IS__CGSCC_NPM: attributes #[[ATTR28]] = { readnone willreturn } 1770; IS__CGSCC_NPM: attributes #[[ATTR29]] = { nounwind } 1771; IS__CGSCC_NPM: attributes #[[ATTR30]] = { willreturn } 1772;. 1773