603 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 22; RUN: opt -S -passes=instcombine < %s | FileCheck %s --check-prefixes=CHECK,DEFAULT_ITER3; RUN: opt -S -passes='instcombine<max-iterations=1>' < %s | FileCheck %s --check-prefixes=CHECK,MAX14 5declare void @dummy()6declare void @llvm.assume(i1)7 8define i32 @br_true(i1 %x) {9; CHECK-LABEL: define i32 @br_true10; CHECK-SAME: (i1 [[X:%.*]]) {11; CHECK-NEXT: br i1 true, label [[IF:%.*]], label [[ELSE:%.*]]12; CHECK: if:13; CHECK-NEXT: call void @dummy()14; CHECK-NEXT: br label [[JOIN:%.*]]15; CHECK: else:16; CHECK-NEXT: br label [[JOIN]]17; CHECK: join:18; CHECK-NEXT: ret i32 119;20 %c = or i1 %x, true21 br i1 %c, label %if, label %else22 23if:24 call void @dummy()25 br label %join26 27else:28 call void @dummy()29 br label %join30 31join:32 %phi = phi i32 [ 1, %if ], [ 2, %else ]33 ret i32 %phi34}35 36define i32 @br_false(i1 %x) {37; CHECK-LABEL: define i32 @br_false38; CHECK-SAME: (i1 [[X:%.*]]) {39; CHECK-NEXT: br i1 false, label [[IF:%.*]], label [[ELSE:%.*]]40; CHECK: if:41; CHECK-NEXT: br label [[JOIN:%.*]]42; CHECK: else:43; CHECK-NEXT: call void @dummy()44; CHECK-NEXT: br label [[JOIN]]45; CHECK: join:46; CHECK-NEXT: ret i32 247;48 %c = and i1 %x, false49 br i1 %c, label %if, label %else50 51if:52 call void @dummy()53 br label %join54 55else:56 call void @dummy()57 br label %join58 59join:60 %phi = phi i32 [ 1, %if ], [ 2, %else ]61 ret i32 %phi62}63 64define i32 @br_undef(i1 %x) {65; CHECK-LABEL: define i32 @br_undef66; CHECK-SAME: (i1 [[X:%.*]]) {67; CHECK-NEXT: br i1 undef, label [[IF:%.*]], label [[ELSE:%.*]]68; CHECK: if:69; CHECK-NEXT: br label [[JOIN:%.*]]70; CHECK: else:71; CHECK-NEXT: br label [[JOIN]]72; CHECK: join:73; CHECK-NEXT: ret i32 poison74;75 %c = xor i1 %x, undef76 br i1 %c, label %if, label %else77 78if:79 call void @dummy()80 br label %join81 82else:83 call void @dummy()84 br label %join85 86join:87 %phi = phi i32 [ 1, %if ], [ 2, %else ]88 ret i32 %phi89}90 91define i32 @br_true_phi_with_repeated_preds(i1 %x) {92; CHECK-LABEL: define i32 @br_true_phi_with_repeated_preds93; CHECK-SAME: (i1 [[X:%.*]]) {94; CHECK-NEXT: br i1 true, label [[IF:%.*]], label [[ELSE:%.*]]95; CHECK: if:96; CHECK-NEXT: call void @dummy()97; CHECK-NEXT: br label [[JOIN:%.*]]98; CHECK: else:99; CHECK-NEXT: br i1 false, label [[JOIN]], label [[JOIN]]100; CHECK: join:101; CHECK-NEXT: ret i32 1102;103 %c = or i1 %x, true104 br i1 %c, label %if, label %else105 106if:107 call void @dummy()108 br label %join109 110else:111 br i1 false, label %join, label %join112 113join:114 %phi = phi i32 [ 1, %if ], [ 2, %else ], [ 2, %else ]115 ret i32 %phi116}117 118define i32 @br_true_const_phi_direct_edge(i1 %x) {119; CHECK-LABEL: define i32 @br_true_const_phi_direct_edge120; CHECK-SAME: (i1 [[X:%.*]]) {121; CHECK-NEXT: entry:122; CHECK-NEXT: br i1 true, label [[IF:%.*]], label [[JOIN:%.*]]123; CHECK: if:124; CHECK-NEXT: call void @dummy()125; CHECK-NEXT: br label [[JOIN]]126; CHECK: join:127; CHECK-NEXT: ret i32 2128;129entry:130 br i1 true, label %if, label %join131 132if:133 call void @dummy()134 br label %join135 136join:137 %phi = phi i32 [ 1, %entry ], [ 2, %if ]138 ret i32 %phi139}140 141define i32 @br_true_var_phi_direct_edge(i1 %x) {142; CHECK-LABEL: define i32 @br_true_var_phi_direct_edge143; CHECK-SAME: (i1 [[X:%.*]]) {144; CHECK-NEXT: entry:145; CHECK-NEXT: br i1 true, label [[IF:%.*]], label [[JOIN:%.*]]146; CHECK: if:147; CHECK-NEXT: call void @dummy()148; CHECK-NEXT: br label [[JOIN]]149; CHECK: join:150; CHECK-NEXT: ret i32 2151;152entry:153 %c = or i1 %x, true154 br i1 %c, label %if, label %join155 156if:157 call void @dummy()158 br label %join159 160join:161 %phi = phi i32 [ 1, %entry ], [ 2, %if ]162 ret i32 %phi163}164 165define void @switch_case(i32 %x) {166; CHECK-LABEL: define void @switch_case167; CHECK-SAME: (i32 [[X:%.*]]) {168; CHECK-NEXT: switch i32 0, label [[DEFAULT:%.*]] [169; CHECK-NEXT: i32 0, label [[CASE0:%.*]]170; CHECK-NEXT: ]171; CHECK: case0:172; CHECK-NEXT: call void @dummy()173; CHECK-NEXT: ret void174; CHECK: default:175; CHECK-NEXT: ret void176;177 %v = and i32 %x, 0178 switch i32 %v, label %default [179 i32 0, label %case0180 ]181 182case0:183 call void @dummy()184 ret void185 186default:187 call void @dummy()188 ret void189}190 191define void @switch_default(i32 %x) {192; CHECK-LABEL: define void @switch_default193; CHECK-SAME: (i32 [[X:%.*]]) {194; CHECK-NEXT: switch i32 -1, label [[DEFAULT:%.*]] [195; CHECK-NEXT: i32 0, label [[CASE0:%.*]]196; CHECK-NEXT: ]197; CHECK: case0:198; CHECK-NEXT: ret void199; CHECK: default:200; CHECK-NEXT: call void @dummy()201; CHECK-NEXT: ret void202;203 %v = or i32 %x, -1204 switch i32 %v, label %default [205 i32 0, label %case0206 ]207 208case0:209 call void @dummy()210 ret void211 212default:213 call void @dummy()214 ret void215}216 217define void @switch_undef(i32 %x) {218; CHECK-LABEL: define void @switch_undef219; CHECK-SAME: (i32 [[X:%.*]]) {220; CHECK-NEXT: switch i32 undef, label [[DEFAULT:%.*]] [221; CHECK-NEXT: i32 0, label [[CASE0:%.*]]222; CHECK-NEXT: ]223; CHECK: case0:224; CHECK-NEXT: ret void225; CHECK: default:226; CHECK-NEXT: ret void227;228 %v = xor i32 %x, undef229 switch i32 %v, label %default [230 i32 0, label %case0231 ]232 233case0:234 call void @dummy()235 ret void236 237default:238 call void @dummy()239 ret void240}241 242define void @non_term_unreachable() {243; CHECK-LABEL: define void @non_term_unreachable() {244; CHECK-NEXT: call void @dummy()245; CHECK-NEXT: store i1 true, ptr poison, align 1246; CHECK-NEXT: ret void247;248 call void @dummy()249 call void @dummy() nounwind willreturn250 store i1 true, ptr poison251 call void @dummy()252 ret void253}254 255define i32 @non_term_unreachable_phi(i1 %c) {256; CHECK-LABEL: define i32 @non_term_unreachable_phi257; CHECK-SAME: (i1 [[C:%.*]]) {258; CHECK-NEXT: entry:259; CHECK-NEXT: br i1 [[C]], label [[IF:%.*]], label [[JOIN:%.*]]260; CHECK: if:261; CHECK-NEXT: store i1 true, ptr poison, align 1262; CHECK-NEXT: br label [[JOIN]]263; CHECK: join:264; CHECK-NEXT: ret i32 2265;266entry:267 br i1 %c, label %if, label %join268 269if:270 store i1 true, ptr poison271 call void @dummy()272 br label %join273 274join:275 %phi = phi i32 [ 1, %if], [ 2, %entry ]276 ret i32 %phi277}278 279define void @non_term_unreachable_following_blocks() {280; CHECK-LABEL: define void @non_term_unreachable_following_blocks() {281; CHECK-NEXT: call void @dummy()282; CHECK-NEXT: store i1 true, ptr poison, align 1283; CHECK-NEXT: br label [[SPLIT:%.*]]284; CHECK: split:285; CHECK-NEXT: br label [[LOOP:%.*]]286; CHECK: loop:287; CHECK-NEXT: br label [[LOOP]]288;289 call void @dummy()290 store i1 true, ptr poison291 call void @dummy()292 br label %split293 294split:295 call void @dummy()296 br label %loop297 298loop:299 call void @dummy()300 br label %loop301}302 303define void @br_not_into_loop(i1 %x) {304; CHECK-LABEL: define void @br_not_into_loop305; CHECK-SAME: (i1 [[X:%.*]]) {306; CHECK-NEXT: br i1 true, label [[EXIT:%.*]], label [[LOOP:%.*]]307; CHECK: loop:308; CHECK-NEXT: br label [[LOOP]]309; CHECK: exit:310; CHECK-NEXT: call void @dummy()311; CHECK-NEXT: ret void312;313 %c = or i1 %x, true314 br i1 %c, label %exit, label %loop315 316loop:317 call void @dummy()318 br label %loop319 320exit:321 call void @dummy()322 ret void323}324 325define void @br_into_loop(i1 %x) {326; CHECK-LABEL: define void @br_into_loop327; CHECK-SAME: (i1 [[X:%.*]]) {328; CHECK-NEXT: br i1 true, label [[LOOP:%.*]], label [[EXIT:%.*]]329; CHECK: loop:330; CHECK-NEXT: call void @dummy()331; CHECK-NEXT: br label [[LOOP]]332; CHECK: exit:333; CHECK-NEXT: ret void334;335 %c = or i1 %x, true336 br i1 %c, label %loop, label %exit337 338loop:339 call void @dummy()340 br label %loop341 342exit:343 call void @dummy()344 ret void345}346 347define void @two_br_not_into_loop(i1 %x) {348; CHECK-LABEL: define void @two_br_not_into_loop349; CHECK-SAME: (i1 [[X:%.*]]) {350; CHECK-NEXT: br i1 true, label [[BB2:%.*]], label [[LOOP:%.*]]351; CHECK: bb2:352; CHECK-NEXT: br i1 true, label [[EXIT:%.*]], label [[LOOP]]353; CHECK: loop:354; CHECK-NEXT: br label [[LOOP]]355; CHECK: exit:356; CHECK-NEXT: call void @dummy()357; CHECK-NEXT: ret void358;359 %c = or i1 %x, true360 br i1 %c, label %bb2, label %loop361 362bb2:363 %c2 = or i1 %x, true364 br i1 %c2, label %exit, label %loop365 366loop:367 call void @dummy()368 br label %loop369 370exit:371 call void @dummy()372 ret void373}374 375define void @one_br_into_loop_one_not(i1 %x, i1 %c2) {376; CHECK-LABEL: define void @one_br_into_loop_one_not377; CHECK-SAME: (i1 [[X:%.*]], i1 [[C2:%.*]]) {378; CHECK-NEXT: br i1 true, label [[BB2:%.*]], label [[LOOP:%.*]]379; CHECK: bb2:380; CHECK-NEXT: br i1 [[C2]], label [[EXIT:%.*]], label [[LOOP]]381; CHECK: loop:382; CHECK-NEXT: call void @dummy()383; CHECK-NEXT: br label [[LOOP]]384; CHECK: exit:385; CHECK-NEXT: call void @dummy()386; CHECK-NEXT: ret void387;388 %c = or i1 %x, true389 br i1 %c, label %bb2, label %loop390 391bb2:392 br i1 %c2, label %exit, label %loop393 394loop:395 call void @dummy()396 br label %loop397 398exit:399 call void @dummy()400 ret void401}402 403define void @two_br_not_into_loop_with_split(i1 %x) {404; CHECK-LABEL: define void @two_br_not_into_loop_with_split405; CHECK-SAME: (i1 [[X:%.*]]) {406; CHECK-NEXT: br i1 true, label [[BB2:%.*]], label [[SPLIT1:%.*]]407; CHECK: bb2:408; CHECK-NEXT: br i1 true, label [[EXIT:%.*]], label [[SPLIT2:%.*]]409; CHECK: split1:410; CHECK-NEXT: br label [[LOOP:%.*]]411; CHECK: split2:412; CHECK-NEXT: br label [[LOOP]]413; CHECK: loop:414; CHECK-NEXT: br label [[LOOP]]415; CHECK: exit:416; CHECK-NEXT: call void @dummy()417; CHECK-NEXT: ret void418;419 %c = or i1 %x, true420 br i1 %c, label %bb2, label %split1421 422bb2:423 %c2 = or i1 %x, true424 br i1 %c2, label %exit, label %split2425 426split1:427 call void @dummy()428 br label %loop429 430split2:431 call void @dummy()432 br label %loop433 434loop:435 call void @dummy()436 br label %loop437 438exit:439 call void @dummy()440 ret void441}442 443define void @irreducible() {444; CHECK-LABEL: define void @irreducible() {445; CHECK-NEXT: entry:446; CHECK-NEXT: br i1 false, label [[LOOP2:%.*]], label [[LOOP1:%.*]]447; CHECK: loop1:448; CHECK-NEXT: call void @dummy()449; CHECK-NEXT: br label [[LOOP2]]450; CHECK: loop2:451; CHECK-NEXT: call void @dummy()452; CHECK-NEXT: br i1 true, label [[EXIT:%.*]], label [[LOOP1]]453; CHECK: exit:454; CHECK-NEXT: call void @dummy()455; CHECK-NEXT: ret void456;457entry:458 br i1 false, label %loop2, label %loop1459 460loop1:461 call void @dummy()462 br label %loop2463 464loop2:465 call void @dummy()466 br i1 true, label %exit, label %loop1467 468exit:469 call void @dummy()470 ret void471}472 473define void @really_unreachable() {474; CHECK-LABEL: define void @really_unreachable() {475; CHECK-NEXT: entry:476; CHECK-NEXT: ret void477; CHECK: unreachable:478; CHECK-NEXT: ret void479;480entry:481 ret void482 483unreachable:484 call void @dummy()485 ret void486}487 488define void @really_unreachable_predecessor() {489; CHECK-LABEL: define void @really_unreachable_predecessor() {490; CHECK-NEXT: entry:491; CHECK-NEXT: br i1 false, label [[BB:%.*]], label [[EXIT:%.*]]492; CHECK: unreachable:493; CHECK-NEXT: br label [[BB]]494; CHECK: bb:495; CHECK-NEXT: ret void496; CHECK: exit:497; CHECK-NEXT: call void @dummy()498; CHECK-NEXT: ret void499;500entry:501 br i1 false, label %bb, label %exit502 503unreachable:504 call void @dummy()505 br label %bb506 507bb:508 call void @dummy()509 ret void510 511exit:512 call void @dummy()513 ret void514}515 516define i32 @pr64235() {517; CHECK-LABEL: define i32 @pr64235() {518; CHECK-NEXT: entry:519; CHECK-NEXT: br i1 false, label [[BB:%.*]], label [[BB3:%.*]]520; CHECK: bb3:521; CHECK-NEXT: store i1 true, ptr poison, align 1522; CHECK-NEXT: br label [[BB2:%.*]]523; CHECK: bb:524; CHECK-NEXT: br label [[BB2]]525; CHECK: bb2:526; CHECK-NEXT: br label [[BB]]527;528entry:529 br i1 false, label %bb, label %bb3530 531bb3:532 call void @llvm.assume(i1 false)533 br label %bb2534 535bb:536 br label %bb2537 538bb2:539 call void @llvm.assume(i1 false)540 br label %bb541}542 543declare void @invoke(ptr)544declare i32 @__gxx_personality_v0(...)545define void @test(i1 %x) personality ptr @__gxx_personality_v0 {546; CHECK-LABEL: define void @test547; CHECK-SAME: (i1 [[X:%.*]]) personality ptr @__gxx_personality_v0 {548; CHECK-NEXT: entry:549; CHECK-NEXT: br i1 [[X]], label [[IF_ELSE:%.*]], label [[CLEAN1:%.*]]550; CHECK: if.else:551; CHECK-NEXT: store i32 1, ptr undef, align 4552; CHECK-NEXT: invoke void @invoke(ptr poison)553; CHECK-NEXT: to label [[CONT:%.*]] unwind label [[LPAD5:%.*]]554; CHECK: cont:555; CHECK-NEXT: invoke void @invoke(ptr poison)556; CHECK-NEXT: to label [[CLEAN1]] unwind label [[LPAD6:%.*]]557; CHECK: lpad5:558; CHECK-NEXT: [[TMP0:%.*]] = landingpad { ptr, i32 }559; CHECK-NEXT: cleanup560; CHECK-NEXT: br label [[CLEAN1]]561; CHECK: lpad6:562; CHECK-NEXT: [[TMP1:%.*]] = landingpad { ptr, i32 }563; CHECK-NEXT: cleanup564; CHECK-NEXT: br label [[CLEAN2:%.*]]565; CHECK: clean1:566; CHECK-NEXT: ret void567; CHECK: clean2:568; CHECK-NEXT: ret void569;570entry:571 %ref = alloca ptr572 br i1 %x, label %if.else, label %clean1573 574if.else:575 store i32 1, ptr undef576 invoke void @invoke(ptr %ref)577 to label %cont unwind label %lpad5578 579cont:580 invoke void @invoke(ptr %ref)581 to label %clean1 unwind label %lpad6582 583lpad5:584 %13 = landingpad { ptr, i32 }585 cleanup586 br label %clean1587 588lpad6:589 %14 = landingpad { ptr, i32 }590 cleanup591 br label %clean2592 593clean1:594 ret void595 596clean2:597 ret void598}599 600;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:601; DEFAULT_ITER: {{.*}}602; MAX1: {{.*}}603