1146 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=gvn -S | FileCheck %s3 4@a = external global i32 ; <ptr> [#uses=7]5 6define i32 @test1() nounwind {7; CHECK-LABEL: @test1(8; CHECK-NEXT: entry:9; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr @a, align 410; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 411; CHECK-NEXT: br i1 [[TMP1]], label [[BB:%.*]], label [[BB1:%.*]]12; CHECK: bb:13; CHECK-NEXT: br label [[BB8:%.*]]14; CHECK: bb1:15; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP0]], 516; CHECK-NEXT: br i1 [[TMP2]], label [[BB2:%.*]], label [[BB3:%.*]]17; CHECK: bb2:18; CHECK-NEXT: br label [[BB8]]19; CHECK: bb3:20; CHECK-NEXT: br i1 false, label [[BB4:%.*]], label [[BB5:%.*]]21; CHECK: bb4:22; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr @a, align 423; CHECK-NEXT: [[TMP4:%.*]] = add i32 [[TMP3]], 524; CHECK-NEXT: br label [[BB8]]25; CHECK: bb5:26; CHECK-NEXT: br i1 false, label [[BB6:%.*]], label [[BB7:%.*]]27; CHECK: bb6:28; CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr @a, align 429; CHECK-NEXT: [[TMP6:%.*]] = add i32 [[TMP5]], 430; CHECK-NEXT: br label [[BB8]]31; CHECK: bb7:32; CHECK-NEXT: br label [[BB8]]33; CHECK: bb8:34; CHECK-NEXT: [[DOT0:%.*]] = phi i32 [ [[TMP0]], [[BB7]] ], [ poison, [[BB6]] ], [ poison, [[BB4]] ], [ 4, [[BB2]] ], [ 5, [[BB]] ]35; CHECK-NEXT: ret i32 [[DOT0]]36;37entry:38 %0 = load i32, ptr @a, align 439 %1 = icmp eq i32 %0, 440 br i1 %1, label %bb, label %bb141 42bb: ; preds = %entry43 br label %bb844 45bb1: ; preds = %entry46 %2 = load i32, ptr @a, align 447 %3 = icmp eq i32 %2, 548 br i1 %3, label %bb2, label %bb349 50bb2: ; preds = %bb151 br label %bb852 53bb3: ; preds = %bb154 %4 = load i32, ptr @a, align 455 %5 = icmp eq i32 %4, 456 br i1 %5, label %bb4, label %bb557 58bb4: ; preds = %bb359 %6 = load i32, ptr @a, align 460 %7 = add i32 %6, 561 br label %bb862 63bb5: ; preds = %bb364 %8 = load i32, ptr @a, align 465 %9 = icmp eq i32 %8, 566 br i1 %9, label %bb6, label %bb767 68bb6: ; preds = %bb569 %10 = load i32, ptr @a, align 470 %11 = add i32 %10, 471 br label %bb872 73bb7: ; preds = %bb574 %12 = load i32, ptr @a, align 475 br label %bb876 77bb8: ; preds = %bb7, %bb6, %bb4, %bb2, %bb78 %.0 = phi i32 [ %12, %bb7 ], [ %11, %bb6 ], [ %7, %bb4 ], [ 4, %bb2 ], [ 5, %bb ]79 br label %return80 81return: ; preds = %bb882 ret i32 %.083}84 85declare void @foo(i1)86declare void @bar(i32)87 88define void @test3(i32 %x, i32 %y) {89; CHECK-LABEL: @test3(90; CHECK-NEXT: [[XZ:%.*]] = icmp eq i32 [[X:%.*]], 091; CHECK-NEXT: [[YZ:%.*]] = icmp eq i32 [[Y:%.*]], 092; CHECK-NEXT: [[Z:%.*]] = and i1 [[XZ]], [[YZ]]93; CHECK-NEXT: br i1 [[Z]], label [[BOTH_ZERO:%.*]], label [[NOPE:%.*]]94; CHECK: both_zero:95; CHECK-NEXT: call void @foo(i1 true)96; CHECK-NEXT: call void @foo(i1 true)97; CHECK-NEXT: call void @bar(i32 0)98; CHECK-NEXT: call void @bar(i32 0)99; CHECK-NEXT: ret void100; CHECK: nope:101; CHECK-NEXT: call void @foo(i1 false)102; CHECK-NEXT: ret void103;104 %xz = icmp eq i32 %x, 0105 %yz = icmp eq i32 %y, 0106 %z = and i1 %xz, %yz107 br i1 %z, label %both_zero, label %nope108both_zero:109 call void @foo(i1 %xz)110 call void @foo(i1 %yz)111 call void @bar(i32 %x)112 call void @bar(i32 %y)113 ret void114nope:115 call void @foo(i1 %z)116 ret void117}118 119define void @test3_select(i32 %x, i32 %y) {120; CHECK-LABEL: @test3_select(121; CHECK-NEXT: [[XZ:%.*]] = icmp eq i32 [[X:%.*]], 0122; CHECK-NEXT: [[YZ:%.*]] = icmp eq i32 [[Y:%.*]], 0123; CHECK-NEXT: [[Z:%.*]] = select i1 [[XZ]], i1 [[YZ]], i1 false124; CHECK-NEXT: br i1 [[Z]], label [[BOTH_ZERO:%.*]], label [[NOPE:%.*]]125; CHECK: both_zero:126; CHECK-NEXT: call void @foo(i1 true)127; CHECK-NEXT: call void @foo(i1 true)128; CHECK-NEXT: call void @bar(i32 0)129; CHECK-NEXT: call void @bar(i32 0)130; CHECK-NEXT: ret void131; CHECK: nope:132; CHECK-NEXT: call void @foo(i1 false)133; CHECK-NEXT: ret void134;135 %xz = icmp eq i32 %x, 0136 %yz = icmp eq i32 %y, 0137 %z = select i1 %xz, i1 %yz, i1 false138 br i1 %z, label %both_zero, label %nope139both_zero:140 call void @foo(i1 %xz)141 call void @foo(i1 %yz)142 call void @bar(i32 %x)143 call void @bar(i32 %y)144 ret void145nope:146 call void @foo(i1 %z)147 ret void148}149 150define void @test3_or(i32 %x, i32 %y) {151; CHECK-LABEL: @test3_or(152; CHECK-NEXT: [[XZ:%.*]] = icmp ne i32 [[X:%.*]], 0153; CHECK-NEXT: [[YZ:%.*]] = icmp ne i32 [[Y:%.*]], 0154; CHECK-NEXT: [[Z:%.*]] = or i1 [[XZ]], [[YZ]]155; CHECK-NEXT: br i1 [[Z]], label [[NOPE:%.*]], label [[BOTH_ZERO:%.*]]156; CHECK: both_zero:157; CHECK-NEXT: call void @foo(i1 false)158; CHECK-NEXT: call void @foo(i1 false)159; CHECK-NEXT: call void @bar(i32 0)160; CHECK-NEXT: call void @bar(i32 0)161; CHECK-NEXT: ret void162; CHECK: nope:163; CHECK-NEXT: call void @foo(i1 true)164; CHECK-NEXT: ret void165;166 %xz = icmp ne i32 %x, 0167 %yz = icmp ne i32 %y, 0168 %z = or i1 %xz, %yz169 br i1 %z, label %nope, label %both_zero170both_zero:171 call void @foo(i1 %xz)172 call void @foo(i1 %yz)173 call void @bar(i32 %x)174 call void @bar(i32 %y)175 ret void176nope:177 call void @foo(i1 %z)178 ret void179}180 181define void @test3_or_select(i32 %x, i32 %y) {182; CHECK-LABEL: @test3_or_select(183; CHECK-NEXT: [[XZ:%.*]] = icmp ne i32 [[X:%.*]], 0184; CHECK-NEXT: [[YZ:%.*]] = icmp ne i32 [[Y:%.*]], 0185; CHECK-NEXT: [[Z:%.*]] = select i1 [[XZ]], i1 true, i1 [[YZ]]186; CHECK-NEXT: br i1 [[Z]], label [[NOPE:%.*]], label [[BOTH_ZERO:%.*]]187; CHECK: both_zero:188; CHECK-NEXT: call void @foo(i1 false)189; CHECK-NEXT: call void @foo(i1 false)190; CHECK-NEXT: call void @bar(i32 0)191; CHECK-NEXT: call void @bar(i32 0)192; CHECK-NEXT: ret void193; CHECK: nope:194; CHECK-NEXT: call void @foo(i1 true)195; CHECK-NEXT: ret void196;197 %xz = icmp ne i32 %x, 0198 %yz = icmp ne i32 %y, 0199 %z = select i1 %xz, i1 true, i1 %yz200 br i1 %z, label %nope, label %both_zero201both_zero:202 call void @foo(i1 %xz)203 call void @foo(i1 %yz)204 call void @bar(i32 %x)205 call void @bar(i32 %y)206 ret void207nope:208 call void @foo(i1 %z)209 ret void210}211 212define void @test4(i1 %b, i32 %x) {213; CHECK-LABEL: @test4(214; CHECK-NEXT: br i1 [[B:%.*]], label [[SW:%.*]], label [[CASE3:%.*]]215; CHECK: sw:216; CHECK-NEXT: switch i32 [[X:%.*]], label [[DEFAULT:%.*]] [217; CHECK-NEXT: i32 0, label [[CASE0:%.*]]218; CHECK-NEXT: i32 1, label [[CASE1:%.*]]219; CHECK-NEXT: i32 2, label [[CASE0]]220; CHECK-NEXT: i32 3, label [[CASE3]]221; CHECK-NEXT: i32 4, label [[DEFAULT]]222; CHECK-NEXT: ]223; CHECK: default:224; CHECK-NEXT: call void @bar(i32 [[X]])225; CHECK-NEXT: ret void226; CHECK: case0:227; CHECK-NEXT: call void @bar(i32 [[X]])228; CHECK-NEXT: ret void229; CHECK: case1:230; CHECK-NEXT: call void @bar(i32 1)231; CHECK-NEXT: ret void232; CHECK: case3:233; CHECK-NEXT: call void @bar(i32 [[X]])234; CHECK-NEXT: ret void235;236 br i1 %b, label %sw, label %case3237sw:238 switch i32 %x, label %default [239 i32 0, label %case0240 i32 1, label %case1241 i32 2, label %case0242 i32 3, label %case3243 i32 4, label %default244 ]245default:246 call void @bar(i32 %x)247 ret void248case0:249 call void @bar(i32 %x)250 ret void251case1:252 call void @bar(i32 %x)253 ret void254case3:255 call void @bar(i32 %x)256 ret void257}258 259define i1 @test5(i32 %x, i32 %y) {260; CHECK-LABEL: @test5(261; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]262; CHECK-NEXT: br i1 [[CMP]], label [[SAME:%.*]], label [[DIFFERENT:%.*]]263; CHECK: same:264; CHECK-NEXT: ret i1 false265; CHECK: different:266; CHECK-NEXT: ret i1 false267;268 %cmp = icmp eq i32 %x, %y269 br i1 %cmp, label %same, label %different270 271same:272 %cmp2 = icmp ne i32 %x, %y273 ret i1 %cmp2274 275different:276 %cmp3 = icmp eq i32 %x, %y277 ret i1 %cmp3278}279 280define i1 @test6(i32 %x, i32 %y) {281; CHECK-LABEL: @test6(282; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]]283; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X]], [[Y]]284; CHECK-NEXT: br i1 [[CMP]], label [[SAME:%.*]], label [[DIFFERENT:%.*]]285; CHECK: same:286; CHECK-NEXT: ret i1 false287; CHECK: different:288; CHECK-NEXT: ret i1 false289;290 %cmp2 = icmp ne i32 %x, %y291 %cmp = icmp eq i32 %x, %y292 %cmp3 = icmp eq i32 %x, %y293 br i1 %cmp, label %same, label %different294 295same:296 ret i1 %cmp2297 298different:299 ret i1 %cmp3300}301 302define i1 @test6_fp(float %x, float %y) {303; CHECK-LABEL: @test6_fp(304; CHECK-NEXT: [[CMP2:%.*]] = fcmp une float [[X:%.*]], [[Y:%.*]]305; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq float [[X]], [[Y]]306; CHECK-NEXT: br i1 [[CMP]], label [[SAME:%.*]], label [[DIFFERENT:%.*]]307; CHECK: same:308; CHECK-NEXT: ret i1 false309; CHECK: different:310; CHECK-NEXT: ret i1 false311;312 %cmp2 = fcmp une float %x, %y313 %cmp = fcmp oeq float %x, %y314 %cmp3 = fcmp oeq float %x, %y315 br i1 %cmp, label %same, label %different316 317same:318 ret i1 %cmp2319 320different:321 ret i1 %cmp3322}323 324define i1 @test6_phi1(i1 %c, i32 %x, i32 %y) {325; CHECK-LABEL: @test6_phi1(326; CHECK-NEXT: entry:327; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]]328; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]329; CHECK: bb1:330; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X]], [[Y]]331; CHECK-NEXT: br i1 [[CMP]], label [[BB2]], label [[BB3:%.*]]332; CHECK: bb2:333; CHECK-NEXT: [[PHI:%.*]] = phi i1 [ false, [[BB1]] ], [ true, [[ENTRY:%.*]] ]334; CHECK-NEXT: ret i1 [[PHI]]335; CHECK: bb3:336; CHECK-NEXT: ret i1 false337;338entry:339 %cmp.not = icmp ne i32 %x, %y340 br i1 %c, label %bb1, label %bb2341 342bb1:343 %cmp = icmp eq i32 %x, %y344 br i1 %cmp, label %bb2, label %bb3345 346bb2:347 %phi = phi i1 [ %cmp.not, %bb1 ], [ true, %entry ]348 ret i1 %phi349 350bb3:351 ret i1 false352}353 354define i1 @test6_phi2(i1 %c, i32 %x, i32 %y) {355; CHECK-LABEL: @test6_phi2(356; CHECK-NEXT: entry:357; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]358; CHECK: bb1:359; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]]360; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X]], [[Y]]361; CHECK-NEXT: br i1 [[CMP]], label [[BB2]], label [[BB3:%.*]]362; CHECK: bb2:363; CHECK-NEXT: [[PHI:%.*]] = phi i1 [ false, [[BB1]] ], [ true, [[ENTRY:%.*]] ]364; CHECK-NEXT: ret i1 [[PHI]]365; CHECK: bb3:366; CHECK-NEXT: ret i1 false367;368entry:369 br i1 %c, label %bb1, label %bb2370 371bb1:372 %cmp.not = icmp ne i32 %x, %y373 %cmp = icmp eq i32 %x, %y374 br i1 %cmp, label %bb2, label %bb3375 376bb2:377 %phi = phi i1 [ %cmp.not, %bb1 ], [ true, %entry ]378 ret i1 %phi379 380bb3:381 ret i1 false382}383 384define i1 @test7(i32 %x, i32 %y) {385; CHECK-LABEL: @test7(386; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]387; CHECK-NEXT: br i1 [[CMP]], label [[SAME:%.*]], label [[DIFFERENT:%.*]]388; CHECK: same:389; CHECK-NEXT: ret i1 false390; CHECK: different:391; CHECK-NEXT: ret i1 false392;393 %cmp = icmp sgt i32 %x, %y394 br i1 %cmp, label %same, label %different395 396same:397 %cmp2 = icmp sle i32 %x, %y398 ret i1 %cmp2399 400different:401 %cmp3 = icmp sgt i32 %x, %y402 ret i1 %cmp3403}404 405define i1 @test7_fp(float %x, float %y) {406; CHECK-LABEL: @test7_fp(407; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[X:%.*]], [[Y:%.*]]408; CHECK-NEXT: br i1 [[CMP]], label [[SAME:%.*]], label [[DIFFERENT:%.*]]409; CHECK: same:410; CHECK-NEXT: ret i1 false411; CHECK: different:412; CHECK-NEXT: ret i1 false413;414 %cmp = fcmp ogt float %x, %y415 br i1 %cmp, label %same, label %different416 417same:418 %cmp2 = fcmp ule float %x, %y419 ret i1 %cmp2420 421different:422 %cmp3 = fcmp ogt float %x, %y423 ret i1 %cmp3424}425 426define i1 @test8(i32 %x, i32 %y) {427; CHECK-LABEL: @test8(428; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[X:%.*]], [[Y:%.*]]429; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X]], [[Y]]430; CHECK-NEXT: br i1 [[CMP]], label [[SAME:%.*]], label [[DIFFERENT:%.*]]431; CHECK: same:432; CHECK-NEXT: ret i1 false433; CHECK: different:434; CHECK-NEXT: ret i1 false435;436 %cmp2 = icmp sle i32 %x, %y437 %cmp = icmp sgt i32 %x, %y438 %cmp3 = icmp sgt i32 %x, %y439 br i1 %cmp, label %same, label %different440 441same:442 ret i1 %cmp2443 444different:445 ret i1 %cmp3446}447 448define i1 @test8_fp(float %x, float %y) {449; CHECK-LABEL: @test8_fp(450; CHECK-NEXT: [[CMP2:%.*]] = fcmp ule float [[X:%.*]], [[Y:%.*]]451; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[X]], [[Y]]452; CHECK-NEXT: br i1 [[CMP]], label [[SAME:%.*]], label [[DIFFERENT:%.*]]453; CHECK: same:454; CHECK-NEXT: ret i1 false455; CHECK: different:456; CHECK-NEXT: ret i1 false457;458 %cmp2 = fcmp ule float %x, %y459 %cmp = fcmp ogt float %x, %y460 %cmp3 = fcmp ogt float %x, %y461 br i1 %cmp, label %same, label %different462 463same:464 ret i1 %cmp2465 466different:467 ret i1 %cmp3468}469 470; PR1768471define i32 @test9(i32 %i, i32 %j) {472; CHECK-LABEL: @test9(473; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[I:%.*]], [[J:%.*]]474; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[RET:%.*]]475; CHECK: cond_true:476; CHECK-NEXT: ret i32 0477; CHECK: ret:478; CHECK-NEXT: ret i32 5479;480 %cmp = icmp eq i32 %i, %j481 br i1 %cmp, label %cond_true, label %ret482 483cond_true:484 %diff = sub i32 %i, %j485 ret i32 %diff486 487ret:488 ret i32 5489}490 491; PR1768492define i32 @test10(i32 %j, i32 %i) {493; CHECK-LABEL: @test10(494; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[I:%.*]], [[J:%.*]]495; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[RET:%.*]]496; CHECK: cond_true:497; CHECK-NEXT: ret i32 0498; CHECK: ret:499; CHECK-NEXT: ret i32 5500;501 %cmp = icmp eq i32 %i, %j502 br i1 %cmp, label %cond_true, label %ret503 504cond_true:505 %diff = sub i32 %i, %j506 ret i32 %diff507 508ret:509 ret i32 5510}511 512declare i32 @yogibar()513 514define i32 @test11(i32 %x) {515; CHECK-LABEL: @test11(516; CHECK-NEXT: [[V0:%.*]] = call i32 @yogibar()517; CHECK-NEXT: [[V1:%.*]] = call i32 @yogibar()518; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[V0]], [[V1]]519; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[NEXT:%.*]]520; CHECK: cond_true:521; CHECK-NEXT: ret i32 [[V0]]522; CHECK: next:523; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[X:%.*]], [[V0]]524; CHECK-NEXT: br i1 [[CMP2]], label [[COND_TRUE2:%.*]], label [[NEXT2:%.*]]525; CHECK: cond_true2:526; CHECK-NEXT: ret i32 [[X]]527; CHECK: next2:528; CHECK-NEXT: ret i32 0529;530 %v0 = call i32 @yogibar()531 %v1 = call i32 @yogibar()532 %cmp = icmp eq i32 %v0, %v1533 br i1 %cmp, label %cond_true, label %next534 535cond_true:536 ret i32 %v1537 538next:539 %cmp2 = icmp eq i32 %x, %v0540 br i1 %cmp2, label %cond_true2, label %next2541 542cond_true2:543 ret i32 %v0544 545next2:546 ret i32 0547}548 549define i32 @test12(i32 %x) {550; CHECK-LABEL: @test12(551; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 0552; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]553; CHECK: cond_true:554; CHECK-NEXT: br label [[RET:%.*]]555; CHECK: cond_false:556; CHECK-NEXT: br label [[RET]]557; CHECK: ret:558; CHECK-NEXT: [[RES:%.*]] = phi i32 [ 0, [[COND_TRUE]] ], [ [[X]], [[COND_FALSE]] ]559; CHECK-NEXT: ret i32 [[RES]]560;561 %cmp = icmp eq i32 %x, 0562 br i1 %cmp, label %cond_true, label %cond_false563 564cond_true:565 br label %ret566 567cond_false:568 br label %ret569 570ret:571 %res = phi i32 [ %x, %cond_true ], [ %x, %cond_false ]572 ret i32 %res573}574 575; On the path from entry->if->end we know that ptr1==ptr2, so we can determine576; that gep2 does not alias ptr1 on that path (as it would require that577; ptr2==ptr2+2), so we can perform PRE of the load.578define i32 @test13(ptr %ptr1, ptr %ptr2) {579; CHECK-LABEL: @test13(580; CHECK-NEXT: entry:581; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i32, ptr [[PTR2:%.*]], i32 1582; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i32, ptr [[PTR2]], i32 2583; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[PTR1:%.*]], [[PTR2]]584; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]585; CHECK: if:586; CHECK-NEXT: [[VAL1:%.*]] = load i32, ptr [[GEP2]], align 4587; CHECK-NEXT: br label [[END]]588; CHECK: end:589; CHECK-NEXT: [[PHI1:%.*]] = phi ptr [ [[PTR1]], [[IF]] ], [ [[GEP1]], [[ENTRY:%.*]] ]590; CHECK-NEXT: [[PHI2:%.*]] = phi i32 [ [[VAL1]], [[IF]] ], [ 0, [[ENTRY]] ]591; CHECK-NEXT: store i32 0, ptr [[PHI1]], align 4592; CHECK-NEXT: [[VAL2:%.*]] = load i32, ptr [[GEP2]], align 4593; CHECK-NEXT: [[RET:%.*]] = add i32 [[PHI2]], [[VAL2]]594; CHECK-NEXT: ret i32 [[RET]]595;596entry:597 %gep1 = getelementptr i32, ptr %ptr2, i32 1598 %gep2 = getelementptr i32, ptr %ptr2, i32 2599 %cmp = icmp eq ptr %ptr1, %ptr2600 br i1 %cmp, label %if, label %end601 602 603if:604 %val1 = load i32, ptr %gep2, align 4605 br label %end606 607end:608 %phi1 = phi ptr [ %ptr1, %if ], [ %gep1, %entry ]609 %phi2 = phi i32 [ %val1, %if ], [ 0, %entry ]610 store i32 0, ptr %phi1, align 4611 %val2 = load i32, ptr %gep2, align 4612 %ret = add i32 %phi2, %val2613 ret i32 %ret614}615 616define void @test14(ptr %ptr1, ptr noalias %ptr2, i1 %b1, i1 %b2) {617; CHECK-LABEL: @test14(618; CHECK-NEXT: entry:619; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i32, ptr [[PTR1:%.*]], i32 1620; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds i32, ptr [[PTR1]], i32 2621; CHECK-NEXT: br label [[LOOP:%.*]]622; CHECK: loop:623; CHECK-NEXT: br i1 [[B1:%.*]], label [[LOOP_IF1_CRIT_EDGE:%.*]], label [[THEN:%.*]]624; CHECK: loop.if1_crit_edge:625; CHECK-NEXT: [[VAL2_PRE:%.*]] = load i32, ptr [[GEP2]], align 4626; CHECK-NEXT: br label [[IF1:%.*]]627; CHECK: if1:628; CHECK-NEXT: [[VAL2:%.*]] = phi i32 [ [[VAL2_PRE]], [[LOOP_IF1_CRIT_EDGE]] ], [ [[VAL3:%.*]], [[LOOP_END:%.*]] ]629; CHECK-NEXT: store i32 [[VAL2]], ptr [[GEP2]], align 4630; CHECK-NEXT: store i32 0, ptr [[GEP1]], align 4631; CHECK-NEXT: br label [[THEN]]632; CHECK: then:633; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[GEP2]], [[PTR2:%.*]]634; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_END]], label [[IF2:%.*]]635; CHECK: if2:636; CHECK-NEXT: br label [[LOOP_END]]637; CHECK: loop.end:638; CHECK-NEXT: [[PHI3:%.*]] = phi ptr [ [[GEP2]], [[THEN]] ], [ [[PTR1]], [[IF2]] ]639; CHECK-NEXT: [[VAL3]] = load i32, ptr [[GEP2]], align 4640; CHECK-NEXT: store i32 [[VAL3]], ptr [[PHI3]], align 4641; CHECK-NEXT: br i1 [[B2:%.*]], label [[LOOP]], label [[IF1]]642;643entry:644 %gep1 = getelementptr inbounds i32, ptr %ptr1, i32 1645 %gep2 = getelementptr inbounds i32, ptr %ptr1, i32 2646 br label %loop647 648loop:649 %phi1 = phi ptr [ %gep3, %loop.end ], [ %gep1, %entry ]650 br i1 %b1, label %if1, label %then651 652 653if1:654 %val2 = load i32, ptr %gep2, align 4655 store i32 %val2, ptr %gep2, align 4656 store i32 0, ptr %phi1, align 4657 br label %then658 659then:660 %cmp = icmp eq ptr %gep2, %ptr2661 br i1 %cmp, label %loop.end, label %if2662 663if2:664 br label %loop.end665 666loop.end:667 %phi3 = phi ptr [ %gep2, %then ], [ %ptr1, %if2 ]668 %val3 = load i32, ptr %gep2, align 4669 store i32 %val3, ptr %phi3, align 4670 %gep3 = getelementptr inbounds i32, ptr %ptr1, i32 1671 br i1 %b2, label %loop, label %if1672}673 674; Make sure that the call to use_ptr does not have %p1675define void @single_phi1(ptr %p0, ptr %p1, i8 %s) {676; CHECK-LABEL: @single_phi1(677; CHECK-NEXT: entry:678; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P0:%.*]], align 8679; CHECK-NEXT: [[CMP1:%.*]] = icmp eq ptr [[P2]], [[P1:%.*]]680; CHECK-NEXT: br i1 [[CMP1]], label [[BB4:%.*]], label [[BB1:%.*]]681; CHECK: bb1:682; CHECK-NEXT: switch i8 [[S:%.*]], label [[BB2:%.*]] [683; CHECK-NEXT: i8 0, label [[BB1]]684; CHECK-NEXT: i8 1, label [[BB3:%.*]]685; CHECK-NEXT: ]686; CHECK: bb2:687; CHECK-NEXT: unreachable688; CHECK: bb3:689; CHECK-NEXT: br label [[BB4]]690; CHECK: bb4:691; CHECK-NEXT: call void @use_bool(i1 [[CMP1]])692; CHECK-NEXT: call void @use_ptr(ptr [[P2]])693; CHECK-NEXT: ret void694;695entry:696 %p2 = load ptr, ptr %p0, align 8697 %cmp1 = icmp eq ptr %p2, %p1698 br i1 %cmp1, label %bb4, label %bb1699 700bb1:701 switch i8 %s, label %bb2 [702 i8 0, label %bb1703 i8 1, label %bb3704 ]705 706bb2:707 unreachable708 709bb3:710 br label %bb4711 712bb4:713 %phi1 = phi ptr [ %p2, %entry ], [ %p2, %bb3 ]714 %cmp2 = icmp eq ptr %phi1, %p1715 call void @use_bool(i1 %cmp2)716 call void @use_ptr(ptr %phi1)717 ret void718}719 720define void @single_phi2(ptr %p0, ptr %p1, i8 %s) {721; CHECK-LABEL: @single_phi2(722; CHECK-NEXT: entry:723; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P0:%.*]], align 8724; CHECK-NEXT: [[CMP1:%.*]] = icmp eq ptr [[P2]], [[P1:%.*]]725; CHECK-NEXT: br i1 [[CMP1]], label [[BB4:%.*]], label [[BB1:%.*]]726; CHECK: bb1:727; CHECK-NEXT: switch i8 [[S:%.*]], label [[BB2:%.*]] [728; CHECK-NEXT: i8 0, label [[BB1]]729; CHECK-NEXT: i8 1, label [[BB3:%.*]]730; CHECK-NEXT: ]731; CHECK: bb2:732; CHECK-NEXT: br label [[BB4]]733; CHECK: bb3:734; CHECK-NEXT: br label [[BB4]]735; CHECK: bb4:736; CHECK-NEXT: call void @use_bool(i1 [[CMP1]])737; CHECK-NEXT: call void @use_ptr(ptr [[P2]])738; CHECK-NEXT: ret void739;740entry:741 %p2 = load ptr, ptr %p0, align 8742 %cmp1 = icmp eq ptr %p2, %p1743 br i1 %cmp1, label %bb4, label %bb1744 745bb1:746 switch i8 %s, label %bb2 [747 i8 0, label %bb1748 i8 1, label %bb3749 ]750 751bb2:752 br label %bb4753 754bb3:755 br label %bb4756 757bb4:758 %phi1 = phi ptr [ %p2, %entry ], [ %p2, %bb2 ], [ %p2, %bb3 ]759 %cmp2 = icmp eq ptr %phi1, %p1760 call void @use_bool(i1 %cmp2)761 call void @use_ptr(ptr %phi1)762 ret void763}764 765define void @multiple_phi1(ptr %p0, ptr %p1, i8 %s) {766; CHECK-LABEL: @multiple_phi1(767; CHECK-NEXT: entry:768; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P0:%.*]], align 8769; CHECK-NEXT: [[CMP1:%.*]] = icmp eq ptr [[P2]], [[P1:%.*]]770; CHECK-NEXT: br i1 [[CMP1]], label [[BB4:%.*]], label [[BB1:%.*]]771; CHECK: bb1:772; CHECK-NEXT: switch i8 [[S:%.*]], label [[BB2:%.*]] [773; CHECK-NEXT: i8 0, label [[BB1]]774; CHECK-NEXT: i8 1, label [[BB3:%.*]]775; CHECK-NEXT: ]776; CHECK: bb2:777; CHECK-NEXT: unreachable778; CHECK: bb3:779; CHECK-NEXT: br label [[BB4]]780; CHECK: bb4:781; CHECK-NEXT: call void @use_bool(i1 [[CMP1]])782; CHECK-NEXT: br label [[BB5:%.*]]783; CHECK: bb5:784; CHECK-NEXT: call void @use_ptr(ptr [[P2]])785; CHECK-NEXT: br label [[BB5]]786;787entry:788 %p2 = load ptr, ptr %p0, align 8789 %cmp1 = icmp eq ptr %p2, %p1790 br i1 %cmp1, label %bb4, label %bb1791 792bb1:793 switch i8 %s, label %bb2 [794 i8 0, label %bb1795 i8 1, label %bb3796 ]797 798bb2:799 unreachable800 801bb3:802 br label %bb4803 804bb4:805 %phi1 = phi ptr [ %p2, %entry ], [ poison, %bb3 ]806 %cmp2 = icmp eq ptr %phi1, %p1807 call void @use_bool(i1 %cmp2)808 br label %bb5809 810bb5:811 %phi2 = phi ptr [ poison, %bb5 ], [ %phi1, %bb4 ]812 call void @use_ptr(ptr %phi2)813 br label %bb5814}815 816define void @multiple_phi2(ptr %p0, ptr %p1, i8 %s) {817; CHECK-LABEL: @multiple_phi2(818; CHECK-NEXT: entry:819; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P0:%.*]], align 8820; CHECK-NEXT: [[CMP1:%.*]] = icmp eq ptr [[P2]], [[P1:%.*]]821; CHECK-NEXT: br i1 [[CMP1]], label [[BB4:%.*]], label [[BB1:%.*]]822; CHECK: bb1:823; CHECK-NEXT: switch i8 [[S:%.*]], label [[BB2:%.*]] [824; CHECK-NEXT: i8 0, label [[BB1]]825; CHECK-NEXT: i8 1, label [[BB3:%.*]]826; CHECK-NEXT: ]827; CHECK: bb2:828; CHECK-NEXT: br label [[BB4]]829; CHECK: bb3:830; CHECK-NEXT: br label [[BB4]]831; CHECK: bb4:832; CHECK-NEXT: call void @use_bool(i1 [[CMP1]])833; CHECK-NEXT: br label [[BB5:%.*]]834; CHECK: bb5:835; CHECK-NEXT: call void @use_ptr(ptr [[P2]])836; CHECK-NEXT: br label [[BB5]]837;838entry:839 %p2 = load ptr, ptr %p0, align 8840 %cmp1 = icmp eq ptr %p2, %p1841 br i1 %cmp1, label %bb4, label %bb1842 843bb1:844 switch i8 %s, label %bb2 [845 i8 0, label %bb1846 i8 1, label %bb3847 ]848 849bb2:850 br label %bb4851 852bb3:853 br label %bb4854 855bb4:856 %phi1 = phi ptr [ %p2, %entry ], [ %p2, %bb2 ], [ poison, %bb3 ]857 %cmp2 = icmp eq ptr %phi1, %p1858 call void @use_bool(i1 %cmp2)859 br label %bb5860 861bb5:862 %phi2 = phi ptr [ poison, %bb5 ], [ %phi1, %bb4 ]863 call void @use_ptr(ptr %phi2)864 br label %bb5865}866 867define void @select_same_obj(i1 %c, ptr %p, i64 %x) {868; CHECK-LABEL: @select_same_obj(869; CHECK-NEXT: entry:870; CHECK-NEXT: [[P2:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[X:%.*]]871; CHECK-NEXT: [[P3:%.*]] = select i1 [[C:%.*]], ptr [[P]], ptr [[P2]]872; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[P]], [[P3]]873; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[EXIT:%.*]]874; CHECK: if:875; CHECK-NEXT: call void @use_ptr(ptr [[P]])876; CHECK-NEXT: call void @use_ptr(ptr [[P]])877; CHECK-NEXT: ret void878; CHECK: exit:879; CHECK-NEXT: ret void880;881entry:882 %p2 = getelementptr i8, ptr %p, i64 %x883 %p3 = select i1 %c, ptr %p, ptr %p2884 %cmp = icmp eq ptr %p, %p3885 br i1 %cmp, label %if, label %exit886 887if:888 call void @use_ptr(ptr %p)889 call void @use_ptr(ptr %p3)890 ret void891 892exit:893 ret void894}895 896define void @select_different_obj(i1 %c, ptr %p, ptr %p2) {897; CHECK-LABEL: @select_different_obj(898; CHECK-NEXT: entry:899; CHECK-NEXT: [[P3:%.*]] = select i1 [[C:%.*]], ptr [[P:%.*]], ptr [[P2:%.*]]900; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[P]], [[P3]]901; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[EXIT:%.*]]902; CHECK: if:903; CHECK-NEXT: call void @use_ptr(ptr [[P]])904; CHECK-NEXT: call void @use_ptr(ptr [[P3]])905; CHECK-NEXT: ret void906; CHECK: exit:907; CHECK-NEXT: ret void908;909entry:910 %p3 = select i1 %c, ptr %p, ptr %p2911 %cmp = icmp eq ptr %p, %p3912 br i1 %cmp, label %if, label %exit913 914if:915 call void @use_ptr(ptr %p)916 call void @use_ptr(ptr %p3)917 ret void918 919exit:920 ret void921}922 923define void @select_same_obj_is_select(i1 %c, ptr %p, ptr %p2, i64 %x) {924; CHECK-LABEL: @select_same_obj_is_select(925; CHECK-NEXT: entry:926; CHECK-NEXT: [[P3:%.*]] = select i1 [[C:%.*]], ptr [[P:%.*]], ptr [[P2:%.*]]927; CHECK-NEXT: [[P4:%.*]] = getelementptr i8, ptr [[P3]], i64 [[X:%.*]]928; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[P3]], [[P4]]929; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[EXIT:%.*]]930; CHECK: if:931; CHECK-NEXT: call void @use_ptr(ptr [[P3]])932; CHECK-NEXT: call void @use_ptr(ptr [[P3]])933; CHECK-NEXT: ret void934; CHECK: exit:935; CHECK-NEXT: ret void936;937entry:938 %p3 = select i1 %c, ptr %p, ptr %p2939 %p4 = getelementptr i8, ptr %p3, i64 %x940 %cmp = icmp eq ptr %p3, %p4941 br i1 %cmp, label %if, label %exit942 943if:944 call void @use_ptr(ptr %p3)945 call void @use_ptr(ptr %p4)946 ret void947 948exit:949 ret void950}951 952define void @phi_same_obj(i1 %c, ptr %p, i64 %x) {953; CHECK-LABEL: @phi_same_obj(954; CHECK-NEXT: entry:955; CHECK-NEXT: [[P2:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[X:%.*]]956; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[JOIN:%.*]]957; CHECK: if:958; CHECK-NEXT: br label [[JOIN]]959; CHECK: join:960; CHECK-NEXT: [[P3:%.*]] = phi ptr [ [[P]], [[IF]] ], [ [[P2]], [[ENTRY:%.*]] ]961; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[P]], [[P3]]962; CHECK-NEXT: br i1 [[CMP]], label [[IF2:%.*]], label [[EXIT:%.*]]963; CHECK: if2:964; CHECK-NEXT: call void @use_ptr(ptr [[P]])965; CHECK-NEXT: call void @use_ptr(ptr [[P]])966; CHECK-NEXT: ret void967; CHECK: exit:968; CHECK-NEXT: ret void969;970entry:971 %p2 = getelementptr i8, ptr %p, i64 %x972 br i1 %c, label %if, label %join973 974if:975 br label %join976 977join:978 %p3 = phi ptr [ %p, %if ], [ %p2, %entry ]979 %cmp = icmp eq ptr %p, %p3980 br i1 %cmp, label %if2, label %exit981 982if2:983 call void @use_ptr(ptr %p)984 call void @use_ptr(ptr %p3)985 ret void986 987exit:988 ret void989}990 991define void @phi_different_obj(i1 %c, ptr %p, ptr %p2) {992; CHECK-LABEL: @phi_different_obj(993; CHECK-NEXT: entry:994; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[JOIN:%.*]]995; CHECK: if:996; CHECK-NEXT: br label [[JOIN]]997; CHECK: join:998; CHECK-NEXT: [[P3:%.*]] = phi ptr [ [[P:%.*]], [[IF]] ], [ [[P2:%.*]], [[ENTRY:%.*]] ]999; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[P]], [[P3]]1000; CHECK-NEXT: br i1 [[CMP]], label [[IF2:%.*]], label [[EXIT:%.*]]1001; CHECK: if2:1002; CHECK-NEXT: call void @use_ptr(ptr [[P]])1003; CHECK-NEXT: call void @use_ptr(ptr [[P3]])1004; CHECK-NEXT: ret void1005; CHECK: exit:1006; CHECK-NEXT: ret void1007;1008entry:1009 br i1 %c, label %if, label %join1010 1011if:1012 br label %join1013 1014join:1015 %p3 = phi ptr [ %p, %if ], [ %p2, %entry ]1016 %cmp = icmp eq ptr %p, %p31017 br i1 %cmp, label %if2, label %exit1018 1019if2:1020 call void @use_ptr(ptr %p)1021 call void @use_ptr(ptr %p3)1022 ret void1023 1024exit:1025 ret void1026}1027 1028define void @phi_same_obj_cycle(i1 %c, ptr %p, i64 %x) {1029; CHECK-LABEL: @phi_same_obj_cycle(1030; CHECK-NEXT: entry:1031; CHECK-NEXT: br label [[LOOP:%.*]]1032; CHECK: loop:1033; CHECK-NEXT: [[P_IV:%.*]] = phi ptr [ [[P:%.*]], [[ENTRY:%.*]] ], [ [[P_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]1034; CHECK-NEXT: [[P_NEXT]] = getelementptr i8, ptr [[P_IV]], i64 [[X:%.*]]1035; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[P_IV]], [[P]]1036; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[LOOP_LATCH]]1037; CHECK: if:1038; CHECK-NEXT: call void @use_ptr(ptr [[P]])1039; CHECK-NEXT: call void @use_ptr(ptr [[P]])1040; CHECK-NEXT: br label [[LOOP_LATCH]]1041; CHECK: loop.latch:1042; CHECK-NEXT: br label [[LOOP]]1043;1044entry:1045 br label %loop1046 1047loop:1048 %p.iv = phi ptr [ %p, %entry ], [ %p.next, %loop.latch ]1049 %p.next = getelementptr i8, ptr %p.iv, i64 %x1050 %cmp = icmp eq ptr %p.iv, %p1051 br i1 %cmp, label %if, label %loop.latch1052 1053if:1054 call void @use_ptr(ptr %p.iv)1055 call void @use_ptr(ptr %p)1056 br label %loop.latch1057 1058loop.latch:1059 br label %loop1060}1061 1062define i1 @not_cond(i1 %c) {1063; CHECK-LABEL: @not_cond(1064; CHECK-NEXT: [[C_NOT:%.*]] = xor i1 [[C:%.*]], true1065; CHECK-NEXT: br i1 [[C_NOT]], label [[IF:%.*]], label [[ELSE:%.*]]1066; CHECK: if:1067; CHECK-NEXT: ret i1 false1068; CHECK: else:1069; CHECK-NEXT: ret i1 true1070;1071 %c.not = xor i1 %c, true1072 br i1 %c.not, label %if, label %else1073 1074if:1075 ret i1 %c1076 1077else:1078 ret i1 %c1079}1080 1081define i32 @not_cond_icmp(i32 %x) {1082; CHECK-LABEL: @not_cond_icmp(1083; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 421084; CHECK-NEXT: [[CMP_NOT:%.*]] = xor i1 [[CMP]], true1085; CHECK-NEXT: br i1 [[CMP_NOT]], label [[IF:%.*]], label [[ELSE:%.*]]1086; CHECK: if:1087; CHECK-NEXT: ret i32 [[X]]1088; CHECK: else:1089; CHECK-NEXT: ret i32 421090;1091 %cmp = icmp eq i32 %x, 421092 %cmp.not = xor i1 %cmp, true1093 br i1 %cmp.not, label %if, label %else1094 1095if:1096 ret i32 %x1097 1098else:1099 ret i32 %x1100}1101 1102define i1 @not_cond_logic1(i1 %c, i1 %d) {1103; CHECK-LABEL: @not_cond_logic1(1104; CHECK-NEXT: [[C_NOT:%.*]] = xor i1 [[C:%.*]], true1105; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_NOT]], [[D:%.*]]1106; CHECK-NEXT: br i1 [[AND]], label [[IF:%.*]], label [[ELSE:%.*]]1107; CHECK: if:1108; CHECK-NEXT: ret i1 false1109; CHECK: else:1110; CHECK-NEXT: ret i1 [[C]]1111;1112 %c.not = xor i1 %c, true1113 %and = and i1 %c.not, %d1114 br i1 %and, label %if, label %else1115 1116if:1117 ret i1 %c1118 1119else:1120 ret i1 %c1121}1122 1123define i1 @not_cond_logic2(i1 %c, i1 %d) {1124; CHECK-LABEL: @not_cond_logic2(1125; CHECK-NEXT: [[C_NOT:%.*]] = xor i1 [[C:%.*]], true1126; CHECK-NEXT: [[AND:%.*]] = or i1 [[C_NOT]], [[D:%.*]]1127; CHECK-NEXT: br i1 [[AND]], label [[IF:%.*]], label [[ELSE:%.*]]1128; CHECK: if:1129; CHECK-NEXT: ret i1 [[C]]1130; CHECK: else:1131; CHECK-NEXT: ret i1 true1132;1133 %c.not = xor i1 %c, true1134 %or = or i1 %c.not, %d1135 br i1 %or, label %if, label %else1136 1137if:1138 ret i1 %c1139 1140else:1141 ret i1 %c1142}1143 1144declare void @use_bool(i1)1145declare void @use_ptr(ptr)1146