brintos

brintos / llvm-project-archived public Read only

0
0
Text · 11.5 KiB · 94ad657 Raw
316 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes='simple-loop-unswitch<nontrivial>' -S < %s | FileCheck %s3; RUN: opt -passes='loop(simple-loop-unswitch<nontrivial>),verify<loops>' -S < %s | FileCheck %s4 5declare void @may_exit()6declare void @throw_npe()7 8; It is illegal to preserve make_implicit notion of the condition being9; unswitched because we may exit loop before we reach the condition, so10; there is no guarantee that following implicit branch always means getting11; to throw_npe block.12define i32 @test_should_drop_make_implicit(ptr %p1, ptr %p2) {13; CHECK-LABEL: @test_should_drop_make_implicit(14; CHECK-NEXT:  entry:15; CHECK-NEXT:    [[NULL_CHECK:%.*]] = icmp eq ptr [[P2:%.*]], null16; CHECK-NEXT:    [[NULL_CHECK_FR:%.*]] = freeze i1 [[NULL_CHECK]]17; CHECK-NEXT:    br i1 [[NULL_CHECK_FR]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]18; CHECK:       entry.split.us:19; CHECK-NEXT:    br label [[LOOP_US:%.*]]20; CHECK:       loop.us:21; CHECK-NEXT:    [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ]22; CHECK-NEXT:    [[X_US:%.*]] = load i32, ptr [[P1:%.*]], align 423; CHECK-NEXT:    [[SIDE_EXIT_COND_US:%.*]] = icmp eq i32 [[X_US]], 024; CHECK-NEXT:    br i1 [[SIDE_EXIT_COND_US]], label [[SIDE_EXIT_SPLIT_US:%.*]], label [[NULL_CHECK_BLOCK_US:%.*]]25; CHECK:       null_check_block.us:26; CHECK-NEXT:    br label [[THROW_NPE_SPLIT_US:%.*]]27; CHECK:       side_exit.split.us:28; CHECK-NEXT:    br label [[SIDE_EXIT:%.*]]29; CHECK:       throw_npe.split.us:30; CHECK-NEXT:    br label [[THROW_NPE:%.*]]31; CHECK:       entry.split:32; CHECK-NEXT:    br label [[LOOP:%.*]]33; CHECK:       loop:34; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]35; CHECK-NEXT:    [[X:%.*]] = load i32, ptr [[P1]], align 436; CHECK-NEXT:    [[SIDE_EXIT_COND:%.*]] = icmp eq i32 [[X]], 037; CHECK-NEXT:    br i1 [[SIDE_EXIT_COND]], label [[SIDE_EXIT_SPLIT:%.*]], label [[NULL_CHECK_BLOCK:%.*]]38; CHECK:       null_check_block:39; CHECK-NEXT:    br label [[BACKEDGE]]40; CHECK:       backedge:41; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 142; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], 1000043; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]44; CHECK:       side_exit.split:45; CHECK-NEXT:    br label [[SIDE_EXIT]]46; CHECK:       side_exit:47; CHECK-NEXT:    ret i32 048; CHECK:       throw_npe:49; CHECK-NEXT:    call void @throw_npe()50; CHECK-NEXT:    unreachable51; CHECK:       exit:52; CHECK-NEXT:    [[X_LCSSA2:%.*]] = phi i32 [ [[X]], [[BACKEDGE]] ]53; CHECK-NEXT:    ret i32 [[X_LCSSA2]]54;55entry:56  %null_check = icmp eq ptr %p2, null57  br label %loop58loop:59  %iv = phi i32 [0, %entry], [%iv.next, %backedge]60  %x = load i32, ptr %p161  %side_exit_cond = icmp eq i32 %x, 062  br i1 %side_exit_cond, label %side_exit, label %null_check_block63 64null_check_block:65  br i1 %null_check, label %throw_npe, label %backedge, !make.implicit !066 67backedge:68  %iv.next = add i32 %iv,169  %loop_cond = icmp slt i32 %iv.next, 1000070  br i1 %loop_cond, label %loop, label %exit71 72side_exit:73  ret i32 074 75throw_npe:76  call void @throw_npe()77  unreachable78 79exit:80  ret i32 %x81}82 83; Here make.implicit notion may be preserved because we always get to throw_npe84; after following true branch. This is a trivial unswitch.85define i32 @test_may_keep_make_implicit_trivial(ptr %p1, ptr %p2) {86; CHECK-LABEL: @test_may_keep_make_implicit_trivial(87; CHECK-NEXT:  entry:88; CHECK-NEXT:    [[NULL_CHECK:%.*]] = icmp eq ptr [[P2:%.*]], null89; CHECK-NEXT:    br i1 [[NULL_CHECK]], label [[THROW_NPE:%.*]], label [[ENTRY_SPLIT:%.*]], !make.implicit !090; CHECK:       entry.split:91; CHECK-NEXT:    br label [[LOOP:%.*]]92; CHECK:       loop:93; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]94; CHECK-NEXT:    [[X:%.*]] = load i32, ptr [[P1:%.*]], align 495; CHECK-NEXT:    [[SIDE_EXIT_COND:%.*]] = icmp eq i32 [[X]], 096; CHECK-NEXT:    br label [[SIDE_EXIT_BLOCK:%.*]]97; CHECK:       side_exit_block:98; CHECK-NEXT:    br i1 [[SIDE_EXIT_COND]], label [[SIDE_EXIT:%.*]], label [[BACKEDGE]]99; CHECK:       backedge:100; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1101; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], 10000102; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]103; CHECK:       side_exit:104; CHECK-NEXT:    ret i32 0105; CHECK:       throw_npe:106; CHECK-NEXT:    call void @throw_npe()107; CHECK-NEXT:    unreachable108; CHECK:       exit:109; CHECK-NEXT:    [[X_LCSSA2:%.*]] = phi i32 [ [[X]], [[BACKEDGE]] ]110; CHECK-NEXT:    ret i32 [[X_LCSSA2]]111;112entry:113  %null_check = icmp eq ptr %p2, null114  br label %loop115loop:116  %iv = phi i32 [0, %entry], [%iv.next, %backedge]117  %x = load i32, ptr %p1118  %side_exit_cond = icmp eq i32 %x, 0119  br i1 %null_check, label %throw_npe, label %side_exit_block, !make.implicit !0120 121side_exit_block:122  br i1 %side_exit_cond, label %side_exit, label %backedge123 124backedge:125  %iv.next = add i32 %iv,1126  %loop_cond = icmp slt i32 %iv.next, 10000127  br i1 %loop_cond, label %loop, label %exit128 129side_exit:130  ret i32 0131 132throw_npe:133  call void @throw_npe()134  unreachable135 136exit:137  ret i32 %x138}139 140define i32 @test_may_keep_make_implicit_non_trivial(ptr %p1, ptr %p2) {141; CHECK-LABEL: @test_may_keep_make_implicit_non_trivial(142; CHECK-NEXT:  entry:143; CHECK-NEXT:    [[NULL_CHECK:%.*]] = icmp eq ptr [[P2:%.*]], null144; CHECK-NEXT:    br i1 [[NULL_CHECK]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]], !make.implicit !0145; CHECK:       entry.split.us:146; CHECK-NEXT:    br label [[LOOP_US:%.*]]147; CHECK:       loop.us:148; CHECK-NEXT:    [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ]149; CHECK-NEXT:    [[X_US:%.*]] = load i32, ptr [[P1:%.*]], align 4150; CHECK-NEXT:    [[INNER_BLOCK_COND_US:%.*]] = icmp eq i32 [[X_US]], 0151; CHECK-NEXT:    br i1 [[INNER_BLOCK_COND_US]], label [[INNER_BLOCK_US:%.*]], label [[NULL_CHECK_BLOCK_US:%.*]]152; CHECK:       inner_block.us:153; CHECK-NEXT:    br label [[NULL_CHECK_BLOCK_US]]154; CHECK:       null_check_block.us:155; CHECK-NEXT:    br label [[THROW_NPE_SPLIT_US:%.*]]156; CHECK:       throw_npe.split.us:157; CHECK-NEXT:    br label [[THROW_NPE:%.*]]158; CHECK:       entry.split:159; CHECK-NEXT:    br label [[LOOP:%.*]]160; CHECK:       loop:161; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]162; CHECK-NEXT:    [[X:%.*]] = load i32, ptr [[P1]], align 4163; CHECK-NEXT:    [[INNER_BLOCK_COND:%.*]] = icmp eq i32 [[X]], 0164; CHECK-NEXT:    br i1 [[INNER_BLOCK_COND]], label [[INNER_BLOCK:%.*]], label [[NULL_CHECK_BLOCK:%.*]]165; CHECK:       inner_block:166; CHECK-NEXT:    br label [[NULL_CHECK_BLOCK]]167; CHECK:       null_check_block:168; CHECK-NEXT:    br label [[BACKEDGE]]169; CHECK:       backedge:170; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1171; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], 10000172; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]173; CHECK:       throw_npe:174; CHECK-NEXT:    call void @throw_npe()175; CHECK-NEXT:    unreachable176; CHECK:       exit:177; CHECK-NEXT:    [[X_LCSSA1:%.*]] = phi i32 [ [[X]], [[BACKEDGE]] ]178; CHECK-NEXT:    ret i32 [[X_LCSSA1]]179;180entry:181  %null_check = icmp eq ptr %p2, null182  br label %loop183loop:184  %iv = phi i32 [0, %entry], [%iv.next, %backedge]185  %x = load i32, ptr %p1186  %inner_block_cond = icmp eq i32 %x, 0187  br i1 %inner_block_cond, label %inner_block, label %null_check_block188 189inner_block:190  br label %null_check_block191 192null_check_block:193  br i1 %null_check, label %throw_npe, label %backedge, !make.implicit !0194 195backedge:196  %iv.next = add i32 %iv,1197  %loop_cond = icmp slt i32 %iv.next, 10000198  br i1 %loop_cond, label %loop, label %exit199 200throw_npe:201  call void @throw_npe()202  unreachable203 204exit:205  ret i32 %x206}207 208; Here make.implicit notion should be dropped because of exiting call.209define i32 @test_should_drop_make_implicit_exiting_call(ptr %p1, ptr %p2) {210; CHECK-LABEL: @test_should_drop_make_implicit_exiting_call(211; CHECK-NEXT:  entry:212; CHECK-NEXT:    [[NULL_CHECK:%.*]] = icmp eq ptr [[P2:%.*]], null213; CHECK-NEXT:    [[NULL_CHECK_FR:%.*]] = freeze i1 [[NULL_CHECK]]214; CHECK-NEXT:    br i1 [[NULL_CHECK_FR]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]215; CHECK:       entry.split.us:216; CHECK-NEXT:    br label [[LOOP_US:%.*]]217; CHECK:       loop.us:218; CHECK-NEXT:    [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ]219; CHECK-NEXT:    call void @may_exit()220; CHECK-NEXT:    [[X_US:%.*]] = load i32, ptr [[P1:%.*]], align 4221; CHECK-NEXT:    [[SIDE_EXIT_COND_US:%.*]] = icmp eq i32 [[X_US]], 0222; CHECK-NEXT:    br label [[THROW_NPE_SPLIT_US:%.*]]223; CHECK:       throw_npe.split.us:224; CHECK-NEXT:    br label [[THROW_NPE:%.*]]225; CHECK:       entry.split:226; CHECK-NEXT:    br label [[LOOP:%.*]]227; CHECK:       loop:228; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]229; CHECK-NEXT:    call void @may_exit()230; CHECK-NEXT:    [[X:%.*]] = load i32, ptr [[P1]], align 4231; CHECK-NEXT:    [[SIDE_EXIT_COND:%.*]] = icmp eq i32 [[X]], 0232; CHECK-NEXT:    br label [[BACKEDGE]]233; CHECK:       backedge:234; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1235; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], 10000236; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]237; CHECK:       throw_npe:238; CHECK-NEXT:    call void @throw_npe()239; CHECK-NEXT:    unreachable240; CHECK:       exit:241; CHECK-NEXT:    [[X_LCSSA1:%.*]] = phi i32 [ [[X]], [[BACKEDGE]] ]242; CHECK-NEXT:    ret i32 [[X_LCSSA1]]243;244entry:245  %null_check = icmp eq ptr %p2, null246  br label %loop247loop:248  %iv = phi i32 [0, %entry], [%iv.next, %backedge]249  call void @may_exit()250  %x = load i32, ptr %p1251  %side_exit_cond = icmp eq i32 %x, 0252  br i1 %null_check, label %throw_npe, label %backedge, !make.implicit !0253 254backedge:255  %iv.next = add i32 %iv,1256  %loop_cond = icmp slt i32 %iv.next, 10000257  br i1 %loop_cond, label %loop, label %exit258 259throw_npe:260  call void @throw_npe()261  unreachable262 263exit:264  ret i32 %x265}266 267; Here exiting call goes after the null check, so make.implicit may be preserved.268define i32 @test_may_keep_make_implicit_exiting_call(ptr %p1, ptr %p2) {269; CHECK-LABEL: @test_may_keep_make_implicit_exiting_call(270; CHECK-NEXT:  entry:271; CHECK-NEXT:    [[NULL_CHECK:%.*]] = icmp eq ptr [[P2:%.*]], null272; CHECK-NEXT:    br i1 [[NULL_CHECK]], label [[THROW_NPE:%.*]], label [[ENTRY_SPLIT:%.*]], !make.implicit !0273; CHECK:       entry.split:274; CHECK-NEXT:    br label [[LOOP:%.*]]275; CHECK:       loop:276; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]277; CHECK-NEXT:    [[X:%.*]] = load i32, ptr [[P1:%.*]], align 4278; CHECK-NEXT:    [[SIDE_EXIT_COND:%.*]] = icmp eq i32 [[X]], 0279; CHECK-NEXT:    br label [[BACKEDGE]]280; CHECK:       backedge:281; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1282; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], 10000283; CHECK-NEXT:    call void @may_exit()284; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]285; CHECK:       throw_npe:286; CHECK-NEXT:    call void @throw_npe()287; CHECK-NEXT:    unreachable288; CHECK:       exit:289; CHECK-NEXT:    [[X_LCSSA1:%.*]] = phi i32 [ [[X]], [[BACKEDGE]] ]290; CHECK-NEXT:    ret i32 [[X_LCSSA1]]291;292entry:293  %null_check = icmp eq ptr %p2, null294  br label %loop295loop:296  %iv = phi i32 [0, %entry], [%iv.next, %backedge]297  %x = load i32, ptr %p1298  %side_exit_cond = icmp eq i32 %x, 0299  br i1 %null_check, label %throw_npe, label %backedge, !make.implicit !0300 301backedge:302  %iv.next = add i32 %iv,1303  %loop_cond = icmp slt i32 %iv.next, 10000304  call void @may_exit()305  br i1 %loop_cond, label %loop, label %exit306 307throw_npe:308  call void @throw_npe()309  unreachable310 311exit:312  ret i32 %x313}314 315!0 = !{}316