mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
[LoopUnroll] Add a test case for rG7873376bb36b.
rG7873376bb36b fixes a build failure for allyesconfig. The problem happened when the single exiting block doesn't dominate the loop latch, then the immediate dominator of the exit block should not be the exiting block after unrolling. As the exiting block of different unrolled iteration can branch to the exit block, and the ith exiting block doesn't dominate (i+1)th exiting block, the immediate dominator of the exit block should not the nearest common dominator of the exiting block and the loop latch of the same iteration. Differential Revision: https://reviews.llvm.org/D80477
This commit is contained in:
parent
727c874d62
commit
1badd023ca
@ -1,9 +1,12 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||
; RUN: opt < %s -loop-unroll -S | FileCheck %s
|
||||
; RUN: opt < %s -passes='require<opt-remark-emit>,unroll' -S | FileCheck %s
|
||||
; RUN: opt < %s -loop-unroll -unroll-runtime -unroll-count=4 -S | FileCheck %s
|
||||
; RUN: opt < %s -passes='require<opt-remark-emit>,unroll' -unroll-runtime -unroll-count=4 -S | FileCheck %s
|
||||
|
||||
define void @foo(i32* noalias %A) {
|
||||
; CHECK-LABEL: @foo(
|
||||
; Check that loop unroll pass correctly handle loops with
|
||||
; single exiting block not the loop header or latch.
|
||||
|
||||
define void @test1(i32* noalias %A) {
|
||||
; CHECK-LABEL: @test1(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 4
|
||||
; CHECK-NEXT: call void @bar(i32 [[TMP0]])
|
||||
@ -66,4 +69,91 @@ for.end:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Check that loop unroll pass correctly handle loops with
|
||||
; (1) exiting block not dominating the loop latch; and
|
||||
; (2) exiting terminator instructions cannot be simplified to unconditional.
|
||||
|
||||
define void @test2(i32* noalias %A) {
|
||||
; CHECK-LABEL: @test2(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: br i1 true, label [[FOR_PREHEADER:%.*]], label [[FOR_END:%.*]]
|
||||
; CHECK: for.preheader:
|
||||
; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A:%.*]], align 4
|
||||
; CHECK-NEXT: call void @bar(i32 [[TMP0]])
|
||||
; CHECK-NEXT: br label [[FOR_HEADER:%.*]]
|
||||
; CHECK: for.header:
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = phi i32 [ [[TMP0]], [[FOR_PREHEADER]] ], [ [[DOTPRE_3:%.*]], [[FOR_BODY_FOR_BODY_CRIT_EDGE_3:%.*]] ]
|
||||
; CHECK-NEXT: [[I:%.*]] = phi i64 [ 0, [[FOR_PREHEADER]] ], [ [[INC_3:%.*]], [[FOR_BODY_FOR_BODY_CRIT_EDGE_3]] ]
|
||||
; CHECK-NEXT: call void @bar(i32 [[TMP1]])
|
||||
; CHECK-NEXT: [[INC:%.*]] = add nuw nsw i64 [[I]], 1
|
||||
; CHECK-NEXT: br i1 true, label [[FOR_BODY:%.*]], label [[FOR_BODY_FOR_BODY_CRIT_EDGE:%.*]]
|
||||
; CHECK: for.body:
|
||||
; CHECK-NEXT: [[CMP:%.*]] = call i1 @foo(i64 [[I]])
|
||||
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY_FOR_BODY_CRIT_EDGE]], label [[FOR_END_LOOPEXIT:%.*]]
|
||||
; CHECK: for.body.for.body_crit_edge:
|
||||
; CHECK-NEXT: [[ARRAYIDX_PHI_TRANS_INSERT:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INC]]
|
||||
; CHECK-NEXT: [[DOTPRE:%.*]] = load i32, i32* [[ARRAYIDX_PHI_TRANS_INSERT]], align 4
|
||||
; CHECK-NEXT: call void @bar(i32 [[DOTPRE]])
|
||||
; CHECK-NEXT: [[INC_1:%.*]] = add nuw nsw i64 [[INC]], 1
|
||||
; CHECK-NEXT: br i1 true, label [[FOR_BODY_1:%.*]], label [[FOR_BODY_FOR_BODY_CRIT_EDGE_1:%.*]]
|
||||
; CHECK: for.end.loopexit:
|
||||
; CHECK-NEXT: br label [[FOR_END]]
|
||||
; CHECK: for.end:
|
||||
; CHECK-NEXT: ret void
|
||||
; CHECK: for.body.1:
|
||||
; CHECK-NEXT: [[CMP_1:%.*]] = call i1 @foo(i64 [[INC]])
|
||||
; CHECK-NEXT: br i1 [[CMP_1]], label [[FOR_BODY_FOR_BODY_CRIT_EDGE_1]], label [[FOR_END_LOOPEXIT]]
|
||||
; CHECK: for.body.for.body_crit_edge.1:
|
||||
; CHECK-NEXT: [[ARRAYIDX_PHI_TRANS_INSERT_1:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INC_1]]
|
||||
; CHECK-NEXT: [[DOTPRE_1:%.*]] = load i32, i32* [[ARRAYIDX_PHI_TRANS_INSERT_1]], align 4
|
||||
; CHECK-NEXT: call void @bar(i32 [[DOTPRE_1]])
|
||||
; CHECK-NEXT: [[INC_2:%.*]] = add nuw nsw i64 [[INC_1]], 1
|
||||
; CHECK-NEXT: br i1 true, label [[FOR_BODY_2:%.*]], label [[FOR_BODY_FOR_BODY_CRIT_EDGE_2:%.*]]
|
||||
; CHECK: for.body.2:
|
||||
; CHECK-NEXT: [[CMP_2:%.*]] = call i1 @foo(i64 [[INC_1]])
|
||||
; CHECK-NEXT: br i1 [[CMP_2]], label [[FOR_BODY_FOR_BODY_CRIT_EDGE_2]], label [[FOR_END_LOOPEXIT]]
|
||||
; CHECK: for.body.for.body_crit_edge.2:
|
||||
; CHECK-NEXT: [[ARRAYIDX_PHI_TRANS_INSERT_2:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INC_2]]
|
||||
; CHECK-NEXT: [[DOTPRE_2:%.*]] = load i32, i32* [[ARRAYIDX_PHI_TRANS_INSERT_2]], align 4
|
||||
; CHECK-NEXT: call void @bar(i32 [[DOTPRE_2]])
|
||||
; CHECK-NEXT: [[INC_3]] = add nsw i64 [[INC_2]], 1
|
||||
; CHECK-NEXT: br i1 true, label [[FOR_BODY_3:%.*]], label [[FOR_BODY_FOR_BODY_CRIT_EDGE_3]]
|
||||
; CHECK: for.body.3:
|
||||
; CHECK-NEXT: [[CMP_3:%.*]] = call i1 @foo(i64 [[INC_2]])
|
||||
; CHECK-NEXT: br i1 [[CMP_3]], label [[FOR_BODY_FOR_BODY_CRIT_EDGE_3]], label [[FOR_END_LOOPEXIT]]
|
||||
; CHECK: for.body.for.body_crit_edge.3:
|
||||
; CHECK-NEXT: [[ARRAYIDX_PHI_TRANS_INSERT_3:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INC_3]]
|
||||
; CHECK-NEXT: [[DOTPRE_3]] = load i32, i32* [[ARRAYIDX_PHI_TRANS_INSERT_3]], align 4
|
||||
; CHECK-NEXT: br label [[FOR_HEADER]], !llvm.loop !0
|
||||
;
|
||||
entry:
|
||||
br i1 true, label %for.preheader, label %for.end
|
||||
|
||||
for.preheader:
|
||||
%0 = load i32, i32* %A, align 4
|
||||
call void @bar(i32 %0)
|
||||
br label %for.header
|
||||
|
||||
for.header:
|
||||
%1 = phi i32 [ %0, %for.preheader ], [ %.pre, %for.body.for.body_crit_edge ]
|
||||
%i = phi i64 [ 0, %for.preheader ], [ %inc, %for.body.for.body_crit_edge ]
|
||||
%arrayidx = getelementptr inbounds i32, i32* %A, i64 %i
|
||||
call void @bar(i32 %1)
|
||||
%inc = add nsw i64 %i, 1
|
||||
br i1 true, label %for.body, label %for.body.for.body_crit_edge
|
||||
|
||||
for.body:
|
||||
%cmp = call i1 @foo(i64 %i)
|
||||
br i1 %cmp, label %for.body.for.body_crit_edge, label %for.end
|
||||
|
||||
for.body.for.body_crit_edge:
|
||||
%arrayidx.phi.trans.insert = getelementptr inbounds i32, i32* %A, i64 %inc
|
||||
%.pre = load i32, i32* %arrayidx.phi.trans.insert, align 4
|
||||
br label %for.header
|
||||
|
||||
for.end:
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @bar(i32)
|
||||
declare i1 @foo(i64)
|
||||
|
Loading…
x
Reference in New Issue
Block a user