1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-02-01 05:01:59 +01:00
llvm-mirror/test/Transforms/LoopInterchange/pr43176-move-to-new-latch.ll
Florian Hahn cc445a07d6 [LoopInterchange] Properly move condition, induction increment and ops to latch.
Currently we only rely on the induction increment to come before the
condition to ensure the required instructions get moved to the new
latch.

This patch duplicates and moves the required instructions to the
newly created latch. We move the condition to the end of the new block,
then process its operands. We stop at operands that are defined
outside the loop, or are the induction PHI.

We duplicate the instructions and update the uses in the moved
instructions, to ensure other users remain intact. See the added
test2 for such an example.

Reviewers: efriedma, mcrosier

Reviewed By: efriedma

Differential Revision: https://reviews.llvm.org/D67367

llvm-svn: 371595
2019-09-11 08:23:23 +00:00

141 lines
6.0 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -loop-interchange -verify-loop-lcssa -verify-dom-info -S %s | FileCheck %s
@b = external dso_local global [5 x i32], align 16
define void @test1() {
; CHECK-LABEL: @test1(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[FOR_BODY2_PREHEADER:%.*]]
; CHECK: for.body.preheader:
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
; CHECK: for.body:
; CHECK-NEXT: [[INC41:%.*]] = phi i32 [ [[INC4:%.*]], [[FOR_INC3:%.*]] ], [ undef, [[FOR_BODY_PREHEADER:%.*]] ]
; CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[INC41]] to i64
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [5 x i32], [5 x i32]* @b, i64 0, i64 [[IDXPROM]]
; CHECK-NEXT: br label [[FOR_BODY2_SPLIT:%.*]]
; CHECK: for.body2.preheader:
; CHECK-NEXT: br label [[FOR_BODY2:%.*]]
; CHECK: for.body2:
; CHECK-NEXT: [[LSR_IV:%.*]] = phi i32 [ [[TMP1:%.*]], [[FOR_INC_SPLIT:%.*]] ], [ 1, [[FOR_BODY2_PREHEADER]] ]
; CHECK-NEXT: br label [[FOR_BODY_PREHEADER]]
; CHECK: for.body2.split:
; CHECK-NEXT: br label [[FOR_INC:%.*]]
; CHECK: for.inc:
; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
; CHECK-NEXT: store i32 undef, i32* [[ARRAYIDX]], align 4
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[LSR_IV]], 4
; CHECK-NEXT: [[LSR_IV_NEXT:%.*]] = add nuw nsw i32 [[LSR_IV]], 1
; CHECK-NEXT: br label [[FOR_COND1_FOR_END_CRIT_EDGE:%.*]]
; CHECK: for.inc.split:
; CHECK-NEXT: [[TMP1]] = add nuw nsw i32 [[LSR_IV]], 1
; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[LSR_IV]], 4
; CHECK-NEXT: br i1 [[TMP2]], label [[FOR_BODY2]], label [[FOR_COND_FOR_END5_CRIT_EDGE:%.*]]
; CHECK: for.cond1.for.end_crit_edge:
; CHECK-NEXT: br label [[FOR_INC3]]
; CHECK: for.inc3:
; CHECK-NEXT: [[INC4]] = add nsw i32 [[INC41]], 1
; CHECK-NEXT: br i1 false, label [[FOR_BODY]], label [[FOR_INC_SPLIT]]
; CHECK: for.cond.for.end5_crit_edge:
; CHECK-NEXT: ret void
;
entry:
br label %for.body
for.body: ; preds = %for.inc3, %entry
%inc41 = phi i32 [ %inc4, %for.inc3 ], [ undef, %entry ]
br label %for.body2
for.body2: ; preds = %for.inc, %for.body
%lsr.iv = phi i32 [ %lsr.iv.next, %for.inc ], [ 1, %for.body ]
br label %for.inc
for.inc: ; preds = %for.body2
%idxprom = sext i32 %inc41 to i64
%arrayidx = getelementptr inbounds [5 x i32], [5 x i32]* @b, i64 0, i64 %idxprom
%0 = load i32, i32* %arrayidx, align 4
store i32 undef, i32* %arrayidx, align 4
%cmp = icmp slt i32 %lsr.iv, 4
%lsr.iv.next = add nuw nsw i32 %lsr.iv, 1
br i1 %cmp, label %for.body2, label %for.cond1.for.end_crit_edge
for.cond1.for.end_crit_edge: ; preds = %for.inc
br label %for.inc3
for.inc3: ; preds = %for.cond1.for.end_crit_edge
%inc4 = add nsw i32 %inc41, 1
br i1 undef, label %for.body, label %for.cond.for.end5_crit_edge
for.cond.for.end5_crit_edge: ; preds = %for.inc3
ret void
}
define void @test2() {
; CHECK-LABEL: @test2(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[FOR_BODY2_PREHEADER:%.*]]
; CHECK: for.body.preheader:
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
; CHECK: for.body:
; CHECK-NEXT: [[INC41:%.*]] = phi i32 [ [[INC4:%.*]], [[FOR_INC3:%.*]] ], [ undef, [[FOR_BODY_PREHEADER:%.*]] ]
; CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[INC41]] to i64
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [5 x i32], [5 x i32]* @b, i64 0, i64 [[IDXPROM]]
; CHECK-NEXT: br label [[FOR_BODY2_SPLIT:%.*]]
; CHECK: for.body2.preheader:
; CHECK-NEXT: br label [[FOR_BODY2:%.*]]
; CHECK: for.body2:
; CHECK-NEXT: [[LSR_IV:%.*]] = phi i32 [ [[TMP1:%.*]], [[FOR_INC_SPLIT:%.*]] ], [ 1, [[FOR_BODY2_PREHEADER]] ]
; CHECK-NEXT: br label [[FOR_BODY_PREHEADER]]
; CHECK: for.body2.split:
; CHECK-NEXT: br label [[FOR_INC:%.*]]
; CHECK: for.inc:
; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[LSR_IV]], 4
; CHECK-NEXT: [[CMP_ZEXT:%.*]] = zext i1 [[CMP]] to i32
; CHECK-NEXT: store i32 [[CMP_ZEXT]], i32* [[ARRAYIDX]], align 4
; CHECK-NEXT: [[LSR_IV_NEXT:%.*]] = add nuw nsw i32 [[LSR_IV]], 1
; CHECK-NEXT: br label [[FOR_COND1_FOR_END_CRIT_EDGE:%.*]]
; CHECK: for.inc.split:
; CHECK-NEXT: [[TMP1]] = add nuw nsw i32 [[LSR_IV]], 1
; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[LSR_IV]], 4
; CHECK-NEXT: br i1 [[TMP2]], label [[FOR_BODY2]], label [[FOR_COND_FOR_END5_CRIT_EDGE:%.*]]
; CHECK: for.cond1.for.end_crit_edge:
; CHECK-NEXT: br label [[FOR_INC3]]
; CHECK: for.inc3:
; CHECK-NEXT: [[INC4]] = add nsw i32 [[INC41]], 1
; CHECK-NEXT: br i1 false, label [[FOR_BODY]], label [[FOR_INC_SPLIT]]
; CHECK: for.cond.for.end5_crit_edge:
; CHECK-NEXT: ret void
;
entry:
br label %for.body
for.body: ; preds = %for.inc3, %entry
%inc41 = phi i32 [ %inc4, %for.inc3 ], [ undef, %entry ]
br label %for.body2
for.body2: ; preds = %for.inc, %for.body
%lsr.iv = phi i32 [ %lsr.iv.next, %for.inc ], [ 1, %for.body ]
br label %for.inc
for.inc: ; preds = %for.body2
%idxprom = sext i32 %inc41 to i64
%arrayidx = getelementptr inbounds [5 x i32], [5 x i32]* @b, i64 0, i64 %idxprom
%0 = load i32, i32* %arrayidx, align 4
%cmp = icmp slt i32 %lsr.iv, 4
%cmp.zext = zext i1 %cmp to i32
store i32 %cmp.zext, i32* %arrayidx, align 4
%lsr.iv.next = add nuw nsw i32 %lsr.iv, 1
br i1 %cmp, label %for.body2, label %for.cond1.for.end_crit_edge
for.cond1.for.end_crit_edge: ; preds = %for.inc
br label %for.inc3
for.inc3: ; preds = %for.cond1.for.end_crit_edge
%inc4 = add nsw i32 %inc41, 1
br i1 undef, label %for.body, label %for.cond.for.end5_crit_edge
for.cond.for.end5_crit_edge: ; preds = %for.inc3
ret void
}