brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.8 KiB · b42d538 Raw
256 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=loop-unroll -unroll-runtime -unroll-count=4 -S | FileCheck %s3; RUN: opt < %s -passes='require<opt-remark-emit>,loop-unroll' -unroll-runtime -unroll-count=4 -S | FileCheck %s4 5; Check that loop unroll pass correctly handle loops with6; single exiting block not the loop header or latch.7 8define void @test1(ptr noalias %A) {9; CHECK-LABEL: @test1(10; CHECK-NEXT:  entry:11; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[A:%.*]], align 412; CHECK-NEXT:    call void @bar(i32 [[TMP0]])13; CHECK-NEXT:    br label [[FOR_HEADER:%.*]]14; CHECK:       for.header:15; CHECK-NEXT:    call void @bar(i32 [[TMP0]])16; CHECK-NEXT:    br label [[FOR_BODY:%.*]]17; CHECK:       for.body:18; CHECK-NEXT:    br label [[FOR_BODY_FOR_BODY_CRIT_EDGE:%.*]]19; CHECK:       for.body.for.body_crit_edge:20; CHECK-NEXT:    [[ARRAYIDX_PHI_TRANS_INSERT:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 121; CHECK-NEXT:    [[DOTPRE:%.*]] = load i32, ptr [[ARRAYIDX_PHI_TRANS_INSERT]], align 422; CHECK-NEXT:    call void @bar(i32 [[DOTPRE]])23; CHECK-NEXT:    br label [[FOR_BODY_1:%.*]]24; CHECK:       for.body.1:25; CHECK-NEXT:    br label [[FOR_BODY_FOR_BODY_CRIT_EDGE_1:%.*]]26; CHECK:       for.body.for.body_crit_edge.1:27; CHECK-NEXT:    [[ARRAYIDX_PHI_TRANS_INSERT_1:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 228; CHECK-NEXT:    [[DOTPRE_1:%.*]] = load i32, ptr [[ARRAYIDX_PHI_TRANS_INSERT_1]], align 429; CHECK-NEXT:    call void @bar(i32 [[DOTPRE_1]])30; CHECK-NEXT:    br label [[FOR_BODY_2:%.*]]31; CHECK:       for.body.2:32; CHECK-NEXT:    br label [[FOR_BODY_FOR_BODY_CRIT_EDGE_2:%.*]]33; CHECK:       for.body.for.body_crit_edge.2:34; CHECK-NEXT:    [[ARRAYIDX_PHI_TRANS_INSERT_2:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 335; CHECK-NEXT:    [[DOTPRE_2:%.*]] = load i32, ptr [[ARRAYIDX_PHI_TRANS_INSERT_2]], align 436; CHECK-NEXT:    call void @bar(i32 [[DOTPRE_2]])37; CHECK-NEXT:    br label [[FOR_BODY_3:%.*]]38; CHECK:       for.body.3:39; CHECK-NEXT:    br i1 false, label [[FOR_BODY_FOR_BODY_CRIT_EDGE_3:%.*]], label [[FOR_END:%.*]]40; CHECK:       for.body.for.body_crit_edge.3:41; CHECK-NEXT:    unreachable42; CHECK:       for.end:43; CHECK-NEXT:    ret void44;45entry:46  %0 = load i32, ptr %A, align 447  call void @bar(i32 %0)48  br label %for.header49 50for.header:51  %1 = phi i32 [ %0, %entry ], [ %.pre, %for.body.for.body_crit_edge ]52  %i = phi i64 [ 0, %entry ], [ %inc, %for.body.for.body_crit_edge ]53  %arrayidx = getelementptr inbounds i32, ptr %A, i64 %i54  call void @bar(i32 %1)55  br label %for.body56 57for.body:58  %inc = add nsw i64 %i, 159  %cmp = icmp slt i64 %inc, 460  br i1 %cmp, label %for.body.for.body_crit_edge, label %for.end61 62for.body.for.body_crit_edge:63  %arrayidx.phi.trans.insert = getelementptr inbounds i32, ptr %A, i64 %inc64  %.pre = load i32, ptr %arrayidx.phi.trans.insert, align 465  br label %for.header66 67for.end:68  ret void69}70 71; Check that loop unroll pass correctly handle loops with72; (1) exiting block not dominating the loop latch; and73; (2) exiting terminator instructions cannot be simplified to unconditional.74 75define void @test2(ptr noalias %A) {76; CHECK-LABEL: @test2(77; CHECK-NEXT:  entry:78; CHECK-NEXT:    br i1 true, label [[FOR_PREHEADER:%.*]], label [[FOR_END:%.*]]79; CHECK:       for.preheader:80; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[A:%.*]], align 481; CHECK-NEXT:    call void @bar(i32 [[TMP0]])82; CHECK-NEXT:    br label [[FOR_HEADER:%.*]]83; CHECK:       for.header:84; CHECK-NEXT:    [[TMP1:%.*]] = phi i32 [ [[TMP0]], [[FOR_PREHEADER]] ], [ [[DOTPRE_3:%.*]], [[FOR_BODY_FOR_BODY_CRIT_EDGE_3:%.*]] ]85; CHECK-NEXT:    [[I:%.*]] = phi i64 [ 0, [[FOR_PREHEADER]] ], [ [[INC_3:%.*]], [[FOR_BODY_FOR_BODY_CRIT_EDGE_3]] ]86; CHECK-NEXT:    call void @bar(i32 [[TMP1]])87; CHECK-NEXT:    [[INC:%.*]] = add nuw nsw i64 [[I]], 188; CHECK-NEXT:    br i1 true, label [[FOR_BODY:%.*]], label [[FOR_BODY_FOR_BODY_CRIT_EDGE:%.*]]89; CHECK:       for.body:90; CHECK-NEXT:    [[CMP:%.*]] = call i1 @foo(i64 [[I]])91; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY_FOR_BODY_CRIT_EDGE]], label [[FOR_END_LOOPEXIT:%.*]]92; CHECK:       for.body.for.body_crit_edge:93; CHECK-NEXT:    [[ARRAYIDX_PHI_TRANS_INSERT:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INC]]94; CHECK-NEXT:    [[DOTPRE:%.*]] = load i32, ptr [[ARRAYIDX_PHI_TRANS_INSERT]], align 495; CHECK-NEXT:    call void @bar(i32 [[DOTPRE]])96; CHECK-NEXT:    [[INC_1:%.*]] = add nuw nsw i64 [[I]], 297; CHECK-NEXT:    br i1 true, label [[FOR_BODY_1:%.*]], label [[FOR_BODY_FOR_BODY_CRIT_EDGE_1:%.*]]98; CHECK:       for.body.1:99; CHECK-NEXT:    [[CMP_1:%.*]] = call i1 @foo(i64 [[INC]])100; CHECK-NEXT:    br i1 [[CMP_1]], label [[FOR_BODY_FOR_BODY_CRIT_EDGE_1]], label [[FOR_END_LOOPEXIT]]101; CHECK:       for.body.for.body_crit_edge.1:102; CHECK-NEXT:    [[ARRAYIDX_PHI_TRANS_INSERT_1:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INC_1]]103; CHECK-NEXT:    [[DOTPRE_1:%.*]] = load i32, ptr [[ARRAYIDX_PHI_TRANS_INSERT_1]], align 4104; CHECK-NEXT:    call void @bar(i32 [[DOTPRE_1]])105; CHECK-NEXT:    [[INC_2:%.*]] = add nuw nsw i64 [[I]], 3106; CHECK-NEXT:    br i1 true, label [[FOR_BODY_2:%.*]], label [[FOR_BODY_FOR_BODY_CRIT_EDGE_2:%.*]]107; CHECK:       for.body.2:108; CHECK-NEXT:    [[CMP_2:%.*]] = call i1 @foo(i64 [[INC_1]])109; CHECK-NEXT:    br i1 [[CMP_2]], label [[FOR_BODY_FOR_BODY_CRIT_EDGE_2]], label [[FOR_END_LOOPEXIT]]110; CHECK:       for.body.for.body_crit_edge.2:111; CHECK-NEXT:    [[ARRAYIDX_PHI_TRANS_INSERT_2:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INC_2]]112; CHECK-NEXT:    [[DOTPRE_2:%.*]] = load i32, ptr [[ARRAYIDX_PHI_TRANS_INSERT_2]], align 4113; CHECK-NEXT:    call void @bar(i32 [[DOTPRE_2]])114; CHECK-NEXT:    [[INC_3]] = add nsw i64 [[I]], 4115; CHECK-NEXT:    br i1 true, label [[FOR_BODY_3:%.*]], label [[FOR_BODY_FOR_BODY_CRIT_EDGE_3]]116; CHECK:       for.body.3:117; CHECK-NEXT:    [[CMP_3:%.*]] = call i1 @foo(i64 [[INC_2]])118; CHECK-NEXT:    br i1 [[CMP_3]], label [[FOR_BODY_FOR_BODY_CRIT_EDGE_3]], label [[FOR_END_LOOPEXIT]]119; CHECK:       for.body.for.body_crit_edge.3:120; CHECK-NEXT:    [[ARRAYIDX_PHI_TRANS_INSERT_3:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INC_3]]121; CHECK-NEXT:    [[DOTPRE_3]] = load i32, ptr [[ARRAYIDX_PHI_TRANS_INSERT_3]], align 4122; CHECK-NEXT:    br label [[FOR_HEADER]], !llvm.loop [[LOOP0:![0-9]+]]123; CHECK:       for.end.loopexit:124; CHECK-NEXT:    br label [[FOR_END]]125; CHECK:       for.end:126; CHECK-NEXT:    ret void127;128entry:129  br i1 true, label %for.preheader, label %for.end130 131for.preheader:132  %0 = load i32, ptr %A, align 4133  call void @bar(i32 %0)134  br label %for.header135 136for.header:137  %1 = phi i32 [ %0, %for.preheader ], [ %.pre, %for.body.for.body_crit_edge ]138  %i = phi i64 [ 0, %for.preheader ], [ %inc, %for.body.for.body_crit_edge ]139  %arrayidx = getelementptr inbounds i32, ptr %A, i64 %i140  call void @bar(i32 %1)141  %inc = add nsw i64 %i, 1142  br i1 true, label %for.body, label %for.body.for.body_crit_edge143 144for.body:145  %cmp = call i1 @foo(i64 %i)146  br i1 %cmp, label %for.body.for.body_crit_edge, label %for.end147 148for.body.for.body_crit_edge:149  %arrayidx.phi.trans.insert = getelementptr inbounds i32, ptr %A, i64 %inc150  %.pre = load i32, ptr %arrayidx.phi.trans.insert, align 4151  br label %for.header152 153for.end:154  ret void155}156 157; Check that loop unroll pass correctly handle loops with158; (1) multiple exiting blocks; and159; (2) loop latch is not an exiting block.160 161define void @test3(ptr noalias %A, i1 %cond) {162; CHECK-LABEL: @test3(163; CHECK-NEXT:  entry:164; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[A:%.*]], align 4165; CHECK-NEXT:    call void @bar(i32 [[TMP0]])166; CHECK-NEXT:    br label [[FOR_HEADER:%.*]]167; CHECK:       for.header:168; CHECK-NEXT:    call void @bar(i32 [[TMP0]])169; CHECK-NEXT:    br i1 [[COND:%.*]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]170; CHECK:       for.body:171; CHECK-NEXT:    br label [[FOR_BODY_FOR_BODY_CRIT_EDGE:%.*]]172; CHECK:       for.body.for.body_crit_edge:173; CHECK-NEXT:    [[ARRAYIDX_PHI_TRANS_INSERT:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 1174; CHECK-NEXT:    [[DOTPRE:%.*]] = load i32, ptr [[ARRAYIDX_PHI_TRANS_INSERT]], align 4175; CHECK-NEXT:    call void @bar(i32 [[DOTPRE]])176; CHECK-NEXT:    br i1 [[COND]], label [[FOR_BODY_1:%.*]], label [[FOR_END]]177; CHECK:       for.body.1:178; CHECK-NEXT:    br label [[FOR_BODY_FOR_BODY_CRIT_EDGE_1:%.*]]179; CHECK:       for.body.for.body_crit_edge.1:180; CHECK-NEXT:    [[ARRAYIDX_PHI_TRANS_INSERT_1:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 2181; CHECK-NEXT:    [[DOTPRE_1:%.*]] = load i32, ptr [[ARRAYIDX_PHI_TRANS_INSERT_1]], align 4182; CHECK-NEXT:    call void @bar(i32 [[DOTPRE_1]])183; CHECK-NEXT:    br i1 [[COND]], label [[FOR_BODY_2:%.*]], label [[FOR_END]]184; CHECK:       for.body.2:185; CHECK-NEXT:    br label [[FOR_BODY_FOR_BODY_CRIT_EDGE_2:%.*]]186; CHECK:       for.body.for.body_crit_edge.2:187; CHECK-NEXT:    [[ARRAYIDX_PHI_TRANS_INSERT_2:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 3188; CHECK-NEXT:    [[DOTPRE_2:%.*]] = load i32, ptr [[ARRAYIDX_PHI_TRANS_INSERT_2]], align 4189; CHECK-NEXT:    call void @bar(i32 [[DOTPRE_2]])190; CHECK-NEXT:    br i1 [[COND]], label [[FOR_BODY_3:%.*]], label [[FOR_END]]191; CHECK:       for.body.3:192; CHECK-NEXT:    br i1 false, label [[FOR_BODY_FOR_BODY_CRIT_EDGE_3:%.*]], label [[FOR_END]]193; CHECK:       for.body.for.body_crit_edge.3:194; CHECK-NEXT:    unreachable195; CHECK:       for.end:196; CHECK-NEXT:    ret void197;198entry:199  %0 = load i32, ptr %A, align 4200  call void @bar(i32 %0)201  br label %for.header202 203for.header:204  %1 = phi i32 [ %0, %entry ], [ %.pre, %for.body.for.body_crit_edge ]205  %i = phi i64 [ 0, %entry ], [ %inc, %for.body.for.body_crit_edge ]206  %arrayidx = getelementptr inbounds i32, ptr %A, i64 %i207  call void @bar(i32 %1)208  br i1 %cond, label %for.body, label %for.end209 210for.body:211  %inc = add nsw i64 %i, 1212  %cmp = icmp slt i64 %inc, 4213  br i1 %cmp, label %for.body.for.body_crit_edge, label %for.end214 215for.body.for.body_crit_edge:216  %arrayidx.phi.trans.insert = getelementptr inbounds i32, ptr %A, i64 %inc217  %.pre = load i32, ptr %arrayidx.phi.trans.insert, align 4218  br label %for.header219 220for.end:221  ret void222}223 224; Test it doesn't crash.225define void @test4(i32 %arg) {226; CHECK-LABEL: @test4(227; CHECK-NEXT:  bb:228; CHECK-NEXT:    br label [[BB1:%.*]]229; CHECK:       bb1:230; CHECK-NEXT:    br i1 false, label [[BB4:%.*]], label [[BB1_1:%.*]]231; CHECK:       bb1.1:232; CHECK-NEXT:    br i1 false, label [[BB4]], label [[BB1_2:%.*]]233; CHECK:       bb1.2:234; CHECK-NEXT:    br i1 false, label [[BB4]], label [[BB1_3:%.*]]235; CHECK:       bb1.3:236; CHECK-NEXT:    br i1 false, label [[BB4]], label [[BB1]], !llvm.loop [[LOOP2:![0-9]+]]237; CHECK:       bb4:238; CHECK-NEXT:    unreachable239;240bb:241  br label %bb1242 243bb1:                                              ; preds = %bb1, %bb244  %tmp = phi i64 [ 0, %bb ], [ 65, %bb1 ]245  %tmp2 = phi i32 [ %arg, %bb ], [ %tmp3, %bb1 ]246  %tmp3 = add i32 0, -1880031232247  br i1 false, label %bb4, label %bb1248 249bb4:                                              ; preds = %bb1250  unreachable251}252 253 254declare void @bar(i32)255declare i1 @foo(i64)256