1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes --check-globals --version 2 2; RUN: opt -passes=function-attrs -S < %s | FileCheck --check-prefixes=COMMON,FNATTRS %s 3; RUN: opt -passes=attributor-light -S < %s | FileCheck --check-prefixes=COMMON,ATTRIBUTOR %s 4 5declare i32 @get_val() 6 7declare void @cold0() cold 8declare void @cold1() cold 9declare void @cold_at_cb() 10 11declare void @not_cold0() 12declare void @not_cold1() 13declare void @not_cold2() 14 15define void @test_no_exit_fail() { 16; COMMON: Function Attrs: nofree norecurse noreturn nosync nounwind memory(none) 17; COMMON-LABEL: define void @test_no_exit_fail 18; COMMON-SAME: () #[[ATTR1:[0-9]+]] { 19; COMMON-NEXT: entry: 20; COMMON-NEXT: br label [[WHILE_BODY:%.*]] 21; COMMON: while.body: 22; COMMON-NEXT: br label [[WHILE_BODY]] 23; 24entry: 25 br label %while.body 26 27while.body: 28 br label %while.body 29} 30 31define void @test_no_exit_fail2() { 32; COMMON: Function Attrs: noreturn 33; COMMON-LABEL: define void @test_no_exit_fail2 34; COMMON-SAME: () #[[ATTR2:[0-9]+]] { 35; COMMON-NEXT: entry: 36; COMMON-NEXT: br label [[WHILE_BODY:%.*]] 37; COMMON: while.body: 38; COMMON-NEXT: call void @not_cold0() 39; COMMON-NEXT: br label [[WHILE_BODY2:%.*]] 40; COMMON: while.body2: 41; COMMON-NEXT: call void @not_cold1() 42; COMMON-NEXT: br label [[WHILE_BODY]] 43; 44entry: 45 br label %while.body 46 47while.body: 48 call void @not_cold0() 49 br label %while.body2 50 51while.body2: 52 call void @not_cold1() 53 br label %while.body 54} 55 56define void @test_no_exit() { 57; FNATTRS: Function Attrs: cold noreturn 58; FNATTRS-LABEL: define void @test_no_exit 59; FNATTRS-SAME: () #[[ATTR3:[0-9]+]] { 60; FNATTRS-NEXT: entry: 61; FNATTRS-NEXT: br label [[WHILE_BODY:%.*]] 62; FNATTRS: while.body: 63; FNATTRS-NEXT: call void @cold0() 64; FNATTRS-NEXT: br label [[WHILE_BODY]] 65; 66; ATTRIBUTOR: Function Attrs: noreturn 67; ATTRIBUTOR-LABEL: define void @test_no_exit 68; ATTRIBUTOR-SAME: () #[[ATTR2]] { 69; ATTRIBUTOR-NEXT: entry: 70; ATTRIBUTOR-NEXT: br label [[WHILE_BODY:%.*]] 71; ATTRIBUTOR: while.body: 72; ATTRIBUTOR-NEXT: call void @cold0() 73; ATTRIBUTOR-NEXT: br label [[WHILE_BODY]] 74; 75entry: 76 br label %while.body 77 78while.body: 79 call void @cold0() 80 br label %while.body 81} 82 83define void @test_no_exit2() { 84; FNATTRS: Function Attrs: cold noreturn 85; FNATTRS-LABEL: define void @test_no_exit2 86; FNATTRS-SAME: () #[[ATTR3]] { 87; FNATTRS-NEXT: entry: 88; FNATTRS-NEXT: br label [[WHILE_BODY:%.*]] 89; FNATTRS: while.body: 90; FNATTRS-NEXT: call void @not_cold0() 91; FNATTRS-NEXT: br label [[WHILE_BODY2:%.*]] 92; FNATTRS: while.body2: 93; FNATTRS-NEXT: call void @cold1() 94; FNATTRS-NEXT: br label [[WHILE_BODY]] 95; 96; ATTRIBUTOR: Function Attrs: noreturn 97; ATTRIBUTOR-LABEL: define void @test_no_exit2 98; ATTRIBUTOR-SAME: () #[[ATTR2]] { 99; ATTRIBUTOR-NEXT: entry: 100; ATTRIBUTOR-NEXT: br label [[WHILE_BODY:%.*]] 101; ATTRIBUTOR: while.body: 102; ATTRIBUTOR-NEXT: call void @not_cold0() 103; ATTRIBUTOR-NEXT: br label [[WHILE_BODY2:%.*]] 104; ATTRIBUTOR: while.body2: 105; ATTRIBUTOR-NEXT: call void @cold1() 106; ATTRIBUTOR-NEXT: br label [[WHILE_BODY]] 107; 108entry: 109 br label %while.body 110 111while.body: 112 call void @not_cold0() 113 br label %while.body2 114 115while.body2: 116 call void @cold1() 117 br label %while.body 118} 119 120define dso_local void @test_entry(i32 noundef %x) { 121; FNATTRS: Function Attrs: cold 122; FNATTRS-LABEL: define dso_local void @test_entry 123; FNATTRS-SAME: (i32 noundef [[X:%.*]]) #[[ATTR0:[0-9]+]] { 124; FNATTRS-NEXT: entry: 125; FNATTRS-NEXT: tail call void @cold0() 126; FNATTRS-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[X]], 0 127; FNATTRS-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] 128; FNATTRS: if.then: 129; FNATTRS-NEXT: tail call void @not_cold0() 130; FNATTRS-NEXT: br label [[IF_END]] 131; FNATTRS: if.end: 132; FNATTRS-NEXT: tail call void @not_cold1() 133; FNATTRS-NEXT: ret void 134; 135; ATTRIBUTOR-LABEL: define dso_local void @test_entry 136; ATTRIBUTOR-SAME: (i32 noundef [[X:%.*]]) { 137; ATTRIBUTOR-NEXT: entry: 138; ATTRIBUTOR-NEXT: tail call void @cold0() 139; ATTRIBUTOR-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[X]], 0 140; ATTRIBUTOR-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] 141; ATTRIBUTOR: if.then: 142; ATTRIBUTOR-NEXT: tail call void @not_cold0() 143; ATTRIBUTOR-NEXT: br label [[IF_END]] 144; ATTRIBUTOR: if.end: 145; ATTRIBUTOR-NEXT: tail call void @not_cold1() 146; ATTRIBUTOR-NEXT: ret void 147; 148entry: 149 tail call void @cold0() 150 %tobool.not = icmp eq i32 %x, 0 151 br i1 %tobool.not, label %if.end, label %if.then 152 153if.then: 154 tail call void @not_cold0() 155 br label %if.end 156 157if.end: 158 tail call void @not_cold1() 159 ret void 160} 161 162define dso_local void @test_hot_fail(i32 noundef %x) hot { 163; FNATTRS: Function Attrs: hot 164; FNATTRS-LABEL: define dso_local void @test_hot_fail 165; FNATTRS-SAME: (i32 noundef [[X:%.*]]) #[[ATTR4:[0-9]+]] { 166; FNATTRS-NEXT: entry: 167; FNATTRS-NEXT: tail call void @cold0() 168; FNATTRS-NEXT: ret void 169; 170; ATTRIBUTOR: Function Attrs: hot 171; ATTRIBUTOR-LABEL: define dso_local void @test_hot_fail 172; ATTRIBUTOR-SAME: (i32 noundef [[X:%.*]]) #[[ATTR3:[0-9]+]] { 173; ATTRIBUTOR-NEXT: entry: 174; ATTRIBUTOR-NEXT: tail call void @cold0() 175; ATTRIBUTOR-NEXT: ret void 176; 177entry: 178 tail call void @cold0() 179 ret void 180} 181 182define dso_local void @test_br2(i32 noundef %x) { 183; FNATTRS: Function Attrs: cold 184; FNATTRS-LABEL: define dso_local void @test_br2 185; FNATTRS-SAME: (i32 noundef [[X:%.*]]) #[[ATTR0]] { 186; FNATTRS-NEXT: entry: 187; FNATTRS-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[X]], 0 188; FNATTRS-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]] 189; FNATTRS: if.then: 190; FNATTRS-NEXT: tail call void @cold0() 191; FNATTRS-NEXT: br label [[IF_END:%.*]] 192; FNATTRS: if.else: 193; FNATTRS-NEXT: tail call void @cold1() 194; FNATTRS-NEXT: br label [[IF_END]] 195; FNATTRS: if.end: 196; FNATTRS-NEXT: ret void 197; 198; ATTRIBUTOR-LABEL: define dso_local void @test_br2 199; ATTRIBUTOR-SAME: (i32 noundef [[X:%.*]]) { 200; ATTRIBUTOR-NEXT: entry: 201; ATTRIBUTOR-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[X]], 0 202; ATTRIBUTOR-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]] 203; ATTRIBUTOR: if.then: 204; ATTRIBUTOR-NEXT: tail call void @cold0() 205; ATTRIBUTOR-NEXT: br label [[IF_END:%.*]] 206; ATTRIBUTOR: if.else: 207; ATTRIBUTOR-NEXT: tail call void @cold1() 208; ATTRIBUTOR-NEXT: br label [[IF_END]] 209; ATTRIBUTOR: if.end: 210; ATTRIBUTOR-NEXT: ret void 211; 212entry: 213 %tobool.not = icmp eq i32 %x, 0 214 br i1 %tobool.not, label %if.else, label %if.then 215 216if.then: 217 tail call void @cold0() 218 br label %if.end 219 220if.else: 221 tail call void @cold1() 222 br label %if.end 223 224if.end: 225 ret void 226} 227 228define dso_local void @test_exit(i32 noundef %x) { 229; FNATTRS: Function Attrs: cold 230; FNATTRS-LABEL: define dso_local void @test_exit 231; FNATTRS-SAME: (i32 noundef [[X:%.*]]) #[[ATTR0]] { 232; FNATTRS-NEXT: entry: 233; FNATTRS-NEXT: tail call void @not_cold0() 234; FNATTRS-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[X]], 0 235; FNATTRS-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]] 236; FNATTRS: if.then: 237; FNATTRS-NEXT: tail call void @not_cold1() 238; FNATTRS-NEXT: br label [[IF_END:%.*]] 239; FNATTRS: if.else: 240; FNATTRS-NEXT: tail call void @not_cold2() 241; FNATTRS-NEXT: br label [[IF_END]] 242; FNATTRS: if.end: 243; FNATTRS-NEXT: tail call void @cold0() 244; FNATTRS-NEXT: ret void 245; 246; ATTRIBUTOR-LABEL: define dso_local void @test_exit 247; ATTRIBUTOR-SAME: (i32 noundef [[X:%.*]]) { 248; ATTRIBUTOR-NEXT: entry: 249; ATTRIBUTOR-NEXT: tail call void @not_cold0() 250; ATTRIBUTOR-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[X]], 0 251; ATTRIBUTOR-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]] 252; ATTRIBUTOR: if.then: 253; ATTRIBUTOR-NEXT: tail call void @not_cold1() 254; ATTRIBUTOR-NEXT: br label [[IF_END:%.*]] 255; ATTRIBUTOR: if.else: 256; ATTRIBUTOR-NEXT: tail call void @not_cold2() 257; ATTRIBUTOR-NEXT: br label [[IF_END]] 258; ATTRIBUTOR: if.end: 259; ATTRIBUTOR-NEXT: tail call void @cold0() 260; ATTRIBUTOR-NEXT: ret void 261; 262entry: 263 tail call void @not_cold0() 264 %tobool.not = icmp eq i32 %x, 0 265 br i1 %tobool.not, label %if.else, label %if.then 266 267if.then: 268 tail call void @not_cold1() 269 br label %if.end 270 271if.else: 272 tail call void @not_cold2() 273 br label %if.end 274 275if.end: 276 tail call void @cold0() 277 ret void 278} 279 280define dso_local void @test_complex(i32 noundef %x) { 281; FNATTRS: Function Attrs: cold 282; FNATTRS-LABEL: define dso_local void @test_complex 283; FNATTRS-SAME: (i32 noundef [[X:%.*]]) #[[ATTR0]] { 284; FNATTRS-NEXT: entry: 285; FNATTRS-NEXT: tail call void @not_cold0() 286; FNATTRS-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[X]], 0 287; FNATTRS-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_ELSE11:%.*]], label [[IF_THEN:%.*]] 288; FNATTRS: if.then: 289; FNATTRS-NEXT: [[CALL:%.*]] = tail call i32 @get_val() 290; FNATTRS-NEXT: [[TOBOOL1_NOT:%.*]] = icmp eq i32 [[CALL]], 0 291; FNATTRS-NEXT: br i1 [[TOBOOL1_NOT]], label [[IF_ELSE:%.*]], label [[IF_THEN2:%.*]] 292; FNATTRS: if.then2: 293; FNATTRS-NEXT: tail call void @cold1() 294; FNATTRS-NEXT: br label [[IF_END12:%.*]] 295; FNATTRS: if.else: 296; FNATTRS-NEXT: [[CALL3:%.*]] = tail call i32 @get_val() 297; FNATTRS-NEXT: [[TOBOOL4_NOT:%.*]] = icmp eq i32 [[CALL3]], 0 298; FNATTRS-NEXT: br i1 [[TOBOOL4_NOT]], label [[IF_ELSE6:%.*]], label [[IF_THEN5:%.*]] 299; FNATTRS: if.then5: 300; FNATTRS-NEXT: tail call void @cold0() 301; FNATTRS-NEXT: br label [[IF_END12]] 302; FNATTRS: if.else6: 303; FNATTRS-NEXT: tail call void @not_cold0() 304; FNATTRS-NEXT: [[CALL7:%.*]] = tail call i32 @get_val() 305; FNATTRS-NEXT: switch i32 [[CALL7]], label [[SW_DEFAULT:%.*]] [ 306; FNATTRS-NEXT: i32 0, label [[SW_BB:%.*]] 307; FNATTRS-NEXT: i32 1, label [[SW_BB8:%.*]] 308; FNATTRS-NEXT: i32 2, label [[SW_BB9:%.*]] 309; FNATTRS-NEXT: ] 310; FNATTRS: sw.bb: 311; FNATTRS-NEXT: tail call void @not_cold0() 312; FNATTRS-NEXT: br label [[CALL_COLD:%.*]] 313; FNATTRS: sw.bb8: 314; FNATTRS-NEXT: tail call void @not_cold1() 315; FNATTRS-NEXT: br label [[CALL_COLD]] 316; FNATTRS: sw.bb9: 317; FNATTRS-NEXT: tail call void @not_cold2() 318; FNATTRS-NEXT: br label [[CALL_COLD]] 319; FNATTRS: sw.default: 320; FNATTRS-NEXT: tail call void @cold0() 321; FNATTRS-NEXT: br label [[IF_END12]] 322; FNATTRS: call_cold: 323; FNATTRS-NEXT: tail call void @cold_at_cb() #[[ATTR0]] 324; FNATTRS-NEXT: br label [[IF_END12]] 325; FNATTRS: if.else11: 326; FNATTRS-NEXT: tail call void @cold0() 327; FNATTRS-NEXT: br label [[IF_END12]] 328; FNATTRS: if.end12: 329; FNATTRS-NEXT: ret void 330; 331; ATTRIBUTOR-LABEL: define dso_local void @test_complex 332; ATTRIBUTOR-SAME: (i32 noundef [[X:%.*]]) { 333; ATTRIBUTOR-NEXT: entry: 334; ATTRIBUTOR-NEXT: tail call void @not_cold0() 335; ATTRIBUTOR-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[X]], 0 336; ATTRIBUTOR-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_ELSE11:%.*]], label [[IF_THEN:%.*]] 337; ATTRIBUTOR: if.then: 338; ATTRIBUTOR-NEXT: [[CALL:%.*]] = tail call i32 @get_val() 339; ATTRIBUTOR-NEXT: [[TOBOOL1_NOT:%.*]] = icmp eq i32 [[CALL]], 0 340; ATTRIBUTOR-NEXT: br i1 [[TOBOOL1_NOT]], label [[IF_ELSE:%.*]], label [[IF_THEN2:%.*]] 341; ATTRIBUTOR: if.then2: 342; ATTRIBUTOR-NEXT: tail call void @cold1() 343; ATTRIBUTOR-NEXT: br label [[IF_END12:%.*]] 344; ATTRIBUTOR: if.else: 345; ATTRIBUTOR-NEXT: [[CALL3:%.*]] = tail call i32 @get_val() 346; ATTRIBUTOR-NEXT: [[TOBOOL4_NOT:%.*]] = icmp eq i32 [[CALL3]], 0 347; ATTRIBUTOR-NEXT: br i1 [[TOBOOL4_NOT]], label [[IF_ELSE6:%.*]], label [[IF_THEN5:%.*]] 348; ATTRIBUTOR: if.then5: 349; ATTRIBUTOR-NEXT: tail call void @cold0() 350; ATTRIBUTOR-NEXT: br label [[IF_END12]] 351; ATTRIBUTOR: if.else6: 352; ATTRIBUTOR-NEXT: tail call void @not_cold0() 353; ATTRIBUTOR-NEXT: [[CALL7:%.*]] = tail call i32 @get_val() 354; ATTRIBUTOR-NEXT: switch i32 [[CALL7]], label [[SW_DEFAULT:%.*]] [ 355; ATTRIBUTOR-NEXT: i32 0, label [[SW_BB:%.*]] 356; ATTRIBUTOR-NEXT: i32 1, label [[SW_BB8:%.*]] 357; ATTRIBUTOR-NEXT: i32 2, label [[SW_BB9:%.*]] 358; ATTRIBUTOR-NEXT: ] 359; ATTRIBUTOR: sw.bb: 360; ATTRIBUTOR-NEXT: tail call void @not_cold0() 361; ATTRIBUTOR-NEXT: br label [[CALL_COLD:%.*]] 362; ATTRIBUTOR: sw.bb8: 363; ATTRIBUTOR-NEXT: tail call void @not_cold1() 364; ATTRIBUTOR-NEXT: br label [[CALL_COLD]] 365; ATTRIBUTOR: sw.bb9: 366; ATTRIBUTOR-NEXT: tail call void @not_cold2() 367; ATTRIBUTOR-NEXT: br label [[CALL_COLD]] 368; ATTRIBUTOR: sw.default: 369; ATTRIBUTOR-NEXT: tail call void @cold0() 370; ATTRIBUTOR-NEXT: br label [[IF_END12]] 371; ATTRIBUTOR: call_cold: 372; ATTRIBUTOR-NEXT: tail call void @cold_at_cb() #[[ATTR0:[0-9]+]] 373; ATTRIBUTOR-NEXT: br label [[IF_END12]] 374; ATTRIBUTOR: if.else11: 375; ATTRIBUTOR-NEXT: tail call void @cold0() 376; ATTRIBUTOR-NEXT: br label [[IF_END12]] 377; ATTRIBUTOR: if.end12: 378; ATTRIBUTOR-NEXT: ret void 379; 380entry: 381 tail call void @not_cold0() 382 %tobool.not = icmp eq i32 %x, 0 383 br i1 %tobool.not, label %if.else11, label %if.then 384 385if.then: 386 %call = tail call i32 @get_val() 387 %tobool1.not = icmp eq i32 %call, 0 388 br i1 %tobool1.not, label %if.else, label %if.then2 389 390if.then2: 391 tail call void @cold1() 392 br label %if.end12 393 394if.else: 395 %call3 = tail call i32 @get_val() 396 %tobool4.not = icmp eq i32 %call3, 0 397 br i1 %tobool4.not, label %if.else6, label %if.then5 398 399if.then5: 400 tail call void @cold0() 401 br label %if.end12 402 403if.else6: 404 tail call void @not_cold0() 405 %call7 = tail call i32 @get_val() 406 switch i32 %call7, label %sw.default [ 407 i32 0, label %sw.bb 408 i32 1, label %sw.bb8 409 i32 2, label %sw.bb9 410 ] 411 412sw.bb: 413 tail call void @not_cold0() 414 br label %call_cold 415 416sw.bb8: 417 tail call void @not_cold1() 418 br label %call_cold 419 420sw.bb9: 421 tail call void @not_cold2() 422 br label %call_cold 423 424sw.default: 425 tail call void @cold0() 426 br label %if.end12 427 428call_cold: 429 tail call void @cold_at_cb() cold 430 br label %if.end12 431 432if.else11: 433 tail call void @cold0() 434 br label %if.end12 435 436if.end12: 437 ret void 438} 439 440define dso_local void @test_complex2(i32 noundef %x) { 441; FNATTRS: Function Attrs: cold 442; FNATTRS-LABEL: define dso_local void @test_complex2 443; FNATTRS-SAME: (i32 noundef [[X:%.*]]) #[[ATTR0]] { 444; FNATTRS-NEXT: entry: 445; FNATTRS-NEXT: tail call void @not_cold0() 446; FNATTRS-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[X]], 0 447; FNATTRS-NEXT: [[CALL12:%.*]] = tail call i32 @get_val() 448; FNATTRS-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_ELSE11:%.*]], label [[IF_THEN:%.*]] 449; FNATTRS: if.then: 450; FNATTRS-NEXT: [[TOBOOL1_NOT:%.*]] = icmp eq i32 [[CALL12]], 0 451; FNATTRS-NEXT: br i1 [[TOBOOL1_NOT]], label [[IF_ELSE:%.*]], label [[IF_THEN2:%.*]] 452; FNATTRS: if.then2: 453; FNATTRS-NEXT: tail call void @cold1() 454; FNATTRS-NEXT: br label [[IF_END16:%.*]] 455; FNATTRS: if.else: 456; FNATTRS-NEXT: [[CALL3:%.*]] = tail call i32 @get_val() 457; FNATTRS-NEXT: [[TOBOOL4_NOT:%.*]] = icmp eq i32 [[CALL3]], 0 458; FNATTRS-NEXT: br i1 [[TOBOOL4_NOT]], label [[IF_ELSE6:%.*]], label [[IF_THEN5:%.*]] 459; FNATTRS: if.then5: 460; FNATTRS-NEXT: tail call void @cold0() 461; FNATTRS-NEXT: br label [[IF_END16]] 462; FNATTRS: if.else6: 463; FNATTRS-NEXT: tail call void @not_cold0() 464; FNATTRS-NEXT: [[CALL7:%.*]] = tail call i32 @get_val() 465; FNATTRS-NEXT: switch i32 [[CALL7]], label [[SW_DEFAULT:%.*]] [ 466; FNATTRS-NEXT: i32 0, label [[SW_BB:%.*]] 467; FNATTRS-NEXT: i32 1, label [[SW_BB8:%.*]] 468; FNATTRS-NEXT: i32 2, label [[SW_BB9:%.*]] 469; FNATTRS-NEXT: ] 470; FNATTRS: sw.bb: 471; FNATTRS-NEXT: tail call void @not_cold0() 472; FNATTRS-NEXT: br label [[CALL_COLD:%.*]] 473; FNATTRS: sw.bb8: 474; FNATTRS-NEXT: tail call void @not_cold1() 475; FNATTRS-NEXT: br label [[CALL_COLD]] 476; FNATTRS: sw.bb9: 477; FNATTRS-NEXT: tail call void @not_cold2() 478; FNATTRS-NEXT: br label [[CALL_COLD]] 479; FNATTRS: sw.default: 480; FNATTRS-NEXT: tail call void @cold0() 481; FNATTRS-NEXT: br label [[IF_END16]] 482; FNATTRS: call_cold: 483; FNATTRS-NEXT: tail call void @cold_at_cb() #[[ATTR0]] 484; FNATTRS-NEXT: br label [[IF_END16]] 485; FNATTRS: if.else11: 486; FNATTRS-NEXT: [[CMP:%.*]] = icmp slt i32 [[CALL12]], 1 487; FNATTRS-NEXT: br i1 [[CMP]], label [[IF_END14:%.*]], label [[FOR_BODY:%.*]] 488; FNATTRS: if.end14: 489; FNATTRS-NEXT: tail call void @cold1() 490; FNATTRS-NEXT: br label [[IF_END16]] 491; FNATTRS: for.body: 492; FNATTRS-NEXT: [[I_021:%.*]] = phi i32 [ [[INC:%.*]], [[FOR_BODY]] ], [ 0, [[IF_ELSE11]] ] 493; FNATTRS-NEXT: tail call void @cold0() 494; FNATTRS-NEXT: [[INC]] = add nuw nsw i32 [[I_021]], 1 495; FNATTRS-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], [[CALL12]] 496; FNATTRS-NEXT: br i1 [[EXITCOND_NOT]], label [[IF_END16]], label [[FOR_BODY]] 497; FNATTRS: if.end16: 498; FNATTRS-NEXT: ret void 499; 500; ATTRIBUTOR-LABEL: define dso_local void @test_complex2 501; ATTRIBUTOR-SAME: (i32 noundef [[X:%.*]]) { 502; ATTRIBUTOR-NEXT: entry: 503; ATTRIBUTOR-NEXT: tail call void @not_cold0() 504; ATTRIBUTOR-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[X]], 0 505; ATTRIBUTOR-NEXT: [[CALL12:%.*]] = tail call i32 @get_val() 506; ATTRIBUTOR-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_ELSE11:%.*]], label [[IF_THEN:%.*]] 507; ATTRIBUTOR: if.then: 508; ATTRIBUTOR-NEXT: [[TOBOOL1_NOT:%.*]] = icmp eq i32 [[CALL12]], 0 509; ATTRIBUTOR-NEXT: br i1 [[TOBOOL1_NOT]], label [[IF_ELSE:%.*]], label [[IF_THEN2:%.*]] 510; ATTRIBUTOR: if.then2: 511; ATTRIBUTOR-NEXT: tail call void @cold1() 512; ATTRIBUTOR-NEXT: br label [[IF_END16:%.*]] 513; ATTRIBUTOR: if.else: 514; ATTRIBUTOR-NEXT: [[CALL3:%.*]] = tail call i32 @get_val() 515; ATTRIBUTOR-NEXT: [[TOBOOL4_NOT:%.*]] = icmp eq i32 [[CALL3]], 0 516; ATTRIBUTOR-NEXT: br i1 [[TOBOOL4_NOT]], label [[IF_ELSE6:%.*]], label [[IF_THEN5:%.*]] 517; ATTRIBUTOR: if.then5: 518; ATTRIBUTOR-NEXT: tail call void @cold0() 519; ATTRIBUTOR-NEXT: br label [[IF_END16]] 520; ATTRIBUTOR: if.else6: 521; ATTRIBUTOR-NEXT: tail call void @not_cold0() 522; ATTRIBUTOR-NEXT: [[CALL7:%.*]] = tail call i32 @get_val() 523; ATTRIBUTOR-NEXT: switch i32 [[CALL7]], label [[SW_DEFAULT:%.*]] [ 524; ATTRIBUTOR-NEXT: i32 0, label [[SW_BB:%.*]] 525; ATTRIBUTOR-NEXT: i32 1, label [[SW_BB8:%.*]] 526; ATTRIBUTOR-NEXT: i32 2, label [[SW_BB9:%.*]] 527; ATTRIBUTOR-NEXT: ] 528; ATTRIBUTOR: sw.bb: 529; ATTRIBUTOR-NEXT: tail call void @not_cold0() 530; ATTRIBUTOR-NEXT: br label [[CALL_COLD:%.*]] 531; ATTRIBUTOR: sw.bb8: 532; ATTRIBUTOR-NEXT: tail call void @not_cold1() 533; ATTRIBUTOR-NEXT: br label [[CALL_COLD]] 534; ATTRIBUTOR: sw.bb9: 535; ATTRIBUTOR-NEXT: tail call void @not_cold2() 536; ATTRIBUTOR-NEXT: br label [[CALL_COLD]] 537; ATTRIBUTOR: sw.default: 538; ATTRIBUTOR-NEXT: tail call void @cold0() 539; ATTRIBUTOR-NEXT: br label [[IF_END16]] 540; ATTRIBUTOR: call_cold: 541; ATTRIBUTOR-NEXT: tail call void @cold_at_cb() #[[ATTR0]] 542; ATTRIBUTOR-NEXT: br label [[IF_END16]] 543; ATTRIBUTOR: if.else11: 544; ATTRIBUTOR-NEXT: [[CMP:%.*]] = icmp slt i32 [[CALL12]], 1 545; ATTRIBUTOR-NEXT: br i1 [[CMP]], label [[IF_END14:%.*]], label [[FOR_BODY:%.*]] 546; ATTRIBUTOR: if.end14: 547; ATTRIBUTOR-NEXT: tail call void @cold1() 548; ATTRIBUTOR-NEXT: br label [[IF_END16]] 549; ATTRIBUTOR: for.body: 550; ATTRIBUTOR-NEXT: [[I_021:%.*]] = phi i32 [ [[INC:%.*]], [[FOR_BODY]] ], [ 0, [[IF_ELSE11]] ] 551; ATTRIBUTOR-NEXT: tail call void @cold0() 552; ATTRIBUTOR-NEXT: [[INC]] = add nuw nsw i32 [[I_021]], 1 553; ATTRIBUTOR-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], [[CALL12]] 554; ATTRIBUTOR-NEXT: br i1 [[EXITCOND_NOT]], label [[IF_END16]], label [[FOR_BODY]] 555; ATTRIBUTOR: if.end16: 556; ATTRIBUTOR-NEXT: ret void 557; 558entry: 559 tail call void @not_cold0() 560 %tobool.not = icmp eq i32 %x, 0 561 %call12 = tail call i32 @get_val() 562 br i1 %tobool.not, label %if.else11, label %if.then 563 564if.then: 565 %tobool1.not = icmp eq i32 %call12, 0 566 br i1 %tobool1.not, label %if.else, label %if.then2 567 568if.then2: 569 tail call void @cold1() 570 br label %if.end16 571 572if.else: 573 %call3 = tail call i32 @get_val() 574 %tobool4.not = icmp eq i32 %call3, 0 575 br i1 %tobool4.not, label %if.else6, label %if.then5 576 577if.then5: 578 tail call void @cold0() 579 br label %if.end16 580 581if.else6: 582 tail call void @not_cold0() 583 %call7 = tail call i32 @get_val() 584 switch i32 %call7, label %sw.default [ 585 i32 0, label %sw.bb 586 i32 1, label %sw.bb8 587 i32 2, label %sw.bb9 588 ] 589 590sw.bb: 591 tail call void @not_cold0() 592 br label %call_cold 593 594sw.bb8: 595 tail call void @not_cold1() 596 br label %call_cold 597 598sw.bb9: 599 tail call void @not_cold2() 600 br label %call_cold 601 602sw.default: 603 tail call void @cold0() 604 br label %if.end16 605 606call_cold: 607 tail call void @cold_at_cb() cold 608 br label %if.end16 609 610if.else11: 611 %cmp = icmp slt i32 %call12, 1 612 br i1 %cmp, label %if.end14, label %for.body 613 614if.end14: 615 tail call void @cold1() 616 br label %if.end16 617 618for.body: 619 %i.021 = phi i32 [ %inc, %for.body ], [ 0, %if.else11 ] 620 tail call void @cold0() 621 %inc = add nuw nsw i32 %i.021, 1 622 %exitcond.not = icmp eq i32 %inc, %call12 623 br i1 %exitcond.not, label %if.end16, label %for.body 624 625if.end16: 626 ret void 627} 628 629define dso_local void @test_complex_fail(i32 noundef %x) { 630; COMMON-LABEL: define dso_local void @test_complex_fail 631; COMMON-SAME: (i32 noundef [[X:%.*]]) { 632; COMMON-NEXT: entry: 633; COMMON-NEXT: tail call void @not_cold0() 634; COMMON-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[X]], 0 635; COMMON-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_ELSE11:%.*]], label [[IF_THEN:%.*]] 636; COMMON: if.then: 637; COMMON-NEXT: [[CALL:%.*]] = tail call i32 @get_val() 638; COMMON-NEXT: [[TOBOOL1_NOT:%.*]] = icmp eq i32 [[CALL]], 0 639; COMMON-NEXT: br i1 [[TOBOOL1_NOT]], label [[IF_ELSE:%.*]], label [[IF_THEN2:%.*]] 640; COMMON: if.then2: 641; COMMON-NEXT: tail call void @cold1() 642; COMMON-NEXT: br label [[IF_END12:%.*]] 643; COMMON: if.else: 644; COMMON-NEXT: [[CALL3:%.*]] = tail call i32 @get_val() 645; COMMON-NEXT: [[TOBOOL4_NOT:%.*]] = icmp eq i32 [[CALL3]], 0 646; COMMON-NEXT: br i1 [[TOBOOL4_NOT]], label [[IF_ELSE6:%.*]], label [[IF_THEN5:%.*]] 647; COMMON: if.then5: 648; COMMON-NEXT: tail call void @cold0() 649; COMMON-NEXT: br label [[IF_END12]] 650; COMMON: if.else6: 651; COMMON-NEXT: tail call void @not_cold0() 652; COMMON-NEXT: [[CALL7:%.*]] = tail call i32 @get_val() 653; COMMON-NEXT: switch i32 [[CALL7]], label [[SW_DEFAULT:%.*]] [ 654; COMMON-NEXT: i32 0, label [[SW_BB:%.*]] 655; COMMON-NEXT: i32 1, label [[SW_BB8:%.*]] 656; COMMON-NEXT: i32 2, label [[SW_BB9:%.*]] 657; COMMON-NEXT: ] 658; COMMON: sw.bb: 659; COMMON-NEXT: tail call void @not_cold0() 660; COMMON-NEXT: br label [[CALL_COLD:%.*]] 661; COMMON: sw.bb8: 662; COMMON-NEXT: tail call void @not_cold1() 663; COMMON-NEXT: br label [[CALL_COLD]] 664; COMMON: sw.bb9: 665; COMMON-NEXT: tail call void @not_cold2() 666; COMMON-NEXT: br label [[IF_END12]] 667; COMMON: sw.default: 668; COMMON-NEXT: tail call void @cold0() 669; COMMON-NEXT: br label [[IF_END12]] 670; COMMON: call_cold: 671; COMMON-NEXT: tail call void @cold_at_cb() #[[ATTR0:[0-9]+]] 672; COMMON-NEXT: br label [[IF_END12]] 673; COMMON: if.else11: 674; COMMON-NEXT: tail call void @cold0() 675; COMMON-NEXT: br label [[IF_END12]] 676; COMMON: if.end12: 677; COMMON-NEXT: ret void 678; 679entry: 680 tail call void @not_cold0() 681 %tobool.not = icmp eq i32 %x, 0 682 br i1 %tobool.not, label %if.else11, label %if.then 683 684if.then: 685 %call = tail call i32 @get_val() 686 %tobool1.not = icmp eq i32 %call, 0 687 br i1 %tobool1.not, label %if.else, label %if.then2 688 689if.then2: 690 tail call void @cold1() 691 br label %if.end12 692 693if.else: 694 %call3 = tail call i32 @get_val() 695 %tobool4.not = icmp eq i32 %call3, 0 696 br i1 %tobool4.not, label %if.else6, label %if.then5 697 698if.then5: 699 tail call void @cold0() 700 br label %if.end12 701 702if.else6: 703 tail call void @not_cold0() 704 %call7 = tail call i32 @get_val() 705 switch i32 %call7, label %sw.default [ 706 i32 0, label %sw.bb 707 i32 1, label %sw.bb8 708 i32 2, label %sw.bb9 709 ] 710 711sw.bb: 712 tail call void @not_cold0() 713 br label %call_cold 714 715sw.bb8: 716 tail call void @not_cold1() 717 br label %call_cold 718 719sw.bb9: 720 tail call void @not_cold2() 721 br label %if.end12 722 723sw.default: 724 tail call void @cold0() 725 br label %if.end12 726 727call_cold: 728 tail call void @cold_at_cb() cold 729 br label %if.end12 730 731if.else11: 732 tail call void @cold0() 733 br label %if.end12 734 735if.end12: 736 ret void 737} 738 739define dso_local void @test_complex2_fail(i32 noundef %x) { 740; COMMON-LABEL: define dso_local void @test_complex2_fail 741; COMMON-SAME: (i32 noundef [[X:%.*]]) { 742; COMMON-NEXT: entry: 743; COMMON-NEXT: tail call void @not_cold0() 744; COMMON-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[X]], 0 745; COMMON-NEXT: [[CALL12:%.*]] = tail call i32 @get_val() 746; COMMON-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_ELSE11:%.*]], label [[IF_THEN:%.*]] 747; COMMON: if.then: 748; COMMON-NEXT: [[TOBOOL1_NOT:%.*]] = icmp eq i32 [[CALL12]], 0 749; COMMON-NEXT: br i1 [[TOBOOL1_NOT]], label [[IF_ELSE:%.*]], label [[IF_THEN2:%.*]] 750; COMMON: if.then2: 751; COMMON-NEXT: tail call void @cold1() 752; COMMON-NEXT: br label [[IF_END16:%.*]] 753; COMMON: if.else: 754; COMMON-NEXT: [[CALL3:%.*]] = tail call i32 @get_val() 755; COMMON-NEXT: [[TOBOOL4_NOT:%.*]] = icmp eq i32 [[CALL3]], 0 756; COMMON-NEXT: br i1 [[TOBOOL4_NOT]], label [[IF_ELSE6:%.*]], label [[IF_THEN5:%.*]] 757; COMMON: if.then5: 758; COMMON-NEXT: tail call void @cold0() 759; COMMON-NEXT: br label [[IF_END16]] 760; COMMON: if.else6: 761; COMMON-NEXT: tail call void @not_cold0() 762; COMMON-NEXT: [[CALL7:%.*]] = tail call i32 @get_val() 763; COMMON-NEXT: switch i32 [[CALL7]], label [[SW_DEFAULT:%.*]] [ 764; COMMON-NEXT: i32 0, label [[SW_BB:%.*]] 765; COMMON-NEXT: i32 1, label [[SW_BB8:%.*]] 766; COMMON-NEXT: i32 2, label [[SW_BB9:%.*]] 767; COMMON-NEXT: ] 768; COMMON: sw.bb: 769; COMMON-NEXT: tail call void @not_cold0() 770; COMMON-NEXT: br label [[CALL_COLD:%.*]] 771; COMMON: sw.bb8: 772; COMMON-NEXT: tail call void @not_cold1() 773; COMMON-NEXT: br label [[CALL_COLD]] 774; COMMON: sw.bb9: 775; COMMON-NEXT: tail call void @not_cold2() 776; COMMON-NEXT: br label [[CALL_COLD]] 777; COMMON: sw.default: 778; COMMON-NEXT: tail call void @cold0() 779; COMMON-NEXT: br label [[IF_END16]] 780; COMMON: call_cold: 781; COMMON-NEXT: tail call void @cold_at_cb() #[[ATTR0]] 782; COMMON-NEXT: br label [[IF_END16]] 783; COMMON: if.else11: 784; COMMON-NEXT: [[CMP:%.*]] = icmp slt i32 [[CALL12]], 1 785; COMMON-NEXT: br i1 [[CMP]], label [[IF_END14:%.*]], label [[FOR_BODY:%.*]] 786; COMMON: if.end14: 787; COMMON-NEXT: tail call void @not_cold1() 788; COMMON-NEXT: br label [[IF_END16]] 789; COMMON: for.body: 790; COMMON-NEXT: [[I_021:%.*]] = phi i32 [ [[INC:%.*]], [[FOR_BODY]] ], [ 0, [[IF_ELSE11]] ] 791; COMMON-NEXT: tail call void @cold0() 792; COMMON-NEXT: [[INC]] = add nuw nsw i32 [[I_021]], 1 793; COMMON-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], [[CALL12]] 794; COMMON-NEXT: br i1 [[EXITCOND_NOT]], label [[IF_END16]], label [[FOR_BODY]] 795; COMMON: if.end16: 796; COMMON-NEXT: ret void 797; 798entry: 799 tail call void @not_cold0() 800 %tobool.not = icmp eq i32 %x, 0 801 %call12 = tail call i32 @get_val() 802 br i1 %tobool.not, label %if.else11, label %if.then 803 804if.then: 805 %tobool1.not = icmp eq i32 %call12, 0 806 br i1 %tobool1.not, label %if.else, label %if.then2 807 808if.then2: 809 tail call void @cold1() 810 br label %if.end16 811 812if.else: 813 %call3 = tail call i32 @get_val() 814 %tobool4.not = icmp eq i32 %call3, 0 815 br i1 %tobool4.not, label %if.else6, label %if.then5 816 817if.then5: 818 tail call void @cold0() 819 br label %if.end16 820 821if.else6: 822 tail call void @not_cold0() 823 %call7 = tail call i32 @get_val() 824 switch i32 %call7, label %sw.default [ 825 i32 0, label %sw.bb 826 i32 1, label %sw.bb8 827 i32 2, label %sw.bb9 828 ] 829 830sw.bb: 831 tail call void @not_cold0() 832 br label %call_cold 833 834sw.bb8: 835 tail call void @not_cold1() 836 br label %call_cold 837 838sw.bb9: 839 tail call void @not_cold2() 840 br label %call_cold 841 842sw.default: 843 tail call void @cold0() 844 br label %if.end16 845 846call_cold: 847 tail call void @cold_at_cb() cold 848 br label %if.end16 849 850if.else11: 851 %cmp = icmp slt i32 %call12, 1 852 br i1 %cmp, label %if.end14, label %for.body 853 854if.end14: 855 tail call void @not_cold1() 856 br label %if.end16 857 858for.body: 859 %i.021 = phi i32 [ %inc, %for.body ], [ 0, %if.else11 ] 860 tail call void @cold0() 861 %inc = add nuw nsw i32 %i.021, 1 862 %exitcond.not = icmp eq i32 %inc, %call12 863 br i1 %exitcond.not, label %if.end16, label %for.body 864 865if.end16: 866 ret void 867} 868 869;. 870; FNATTRS: attributes #[[ATTR0]] = { cold } 871; FNATTRS: attributes #[[ATTR1]] = { nofree norecurse noreturn nosync nounwind memory(none) } 872; FNATTRS: attributes #[[ATTR2]] = { noreturn } 873; FNATTRS: attributes #[[ATTR3]] = { cold noreturn } 874; FNATTRS: attributes #[[ATTR4]] = { hot } 875;. 876; ATTRIBUTOR: attributes #[[ATTR0]] = { cold } 877; ATTRIBUTOR: attributes #[[ATTR1]] = { nofree norecurse noreturn nosync nounwind memory(none) } 878; ATTRIBUTOR: attributes #[[ATTR2]] = { noreturn } 879; ATTRIBUTOR: attributes #[[ATTR3]] = { hot } 880;. 881