1
0
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:
Whitney Tsang 2020-05-30 20:24:10 +00:00
parent 727c874d62
commit 1badd023ca

View File

@ -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)